views:

885

answers:

6

Here's the situ: A page which contains html and using the jQuery libray and tabs jQuery UI plugin loads another page when some tab is clicked. The problem is that when the page/html is loaded/rendered (let's simplify this and say it's just doing something like $("#myDiv").load(url);), the ready event is not fired because of course the "window" has already loaded and fired the load event. This means that none of the jQuery things I want to do on load (partial load) of the page are executed. The UI.tabs plugin is designed to load pages into other tabs and we can assume that other pages may contain their own jQuery... so there should be some way around this..

I can think of very horrible ways to get over the problem, like have a script block at the bottom of the page being rendered (loaded into a div) which does all things I would do when ready is fired (as you can assume the browser has rendered the page already if the script block is hit). This however is VERY bad practise. Any suggestions?

+2  A: 

I believe you can do something like this (derived from ASP.NET):

<script type=”text/javascript”>
     <!--
     Sys.WebForms.PageRequestManager.getInstance().add_EndRequest(Request_End);
     function Request_End(sender, args)
     {
          // Insert code you want to occur after partial page load here
     }
     // -->
</script>

Which should hook into the end request event that includes partial page updates. You'd obviously update the example above to call the appropriate JS function that you'd like.

Brian Hasden
+4  A: 

The load method offers a callback which is executed after the content has been loaded.

$("#myDiv").load(url, null, function() { 
   //do your stuff here 
});

Full documentation and examples at jQuery.com: http://docs.jquery.com/Ajax/load

mkedobbs
+1  A: 

How are you firing the AJAX request to the server? If you're using ASP.NET AJAX, then Brian Hasden's answer is what you are looking for. If you are using jQuery to send the request, then you can either set a call back using the load function.

$(".ajaxLink").load(url, null, function() {
    // code here
});

load() Documentation

or set a global ajaxComplete event that is fired every time an ajax call is complete.

$(document).ajaxComplete(function() {
    // code here
});

ajaxComplete() Documentation

Kyle Trauberman
+1  A: 

Well - I'm using ASP.NET MVC with jQuery. I am NOT using partial view (ascx) for this part of the application, instead I am sing full views, but loading them in to divs. So I have a main view with a head with some reference to a js file which is the client side logic for this "type" of view. When clicking some tab on this view we use the jquery tabs to "load" antoher view into some div. The way tabs are loaded using this plugin is by simply giving a url (rather than using load to which - as pointed out - i could add a call back function rather than rely on ready).

However. I dont want ALL the client logic to be in some parent view, as any view should be able to load another view by url (sub views include a link to their related js file which contains all the logic to format/hookup when loaded).

What is REALLY confusing to me now is that it seems to be working in some situations and not in others; for example 1) when the parent view is opened in a frame in IE, the sub view readys are never triggered 2) when opening the same url directly in IE, the sub views readys ARE triggered 3) when opening the same URL in FFX2 the ready every are NOT triggered 4) finally.. but when opening a sub view (which has sub views) of this parent in FFX2, the child ready event ARE triggered!.. baffling..

I'mm gonna run some tests n get get back to ya, but any suggestions on why this behaviour might be different would be much appreciated

UPDATE: Ah ha!.. looks like even with the above hurdles cleared, there is a browser difference (obviously from reading above).. the below simple test works fine in IE7 but fails in FFX2. The ready event is triggered in IE but not FFX when loading Test2.htm into Test1.htm. From experience I know this means that IE has a "quirk" and FFX is working as you would expect based on W3C. So it looks like this approach is a no no, unless anyone has any suggestions?:

Test1.htm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org        /TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title></title>
    <script type="text/javascript" language="javascript" src="Scripts/jquery-1.3.2.js">    </script>
    <script type="text/javascript" language="javascript">
    <!--
        $(document).ready(function() {
            alert("Test1.htm");
            $("#Test1").load("Test2.htm");
        });
    //-->
    </script>
</head>
<body>
    <h3>SOME TEST</h3>
    <div id="Test1">EMPTY</div>
</body>
</html>

Test2.htm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org        /TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title></title>
    <script type="text/javascript" language="javascript" src="Scripts/jquery-1.3.2.js">    </script>
    <script type="text/javascript" language="javascript">
    <!--
        $(document).ready(function() {
            alert("Test2.htm");
            //$("#Test1").load("Test3.htm"); // load more
        });
    //-->
    </script>
</head>
<body>
    <h3>SOME TEST</h3>
    <div id="Test2">EMPTY</div>
</body>
</html>
Mr AH
A: 

OK.. so i have a simple answer to this problem now, which should mean minimal code changes. Rather than the sub views (these are real aspx views which have no html, head or body tags) having a js include (essentially the client side behaviour model) which responds to $(document).ready, we can use the suggestion from mkedobbs to provide something similar. Simply:

$("#MyDiv").load("page.htm", null, function(){ $(document).trigger("PartialLoaded"); });

Then in the sub view js include

$(document).bind("PartialLoaded", function(){ .........});
Mr AH
A: 

To Brian and Kyle:

Brian - Thanks but I'm not using ASP.NET Ajax in this case, simply ASP.Net MVC for server and jQuery for client

Kyle - Thanks, that's pretty much what I ended up with except I dont want to respond to all Ajax calls, as there are several areas like auto complete, configuration retrieval etc which would also use Ajax.

Mr AH