diff --git a/addons/pager/jquery.tablesorter.pager.js b/addons/pager/jquery.tablesorter.pager.js index 3fb9b9a8..0cc4e497 100644 --- a/addons/pager/jquery.tablesorter.pager.js +++ b/addons/pager/jquery.tablesorter.pager.js @@ -1,6 +1,6 @@ /*! * tablesorter pager plugin - * updated 4/12/2013 + * updated 5/7/2013 */ /*jshint browser:true, jquery:true, unused:false */ ;(function($) { @@ -100,7 +100,7 @@ tc = table.config, f = $(table).hasClass('hasFilters') && !c.ajaxUrl; c.totalPages = Math.ceil( c.totalRows / c.size ); // needed for "pageSize" method - c.filteredRows = (f) ? tc.$tbodies.children('tr:not(.' + (tc.widgetOptions && tc.widgetOptions.filter_filteredRow || 'filtered') + ',' + tc.selectorRemove + ')').length : c.totalRows; + c.filteredRows = (f) ? tc.$tbodies.eq(0).children('tr:not(.' + (tc.widgetOptions && tc.widgetOptions.filter_filteredRow || 'filtered') + ',' + tc.selectorRemove + ')').length : c.totalRows; c.filteredPages = (f) ? Math.ceil( c.filteredRows / c.size ) : c.totalPages; if ( Math.min( c.totalPages, c.filteredPages ) > 0 ) { t = (c.size * c.page > c.filteredRows); @@ -137,7 +137,7 @@ }, fixHeight = function(table, c) { - var d, h, $b = $(table.tBodies[0]); + var d, h, $b = table.config.$tbodies.eq(0); if (c.fixedHeight) { $b.find('tr.pagerSavedHeightSpacer').remove(); h = $.data(table, 'pagerSavedHeight'); @@ -151,7 +151,7 @@ }, changeHeight = function(table, c) { - var $b = $(table.tBodies[0]); + var $b = table.config.$tbodies.eq(0); $b.find('tr.pagerSavedHeightSpacer').remove(); $.data(table, 'pagerSavedHeight', $b.height()); fixHeight(table, c); @@ -162,7 +162,7 @@ if (!c.ajaxUrl) { var i, tc = table.config, - rows = tc.$tbodies.children('tr:not(.' + tc.cssChildRow + ')'), + rows = tc.$tbodies.eq(0).children('tr:not(.' + tc.cssChildRow + ')'), l = rows.length, s = ( c.page * c.size ), e = s + c.size, @@ -189,62 +189,82 @@ } }, - renderAjax = function(data, table, c, exception){ + renderAjax = function(data, table, c, xhr, exception){ // process data if ( typeof(c.ajaxProcessing) === "function" ) { // ajaxProcessing result: [ total, rows, headers ] - var i, j, hsh, $f, $sh, th, d, l, + var i, j, hsh, $f, $sh, th, d, l, $err, $t = $(table), tc = table.config, hl = $t.find('thead th').length, tds = '', - err = '' + - (exception ? exception.message + ' (' + exception.name + ')' : 'No rows found') + '', - result = c.ajaxProcessing(data) || [ 0, [] ], + result = c.ajaxProcessing(data, table) || [ 0, [] ], // allow [ total, rows, headers ] or [ rows, total, headers ] t = isNaN(result[0]) && !isNaN(result[1]); - c.totalRows = result[t ? 1 : 0] || 0; - d = result[t ? 0 : 1] || []; // row data - l = d.length; - th = result[2]; // headers - if ( l > 0 ) { - for ( i = 0; i < l; i++ ) { - tds += ''; - for ( j = 0; j < d[i].length; j++ ) { - // build tbody cells - tds += '' + d[i][j] + ''; - } - tds += ''; - } - } - // only add new header text if the length matches - if ( th && th.length === hl ) { - hsh = $t.hasClass('hasStickyHeaders'); - $sh = $t.find('.' + ((tc.widgetOptions && tc.widgetOptions.stickyHeaders) || 'tablesorter-stickyheader')); - $f = $t.find('tfoot tr:first').children(); - $t.find('th.' + tc.cssHeader).each(function(j){ - var $t = $(this), icn; - // add new test within the first span it finds, or just in the header - if ( $t.find('.' + tc.cssIcon).length ) { - icn = $t.find('.' + tc.cssIcon).clone(true); - $t.find('.tablesorter-header-inner').html( th[j] ).append(icn); - if ( hsh && $sh.length ) { - icn = $sh.find('th').eq(j).find('.' + tc.cssIcon).clone(true); - $sh.find('th').eq(j).find('.tablesorter-header-inner').html( th[j] ).append(icn); - } - } else { - $t.find('.tablesorter-header-inner').html( th[j] ); - $sh.find('th').eq(j).find('.tablesorter-header-inner').html( th[j] ); - } - $f.eq(j).html( th[j] ); - }); - } $t.find('thead tr.' + c.cssErrorRow).remove(); // Clean up any previous error. + if ( exception ) { + $err = $('' + ( + xhr.status === 0 ? 'Not connected, verify Network' : + xhr.status === 404 ? 'Requested page not found [404]' : + xhr.status === 500 ? 'Internal Server Error [500]' : + exception === 'parsererror' ? 'Requested JSON parse failed' : + exception === 'timeout' ? 'Time out error' : + exception === 'abort' ? 'Ajax Request aborted' : + 'Uncaught error: ' + xhr.statusText + ' [' + xhr.status + ']' ) + '') + .click(function(){ + $(this).remove(); + }) // add error row to thead instead of tbody, or clicking on the header will result in a parser error - $t.find('thead').append(err); + .appendTo( $t.find('thead:first') ); + tc.$tbodies.eq(0).empty(); } else { - $(table.tBodies[0]).html( tds ); // add rows to first tbody + c.totalRows = result[t ? 1 : 0] || c.totalRows || 0; + d = result[t ? 0 : 1] || []; // row data + l = d.length; + th = result[2]; // headers + if (d instanceof jQuery) { + // append jQuery object + tc.$tbodies.eq(0).empty().append(d); + } else if (d.length) { + // build table from array + if ( l > 0 ) { + for ( i = 0; i < l; i++ ) { + tds += ''; + for ( j = 0; j < d[i].length; j++ ) { + // build tbody cells + tds += '' + d[i][j] + ''; + } + tds += ''; + } + } + // add rows to first tbody + tc.$tbodies.eq(0).html( tds ); + } + // only add new header text if the length matches + if ( th && th.length === hl ) { + hsh = $t.hasClass('hasStickyHeaders'); + $sh = hsh ? tc.$sticky.children('thead:first').children().children() : ''; + $f = $t.find('tfoot tr:first').children(); + $t.find('th.' + tc.cssHeader).each(function(j){ + var $t = $(this), icn; + // add new test within the first span it finds, or just in the header + if ( $t.find('.' + tc.cssIcon).length ) { + icn = $t.find('.' + tc.cssIcon).clone(true); + $t.find('.tablesorter-header-inner').html( th[j] ).append(icn); + if ( hsh && $sh.length ) { + icn = $sh.eq(j).find('.' + tc.cssIcon).clone(true); + $sh.eq(j).find('.tablesorter-header-inner').html( th[j] ).append(icn); + } + } else { + $t.find('.tablesorter-header-inner').html( th[j] ); + if (hsh && $sh.length) { + $sh.eq(j).find('.tablesorter-header-inner').html( th[j] ); + } + } + $f.eq(j).html( th[j] ); + }); + } } if (tc.showProcessing) { $.tablesorter.isProcessing(table); // remove loading icon @@ -263,20 +283,21 @@ getAjax = function(table, c){ var url = getAjaxUrl(table, c), + $doc = $(document), tc = table.config; if ( url !== '' ) { if (tc.showProcessing) { $.tablesorter.isProcessing(table, true); // show loading icon } - $(document).bind('ajaxError.pager', function(e, xhr, settings, exception) { - if (settings.url === url) { - renderAjax(null, table, c, exception); - $(document).unbind('ajaxError.pager'); + $doc.bind('ajaxError.pager', function(e, xhr, settings, exception) { + if (url.match(settings.url)) { + renderAjax(null, table, c, xhr, exception); + $doc.unbind('ajaxError.pager'); } }); $.getJSON(url, function(data) { renderAjax(data, table, c); - $(document).unbind('ajaxError.pager'); + $doc.unbind('ajaxError.pager'); }); } }, @@ -318,8 +339,7 @@ renderTable = function(table, rows, c) { c.isDisabled = false; // needed because sorting will change the page and re-enable the pager - var i, j, o, - f = document.createDocumentFragment(), + var i, j, o, $tb, l = rows.length, s = ( c.page * c.size ), e = ( s + c.size ); @@ -331,17 +351,16 @@ if ( e > rows.length ) { e = rows.length; } - $(table.tBodies[0]).addClass('tablesorter-hidden'); $.tablesorter.clearTableBody(table); + $tb = $.tablesorter.processTbody(table, table.config.$tbodies.eq(0), true); for ( i = s; i < e; i++ ) { o = rows[i]; l = o.length; for ( j = 0; j < l; j++ ) { - f.appendChild(o[j]); + $tb.appendChild(o[j]); } } - table.tBodies[0].appendChild(f); - $(table.tBodies[0]).removeClass('tablesorter-hidden'); + $.tablesorter.processTbody(table, $tb, false); } if ( c.page >= c.totalPages ) { moveToLastPage(table, c); @@ -361,7 +380,7 @@ c.page = 0; c.size = c.totalRows; c.totalPages = 1; - $('tr.pagerSavedHeightSpacer', table.tBodies[0]).remove(); + $(table).find('tr.pagerSavedHeightSpacer').remove(); renderTable(table, table.config.rowsCopy, c); } // disable size selector diff --git a/css/theme.black-ice.css b/css/theme.black-ice.css index e388e17a..5b46fc17 100644 --- a/css/theme.black-ice.css +++ b/css/theme.black-ice.css @@ -172,3 +172,9 @@ caption { -o-transition: height 0.1s ease; transition: height 0.1s ease; } + +/* ajax error row */ +.tablesorter .tablesorter-errorRow td { + cursor: pointer; + background-color: #e6bf99; +} diff --git a/css/theme.blue.css b/css/theme.blue.css index 93b45a5c..ede9631d 100644 --- a/css/theme.blue.css +++ b/css/theme.blue.css @@ -207,3 +207,9 @@ caption { -o-transition: height 0.1s ease; transition: height 0.1s ease; } + +/* ajax error row */ +.tablesorter .tablesorter-errorRow td { + cursor: pointer; + background-color: #e6bf99; +} diff --git a/css/theme.bootstrap.css b/css/theme.bootstrap.css index 38c7e3ab..4c67f59c 100644 --- a/css/theme.bootstrap.css +++ b/css/theme.bootstrap.css @@ -131,3 +131,9 @@ caption { .tablesorter-bootstrap .tablesorter-pager .pagedisplay { border: 0; } + +/* ajax error row */ +.tablesorter .tablesorter-errorRow td { + cursor: pointer; + background-color: #e6bf99; +} diff --git a/css/theme.dark.css b/css/theme.dark.css index 1334d9da..a763fa2e 100644 --- a/css/theme.dark.css +++ b/css/theme.dark.css @@ -173,3 +173,9 @@ caption { -o-transition: height 0.1s ease; transition: height 0.1s ease; } + +/* ajax error row */ +.tablesorter .tablesorter-errorRow td { + cursor: pointer; + background-color: #e6bf99; +} diff --git a/css/theme.default.css b/css/theme.default.css index 0756d139..2f158b79 100644 --- a/css/theme.default.css +++ b/css/theme.default.css @@ -175,3 +175,9 @@ caption { -o-transition: height 0.1s ease; transition: height 0.1s ease; } + +/* ajax error row */ +.tablesorter .tablesorter-errorRow td { + cursor: pointer; + background-color: #e6bf99; +} diff --git a/css/theme.dropbox.css b/css/theme.dropbox.css index 825c300d..f056f0b3 100644 --- a/css/theme.dropbox.css +++ b/css/theme.dropbox.css @@ -193,3 +193,9 @@ caption { -o-transition: height 0.1s ease; transition: height 0.1s ease; } + +/* ajax error row */ +.tablesorter .tablesorter-errorRow td { + cursor: pointer; + background-color: #e6bf99; +} diff --git a/css/theme.green.css b/css/theme.green.css index eae8bcc4..836e3737 100644 --- a/css/theme.green.css +++ b/css/theme.green.css @@ -190,3 +190,9 @@ caption { -o-transition: height 0.1s ease; transition: height 0.1s ease; } + +/* ajax error row */ +.tablesorter .tablesorter-errorRow td { + cursor: pointer; + background-color: #e6bf99; +} diff --git a/css/theme.grey.css b/css/theme.grey.css index 37287755..2ec36699 100644 --- a/css/theme.grey.css +++ b/css/theme.grey.css @@ -226,3 +226,9 @@ caption { -o-transition: height 0.1s ease; transition: height 0.1s ease; } + +/* ajax error row */ +.tablesorter .tablesorter-errorRow td { + cursor: pointer; + background-color: #e6bf99; +} diff --git a/css/theme.ice.css b/css/theme.ice.css index 044911dc..44596194 100644 --- a/css/theme.ice.css +++ b/css/theme.ice.css @@ -181,3 +181,9 @@ caption { -o-transition: height 0.1s ease; transition: height 0.1s ease; } + +/* ajax error row */ +.tablesorter .tablesorter-errorRow td { + cursor: pointer; + background-color: #e6bf99; +} diff --git a/css/theme.jui.css b/css/theme.jui.css index be00c965..da00e00f 100644 --- a/css/theme.jui.css +++ b/css/theme.jui.css @@ -137,3 +137,9 @@ caption { -o-transition: height 0.1s ease; transition: height 0.1s ease; } + +/* ajax error row */ +.tablesorter .tablesorter-errorRow td { + cursor: pointer; + background-color: #e6bf99; +} diff --git a/css/theme.less b/css/theme.less index 99e071af..5ac6444d 100644 --- a/css/theme.less +++ b/css/theme.less @@ -27,10 +27,11 @@ @bodyBackground : #fff; @bodyTextColor : #000; -@headerSortUp : lighten(spin(@headerBackground, 5), 10%); /* desaturate(@headerBackground, 10%); */ -@headerSortDown : darken(spin(@headerBackground, -5), 10%); /* darken(@headerSortUp, 5%); */ +@headerAsc : darken(spin(@headerBackground, 5), 10%); /* darken(@headerBackground, 10%); */ +@headerDesc : lighten(spin(@headerBackground, -5), 10%); /* desaturate(@headerAsc, 5%); */ @captionBackground : #fff; /* it might be best to match the document body background color here */ +@errorBackground : #e6bf99; /* ajax error message (added to thead) */ @filterCellBackground : #eee; @filterElementTextColor: #333; @@ -90,15 +91,15 @@ /* black */ @unsortedBlack : url(data:image/gif;base64,R0lGODlhFQAJAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==); -@sortUpBlack : url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7); -@sortDownBlack : url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7); +@sortAscBlack : url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7); +@sortDescBlack : url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7); @filterIconBlack : url(data:image/gif;base64,R0lGODlhCgAMALMAAEpKSklJSUNDQ0FBQUBAQDk5OTc3NzY2NiQkJP///wAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAkALAAAAAAKAAwAAAQnEMlJk72YamQE+KBgJEcAAsFxFWeBJcRHvInxjfRHW/oODLsEEBMBADs=); /* white */ @unsortedWhite : url(data:image/gif;base64,R0lGODlhFQAJAIAAAP///////yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==); -@sortUpWhite : url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7); -@sortDownWhite : url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7); +@sortAscWhite : url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7); +@sortDescWhite : url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7); @filterIconWhite : url(data:image/gif;base64,R0lGODlhCgANALMAAP////r6+u7u7ufn5+Hh4d3d3cXFxb+/v76+vru7u7m5uf///wAAAAAAAAAAAAAAACH5BAEAAAsALAAAAAAKAA0AAAQpUMhJl72YanEG+OBwLEkAAkFyGaeBLcVXvAvyIfTy5TrAAwQeQcEjYiIAOw==); @@ -111,20 +112,20 @@ background-image: @unsortedWhite; color: lighten(@headerTextColor, 90%); } -.sortUp (@a) when (lightness(@a) >= 50%) { - background-image: @sortUpBlack; +.sortAsc (@a) when (lightness(@a) >= 50%) { + background-image: @sortAscBlack; color: @headerTextColor; } -.sortUp (@a) when (lightness(@a) < 50%) { - background-image: @sortUpWhite; +.sortAsc (@a) when (lightness(@a) < 50%) { + background-image: @sortAscWhite; color: lighten(@headerTextColor, 90%); } -.sortDown (@a) when (lightness(@a) >= 50%) { - background-image: @sortDownBlack; +.sortDesc (@a) when (lightness(@a) >= 50%) { + background-image: @sortDescBlack; color: @headerTextColor; } -.sortDown (@a) when (lightness(@a) < 50%) { - background-image: @sortDownWhite; +.sortDesc (@a) when (lightness(@a) < 50%) { + background-image: @sortDescWhite; color: lighten(@headerTextColor, 90%); } .filterIcon (@a) when (lightness(@a) >= 50%) { @@ -181,19 +182,19 @@ padding: @overallPadding; } - .tablesorter-headerSortUp { - background-color: @headerSortUp; - .sortUp(@headerBackground); + .tablesorter-headerAsc { + background-color: @headerAsc; + .sortAsc(@headerBackground); } - .tablesorter-headerSortDown { - background-color: @headerSortDown; - .sortDown(@headerBackground); + .tablesorter-headerDesc { + background-color: @headerDesc; + .sortDesc(@headerBackground); } /* tfoot */ - tfoot .tablesorter-headerSortUp, - tfoot .tablesorter-headerSortDown { + tfoot .tablesorter-headerAsc, + tfoot .tablesorter-headerDesc { /* remove sort arrows from footer */ background-image: none; } @@ -316,4 +317,10 @@ filter: alpha(opacity=0); } + /* ajax error row */ + .tablesorter-errorRow td { + cursor: pointer; + background-color: @errorBackground; + } + }