7
\$\begingroup\$

This plugin is written in jQuery and is made to support the codeigniter framework. It is an ajax powered table pagination plugin designed to provide only that. You should be able to use almost any other table scripts with this plugin.

(function($){
    $.fn.extend({
        tpaginate: function(options) {

            //Settings list and the default values
            var defaults = {
                page: 0,
                url : null,
                rows: 20,
                nodata: 'The table is empty!',
                actions: true
            };

            var table;
            var foot;
            var body;
            var curpagespan;
            var totpagespan;
            var oldbody;
            var replaced = false;

            var options = $.extend(defaults, options);

            return this.each(function() {
                table = this;
                foot = $(table).find(' > tfoot > tr > td');
                body = $(table).find(' > tbody');
                create_footer(foot);
                curpagespan = foot.find(' > #table_pagecount > span#page');
                totpagespan = foot.find(' > #table_pagecount > span#page_total');
                curpagespan.html(0);
                totpagespan.html(0);
                $('#searchButton').click(function(){
                    var term = $('#search').val();
                    if(term.length >= 3){
                        if(replaced)
                            load_data(1, term, true, false);
                        else
                            load_data(1, term, true, true);
                    }
                });
                $('#search').keyup(function(){
                    if($(this).val() == ''){
                        create_tbody(false, false, true);
                    }
                });
            });

            function create_footer() {
                var pagecount = $('<div id="table_pagecount">Page <span id="page"></span> of <span id="page_total"></span></div>');
                var pager = $('<div id="table_pageination"><a class="link" id="first" style="display:none;">First</a><a class="link" id="prev" style="display:none;">Prev</a><span id="pages"></span><a class="link" id="next" style="display:none;">Next</a><a class="link" id="last" style="display:none;">Last</a></div>');
                foot.append(pagecount);
                foot.append(pager);
                load_data(1, '', true);
            }

            function current_page(page){
                curpagespan.html(page);
            }

            function total_page(page){
                totpagespan.html(Math.ceil(page/options.rows));
            }

            function load_data(page, search, action, save){
                if(save == null)
                    save = false;
                else
                    save = true;
                $('#table_pageination a.link').unbind('click');
                search = (search == null ? '' : search);
                var start = (page-1)*options.rows;
                if(page == 1)
                    start = 0;
                var url = options.url+'/'+start+'/'+action+'/'+search;
                $.ajax({
                    url: url,
                    success: function(data) {
                        if(data.total != 0){
                            current_page(page);
                            total_page(data.total);
                            create_tbody(data.members, save);
                            update_pages(page, Math.ceil(data.total/options.rows));
                        } else{
                            current_page(0);
                            total_page(0);
                            foot.find(' > #table_pageination > #pages').html('<a class="link">0</a>');
                            var newtr = $('<tr></tr>');
                            var newtd = $('<td style="font-weight:bold;text-align: center;"></td>').attr('colspan', foot.attr('colspan')).text(options.nodata);
                            body.html(newtr.append(newtd));
                        }
                    }
                });
            }

            function create_tbody(rows, save, revert){
                if(save == true){
                    oldbody = body.html();
                    replaced = true;
                }
                var newbody = $('<tbody />');
                if(revert == null){
                    for(var i in rows){
                        var row = $('<tr />');
                        for(var j in rows[i]){
                            if(j != 'id' && j != 'actions')
                                row.append('<td class="'+j+'td">'+(rows[i][j] == null ? '' : rows[i][j])+'</td>');
                            if(j == 'actions' && rows[i][j] != null && options.actions)
                                row.append(rows[i][j]);
                        }
                        newbody.append(row);
                    }
                } else{
                    newbody.html(oldbody);
                    replaced = false;
                }
                body.html(newbody.html());
                $(table).trigger("update");
            }

            function update_pages(page, total){
                foot.find(' > #table_pageination > #pages').html(ranger(page, 5, total));
                if(page == 1){
                    foot.find(' > #table_pageination > a#first').fadeOut('slow');
                    foot.find(' > #table_pageination > a#prev').fadeOut('slow');
                } else{
                    foot.find(' > #table_pageination > a#first').attr('rel', 1).fadeIn('slow');
                    if(page != 2)
                        foot.find(' > #table_pageination > a#prev').attr('rel', page-1).fadeIn('slow');
                }
                if(total != page){
                    foot.find(' > #table_pageination > a#last').attr('rel', total).fadeIn('slow');
                    if(total != page+1)
                        foot.find(' > #table_pageination > a#next').attr('rel', ++page).fadeIn('slow');
                } else{
                    foot.find(' > #table_pageination > a#last').attr('rel', total).fadeOut('slow');
                    foot.find(' > #table_pageination > a#next').attr('rel', total).fadeOut('slow');
                }

                $('#table_pageination a.link').click(function(){
                    replaced = false;
                    load_data($(this).attr('rel'), '', true);
                });
            }

            function ranger(num, range, max) {
                var left = num*1;
                var right = num*1;

                while (right - left < range * 2) {
                    if (right + 1 <= max)
                        right++;

                    if (left - 1 > 0)
                        left--;

                    if (right == max && left == 1)
                        break;
                }

                var str = '';
                for (var i = left; i <= right; i++) {
                    if(i != num)
                        str += '<a class="link" rel="'+i+'">'+i+'</a>';
                    if(i == num)
                        str += '<a rel="nolink">'+i+'</a>';
                }
                return str;
            }
        }
    });
})(jQuery);
\$\endgroup\$
  • 2
    \$\begingroup\$ I don't have time to take a bigger look at the code right now but I can point out some obvious issues. Not using the strict equals operator (===) may lead to subtle bugs. Not using hasOwnProperty in a for in is bad practice. Both of these combined will lead to bugs when native prototypes have been extended (e.g. in create_tbody). There might also be some leakage from the closures of the event handlers but I'm not sure how much of an issue that would be without digging further into the code. Overall structure looks good but many small changes could be made, gonna post something later \$\endgroup\$ – Ivo Wetzel Jan 20 '11 at 12:10
  • \$\begingroup\$ Users hate pagination. Are you sure you want to show only 20 items per page? Consider showing more items per page, like 200. Just a suggestion. :) \$\endgroup\$ – rightfold Jan 21 '11 at 15:14
  • 1
    \$\begingroup\$ @Ivo Wetzel, Thankyou for your comment, I had not even thought about using the strict equality operator. Will update the codebase with that code. @Time Machine the 20 rows at a time can be overwritten when you call the plugin using $(table).tpaginate({rows: 200}); and Yes, I agree users hate pagination, So Do I, but with 60k rows, sometimes it is necessary! \$\endgroup\$ – Hailwood Jan 22 '11 at 4:39
  • \$\begingroup\$ Consider using classes instead of IDs for the HTML elements you're inserting. IDs should be unique, and since they have generic names (like #prev), there is a high likelihood of unintended conflict with pre-existing markup. \$\endgroup\$ – VLS Nov 24 '13 at 21:56
3
\$\begingroup\$

That's a large piece of code.

I highly recommended to use lower camel case for variables.

Here are some hints from me, just only micro-refactoring.

if(term.length >= 3) {
  if(replaced)
    load_data(1, term, true, false);
  else
    load_data(1, term, true, true);
}

into:

if(term.length >= 3) {
  load_data(1, term, true, !replaced);                        
}

function load_data(page, search, action, save) {
   if(save == null)
     save = false;
   else
     save = true;
 ...

into:

function load_data(page, search, action, save) {
  save = save == null ? false : true;
...

for(var j in rows[i]) {
   if(j != 'id' && j != 'actions')
     row.append('<td class="'+j+'td">'+(rows[i][j] == null ? '' : rows[i][j])+'</td>');
   if(j == 'actions' && rows[i][j] != null && options.actions)
     row.append(rows[i][j]);
 }

into:

for(var j in rows[i]) {
  var rowsIJ = rows[i][j];

  if(j != 'id' && j != 'actions')
    row.append('<td class="'+j+'td">'+(rowsIJ == null ? '' : rowsIJ)+'</td>');
  if(j == 'actions' && rowsIJ != null && options.actions)
    row.append(rowsIJ);
}
\$\endgroup\$
  • 1
    \$\begingroup\$ points one and two I agree with, however I fail to see the points of number 3? I will make the suggested changes for 1 and 2. \$\endgroup\$ – Hailwood Jan 28 '11 at 2:02
-1
\$\begingroup\$

As far as i remember, use of for … in statements is strongly discouraged. Also, jQuery has a great $.each() function.

So, this

for(var i in rows){
    var row = $('<tr />');
    for(var j in rows[i]){
        if(j != 'id' && j != 'actions')
            row.append('<td class="'+j+'td">'+(rows[i][j] == null ? '' : rows[i][j])+'</td>');
        if(j == 'actions' && rows[i][j] != null && options.actions)
            row.append(rows[i][j]);
    }
    newbody.append(row);
}

should rather be something along the lines of

$.each(rows, function(i,e){
    var row = $('<tr />');  
    $.each(rows[i], function(j,ee){
        if(j != 'id' && j != 'actions')
            row.append('<td class="'+j+'td">'+(rows[i][j] == null ? '' : rows[i][j])+'</td>');
        if(j == 'actions' && rows[i][j] != null && options.actions)
            row.append(rows[i][j]);
    });
    newbody.append(row);
});
\$\endgroup\$
  • 1
    \$\begingroup\$ you should read all the comments and all the answers and all the links on that question before giving it as an answer on another question. you need to fully understand what is going on in both circumstances to make sure they are both talking about the same thing. \$\endgroup\$ – Malachi Nov 24 '13 at 18:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.