source: extensions/LCAS/tags/2.3.0/admin/template/js/jquery.tablesorter.pager.js @ 27186

Last change on this file since 27186 was 27186, checked in by LucMorizur, 10 years ago

Version 2.3.0, compatibility with Piwigo 2.6

  • Property svn:eol-style set to LF
File size: 25.1 KB
Line 
1/*!
2 * tablesorter pager plugin
3 * updated 12/16/2013 (v2.14.5)
4 */
5/*jshint browser:true, jquery:true, unused:false */
6;(function($) {
7        "use strict";
8        /*jshint supernew:true */
9        var ts = $.tablesorter;
10
11        $.extend({ tablesorterPager: new function() {
12
13                this.defaults = {
14                        // target the pager markup
15                        container: null,
16
17                        // use this format: "http://mydatabase.com?page={page}&size={size}&{sortList:col}&{filterList:fcol}"
18                        // where {page} is replaced by the page number, {size} is replaced by the number of records to show,
19                        // {sortList:col} adds the sortList to the url into a "col" array, and {filterList:fcol} adds
20                        // the filterList to the url into an "fcol" array.
21                        // So a sortList = [[2,0],[3,0]] becomes "&col[2]=0&col[3]=0" in the url
22                        // and a filterList = [[2,Blue],[3,13]] becomes "&fcol[2]=Blue&fcol[3]=13" in the url
23                        ajaxUrl: null,
24
25                        // modify the url after all processing has been applied
26                        customAjaxUrl: function(table, url) { return url; },
27
28                        // modify the $.ajax object to allow complete control over your ajax requests
29                        ajaxObject: {
30                                dataType: 'json'
31                        },
32
33                        // set this to false if you want to block ajax loading on init
34                        processAjaxOnInit: true,
35
36                        // process ajax so that the following information is returned:
37                        // [ total_rows (number), rows (array of arrays), headers (array; optional) ]
38                        // example:
39                        // [
40                        //   100,  // total rows
41                        //   [
42                        //     [ "row1cell1", "row1cell2", ... "row1cellN" ],
43                        //     [ "row2cell1", "row2cell2", ... "row2cellN" ],
44                        //     ...
45                        //     [ "rowNcell1", "rowNcell2", ... "rowNcellN" ]
46                        //   ],
47                        //   [ "header1", "header2", ... "headerN" ] // optional
48                        // ]
49                        ajaxProcessing: function(ajax){ return [ 0, [], null ]; },
50
51                        // output default: '{page}/{totalPages}'
52                        // possible variables: {page}, {totalPages}, {filteredPages}, {startRow}, {endRow}, {filteredRows} and {totalRows}
53                        output: '{startRow} to {endRow} of {totalRows} rows', // '{page}/{totalPages}'
54
55                        // apply disabled classname to the pager arrows when the rows at either extreme is visible
56                        updateArrows: true,
57
58                        // starting page of the pager (zero based index)
59                        page: 0,
60
61                        // Number of visible rows
62                        size: 10,
63
64                        // Save pager page & size if the storage script is loaded (requires $.tablesorter.storage in jquery.tablesorter.widgets.js)
65                        savePages: true,
66
67                        // if true, the table will remain the same height no matter how many records are displayed. The space is made up by an empty
68                        // table row set to a height to compensate; default is false
69                        fixedHeight: false,
70
71                        // count child rows towards the set page size? (set true if it is a visible table row within the pager)
72                        // if true, child row(s) may not appear to be attached to its parent row, may be split across pages or
73                        // may distort the table if rowspan or cellspans are included.
74                        countChildRows: false,
75
76                        // remove rows from the table to speed up the sort of large tables.
77                        // setting this to false, only hides the non-visible rows; needed if you plan to add/remove rows with the pager enabled.
78                        removeRows: false, // removing rows in larger tables speeds up the sort
79
80                        // css class names of pager arrows
81                        cssFirst: '.first', // go to first page arrow
82                        cssPrev: '.prev', // previous page arrow
83                        cssNext: '.next', // next page arrow
84                        cssLast: '.last', // go to last page arrow
85                        cssGoto: '.gotoPage', // go to page selector - select dropdown that sets the current page
86                        cssPageDisplay: '.pagedisplay', // location of where the "output" is displayed
87                        cssPageSize: '.pagesize', // page size selector - select dropdown that sets the "size" option
88                        cssErrorRow: 'tablesorter-errorRow', // error information row
89
90                        // class added to arrows when at the extremes (i.e. prev/first arrows are "disabled" when on the first page)
91                        cssDisabled: 'disabled', // Note there is no period "." in front of this class name
92
93                        // stuff not set by the user
94                        totalRows: 0,
95                        totalPages: 0,
96                        filteredRows: 0,
97                        filteredPages: 0,
98                        ajaxCounter: 0,
99                        currentFilters: [],
100                        startRow: 0,
101                        endRow: 0,
102                        $size: null,
103                        last: {}
104
105                };
106
107                var $this = this,
108
109                // hide arrows at extremes
110                pagerArrows = function(p, disable) {
111                        var a = 'addClass',
112                        r = 'removeClass',
113                        d = p.cssDisabled,
114                        dis = !!disable,
115                        tp = Math.min( p.totalPages, p.filteredPages );
116                        if ( p.updateArrows ) {
117                                p.$container.find(p.cssFirst + ',' + p.cssPrev)[ ( dis || p.page === 0 ) ? a : r ](d);
118                                p.$container.find(p.cssNext + ',' + p.cssLast)[ ( dis || p.page === tp - 1 || p.totalPages === 0 ) ? a : r ](d);
119                        }
120                },
121
122                updatePageDisplay = function(table, p, flag) {
123                        var i, pg, s, out,
124                                c = table.config,
125                                f = c.$table.hasClass('hasFilters') && !p.ajaxUrl,
126                                t = (c.widgetOptions && c.widgetOptions.filter_filteredRow || 'filtered') + ',' + c.selectorRemove +
127                                        (p.countChildRows ? '' : ',.' + c.cssChildRow),
128                                sz = p.size || 10; // don't allow dividing by zero
129                        p.totalPages = Math.ceil( p.totalRows / sz ); // needed for "pageSize" method
130                        p.filteredRows = (f) ? c.$tbodies.eq(0).children('tr').not('.' + t ).length : p.totalRows;
131                        p.filteredPages = (f) ? Math.ceil( p.filteredRows / sz ) || 1 : p.totalPages;
132                        if ( Math.min( p.totalPages, p.filteredPages ) >= 0 ) {
133                                t = (p.size * p.page > p.filteredRows);
134                                p.startRow = (t) ? 1 : (p.filteredRows === 0 ? 0 : p.size * p.page + 1);
135                                p.page = (t) ? 0 : p.page;
136                                p.endRow = Math.min( p.filteredRows, p.totalRows, p.size * ( p.page + 1 ) );
137                                out = p.$container.find(p.cssPageDisplay);
138                                // form the output string (can now get a new output string from the server)
139                                s = ( p.ajaxData && p.ajaxData.output ? p.ajaxData.output || p.output : p.output )
140                                        // {page} = one-based index; {page+#} = zero based index +/- value
141                                        .replace(/\{page([\-+]\d+)?\}/gi, function(m,n){
142                                                return p.totalPages ? p.page + (n ? parseInt(n, 10) : 1) : 0;
143                                        })
144                                        // {totalPages}, {extra}, {extra:0} (array) or {extra : key} (object)
145                                        .replace(/\{\w+(\s*:\s*\w+)?\}/gi, function(m){
146                                                var str = m.replace(/[{}\s]/g,''),
147                                                        extra = str.split(':'),
148                                                        data = p.ajaxData,
149                                                        // return zero for default page/row numbers
150                                                        deflt = /(rows?|pages?)$/i.test(str) ? 0 : '';
151                                                return extra.length > 1 && data && data[extra[0]] ? data[extra[0]][extra[1]] : p[str] || (data ? data[str] : deflt) || deflt;
152                                        });
153                                if (out.length) {
154                                        out[ (out[0].tagName === 'INPUT') ? 'val' : 'html' ](s);
155                                        if ( p.$goto.length ) {
156                                                t = '';
157                                                pg = Math.min( p.totalPages, p.filteredPages );
158                                                for ( i = 1; i <= pg; i++ ) {
159                                                        t += '<option>' + i + '</option>';
160                                                }
161                                                p.$goto.html(t).val( p.page + 1 );
162                                        }
163                                }
164                        }
165                        pagerArrows(p);
166                        if (p.initialized && flag !== false) {
167                                c.$table.trigger('pagerComplete', p);
168                                // save pager info to storage
169                                if (p.savePages && ts.storage) {
170                                        ts.storage(table, 'tablesorter-pager', {
171                                                page : p.page,
172                                                size : p.size
173                                        });
174                                }
175                        }
176                },
177
178                fixHeight = function(table, p) {
179                        var d, h,
180                                c = table.config,
181                                $b = c.$tbodies.eq(0);
182                        if (p.fixedHeight) {
183                                $b.find('tr.pagerSavedHeightSpacer').remove();
184                                h = $.data(table, 'pagerSavedHeight');
185                                if (h) {
186                                        d = h - $b.height();
187                                        if ( d > 5 && $.data(table, 'pagerLastSize') === p.size && $b.children('tr:visible').length < p.size ) {
188                                                $b.append('<tr class="pagerSavedHeightSpacer ' + c.selectorRemove.replace(/(tr)?\./g,'') + '" style="height:' + d + 'px;"></tr>');
189                                        }
190                                }
191                        }
192                },
193
194                changeHeight = function(table, p) {
195                        var $b = table.config.$tbodies.eq(0);
196                        $b.find('tr.pagerSavedHeightSpacer').remove();
197                        $.data(table, 'pagerSavedHeight', $b.height());
198                        fixHeight(table, p);
199                        $.data(table, 'pagerLastSize', p.size);
200                },
201
202                hideRows = function(table, p){
203                        if (!p.ajaxUrl) {
204                                var i,
205                                c = table.config,
206                                rows = c.$tbodies.eq(0).children(),
207                                l = rows.length,
208                                s = ( p.page * p.size ),
209                                e =  s + p.size,
210                                f = c.widgetOptions && c.widgetOptions.filter_filteredRow || 'filtered',
211                                j = 0; // size counter
212                                for ( i = 0; i < l; i++ ){
213                                        if ( !rows[i].className.match(f) ) {
214                                                rows[i].style.display = ( j >= s && j < e ) ? '' : 'none';
215                                                // don't count child rows
216                                                j += rows[i].className.match(c.cssChildRow + '|' + c.selectorRemove.slice(1)) && !p.countChildRows ? 0 : 1;
217                                        }
218                                }
219                        }
220                },
221
222                hideRowsSetup = function(table, p){
223                        p.size = parseInt( p.$size.val(), 10 ) || p.size;
224                        $.data(table, 'pagerLastSize', p.size);
225                        pagerArrows(p);
226                        if ( !p.removeRows ) {
227                                hideRows(table, p);
228                                $(table).bind('sortEnd.pager filterEnd.pager', function(){
229                                        hideRows(table, p);
230                                });
231                        }
232                },
233
234                renderAjax = function(data, table, p, xhr, exception){
235                        // process data
236                        if ( typeof(p.ajaxProcessing) === "function" ) {
237                                // ajaxProcessing result: [ total, rows, headers ]
238                                var i, j, hsh, $f, $sh, t, th, d, l, $err, rr_count,
239                                        c = table.config,
240                                        $t = c.$table,
241                                        tds = '',
242                                        result = p.ajaxProcessing(data, table) || [ 0, [] ],
243                                        hl = $t.find('thead th').length;
244
245                                $t.find('thead tr.' + p.cssErrorRow).remove(); // Clean up any previous error.
246
247                                if ( exception ) {
248                                        if (c.debug) {
249                                                ts.log('Ajax Error', xhr, exception);
250                                        }
251                                        $err = $('<tr class="' + p.cssErrorRow + '"><td style="text-align:center;" colspan="' + hl + '">' + (
252                                                xhr.status === 0 ? 'Not connected, verify Network' :
253                                                xhr.status === 404 ? 'Requested page not found [404]' :
254                                                xhr.status === 500 ? 'Internal Server Error [500]' :
255                                                exception === 'parsererror' ? 'Requested JSON parse failed' :
256                                                exception === 'timeout' ? 'Time out error' :
257                                                exception === 'abort' ? 'Ajax Request aborted' :
258                                                'Uncaught error: ' + xhr.statusText + ' [' + xhr.status + ']' ) + '</td></tr>')
259                                        .click(function(){
260                                                $(this).remove();
261                                        })
262                                        // add error row to thead instead of tbody, or clicking on the header will result in a parser error
263                                        .appendTo( $t.find('thead:first') );
264                                        c.$tbodies.eq(0).empty();
265                                } else {
266                                        // process ajax object
267                                        if (!$.isArray(result)) {
268                                                p.ajaxData = result;
269                                                p.totalRows = result.total;
270                                                th = result.headers;
271                                                d = result.rows;
272                                        } else {
273                                                // allow [ total, rows, headers ]  or [ rows, total, headers ]
274                                                t = isNaN(result[0]) && !isNaN(result[1]);
275                                                //ensure a zero returned row count doesn't fail the logical ||
276                                                rr_count = result[t ? 1 : 0];
277                                                p.totalRows = isNaN(rr_count) ? p.totalRows || 0 : rr_count;
278                                                d = p.totalRows === 0 ? [""] : result[t ? 0 : 1] || []; // row data
279                                                th = result[2]; // headers
280                                        }
281                                        l = d.length;
282                                        if (d instanceof jQuery) {
283                                                // append jQuery object
284                                                c.$tbodies.eq(0).empty().append(d);
285                                        } else if (l) {
286                                                // build table from array
287                                                for ( i = 0; i < l; i++ ) {
288                                                        tds += '<tr>';
289                                                        for ( j = 0; j < d[i].length; j++ ) {
290                                                                // build tbody cells; watch for data containing HTML markup - see #434
291                                                                tds += /^\s*<td/.test(d[i][j]) ? $.trim(d[i][j]) : '<td>' + d[i][j] + '</td>';
292                                                        }
293                                                        tds += '</tr>';
294                                                }
295                                                // add rows to first tbody
296                                                p.processAjaxOnInit ? c.$tbodies.eq(0).html( tds ) : p.processAjaxOnInit = true;
297                                        }
298                                        // only add new header text if the length matches
299                                        if ( th && th.length === hl ) {
300                                                hsh = $t.hasClass('hasStickyHeaders');
301                                                $sh = hsh ? c.widgetOptions.$sticky.children('thead:first').children().children() : '';
302                                                $f = $t.find('tfoot tr:first').children();
303                                                // don't change td headers (may contain pager)
304                                                c.$headers.filter('th').each(function(j){
305                                                        var $t = $(this), icn;
306                                                        // add new test within the first span it finds, or just in the header
307                                                        if ( $t.find('.' + ts.css.icon).length ) {
308                                                                icn = $t.find('.' + ts.css.icon).clone(true);
309                                                                $t.find('.tablesorter-header-inner').html( th[j] ).append(icn);
310                                                                if ( hsh && $sh.length ) {
311                                                                        icn = $sh.eq(j).find('.' + ts.css.icon).clone(true);
312                                                                        $sh.eq(j).find('.tablesorter-header-inner').html( th[j] ).append(icn);
313                                                                }
314                                                        } else {
315                                                                $t.find('.tablesorter-header-inner').html( th[j] );
316                                                                if (hsh && $sh.length) {
317                                                                        $sh.eq(j).find('.tablesorter-header-inner').html( th[j] );
318                                                                }
319                                                        }
320                                                        $f.eq(j).html( th[j] );
321                                                });
322                                        }
323                                }
324                                if (c.showProcessing) {
325                                        ts.isProcessing(table); // remove loading icon
326                                }
327                                // make sure last pager settings are saved, prevents multiple server side calls with
328                                // the same parameters
329                                p.last.totalPages =  p.totalPages = Math.ceil( p.totalRows / ( p.size || 10 ) );
330                                p.last.currentFilters = p.currentFilters;
331                                p.last.sortList = (c.sortList || []).join(',');
332                                updatePageDisplay(table, p);
333                                fixHeight(table, p);
334                                // apply widgets after table has rendered
335                                $t.trigger('applyWidgets');
336                                $t.trigger('update', [false, function(){
337                                        if (p.initialized) {
338                                                $t.trigger('updateComplete');
339                                                $t.trigger('pagerChange', p);
340                                        }
341                                }]);
342                        }
343                        if (!p.initialized) {
344                                p.initialized = true;
345                                $(table).trigger('pagerInitialized', p);
346                        }
347                },
348
349                getAjax = function(table, p){
350                        var url = getAjaxUrl(table, p),
351                        $doc = $(document),
352                        counter,
353                        c = table.config;
354                        if ( url !== '' ) {
355                                if (c.showProcessing) {
356                                        ts.isProcessing(table, true); // show loading icon
357                                }
358                                $doc.bind('ajaxError.pager', function(e, xhr, settings, exception) {
359                                        renderAjax(null, table, p, xhr, exception);
360                                        $doc.unbind('ajaxError.pager');
361                                });
362
363                                counter = ++p.ajaxCounter;
364
365                                p.ajaxObject.url = url; // from the ajaxUrl option and modified by customAjaxUrl
366                                p.ajaxObject.success = function(data) {
367                                        // Refuse to process old ajax commands that were overwritten by new ones - see #443
368                                        if (counter < p.ajaxCounter){
369                                                return;
370                                        }
371                                        renderAjax(data, table, p);
372                                        $doc.unbind('ajaxError.pager');
373                                        if (typeof p.oldAjaxSuccess === 'function') {
374                                                p.oldAjaxSuccess(data);
375                                        }
376                                };
377                                if (c.debug) {
378                                        ts.log('ajax initialized', p.ajaxObject);
379                                }
380                                $.ajax(p.ajaxObject);
381                        }
382                },
383
384                getAjaxUrl = function(table, p) {
385                        var c = table.config,
386                                url = (p.ajaxUrl) ? p.ajaxUrl
387                                // allow using "{page+1}" in the url string to switch to a non-zero based index
388                                .replace(/\{page([\-+]\d+)?\}/, function(s,n){ return p.page + (n ? parseInt(n, 10) : 0); })
389                                .replace(/\{size\}/g, p.size) : '',
390                        sl = c.sortList,
391                        fl = p.currentFilters || $(table).data('lastSearch') || [],
392                        sortCol = url.match(/\{\s*sort(?:List)?\s*:\s*(\w*)\s*\}/),
393                        filterCol = url.match(/\{\s*filter(?:List)?\s*:\s*(\w*)\s*\}/),
394                        arry = [];
395                        if (sortCol) {
396                                sortCol = sortCol[1];
397                                $.each(sl, function(i,v){
398                                        arry.push(sortCol + '[' + v[0] + ']=' + v[1]);
399                                });
400                                // if the arry is empty, just add the col parameter... "&{sortList:col}" becomes "&col"
401                                url = url.replace(/\{\s*sort(?:List)?\s*:\s*(\w*)\s*\}/g, arry.length ? arry.join('&') : sortCol );
402                                arry = [];
403                        }
404                        if (filterCol) {
405                                filterCol = filterCol[1];
406                                $.each(fl, function(i,v){
407                                        if (v) {
408                                                arry.push(filterCol + '[' + i + ']=' + encodeURIComponent(v));
409                                        }
410                                });
411                                // if the arry is empty, just add the fcol parameter... "&{filterList:fcol}" becomes "&fcol"
412                                url = url.replace(/\{\s*filter(?:List)?\s*:\s*(\w*)\s*\}/g, arry.length ? arry.join('&') : filterCol );
413                                p.currentFilters = fl;
414                        }
415                        if ( typeof(p.customAjaxUrl) === "function" ) {
416                                url = p.customAjaxUrl(table, url);
417                        }
418                        if (c.debug) {
419                                ts.log('Pager ajax url: ' + url);
420                        }
421                        return url;
422                },
423
424                renderTable = function(table, rows, p) {
425                        var i, $tb,
426                                l = rows && rows.length || 0, // rows may be undefined
427                                s = ( p.page * p.size ),
428                                e = ( s + p.size );
429                        if ( l < 1 ) { return; } // empty table, abort!
430                        if ( p.page >= p.totalPages ) {
431                                // lets not render the table more than once
432                                moveToLastPage(table, p);
433                        }
434                        p.isDisabled = false; // needed because sorting will change the page and re-enable the pager
435                        if (p.initialized) { $(table).trigger('pagerChange', p); }
436
437                        if ( !p.removeRows ) {
438                                hideRows(table, p);
439                        } else {
440                                if ( e > rows.length ) {
441                                        e = rows.length;
442                                }
443                                ts.clearTableBody(table);
444                                $tb = ts.processTbody(table, table.config.$tbodies.eq(0), true);
445                                for ( i = s; i < e; i++ ) {
446                                        $tb.append(rows[i]);
447                                }
448                                ts.processTbody(table, $tb, false);
449                        }
450
451                        updatePageDisplay(table, p);
452                        if ( !p.isDisabled ) { fixHeight(table, p); }
453                        $(table).trigger('applyWidgets');
454                },
455
456                showAllRows = function(table, p){
457                        if ( p.ajax ) {
458                                pagerArrows(p, true);
459                        } else {
460                                p.isDisabled = true;
461                                $.data(table, 'pagerLastPage', p.page);
462                                $.data(table, 'pagerLastSize', p.size);
463                                p.page = 0;
464                                p.size = p.totalRows;
465                                p.totalPages = 1;
466                                $(table).addClass('pagerDisabled').find('tr.pagerSavedHeightSpacer').remove();
467                                renderTable(table, table.config.rowsCopy, p);
468                                if (table.config.debug) {
469                                        ts.log('pager disabled');
470                                }
471                        }
472                        // disable size selector
473                        p.$size.add(p.$goto).each(function(){
474                                $(this).addClass(p.cssDisabled)[0].disabled = true;
475                        });
476                },
477
478                moveToPage = function(table, p, flag) {
479                        if ( p.isDisabled ) { return; }
480                        var c = table.config,
481                                l = p.last,
482                                pg = Math.min( p.totalPages, p.filteredPages );
483                        if ( p.page < 0 ) { p.page = 0; }
484                        if ( p.page > ( pg - 1 ) && pg !== 0 ) { p.page = pg - 1; }
485                        // don't allow rendering multiple times on the same page/size/totalpages/filters/sorts
486                        if ( l.page === p.page && l.size === p.size && l.totalPages === p.totalPages &&
487                                (l.currentFilters || []).join(',') === (p.currentFilters || []).join(',') &&
488                                l.sortList === (c.sortList || []).join(',') ) { return; }
489                        if (c.debug) {
490                                ts.log('Pager changing to page ' + p.page);
491                        }
492                        p.last = {
493                                page : p.page,
494                                size : p.size,
495                                // fixes #408; modify sortList otherwise it auto-updates
496                                sortList : (c.sortList || []).join(','),
497                                totalPages : p.totalPages,
498                                currentFilters : p.currentFilters || []
499                        };
500                        if (p.ajax) {
501                                getAjax(table, p);
502                        } else if (!p.ajax) {
503                                renderTable(table, table.config.rowsCopy, p);
504                        }
505                        $.data(table, 'pagerLastPage', p.page);
506                        if (p.initialized && flag !== false) {
507                                c.$table.trigger('pageMoved', p);
508                                c.$table.trigger('applyWidgets');
509                        }
510                },
511
512                setPageSize = function(table, size, p) {
513                        p.size = size || p.size || 10;
514                        p.$size.val(p.size);
515                        $.data(table, 'pagerLastPage', p.page);
516                        $.data(table, 'pagerLastSize', p.size);
517                        p.totalPages = Math.ceil( p.totalRows / p.size );
518                        moveToPage(table, p);
519                },
520
521                moveToFirstPage = function(table, p) {
522                        p.page = 0;
523                        moveToPage(table, p);
524                },
525
526                moveToLastPage = function(table, p) {
527                        p.page = ( Math.min( p.totalPages, p.filteredPages ) - 1 );
528                        moveToPage(table, p);
529                },
530
531                moveToNextPage = function(table, p) {
532                        p.page++;
533                        if ( p.page >= ( Math.min( p.totalPages, p.filteredPages ) - 1 ) ) {
534                                p.page = ( Math.min( p.totalPages, p.filteredPages ) - 1 );
535                        }
536                        moveToPage(table, p);
537                },
538
539                moveToPrevPage = function(table, p) {
540                        p.page--;
541                        if ( p.page <= 0 ) {
542                                p.page = 0;
543                        }
544                        moveToPage(table, p);
545                },
546
547                destroyPager = function(table, p){
548                        showAllRows(table, p);
549                        p.$container.hide(); // hide pager
550                        table.config.appender = null; // remove pager appender function
551                        p.initialized = false;
552                        $(table).unbind('destroy.pager sortEnd.pager filterEnd.pager enable.pager disable.pager');
553                        if (ts.storage) {
554                                ts.storage(table, 'tablesorter-pager', '');
555                        }
556                },
557
558                enablePager = function(table, p, triggered){
559                        var pg = p.$size.removeClass(p.cssDisabled).removeAttr('disabled');
560                        p.$goto.removeClass(p.cssDisabled).removeAttr('disabled');
561                        p.isDisabled = false;
562                        p.page = $.data(table, 'pagerLastPage') || p.page || 0;
563                        p.size = $.data(table, 'pagerLastSize') || parseInt(pg.find('option[selected]').val(), 10) || p.size || 10;
564                        pg.val(p.size); // set page size
565                        p.totalPages = Math.ceil( Math.min( p.totalPages, p.filteredPages ) / p.size );
566                        if ( triggered ) {
567                                $(table).trigger('update');
568                                setPageSize(table, p.size, p);
569                                hideRowsSetup(table, p);
570                                fixHeight(table, p);
571                                if (table.config.debug) {
572                                        ts.log('pager enabled');
573                                }
574                        }
575                };
576
577                $this.appender = function(table, rows) {
578                        var c = table.config,
579                                p = c.pager;
580                        if ( !p.ajax ) {
581                                c.rowsCopy = rows;
582                                p.totalRows = p.countChildRows ? c.$tbodies.eq(0).children().length : rows.length;
583                                p.size = $.data(table, 'pagerLastSize') || p.size || 10;
584                                p.totalPages = Math.ceil( p.totalRows / p.size );
585                                renderTable(table, rows, p);
586                        }
587                };
588
589                $this.construct = function(settings) {
590                        return this.each(function() {
591                                // check if tablesorter has initialized
592                                if (!(this.config && this.hasInitialized)) { return; }
593                                var t, ctrls, fxn,
594                                        table = this,
595                                        c = table.config,
596                                        p = c.pager = $.extend( {}, $.tablesorterPager.defaults, settings ),
597                                        $t = c.$table,
598                                        // added in case the pager is reinitialized after being destroyed.
599                                        pager = p.$container = $(p.container).addClass('tablesorter-pager').show();
600                                if (c.debug) {
601                                        ts.log('Pager initializing');
602                                }
603                                p.oldAjaxSuccess = p.oldAjaxSuccess || p.ajaxObject.success;
604                                c.appender = $this.appender;
605                                if (ts.filter && $.inArray('filter', c.widgets) >= 0) {
606                                        // get any default filter settings (data-value attribute) fixes #388
607                                        p.currentFilters = c.$table.data('lastSearch') || ts.filter.setDefaults(table, c, c.widgetOptions) || [];
608                                        // set, but don't apply current filters
609                                        ts.setFilters(table, p.currentFilters, false);
610                                }
611                                if (p.savePages && ts.storage) {
612                                        t = ts.storage(table, 'tablesorter-pager') || {}; // fixes #387
613                                        p.page = isNaN(t.page) ? p.page : t.page;
614                                        p.size = ( isNaN(t.size) ? p.size : t.size ) || 10;
615                                        $.data(table, 'pagerLastSize', p.size);
616                                }
617
618                                $t
619                                        .unbind('filterStart filterEnd sortEnd disable enable destroy update updateRows updateAll addRows pageSize '.split(' ').join('.pager '))
620                                        .bind('filterStart.pager', function(e, filters) {
621                                                p.currentFilters = filters;
622                                                p.page = 0; // fixes #456
623                                        })
624                                        // update pager after filter widget completes
625                                        .bind('filterEnd.pager sortEnd.pager', function() {
626                                                if (p.initialized) {
627                                                        moveToPage(table, p, false);
628                                                        updatePageDisplay(table, p, false);
629                                                        fixHeight(table, p);
630                                                }
631                                        })
632                                        .bind('disable.pager', function(e){
633                                                e.stopPropagation();
634                                                showAllRows(table, p);
635                                        })
636                                        .bind('enable.pager', function(e){
637                                                e.stopPropagation();
638                                                enablePager(table, p, true);
639                                        })
640                                        .bind('destroy.pager', function(e){
641                                                e.stopPropagation();
642                                                destroyPager(table, p);
643                                        })
644                                        .bind('update updateRows updateAll addRows '.split(' ').join('.pager '), function(e){
645                                                e.stopPropagation();
646                                                hideRows(table, p);
647                                        })
648                                        .bind('pageSize.pager', function(e,v){
649                                                e.stopPropagation();
650                                                setPageSize(table, parseInt(v, 10) || 10, p);
651                                                hideRows(table, p);
652                                                updatePageDisplay(table, p, false);
653                                                if (p.$size.length) { p.$size.val(p.size); } // twice?
654                                        })
655                                        .bind('pageSet.pager', function(e,v){
656                                                e.stopPropagation();
657                                                p.page = (parseInt(v, 10) || 1) - 1;
658                                                if (p.$goto.length) { p.$goto.val(p.size); } // twice?
659                                                moveToPage(table, p);
660                                                updatePageDisplay(table, p, false);
661                                        });
662
663                                // clicked controls
664                                ctrls = [ p.cssFirst, p.cssPrev, p.cssNext, p.cssLast ];
665                                fxn = [ moveToFirstPage, moveToPrevPage, moveToNextPage, moveToLastPage ];
666                                pager.find(ctrls.join(','))
667                                        .unbind('click.pager')
668                                        .bind('click.pager', function(e){
669                                                e.stopPropagation();
670                                                var i, $t = $(this), l = ctrls.length;
671                                                if ( !$t.hasClass(p.cssDisabled) ) {
672                                                        for (i = 0; i < l; i++) {
673                                                                if ($t.is(ctrls[i])) {
674                                                                        fxn[i](table, p);
675                                                                        break;
676                                                                }
677                                                        }
678                                                }
679                                        });
680
681                                // goto selector
682                                p.$goto = pager.find(p.cssGoto);
683                                if ( p.$goto.length ) {
684                                        p.$goto
685                                                .unbind('change')
686                                                .bind('change', function(){
687                                                        p.page = $(this).val() - 1;
688                                                        moveToPage(table, p);
689                                                        updatePageDisplay(table, p, false);
690                                                });
691                                }
692
693                                // page size selector
694                                p.$size = pager.find(p.cssPageSize);
695                                if ( p.$size.length ) {
696                                        p.$size.unbind('change.pager').bind('change.pager', function() {
697                                                p.$size.val( $(this).val() ); // in case there are more than one pagers
698                                                if ( !$(this).hasClass(p.cssDisabled) ) {
699                                                        setPageSize(table, parseInt( $(this).val(), 10 ), p);
700                                                        changeHeight(table, p);
701                                                }
702                                                return false;
703                                        });
704                                }
705
706                                // clear initialized flag
707                                p.initialized = false;
708                                // before initialization event
709                                $t.trigger('pagerBeforeInitialized', p);
710
711                                enablePager(table, p, false);
712
713                                if ( typeof(p.ajaxUrl) === 'string' ) {
714                                        // ajax pager; interact with database
715                                        p.ajax = true;
716                                        //When filtering with ajax, allow only custom filtering function, disable default filtering since it will be done server side.
717                                        c.widgetOptions.filter_serversideFiltering = true;
718                                        c.serverSideSorting = true;
719                                        moveToPage(table, p);
720                                } else {
721                                        p.ajax = false;
722                                        // Regular pager; all rows stored in memory
723                                        $(this).trigger("appendCache", true);
724                                        hideRowsSetup(table, p);
725                                }
726
727                                changeHeight(table, p);
728
729                                // pager initialized
730                                if (!p.ajax) {
731                                        p.initialized = true;
732                                        $(table).trigger('pagerInitialized', p);
733                                }
734                        });
735                };
736
737        }()
738});
739// extend plugin scope
740$.fn.extend({
741        tablesorterPager: $.tablesorterPager.construct
742});
743
744})(jQuery);
Note: See TracBrowser for help on using the repository browser.