In my last post I blogged about how jQuery $(document).ready() and ASP.NET Ajax asynchronous postbacks can be made to behave well together. The issue is that normally $(document).ready() is called when the DOM is ready to be manipulated. But this doens’t happen after an ASP.NET Ajax asynch postback occurs.
This means that the initial jQuery bindings won’t be automatically available after the asynchronous postback is over. I underline “automatically” here because my last post describes more possibilities, how this issue can be worked around.
The simplest way to have $(document).ready() run on each async postback is to include the JavaScript logic inside the pageLoad() function.
<script type="text/javascript">
function pageLoad() {
//js logic here, runs on every async postback (and on initial load)
}
</script>
The downside of this is that very often you need to use this function from UserControls, and whenever there are 2 or more UserControls which need to use this pageLoad(), you won’t get the result you expect. And there is no reason to include pageLoad() in the main page on every page because this is simply incorrect.
The next solution available which will definitely work across multiple UserControls on the same page (of course if you name the function so that there are no duplicate function names) is to use the EndRequestHandler from the PageRequestManager class from the ASP.NET Ajax Client Library.
<script type="text/javascript">
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
function EndRequestHandler(sender, args) {
// js code here; runs only on async postbacks
}
</script>
For a full example about this solution read my last post: $(document).ready() and ASP.NET Ajax asynchronous postback.
Now that jQuery 1.3 is out there is a solution from jQuery which solves the issue in the easiest way! There is a new event called live() (with it’s opposite: die()) which according to jQuery: Binds a handler to an event (like click) for all current - and future - matched element. Can also bind custom events.
At the current version (jQuery 1.3.2) the following events are support/not supported:
Possible event values: click, dblclick, mousedown, mouseup, mousemove, mouseover, mouseout, keydown, keypress, keyup
Currently not supported: blur, focus, mouseenter, mouseleave, change, submit
(source: http://docs.jquery.com/Events/live#typefn)
To exaplain the point I kindly invite you to try the following example:
I’ve included 2 buttons on a page within an ASP.NET Ajax UpdatePanel and some jQuery magic to show what happens if simply bind() is called compared to when live() is called. I’m binding the mouseover event and I’m appending the current timestamp to a div tag (there is a separate div tag for both sitatuion: bind, live).
<asp:UpdatePanel ID="uppnl" runat="server">
<ContentTemplate>
<table>
<thead>
<tr>
<th>
jQuery BIND
</th>
<th>
jQuery LIVE
</th>
</tr>
</thead>
<tbody>
<tr valign="top">
<td style="width: 150px">
<asp:Button ID="btnNormal" runat="server" Text="Hover over me" />
<script type="text/javascript">
$(document).ready(function() {
$("#<%= btnNormal.ClientID %>").bind("mouseover", function() {
$("#result").append("entered at: " +
(new Date()).toLocaleTimeString());
});
});
</script>
</td>
<td>
<asp:Button ID="btnLive" runat="server" Text="Hover over me aswell" />
<script type="text/javascript">
$(document).ready(function() {
$("#<%= btnLive.ClientID %>").live("mouseover", function() {
$("#resultLive").append("entered at: " +
(new Date()).toLocaleTimeString());
});
});
</script>
</td>
</tr>
</tbody>
</table>
</ContentTemplate>
</asp:UpdatePanel>
<table>
<tr valign="top">
<td style="width: 150px">
<div id="result">
</div>
</td>
<td>
<div id="resultLive">
</div>
</td>
</tr>
</table>
By hovering over both buttons will execute the JavaScript logic before any postback occurs. But after pressing any button, the first button will lose the jQuery binding and you will be able to see that nothiing happens when hovering over the first button.
Of course the live event won’t be suitable for all the cases when you need to execute a piece of code after an asynchronous postback happened but in many cases by using the jQuery $(document).live() event you can save yourself allot of time and hassle and solve the famous ASP.NET Ajax and jQuery postback problem right away.