Cancel Ajax request from usercontrol

10 posts, 1 answers
  1. Justin Lee
    Justin Lee avatar
    149 posts
    Member since:
    Dec 2009

    Posted 20 May 2010 Link to this post

    I have multiple RadGrids on a page, each in a separate usercontrol.  Each have Export functionality, and the export buttons are in RadMenus.  The page has a RadAjaxManager, and each usercontrol has a RadAjaxManagerProxy.  Since RadAjaxManagerProxy's do not have an OnRequestStart method, I handle the cancel of the ajax request on the main page.

    Code to handle 1 of the usercontrols:
            function PageAjaxRequestStart(sender, args) {  
                if (args.EventTarget == '<%= ctrlGrid1.menu1.UniqueID %>') {  
                    var menu = $find('<%= ctrlGrid1.menu1.ClientID %>');  
                    var index = menu._findItemByValue('EXPORT').get_index().toString();  
                    if (args.EventArgument.match("^"+index) == index) {  
                        args.set_enableAjax(false);  
                    }  
                }  
            } 

    This works fine, but I'm wondering if there is a better way to do it...  To make this solution work, I have to expose the menu in each usercontrol publicly, and the page has to know about the exporting feature of the usercontrol. (any page that the usercontrol is added to would have to implement this solution).  It would be nice if there was some way to handle this from within the usercontrols.  Please let me know if there is a better way.

    Thanks 
  2. Answer
    Veli
    Admin
    Veli avatar
    2002 posts

    Posted 25 May 2010 Link to this post

    Hello Justin,

    You can find the RadAjaxManager instance in the content page from the user control. You can then register a client-side OnRequestStart event handler, the javascript handler of which will be in the user control. The following code can be executed from the Page_Load method of the user control:

    RadAjaxManager.GetCurrent(Page).ClientEvents.OnRequestStart = "ajaxRequestStart";

    Now, the definition of ajaxRequestStart can go into your web control markup inside a RadScriptBlock:

    <telerik:RadScriptBlock ID="RadScriptBlock1" runat="server">
        <script type="text/javascript">
            function ajaxRequestStart(sender, args)
            {
                if (args.get_eventTarget().indexOf("ExportTo") > -1)
                {
                    args.set_enableAjax(false);
                }
            }
        </script>
    </telerik:RadScriptBlock>

    That's it. you are registering an event handler for the manager right from the user control. No need to take the code for disabling AJAX on export outside of the user control where it is relevant.

    Note, however, a few limitations to this approach.

    1. You are overriding the client-side OnRequestStart event handler definition for the AJAX manager. RadAjaxManager.ClientEvents.OnRequestStart accepts a single name of a javascript function. You are accessing the manager from the user control and setting the property. This means that if the content page or another user control also wanted to use this event, only the last set function would be executed. This property can specify only a single event handler and only one party can claim  the event handler in this way.

    2. If you have multiple user controls on the same page, they would all register their own ajaxRequestStart function. This would mean multiple definitions of a javascript function with the same name on page, which means always the last defined function will be executed. Not the behavior you may want.

    To alleviate both of these limitations of the given approach, a safer, more robust approach can be used. We can set a master javascript function as the OnAjaxRequest event handler of the manager. Each user control or another party that wants to use the OnRequestStart event can then specify an event handler that will be called by the master handler.

    So, supposing the following RadAjaxManager definition and event handler:

    <telerik:RadAjaxManager ID="RadAjaxManager1" runat="server">
        <ClientEvents OnRequestStart="OnAjaxRequestStart" />
    </telerik:RadAjaxManager>
     
    <script type="text/javascript">
        function OnAjaxRequestStart(sender, args)
        {
            for (var i = 0; i < OnAjaxRequestStart.handlers.length; i++)
            {
                OnAjaxRequestStart.handlers[i](sender, args);
            }
        }
     
        OnAjaxRequestStart.handlers = [];
    </script>

    You can see I have expanded the OnAjaxRequestStart function with an array that will hold references to the actual event handler that I want executed. The function itself simply iterates over these handlers and calls them.

    Now, what I have in the user control is a startup script that will push a function into OnAjaxRequestStart.handlers which will be executed on AJAX request:

    protected void Page_Load(object sender, EventArgs e)
    {
        ScriptManager.RegisterStartupScript(Page,
            typeof(Page),
            "disableAjaxOnExport_" + this.UniqueID,
            String.Format(@"
                OnAjaxRequestStart.handlers.push(function(sender, args){{
                    var target = args.get_eventTarget();
                    if (target.indexOf('{0}') > -1 && target.indexOf('ExportTo') > -1){{
                        args.set_enableAjax(false);
                    }}
                }});", RadGrid1.UniqueID),
            true);
    }

    The above is the Page_Load method of the user control. Each user control I place on the page registers its own event handler by adding a reference to the function into the handlers array. When an AJAX request is triggered, OnAjaxRequestStart calls all the event handlers in the array.

    Sample page and user control is attached.

    Best wishes,
    Veli
    the Telerik team

    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
  3. UI for ASP.NET Ajax is Ready for VS 2017
  4. Justin Lee
    Justin Lee avatar
    149 posts
    Member since:
    Dec 2009

    Posted 26 May 2010 Link to this post

    Perfect. This is what I was looking for. (the second part) Thank you.
  5. Erin
    Erin avatar
    11 posts
    Member since:
    Jun 2012

    Posted 30 Jul 2012 Link to this post

    I am using almost identical ScriptManager.RegisterStartupScript code in the Page_Load of one of my pages, and I added an alert(OnAjaxRequestStart.handlers); just to make sure everything was being attached correctly (the page has several user controls and instances of RadAjaxManagerProxy, so wires get crossed with Ajax sometimes).  This showed that the handler was being added correctly on Page_Load, but was being added again after every asynchronous Ajax postback.  Whenever I would click a RadButton, the alert would appear again with OnAjaxRequestStart.handlers containing another copy of the function disabling Ajax for the specified button.

    This seems like a problem, since OnAjaxRequestStart.handlers surely has some kind of limits on its capacity, and at the very least it seems like running through potentially hundreds of event handlers could slow the page down.

    I considered placing the ScriptManager.RegisterStartupScript code inside if(!Page.IsPostBack), but then the handlers get cleared when a full postback occurs, which won't work for my project (Ajax still needs to be disabled on the button after a full postback).  What would ideally happen is that the function should only be added to OnAjaxRequestStart.handlers on Page_Load if it is not an Ajax postback, but I don't know if that is possible from the server side.

    Thank you!    
  6. Maria Ilieva
    Admin
    Maria Ilieva avatar
    4017 posts

    Posted 02 Aug 2012 Link to this post

    Hi Erin,

    Note that it is more correct to attach the handler on each request as in most cases the code in the OnRequestStart function will be executed conditionally. However you could try to check if the ScriptManager IsInAsyncPostBack :
    RadScriptManager.GetCurrent(Page).IsInAsyncPostBack()


    All the best,
    Maria Ilieva
    the Telerik team
    If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now.
  7. Nicolaï
    Nicolaï avatar
    160 posts
    Member since:
    Apr 2008

    Posted 02 May 2013 Link to this post

    ..Or just wrap the user control in a radajaxpanel, and set the ClientEvents-OnRequestStart..?
    Can even call the same function name without conflicts.
  8. Joseph
    Joseph avatar
    9 posts
    Member since:
    Jun 2007

    Posted 04 May 2015 Link to this post

    I have a very similar situation to the original poster, and trying the solution works up to the point of registering the function for OnRequestStart.

    I put the RadAjaxManager.GetCurrent(this.Page).ClientEvents.OnRequestStart = ajaxRequestStart; in the page load of my user control, and the function is in a RadScriptBlock on the user control mark up. However when loading the main page I get a javascript error "Uncaught ReferenceError: ajaxRequestStart is not defined". This makes me think that the page load is trying to register the function before the javascript is rendered to the page, so it can't see it. The various controls are in separate radpageviews.

  9. Maria Ilieva
    Admin
    Maria Ilieva avatar
    4017 posts

    Posted 07 May 2015 Link to this post

    Hi Joseph,

    Try to call the "ajaxRequestStart" function with some TimeOut and see if this makes any difference.


    Regards,
    Maria Ilieva
    Telerik
     

    See What's Next in App Development. Register for TelerikNEXT.

     
  10. Joseph
    Joseph avatar
    9 posts
    Member since:
    Jun 2007

    Posted 07 May 2015 Link to this post

    I was using a separate button from the ones built into the grid to export. I was able to get it working by putting "RadAjaxManager.GetCurrent(this.Page).ClientEvents.OnRequestStart = ajaxRequestStart; " in the page prerender event and explicitly ajaxifying the button in the radajaxmangerproxy. 
  11. Maria Ilieva
    Admin
    Maria Ilieva avatar
    4017 posts

    Posted 12 May 2015 Link to this post

    Hi Joseph,

     I'm glad that you were able to fix the issue on your end. Do not hesitate to contact us back if further assistance is needed.

    Regards,
    Maria Ilieva
    Telerik
     

    See What's Next in App Development. Register for TelerikNEXT.

     
Back to Top
UI for ASP.NET Ajax is Ready for VS 2017