WebService Context menu via Grid selection (no root node)

21 posts, 0 answers
  1. Stephane Zanoni
    Stephane Zanoni avatar
    23 posts
    Member since:
    Jul 2005

    Posted 05 Mar 2008 Link to this post

    I'm relatively new to the AJAX RadControl set, so bear with me.

    I've been successful getting an ObjectDataSource displaying properly into the RadGrid control (not using any AJAX yet) and when the user right-clicks or clicks a node a context menu is displayed.

    I've followed the Menu webservice example but the example is limited to displaying a root node, then getting the child nodes via a webservice call.

    How can I have the entire menu be driven via the webservice call?

    Maybe I need to use a Window+Menu ?  Any ideas to get me passed this hurtle would be appreciated.

    It doesn't need to be driven via a WebService call, any other AJAXy way is fine.


    Stéphane
  2. Peter
    Admin
    Peter avatar
    6637 posts

    Posted 06 Mar 2008 Link to this post

    Hello Stephane,

    If I understand you correctly, you want to display different root menu items based on what grid row was clicked. In other words, the menu is not created until a row is clicked. If that's the case, then I suggest you use the client API of RadMenu to create the items in the OnClientShowing event of the control. Here is a simple example:

     <script type="text/javascript">  
            function CreateRootItems(sender)  
            {  
                var menu = sender;  
                menu.trackChanges();  
                var rootItem = new Telerik.Web.UI.RadMenuItem();  
                rootItem.set_text("root item");  
                menu.get_items().add(rootItem);  
                menu.commitChanges();  
            }          
            </script> 
            <telerik:RadContextMenu ID="RadContextMenu1" OnClientShowing="CreateRootItems" 

    Also, I guess you will have to clear the items each time you show the menu. For implementation details, please see the Add / Remove / Disable Items online example.

    I hope this helps.



    Best wishes,
    Peter
    the Telerik team

    Instantly find answers to your questions at the new Telerik Support Center
  3. Stephane Zanoni
    Stephane Zanoni avatar
    23 posts
    Member since:
    Jul 2005

    Posted 06 Mar 2008 Link to this post

    Thank you, Peter.

    You described pretty much what I am looking for.  How would I go about calling the webservice from the client api to retrieve the RadMenuItem the same way as when the node is set to ExpandMode="WebService"?

    Stéphane
  4. Peter
    Admin
    Peter avatar
    6637 posts

    Posted 07 Mar 2008 Link to this post

    Hello Stephane,

    Please, find attached a simple project which demonstrates the desired functionality. Below is the aspx code with key hightlights to help you follow the logic of the implementation.

    <html xmlns="http://www.w3.org/1999/xhtml">  
    <head runat="server">  
        <title>Untitled Page</title> 
        <script type="text/javascript">   
            function itemPopulating(sender, eventArgs)  
            {  
                var item = eventArgs.get_item();  
                var context = eventArgs.get_context();  
                context["CategoryID"] = item.get_value();  
            }         
             function CreateRootItems(sender)     
            {     
                var menu = sender;     
                menu.trackChanges();     
                var rootItem = new Telerik.Web.UI.RadMenuItem();     
                rootItem.set_text("Products");   
                rootItem.set_value("1");  
                rootItem.set_expandMode(Telerik.Web.UI.MenuItemExpandMode.WebService);    
                menu.get_items().add(rootItem);     
                menu.commitChanges();  
            }   
            function ClearItems(sender)  
            {  
                var menu = sender;  
                //debugger;  
                menu.get_items().clear()              
            }         
     
        </script> 
    </head> 
    <body> 
        <form id="form1" runat="server">  
            <asp:ScriptManager ID="ScriptManager" runat="server"></asp:ScriptManager>         
            <telerik:RadContextMenu ID="RadContextMenu1" OnClientItemPopulating="itemPopulating" OnClientHidden="ClearItems" OnClientShowing="CreateRootItems" runat="server" Flow="Horizontal">  
                <WebServiceSettings Path="ProductCategories.asmx" Method="GetMenuCategories" /> 
                <ExpandAnimation Type="OutQuart" /> 
                <DefaultGroupSettings ExpandDirection="Auto" Flow="Vertical" /> 
                <CollapseAnimation Duration="200" Type="OutQuint" />              
                <Targets> 
                <telerik:ContextMenuControlTarget ControlID="Label1" /> 
                </Targets> 
            </telerik:RadContextMenu> 
            <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label> 
        </form> 
    </body> 
    </html> 
     

    Feel free to contact us if you have any questions.


    All the best,
    Peter
    the Telerik team

    Instantly find answers to your questions at the new Telerik Support Center
  5. Stephane Zanoni
    Stephane Zanoni avatar
    23 posts
    Member since:
    Jul 2005

    Posted 08 Mar 2008 Link to this post

    Peter, thank you for the example. 

    However, my objective is not to have any "hard-coded" root node either in JS or the ASPX.  The entire menu needs to come via the web service request.  In our scenario, we have our entire menu based on the type of item which appears in the grid.


    Stéphane
  6. Peter
    Admin
    Peter avatar
    6637 posts

    Posted 11 Mar 2008 Link to this post

    Hello Stephane,

    Please, find attached an example. The demo creates a webservice loader in the OnClientShowing event and loads the root items. The children are loaded in the standard RadMenu way - by using the WebServiceSettings property of the RadContextMenu.


    All the best,
    Peter
    the Telerik team

    Instantly find answers to your questions at the new Telerik Support Center
  7. Stephane Zanoni
    Stephane Zanoni avatar
    23 posts
    Member since:
    Jul 2005

    Posted 11 Mar 2008 Link to this post

    Peter, Thank you!

    That's awesome!  I have been looking around the site for any documentation related to the Telerik.Web.UI.WebServiceLoader and can't seem to find anything.

    I'd like to add the loader to the process.

    Is there a direction you could point me at?  Searching the forum, site, documentation for WebServiceLoader has yielded no results.


    Stéphane
  8. Peter
    Admin
    Peter avatar
    6637 posts

    Posted 11 Mar 2008 Link to this post

    Hi Stephane,

    Loading root items via web service is not supported out-of-the box. WebServiceLoader is an internal class which we have used for this workaround and that is why it is not documented.

    Regards,
    Peter
    the Telerik team

    Instantly find answers to your questions at the new Telerik Support Center
  9. Keith Henkel
    Keith Henkel avatar
    23 posts
    Member since:
    Dec 2006

    Posted 10 Apr 2008 Link to this post

    Thank you! This is exactly what I need. I'm now populating a context menu via a web service based on which grid cell the mouse click occurred on.

    But... I'm getting an error I can't figure out. When clicking one of the context menu items, I get this error and the server event handler is never hit:

    Unable to cast object of type 'System.Boolean' to type 'System.String'.

    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

    Exception Details: System.InvalidCastException: Unable to cast object of type 'System.Boolean' to type 'System.String'.

    Source Error:

    An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

    Stack Trace:

    [InvalidCastException: Unable to cast object of type 'System.Boolean' to type 'System.String'.]
    Telerik.Web.UI.RadMenuItem.LoadFromDictionary(IDictionary`2 dictionary) +688
    Telerik.Web.UI.ClientStateLogPlayer.Insert(ClientStateLogEntry entry) +156
    Telerik.Web.UI.ClientStateLogPlayer.Play(ClientStateLogEntry entry) +84
    Telerik.Web.UI.ClientStateLogPlayer.Play(IEnumerable`1 clientStateLogEntry) +106
    Telerik.Web.UI.RadMenu.LoadClientState(RadMenuClientState clientState) +132
    Telerik.Web.UI.RadMenu.LoadPostData(String postDataKey, NameValueCollection postCollection) +210
    Telerik.Web.UI.RadDataBoundControl.System.Web.UI.IPostBackDataHandler.LoadPostData(String postDataKey, NameValueCollection postCollection) +59
    System.Web.UI.Page.ProcessPostData(NameValueCollection postData, Boolean fBeforeLoad) +661
    System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1575

    Do you know what would cause this? My situation is almost identical to the ContextMenuWebServicePopulation.zip example. I am clearing the menu items collection on each right-click and then repopulating it from the web service though.

    Thank you,
    Terry

  10. Stephane Zanoni
    Stephane Zanoni avatar
    23 posts
    Member since:
    Jul 2005

    Posted 10 Apr 2008 Link to this post

    Keith,

    I see a similar error every once and a while, I have not yet determined the exact cause.

    If you get anywhere on this, I'd love to know.


    Stéphane
  11. Keith Henkel
    Keith Henkel avatar
    23 posts
    Member since:
    Dec 2006

    Posted 10 Apr 2008 Link to this post

    If I only have a static menu item on the menu then the ItemClick event handler will be called on the server, but if I add at least one dynamic menu item as a result of the web service call I get the exception listed further above. The same is true whether I click on the static item or the dynamic one.


  12. Keith Henkel
    Keith Henkel avatar
    23 posts
    Member since:
    Dec 2006

    Posted 10 Apr 2008 Link to this post

    I think I found a pattern that works. First, I have to define one context menu item at design time. It gets cleared out since I'm repopulating all the menu items after returning from the web service, but at least one item has to be there initially. Then, the dynamically added menu items can't include a menu separator. If I do both of those things then it works and my ItemClick event handler gets called on the server. Otherwise, I get the aforementioned exception.

    I think I can live with these two restrictions unless there is a work-around. Is this something I can expect to be stable? Or could the exception start happening randomly at some point?

    Thank you

  13. Keith Henkel
    Keith Henkel avatar
    23 posts
    Member since:
    Dec 2006

    Posted 11 Apr 2008 Link to this post

    I've abandoned this altogether. It's just not going to work.

    The images within the context menu don't render correctly when added dynamically like this. (They change appearance when you hover over them.) Also, we really need the menu separators.
  14. T. Tsonev
    Admin
    T. Tsonev avatar
    2831 posts

    Posted 13 Apr 2008 Link to this post

    Hello Keith,

    I can confirm the issue with dynamically added items with images. We have recently discovered it and we have fixed it. The fix will be included in the official Q1 release next week.

    We will investigate the other two issues and we will try to fix them in time for the release.

    Regards,
    Tsvetomir Tsonev
    the Telerik team

    Instantly find answers to your questions at the new Telerik Support Center
  15. Stephane Zanoni
    Stephane Zanoni avatar
    23 posts
    Member since:
    Jul 2005

    Posted 13 Apr 2008 Link to this post

    That's great news, I look forward to the update.

    The other issues that have been plaguing our dynamic menu are:

    - Menu item sizes don't grow to 100% of the menu, so every item in the context menu has a different width, makes it a little odd.

    - ImageURL causes a second line to draw, for every menu item and doesn't display the image on the "real" menu item until the hover.

    - Menu separators do not display as seperators but normal menu items with no text.  (yes, we've set the IsSeperator = true)

    Any insight into these remaining issues would be great.

    Thank you.
  16. T. Tsonev
    Admin
    T. Tsonev avatar
    2831 posts

    Posted 14 Apr 2008 Link to this post

    Hello Stephane,

    Thanks for the detailed bug report. We have corrected all three issues and the fix will be included in the official Q1 release. Your Telerik points have been updated for your involvement.

    All the best,
    Tsvetomir Tsonev
    the Telerik team

    Instantly find answers to your questions at the new Telerik Support Center
  17. Stephane Zanoni
    Stephane Zanoni avatar
    23 posts
    Member since:
    Jul 2005

    Posted 19 Apr 2008 Link to this post

    Thank you, these all looked fixed.  The menu now looks pretty spiffy!

    Great stuff!
  18. Stephane Zanoni
    Stephane Zanoni avatar
    23 posts
    Member since:
    Jul 2005

    Posted 22 Apr 2008 Link to this post

    I'm still getting this error on a form post after having shown the context menu....

    This is being very problematic!

    [InvalidCastException]: Unable to cast object of type 'System.Boolean' to type 'System.String'.
       at Telerik.Web.UI.RadMenuItem.LoadFromDictionary(IDictionary`2 dictionary)
       at Telerik.Web.UI.ClientStateLogPlayer.Insert(ClientStateLogEntry entry)
       at Telerik.Web.UI.ClientStateLogPlayer.Play(ClientStateLogEntry entry)
       at Telerik.Web.UI.ClientStateLogPlayer.Play(IEnumerable`1 clientStateLogEntry)
       at Telerik.Web.UI.RadMenu.LoadClientState(RadMenuClientState clientState)
       at Telerik.Web.UI.RadMenu.LoadPostData(String postDataKey, NameValueCollection postCollection)
       at Telerik.Web.UI.RadDataBoundControl.System.Web.UI.IPostBackDataHandler.LoadPostData(String postDataKey, NameValueCollection postCollection)
       at System.Web.UI.Page.ProcessPostData(NameValueCollection postData, Boolean fBeforeLoad)
       at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
    [HttpUnhandledException]: Exception of type 'System.Web.HttpUnhandledException' was thrown.
       at System.Web.UI.Page.HandleError(Exception e)
       at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
       at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
       at System.Web.UI.Page.ProcessRequest()
       at System.Web.UI.Page.ProcessRequestWithNoAssert(HttpContext context)
       at System.Web.UI.Page.ProcessRequest(HttpContext context)
       at ASP.helpdesk_aspx.ProcessRequest(HttpContext context) in c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\root\367f47dd\8cacbb25\App_Web_yzizdaec.0.cs:line 0
       at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
       at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
  19. Atanas Korchev
    Admin
    Atanas Korchev avatar
    8462 posts

    Posted 22 Apr 2008 Link to this post

    Hi Stephane Zanoni,

    This is exception is due to a bug introduced in the Q1 2008 release. Please open a support ticket so we can send you a hotfix.

    Regards,
    Albert
    the Telerik team

    Instantly find answers to your questions at the new Telerik Support Center
  20. Stephane Zanoni
    Stephane Zanoni avatar
    23 posts
    Member since:
    Jul 2005

    Posted 22 Apr 2008 Link to this post

    fyi;  ticket ID is : 133695
  21. Greg Chung
    Greg Chung avatar
    48 posts
    Member since:
    Jul 2006

    Posted 24 Jun 2008 Link to this post

    I know this is an older thread, but I found the sample code in ContextMenuWebServicePopulation.zip to be extremely useful.  I'd like to add a small bit of knowledge to the example so that it might help others as well.

    In the example, the following script is used to populate the menu via the web service:
    1 function onClientContextMenuShowing(sender) 
    2
    3     var menu = sender; 
    4      
    5     if (!menu._itemsLoaded) 
    6     { 
    7         var webServiceSettings = new Telerik.Web.UI.WebServiceSettings({}) 
    8         webServiceSettings.set_path("GridContextMenuWebService.asmx"); 
    9         webServiceSettings.set_method("GetContextMenuItems"); 
    10  
    11         var webServiceLoader = new Telerik.Web.UI.WebServiceLoader(webServiceSettings); 
    12         webServiceLoader.add_loadingSuccess(webServiceLoadingSuccess); 
    13  
    14         var itemData = { Text: "ContextMenu1", Value: "ContextMenu1"};   
    15         var params = { item: itemData, context: {}}; 
    16  
    17         webServiceLoader.loadData(params, menu) 
    18         menu._itemsLoaded = true
    19     }        
    20

    The RadContextMenu is defined in the aspx with the setting:
    <WebServiceSettings Path="GridContextMenuWebService.asmx" Method="GetContextMenuItems" /> 

    So, in the script, lines 8 & 9, it'd be better to read the web service settings from the menu object instead of duplicating the path and method values in the function:
    8     webServiceSettings.set_path( menu.get_webServiceSettings().get_path() ); 
    9     webServiceSettings.set_method( menu.get_webServiceSettings().get_method() ); 


    I hope this helps someone like this old post helped me :)

Back to Top