Click here to Skip to main content
Click here to Skip to main content
Technical Blog

Using JQuery to intercept the click of an ASP:Button

, 31 Mar 2009 CPOL
Rate this:
Please Sign up or sign in to vote.
Using JQuery to intercept the click of an ASP:Button

I was working on an interesting problem today. The architecture of a different project I am working on does not use MVC, but ASP.NET controls. We have separated them into a control/controller model so that business logic interacts with a controller, which passes POCOs to a control, and the control knows how to render them. The control knows no business logic, security, etc., while the controller doesn't understand anything about the UI domain EXCEPT for the fact that it is interacting with something derived from "Control" that lives in Web.UI.

Many of the examples in JQuery show you how to "unbind" an event, but I quickly found this wasn't working for me. What I wanted to do was place a traditional ASP.NET button on the page (quite frankly, the button was already buried in another control, so I wanted to work with this rather than come up with a hack to do a lightweight input button). I needed to intercept the click event, perform a call back, and then based on the result either display an error or allow the originally intended event (a postback) to fire.

After lots of searching, I finally settled with decorating my functions with alerts until I figured out exactly what was going on. So let's get started.

First, the button: easy enough.

<asp:Button ID="btnExample" runat="server" Text=" Click Me "/>

On the server side, we can do this:

btnExample.OnClick += MyClickHandler; 
...
protected void MyClickHandler(object sender, EventArgs e)
{
   // do something IF all is well 
}

Of course the server should ALSO check what I'm wiring in for validation, but I'm simplifying this for now. Now the fun part. What we want to do is find the button (I'll leave the JQuery up to you - you can search on the button, emit the client id and go on that, etc. In my case, it's the third button in a div with class "buttonBar"). Let's wire this up:

 $(document).ready(function() {
        var nextButton = $(".buttonBar input:button:eq(2)");
        window.criteria_postback = $(nextButton).attr("onclick");        
        $(nextButton).removeAttr("onclick");
        $(nextButton).unbind().click(function(event) {

            window.criteria_event = event;
            
            event.preventDefault();
        
            $(this).attr("disabled", "disabled");
            $(this).val(" Please wait... ");

            //load cmdString with something useful for the server 

            WebForm_DoCallback('__Page', cmdString, 
		window.Criteria_CallbackHandler, null, null, false);          
            
        });

So let's walk through this. I found for some reason (probably documented somewhere that I just didn't find) that unbinding the click event wasn't working. So instead, I decided to save the existing click event (window.criteria_postback). The reason I save it to the window is because I need to reference it in an eval() expression later on. Microsoft sandboxes evals so they can't see variables unless they are explicitly scoped to global.

Next, we get rid of the attribute (this prevents the event from firing).

Then I wire in my own click event. I SAVE the event to the global space, prevent the default (going through with it), then disable my button so the user doesn't double click.

Finally, I wire in the callback. A few interesting things about callbacks. First, if this code was embedded in a control, I'd need to have a reference to the control instead of the __Page for the control to pick it up. Second, and most importantly, even when you wire your own callback, you MUST let the ClientScript KNOW to listen!. In other words, I told my page to implement ICallbackHandler which exposes:

 public void RaiseCallbackEvent(string eventArgument)
 {
   // do something with the event from the client
 }
 ...
 public string GetCallbackResult() 
 {
   // return a result to the client
 }

Some people mistakenly believe this is enough to be able to capture callbacks, but unless you actually ask for the callback reference, the page/control won't listen! So it's important that even if you don't use the result, you at least make a call like this:

// generate the callback handlers 
Page.ClientScript.GetCallbackEventReference(this, "args", string.Empty, string.Empty);

Now it is happy and listening. We're almost done ... we've intercepted the original postback and saved it, and we've wired in our own callback. In my case, I have a select grid that is harvesting check boxes, so I want to build a light weight list of identifiers. I build that list on the client, then use the callback to send it down and store it on the server for later. A pattern that works well for me with the callback is like this:

private string _callbackResult; 

public void RaiseCallbackEvent(string eventArgument)
{
   try
   {
      ...
      _callbackResult = string.Empty;
   }
   catch(Exception ex) 
   {
     _callbackResult = ex.Message;
   }
}

public string GetCallbackResult()
{
   return _callbackResult; 
}

And now we come back to the client side. Part of the Callback is a delegate to handle the return. In our case, we passed in window.Criteria_CallbackHandler. Here is how we "catch" the result:

window.Criteria_CallbackHandler = function(result, context) {

    if (result == null || result == '') {
        eval(window.criteria_postback + ";onclick(window.criteria_event);");
        return; 
    }
    else {
        alert(result);
    }

    var nextButton = $(".buttonBar input:button:eq(2)");
    
    $(nextButton).val(" Next ");
    $(nextButton).removeAttr("disabled");

}

So what is going on? If I had no issues, I do something interesting. When I saved the "onclick" earlier, you'll find the ASP.NET page wired it in like this:

void onclick(event) { blah; }

So I am basically spitting the function back out in my "eval", then immediately calling it with the event that I saved earlier! This has the result of "business as usual" which in my case is to post to a new page and pick off the list I persisted in the callback to do something with it. Otherwise, I alert the error to the customer (a prettier solution may be to have a div for errors and just write this into the div instead of using the generic alert box), and then regardless, I restore my button so it can be clicked again.

There you go ... buttons, JQuery, and callback handlers all in one post!

Jeremy Likness

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Jeremy Likness
Architect Wintellect
United States United States
Jeremy Likness is a principal consultant at Wintellect. Jeremy, an experienced entrepreneur and technology executive, has successfully helped ship commercial enterprise software for 20 years. He specializes in catalyzing growth, developing ideas and creating value through delivering software in technical enterprises. His roles as business owner, technology executive and hands-on developer provided unique opportunities to directly impact the bottom line of multiple businesses by helping them grow and increase their organizational capacity while improving operational efficiency. He has worked with several initially small companies like Manhattan Associates and AirWatch before they grew large and experienced their transition from good to great while helping direct vision and strategy to embrace changing technology and markets. Jeremy is capable of quickly adapting to new paradigms and helps technology teams endure change by providing strong leadership, working with team members “in the trenches” and mentoring them in the soft skills that are key for engineers to bridge the gap between business and technology.
Follow on   Twitter   Google+   LinkedIn

Comments and Discussions

 
GeneralMy vote of 5 PinmemberDarkjo28-Jan-13 23:07 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.141220.1 | Last Updated 31 Mar 2009
Article Copyright 2009 by Jeremy Likness
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid