views:

167

answers:

4

Let's assume, for instance, an xHTML document as below:

<html>
<head>
</head>
<body>
<div id="wrapper">
  <div id="sidebar"></div>
  <div id="content"></div>
</div>
</body>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"&gt;&lt;/script&gt;
<script type="text/javascript" src="./application.js"></script>
</html>

We'll be performing a GET AJAX request to a PHP script that will query a database and return a response to populate a TABLE element which will be formatted as a sortable grid via JavaScript.

Additionally, we want all of our JavaScript in one file that can easily be included as displayed above.

The options:

  1. Have the PHP script return the TABLE element populated with all of the data. Use jQuery's live() function to actively watch for new TABLE elements in the DOM and apply the sortable grid functionality when it discovers them. This method allows us to manipulate the content retruned from the AJAX request in PHP and returns a completed semantic table to the parent document.

  2. Insert the TABLE element into the script listed above, but leaving it's content empty. jQuery would immediately apply the sortable grid functionality once the document is ready, although no content would exist yet. The GET request would then return a JSON response that would populate the database.

Any other opinions / best practices / use cases you can share for this sort of thing? I am only discussing a TABLE here but we have been discussing the issue with a number of things: lightboxes, drop-down menus, etc.

Currently, we are not using jQuery's live() function nor do the DOM elements exist within the parent document. So, we are having to place small blocks of Javascript at the top of each of our individual Views. Although sloppy, this has allowed us to only load functionality when it is needed, but it is obviously difficult to maintain.

A: 

IMHO, the page should be as complete as possible when first shown to avoids extra requests. So I vote for the first method.

Maurice Perry
A: 

I am currently maintaining a web app based on live() method and also with the DOM elements not existing in the parent document and it seems to be fine. I tried myself inserting pieces of code in the "results" pages but it's very hard to update them all and sometimes you can skip my mistake one or two and then ask yourself "what did I do wrong?" and look for the problem for several hours.

The live() method is very nice because you can keep all your code in one particular file and obviously is easier to maintain rather than the solution above.

The app I was talking you about is now in production and it hadn't failed once so I'm pretty satisfied by this solution (strange though, I use the same pattern with filling a TABLE element with data and showing it as a grid :)

Bogdan Constantinescu
+1  A: 

The jQuery jqGrid Plugin might fit the bill, loads data dynamically through ajax, can be integrated with any server-side technology, allows you to theme it with theme roller.

To update the table yourself you can issue a callback with most jquery ajax functions when the request completes. For example, if you have this in your document:

<div id="output">
   <table>...</table>
</div>

You can load the result with the jquery Ajax Load function:

$('#output').load('results.php',{arg:'val'},updateSort);

function updateSort(){
    $("#output > table").sort();
}

I usually take it a set further:

$('#output')
    .html('<div class="centered_padded_msg_class">Loading data...</div>')
    .load('results.php',{arg:'val'},updateSort);

function updateSort(){
    $("#output > table").sort();
}

Best of luck, -Matt

Matt Gardner
The choice of grid (we opted for extJS) and how it's API isn't the issue. This is merely a question of best practice - do you include the table in the initial load or do you include it in the view of your AJAX'd resource. We've already started reworking our code to use the former method.
Michael Wales
+1  A: 

Its always best to load as much as is reasonable on the initial load. If your site/application requires that you add stuff dynamically via AJAX then I can see you dilemma.

From what I understand, you are wondering what the best/preferred practice would be to keep your JavaScript concise and in on file and not scattered throughout your page. You are saying that currently your scripts are scattered throughout your page because when you are loading in modules/views or whatever they have the js along with them so that when they load their script is run (long-winded, sorry). And, the problem is that you want specific events to be triggered (like instantiating a lightbox or sorting a table) when these views are loaded by using the one omnipotent super global js file.

So, if that sounds right, then here's what I'd do (for any views being loaded in dynamically)...

So, let's assume you have the code you provided:

<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"z&gt;&lt;/script&gt;
<script type="text/javascript" src="./application.js"></script>
</head>
<body>
    <div id="wrapper">
          <div id="sidebar"></div>
          <div id="content"></div>
    </div>
</body>
</html>

If you loaded some content into the '#content' div (say, a table) when the page is fully loaded, and then you wanted to sort that table without putting the script to do so in the HTML that is returned from AJAX, you could have the following code in you main ('./application.js') file:

$(function() {
    load_table();
    $('#content #my_table').live('table_loaded',function() {
        $(this).sort(); // or whatever your sorting method is...
    });
});

function load_table() {
    $.get('mysite.php',{foo:bar,bar:foo},function(data) { 
        $('#content').html(data).find('#my_table').trigger('table_loaded');
    });
}

This uses jquery custom events and the live() event. I haven't tested this out but it should work in theory.

UPDATE: I tested this and it works perfectly using jquery 1.3.2 :)

KyleFarris
Thanks for the response Kyle - based on the replies here we opted to include the empty table tag in the parent resource, we then use jQuery to submit a getJSON request when various links are clicked, and using that response to alter extJS' grid.
Michael Wales