Dynamic ContextMenu via UpdatePanel

12 posts, 0 answers
  1. terrysmith
    terrysmith avatar
    129 posts
    Member since:
    Nov 2006

    Posted 11 Apr 2008 Link to this post

    I am trying to get functionality that used to work before Prometheus working using the new controls.

    We need to dynamically populate a context menu based on which grid cell the right-click occurs upon. We have the context menu within a RadAjaxPanel and before we were using Javascript fired on the right-click to update the RadAjaxPanel, build the context menu, and then display the menu.

    Now that we're using the Prometheus RadAjaxPanel and RadContextMenu I get this error at page load:

    The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>).

    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.Web.HttpException: The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>).

    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:

    [HttpException (0x80004005): The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>).]
    System.Web.UI.ControlCollection.AddAt(Int32 index, Control child) +2108046
    Telerik.Web.UI.RadAjaxControl.MoveUpdatePanel(Control initiator, Control updated) +207
    Telerik.Web.UI.RadAjaxControl.PerformRender() +403
    Telerik.Web.UI.RadAjaxControl.OnPageRender(HtmlTextWriter writer, Control page) +1473
    Telerik.Web.UI.RadAjaxControl.RenderPageInAjaxMode(HtmlTextWriter writer, Control page) +124
    System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +98
    System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +20
    System.Web.UI.Page.Render(HtmlTextWriter writer) +26
    System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +25
    System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +121
    System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +22
    System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2558


    If I replace the RadAjaxPanel with a Microsoft UpdatePanel the problem goes away. However, that creates another problem for us. During the server update of the update panel we place Javascript within it in order to display the context menu in the right position when the update page returns. The RadAjaxPanel let us do that and the Javascript would get executed. The Microsoft UpdatePanel just ignores it.

    I've tried calling a Javascript function within the RadContextMenu's OnClientLoad to show the menu, but that results in yet another error. It breaks within the Telerik Javascript on something to do with the slide animation of displaying the menu. I tried setting the animation to "None", but that didn't resolve it. I suspect the real problem in this case is that menu isn't fully loaded yet, and I'm tyring to call showAt within the load event.

    So my question is.... Is there a workaround to the first problem? If not, is there an alternative solution to the second problem?

    Building the context menu using  a web service would be ideal, but I pursued that as documented in another thread and never got it to work. I know that behavior wasn't officially supported anyway. Even still, I've lost a week of work trying to get this problem fixed.

    Any help would be appreciated.

    Thanks,
    Terry


  2. Erjan Gavalji
    Admin
    Erjan Gavalji avatar
    1455 posts

    Posted 14 Apr 2008 Link to this post

    Hi Terry,

    You can use the RadScriptBlock control for the purpose.

    As a side note, another approach might be to create the items entirely on the client.

    Let me know if that helps.

    Kind regards,
    Erjan Gavalji
    the Telerik team

    Instantly find answers to your questions at the new Telerik Support Center
  3. terrysmith
    terrysmith avatar
    129 posts
    Member since:
    Nov 2006

    Posted 14 Apr 2008 Link to this post

    Thank you,

    Using RadScriptBlock around my Javascript has fixed the "Controls collection cannot be modified" problem.

    I'm still having a problem with the second-part of my question. I have a context menu inside a RadAjaxPanel. After the context menu gets built I need to inject Javascript into the update panel to display it. Before Prometheus, I was simply adding a LiteralControl with the javascript inside it to the Controls collection of the RadAjaxPanel, and the javascript ran when the panel loaded. That no longer works. I've tried adding a RadScriptBlock to the RadAjaxPanel and then putting a PlaceHolder control inside it which I use to write the javascript. That doesn't work either.

    How do I do this?

    Thank you,
    Terry
  4. Erjan Gavalji
    Admin
    Erjan Gavalji avatar
    1455 posts

    Posted 15 Apr 2008 Link to this post

    Hi Terry,

    You should register the script using the
    ScriptManager.RegisterClientScriptBlock
    method.

    Please note, that as the script operates with a control, it should be executed in the load phase. This comes because the client-side part of the controls get created during the client-side init phase.

    Please, find attached a small sample page demonstrating this approach.

    Let me know if that helps.

    Kind regards,
    Erjan Gavalji
    the Telerik team

    Instantly find answers to your questions at the new Telerik Support Center
  5. terrysmith
    terrysmith avatar
    129 posts
    Member since:
    Nov 2006

    Posted 15 Apr 2008 Link to this post

    Thank you. After reading about it I understand I should be using
    RegisterClientScriptBlock
      now; however, I am still having a problem. We have the RadScriptManager defined on our MasterPage and are no longer using the ASP.NET ScriptManager. When I call the RadScriptManager like this:

            RadScriptManager.RegisterClientScriptBlock(MeMe.GetType"GridContextMenuScript", _ 
            "<script type=""text/javascript"">function pageLoad(){{alert(""loaded!"");}}</script>"False

    I get this error:

    Microsoft JScript runtime error: Sys.WebForms.PageRequestManagerServerErrorException: The script tag registered for type 'System.Web.UI.Page' and key 'ctl00$ieWebPartsManager$gwpinsightExplorer$insightExplorer$ctl00$radScript' does not contain any valid script tags.

    I've tried just putting an alert in the script as well as changing the pageLoad function different ways and none of those variations worked.

    Thanks once again,
    Terry
  6. Erjan Gavalji
    Admin
    Erjan Gavalji avatar
    1455 posts

    Posted 16 Apr 2008 Link to this post

    Hi Terry,

    As the RegisterClientScriptBlock is a static method inherited from System.Web.UI.ScriptManager, it is not a problem to have the call as ScriptManager.RegisterClientScriptBlock.

    This is not the reason for the problem though. The call you sent me is valid (please, find attached the page I'm sending). Can you check if you have some other client script registrations in your page?

    Best regards,
    Erjan Gavalji
    the Telerik team

    Instantly find answers to your questions at the new Telerik Support Center
  7. terrysmith
    terrysmith avatar
    129 posts
    Member since:
    Nov 2006

    Posted 17 Apr 2008 Link to this post

    Thanks for all your help...

    I've got the previous issues resolved, and the context menu is displaying now. I still have one issue though.

    When the user clicks a menu item I change an object model on the server to reflect that selection and then update an AJAX panel. After the panel renders the context menu shows itself again. It should be closed at this point.

    Is the pageLoad() javascript that I put in the page using RegisterClientScriptBlock firing a second time? Also, when the context menu redisplays it is still the "old" menu. For instance, if I had clicked a checkbox menu item it redisplays after the server call with the checkbox in the same state even though it shouldn't be. If I click elsewhere on the page and then right-click again the context menu displays like it should.

    I've tried adding an OnClientItemClicked event handler to close the context menu on the click, but the context menu still redisplays itself after the item click.

    Any suggestions?

    Thank you,
    Terry
  8. Erjan Gavalji
    Admin
    Erjan Gavalji avatar
    1455 posts

    Posted 18 Apr 2008 Link to this post

    Hi Terry,

    Up to your questions:

    Yes, the pageLoad function is executed after each Ajax call. Regarding the "old context menu" problem - I'm afraid I'll need to have a look at the source code to find the problem. Can you open a formal support ticket and send me a demo application, please? Just a shot in the dark - is the RadContextMenu located inside the AjaxPanel?

    Kind regards,
    Erjan Gavalji
    the Telerik team

    Instantly find answers to your questions at the new Telerik Support Center
  9. terrysmith
    terrysmith avatar
    129 posts
    Member since:
    Nov 2006

    Posted 18 Apr 2008 Link to this post

    Thank you Erjan,

    The support ticket number is 133080.

    Terry
  10. Erjan Gavalji
    Admin
    Erjan Gavalji avatar
    1455 posts

    Posted 21 Apr 2008 Link to this post

    Hi guys,

    I just wanted to shed some light on the issue - it occurred that some minor tweaks were needed regarding the context menu update and the pageLoad function registration. Terry, would you please update the community if everything is fine after the changes?

    Thanks in advance.

    Cheers,
    Erjan Gavalji
    the Telerik team

    Instantly find answers to your questions at the new Telerik Support Center
  11. terrysmith
    terrysmith avatar
    129 posts
    Member since:
    Nov 2006

    Posted 21 Apr 2008 Link to this post

    Thanks Erjan,

    Yes, its working fine now. As you suggested I had to add a RegisterClientScriptBlock call to the menu_ItemClick event to clear out the previous pageLoad():

    'Disable the startup script, so that the menu is not displayed again: 
    RadScriptManager.RegisterClientScriptBlock(Me.Page, Me.Page.GetType, "GridContextMenuScript", _ 
    "<script type='text/javascript'>function pageLoad(){}</script>", False) 

    I was worried about having to do this in more than one place since the page I'm working with has a few different update panels. If the user displayed the context menu but then dismissed it without clicking anything would the menu still redisplay from the pageLoad() script after another AJAX call on the page? So far, that hasn't been the case, and it is working great.

    Thanks!
    Terry
  12. Erjan Gavalji
    Admin
    Erjan Gavalji avatar
    1455 posts

    Posted 22 Apr 2008 Link to this post

    Hi Terry,

    Yes, the context menu will be "renewed" and displayed on each label right-click - your application logic is done that way:
         when a right-click on the label happens, an Ajax call is made;
         it raises the button click event on the server;
         the button click event handler always registers the pageLoad function (which displays the context menu after the Ajax call finishes).

    Cheers,
    Erjan Gavalji
    the Telerik team

    Instantly find answers to your questions at the new Telerik Support Center
Back to Top