5

If I have a table:

<table>
    <thead>
        <tr>Col1</tr>
        <tr>Col2</tr>
        <tr>Col3</tr>
    </thead>
    <tbody>
    </tbody>
</table>

What is the fastest, most efficient way to fill the tbody with tr elements containing my data from a database using a Jquery Ajax. (unless you have a better way)

Return html code from the webservice OR dynamically create the html code in Javascript?

Also I have to support the user "drilling down; i.e. either clicking a > or double clicking the row to open a pane to show some more information. (including another table and some detail information returned by a separate webservice)

All ideas welcome!

1
  • 1
    I suggest using the jquery template plugin for inserting the data into the table. Commented May 18, 2011 at 13:44

5 Answers 5

3

Unless you need to create literally thousands of rows, performance is just not a concern here. Where you generate the markup is really a design decision. You can generate the markup:

  • Server-side, in your templating language of choice (ASP.NET, PHP, JSP, Django templates...) or
  • Client-side, using JavaScript templates ($.tmpl, Mustache...)

Client side will (theoretically) decrease the load on your server, but this too is likely not a relevant issue. Whichever flavor you choose, you should use that consistently throughout your app unless there is a truly compelling reason to do otherwise.

Sign up to request clarification or add additional context in comments.

9 Comments

How do you draw that conclusion? The ajax call could return HTML data.
@Matt Ball - I'm operating on the assumption that putting the markup in the webservice is not the best approach. You're right, my statement was misleading. I should have clarified.
@SquidScareMe: The server doesn't whether it's an ajax call or not. Is all HTTP to it, baby.
@kralco: it's not a big deal so long as you minimize the number of DOM manipulations. You can build up one big HTML string and insert it once rather than insert every row individually - much better performance.
I agree that a web services emitting HTML mark-up is just flat out wrong because it doesn't support good separation of concerns. I would rather have a web service that returns JSON, that way it can be manipulated easily to fit any evolving design requirements over time. You can always implement a client-side mechanism that loads the data progressively.
|
2

I work on a large-scale enterprise portal that uses jQuery and AJAX. I've implemented jQuery Templates and the jQuery TableSorter plug-in to facilitate this. Here's some example code:

Javascript (Data Provider): Data.Lists.js

myorg.data.list.GetListItems ({
    webURL: "http://our.awesome.portal.com/Lists",
    listName: "Projects List",
    caml: caml,
    CAMLRowLimit: 6,
    callback: function(data) {
        var list = {};
        //code here that formats some data before binding
        list.items = data;
        var templateHtml = $('.ptMyProjects').html()
        .replace("<!--", "").replace("-->","");
        var html = $.tmpl(templateHtml, list);
        $('.ptMyProjects').html(html);
        //make sortable table
        $('.ptMyProjects .tablesorter').tablesorter({
            sortList: [[0,0]],
            headers: {3: {sorter: false}},
            widgets: ['zebra']
        });
        //class last row
        $('.ptMyProjects .tablesorter thead th').last().addClass('last');
        //add hover effect
        $('.ptMyProjects .tablesorter tbody tr, .tablesorter thead .header').hover(function(){
            $(this).addClass('hover');
        }, function(){
            $(this).removeClass('hover');
        });
        //add tooltips
        $('.ptMyProjects .vg_icon').tipsy({gravity: 's'});
    }
});

HTML (the template)

<div class="ptMyProjects ptTemplate">
    <!--
    <table class="tablesorter" border="0" cellpadding="0" cellspacing="0">
        <thead>
            <tr class="gradient_gray">
                <th>Title</th>
                <th>Status</th>
                <th style="border-right: none;">Progress</th>
                <th>Actions</th>
            </tr>
        </thead>
        <tbody>
        {{if items.length > 0}}
            {{each items}}
                <tr class='item' recordid="${ows_ID}">
                    <td ><a class='{{if ows_Critical_x0020_Project == "1"}}critical{{/if}}' href="${DisplayURL}">${ows_Title}</a> </td>
                    <td class="status">
                        <a href="#" class="pstatus">${ows_ProjStatus}</a>
                        <div style='display: none;'>
                            {{if ows_ProjComments}}
                                <div style="padding-bottom: 10px;">${ows_ProjComments}</div>
                            {{/if}}
                            <div style="font-weight: bold;">Lasted Edited By ${Editor}</div>
                            <div style="font-style: italic;">${when}</div>
                        </div>
                    </td>
                    <td>
                    <div class="ui-widget-default">
                        <div class="progressbar" value="${ows_PercentComplete}" style="height:100%;"></div>
                    </div>
                    </td>
                    <td class="actions">
                        {{if ows_ProjStatus != "Completed"}}<a href="#" class="vg_icon tick" title="Mark Completed"></a>{{/if}}
                        <a href="${EditURL}" class="vg_icon pencil" title="Edit"></a>
                        <a href="#" class="vg_icon comment" title="Comments"></a>
                    </td>
                </tr>
            {{/each}}
        {{else}}
            <tr><td colspan="4">You have no projects.</td></tr>
        {{/if}}
        </tbody>
    </table>
-->
</div>

15 Comments

I get what the Jquery/javascript code is doing in the callback function. However, what is that Data.Lists.js and GetListItems stuff?
As an aside, with table sorter there is no way to get excel like filtering, is there? Also expanding the table so I can show detail information would also be difficult I think? Adding another row for detail information would mess up the sorting...
I created a wrapper class that consolidates our $.ajax calls. This is good because we can update the data layer in one location. For example, jQuery overhauled the entire $.ajax namespace in the latest version, and instead of changing all the ajax throughout the site, we just updated the data class files :) our data classes are structured like so: data.js, data.lists.js, data.users, data.groups.js, data.cache.js, etc...
You could write excel-like-filtering custom (as I've done before) or implement a plug-in. Adding another row may conflict with sorting but I would handle it differently. For example, on one of our tables, when a user clicks on an action we just make another ajax request and show more information in a tooltip or pop-up modal div.
ah yes, i see. We did a similar thing, just on a smaller scale, I have a function that takes in the basic stuff like the service name, parameters, success and fail callbacks... So I would only have to change something once in that function. Not as good as what you did however... :-p
|
2

Returning HTML from the webservice tightly couples your code. The better of the two ways is to create the HTML in Javascript.

1 Comment

I don't like it, but if it's faster i'll do it... I'm just afraid JavaScript might be too slow.
2

You can use jQuery .ajax() call to return the data in a JSON object and use the .tmpl() templating plugin to render the html.

You can view the templating documentation here : http://api.jquery.com/tmpl/

Update: I posted an example as an answer to another question

Comments

1

This solution works extremely well for me.

I simply retrieve a two dimension JSONed array from an AJAX PHP call.
(Using the php function json_encode())

Then simply iterate over the array to construct insertable table rows. as shown here.

$.post("./pdo_select.php", {post_query : view_q }, function(data) {
            var textToInsert = '';
            $.each(data, function(row, rowdata) {
               textToInsert += '<tr>';
               $.each(rowdata, function (ele, eledata){
                  textToInsert  += '<td>' + eledata + '</td>';
               });
               textToInsert += '</tr>';
            });
            $("#questions_table").append(textToInsert);

}, 'json'); 

Note the additional 'json' parameter.

The whole table can be quiet easily manipulated with standard jQuery, from adding a header row, turning one or more rows or tables into input fields.

I guess you don't have to use PDO routines to obtain the details from the database if you don't want to.

Below is a image of a table constructed using the technique listed above enter image description here

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.