How jQuery event handlers can survive AJAX refresh using event delegation

How many time you were working hard to add smart AJAX (or similar) refresh function to your complex user interface just to find out that your jQuery event handlers are not working anymore after the refresh? That is, as you your original DOM elements are gone, event handlers assigned to them are gone too. That’s so much frustrating, when you almost get it working, you realize that you have to rewrite most of your shiny JS code in order to stay working after AJAX refresh.

I used to implement clumsy workarounds by supplying event handlers initialization code with HTML returned by AJAX. But that code is run by jQuery using eval() function making it impossible to debug. So I switched to encapsulating event handlers into a function that could be called after each refresh. But once again, I need to rewrite my code so that event handlers are assigned to the elements of refreshed container, otherwise I end up assigning event handlers to elements that already have them.

That was much pain resulting in dirty code until I found out jQuery (and JS) already have a solution to this problem via delegation of events. In easy words: you can assign event handlers to static elements that are not refreshed but contain refreshed elements. You just have to add a selector specifying child elements you want the event to be handled for. If you have no idea, you can assign event handlers to body element as it will always stay there.

So if you have a code like this:

$('.my-button').click(function() { 
    alert('My button is clicked'); 

…and you find out that the button is replaced by AJAX and stops working, you can simply rewrite it to the following syntax:

$('body').on('click', '.my-button', function() { 
    alert('My button is clicked'); 

And this event handler will still work after AJAX refresh!!!

Despite the handler is assigned to “body” element, the “this” variable passed to the event handler will still contain “.my-button” element, so no change to the event handler body is usually required.

Notice the code change is quite minimal, isn’t it? You just need to change the way event handler is assigned a bit, you can even automate that code rewrite with regular expressions. No more moving code to HTML returned by AJAX, no more “init” functions that restore event handlers, no tears: it just works.

At the moment I’m not aware of any drawbacks of this method. Maybe performance?

As I’m not really a big JS expert, I was afraid it could work for simple events like “click” but not work for more specific ones like “change”. So I wrote this simple example to verify if it works for “change” event: Yes, it works! I also tested focus event and it works toothanks to bubbling of JS events. I think only custom event handler that stops bubbling may prevent it form working as expected but still you can handle the even in an element inside the one that stops bubbling.

So have fun writing nice jQuery user interface automation and make sure it still works like a charm (but easy to debug just in case;) even if you heavily refresh parts of your screen with AJAX.

Enabling/Disabling HTML elements with jQuery 1.6+

After upgrading to jQuery 1.6+ you’ll find that code you used to enable/disable elements doesn’t work anymore:

//This is supposed to enable element(s) before jQuery 1.6:
$("some-selector").attr("disabled", "");
//This is supposed to disable element(s) before jQuery 1.6:
$("some-selector").attr("disabled", "disabled"); 

But now the code above doesn’t change anything. So what’s the problem?

Read more

Flot: Amazing JavaScript/jQuery/AJAX charting library

When I developed Windows desktop applications I was tied to ProEssentials library which was powerful yet expensive and had weird and very limiting API. Don’t want to say anything bad about ProEssentials developers but, OMG, their API contains hundreds of properties and functions you have to go through just to find few ones you really need. Not only do many of them have strange names, but they also do very strange things))).
How do you like “ForceVerticalPoints” property? How in this World could points be vertical or horizontal? Well, it’s actually about point labels… Enough about that horror.

Thank to Flot library, charting for the Web made extremely easy yet powerful and extensible. Flot is jQuery plug-in which means you can use all power of jQuery for setting it up, passing data to it and reacting to its events. Moreover, chart plotting happens on the browser side which means your server isn’t slowed down by producing chart pictures. And this also means you can add interactive features to your chart like point tooltips, zooming, live AJAX updates or display options applied w/o page reload.

Read more