From 396952b57ada52e1b70afd5b76e4492cab6b4811 Mon Sep 17 00:00:00 2001 From: Mottie Date: Sat, 1 Feb 2014 22:06:01 -0600 Subject: [PATCH] Add filter_hideEmpty; Correct pager & widget updating. Fixes #450. When all rows are removed from the table, ensure widgets are applied (including refreshing the filter search), and ensure the pager display updates. Add filter_hideEmpty option to allow setting hiding the filter row when the table doesn't contain any tbody rows. --- addons/pager/jquery.tablesorter.pager.js | 6 ++++-- docs/index.html | 25 ++++++++++++++++++++++++ js/jquery.tablesorter.js | 6 +++++- js/jquery.tablesorter.widgets.js | 12 ++++++++---- js/widgets/widget-pager.js | 13 ++++++++---- 5 files changed, 51 insertions(+), 11 deletions(-) diff --git a/addons/pager/jquery.tablesorter.pager.js b/addons/pager/jquery.tablesorter.pager.js index 996af125..72f47eb3 100644 --- a/addons/pager/jquery.tablesorter.pager.js +++ b/addons/pager/jquery.tablesorter.pager.js @@ -116,8 +116,8 @@ d = p.cssDisabled, dis = !!disable, first = ( dis || p.page === 0 ), - last = ( dis || p.page === tp - 1 || p.totalPages === 0 ), - tp = Math.min( p.totalPages, p.filteredPages ); + tp = Math.min( p.totalPages, p.filteredPages ), + last = ( dis || (p.page === tp - 1) || p.totalPages === 0 ); if ( p.updateArrows ) { p.$container.find(p.cssFirst + ',' + p.cssPrev)[ first ? a : r ](d).attr('aria-disabled', first); p.$container.find(p.cssNext + ',' + p.cssLast)[ last ? a : r ](d).attr('aria-disabled', last); @@ -603,6 +603,8 @@ p.size = $.data(table, 'pagerLastSize') || p.size || 10; p.totalPages = Math.ceil( p.totalRows / p.size ); renderTable(table, rows, p); + // update display here in case all rows are removed + updatePageDisplay(table, p, false); } }; diff --git a/docs/index.html b/docs/index.html index 9a9daa3d..d1357fe0 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1508,6 +1508,8 @@ $(function(){ filter_formatter : null, // add custom filter functions using this option. filter_functions : null, + // hide filter row when table is empty + filter_hideEmpty : true, // if true, the filter row is hidden initially until hovered/focused. filter_hideFilters : false, // if true, make all searches case-insensitive. @@ -2083,6 +2085,29 @@ $(function(){ Example + : true, // hide filter row when table is empty + + + + Boolean + true + + Filter widget: Set this option to false to always show the filter row; by default, the filter row is completely hidden when no rows exist within the tbody (v2.15). +
+
+ Use the filter_hideEmpty option as follows: +
$(function(){
+  $("table").tablesorter({
+    widgets: ["filter"],
+    widgetOptions : {
+      filter_hideEmpty : false
+    }
+  });
+});
+ + + + Boolean diff --git a/js/jquery.tablesorter.js b/js/jquery.tablesorter.js index 647028d1..9a474512 100644 --- a/js/jquery.tablesorter.js +++ b/js/jquery.tablesorter.js @@ -327,7 +327,11 @@ c2 = c.cache, r, n, totalRows, checkCell, $bk, $tb, i, j, k, l, pos, appendTime; - if (isEmptyObject(c2)) { return; } // empty table - fixes #206/#346 + // empty table - fixes #206/#346 + if (isEmptyObject(c2)) { + // run pager appender in case the table was just emptied + return c.appender ? c.appender(table, rows) : ''; + } if (c.debug) { appendTime = new Date(); } diff --git a/js/jquery.tablesorter.widgets.js b/js/jquery.tablesorter.widgets.js index 84a683b2..06fd5c90 100644 --- a/js/jquery.tablesorter.widgets.js +++ b/js/jquery.tablesorter.widgets.js @@ -355,6 +355,7 @@ ts.addWidget({ filter_filteredRow : 'filtered', // class added to filtered rows; needed by pager plugin filter_formatter : null, // add custom filter elements to the filter row filter_functions : null, // add custom filter functions using this option + filter_hideEmpty : true, // hide filter row when table is empty filter_hideFilters : false, // collapse filter row when mouse leaves the area filter_ignoreCase : true, // if true, make all searches case-insensitive filter_liveSearch : true, // if true, search column content while the user types (with a delay) @@ -369,9 +370,7 @@ ts.addWidget({ }, format: function(table, c, wo) { if (!c.$table.hasClass('hasFilters')) { - if (c.parsers || !c.parsers && wo.filter_serversideFiltering) { - ts.filter.init(table, c, wo); - } + ts.filter.init(table, c, wo); } }, remove: function(table, c, wo) { @@ -560,7 +559,8 @@ ts.filter = { } c.$table.bind('addRows updateCell update updateRows updateComplete appendCache filterReset filterEnd search '.split(' ').join('.tsfilter '), function(event, filter) { - if ( !/(search|filterReset|filterEnd)/.test(event.type) ) { + c.$table.find('.' + ts.css.filterRow).toggle( !(wo.filter_hideEmpty && $.isEmptyObject(c.cache)) ); // fixes #450 + if ( !/(search|filter)/.test(event.type) ) { event.stopPropagation(); ts.filter.buildDefault(table, true); } @@ -571,6 +571,10 @@ ts.filter = { } else { // send false argument to force a new search; otherwise if the filter hasn't changed, it will return filter = event.type === 'search' ? filter : event.type === 'updateComplete' ? c.$table.data('lastSearch') : ''; + if (/(update|add)/.test(event.type)) { + // force a new search since content has changed + c.lastCombinedFilter = null; + } // pass true (dontSkip) to prevent the tablesorter.setFilters function from skipping the first input // ensures all inputs are updated when a search is triggered on the table $('table').trigger('search', [...]); ts.filter.searching(table, filter, true); diff --git a/js/widgets/widget-pager.js b/js/widgets/widget-pager.js index 216c313f..56166d85 100644 --- a/js/widgets/widget-pager.js +++ b/js/widgets/widget-pager.js @@ -301,10 +301,10 @@ tsp = ts.pager = { var p = c.pager, dis = !!disable, first = dis || p.page === 0, + tp = Math.min( p.totalPages, p.filteredPages ), last = dis || p.page === tp - 1 || p.totalPages === 0, wo = c.widgetOptions, - s = wo.pager_selectors, - tp = Math.min( p.totalPages, p.filteredPages ); + s = wo.pager_selectors; if ( wo.pager_updateArrows ) { p.$container.find(s.first + ',' + s.prev).toggleClass(wo.pager_css.disabled, first).attr('aria-disabled', first); p.$container.find(s.next + ',' + s.last).toggleClass(wo.pager_css.disabled, last).attr('aria-disabled', last); @@ -695,7 +695,10 @@ tsp = ts.pager = { // don't allow rendering multiple times on the same page/size/totalpages/filters/sorts if ( l.page === p.page && l.size === p.size && l.totalPages === p.totalPages && (l.currentFilters || []).join(',') === (p.currentFilters || []).join(',') && - l.sortList === (c.sortList || []).join(',') ) { return; } + l.sortList === (c.sortList || []).join(',') ) { + // make sure widgets are applied - fixes #450 + return flag === true ? c.$table.trigger('applyWidgets') : ''; + } if (c.debug) { ts.log('Pager changing to page ' + p.page); } @@ -801,7 +804,9 @@ tsp = ts.pager = { p.totalRows = c.widgetOptions.pager_countChildRows ? c.$tbodies.eq(0).children().length : rows.length; p.size = $.data(table, 'pagerLastSize') || p.size || wo.pager_size || 10; p.totalPages = Math.ceil( p.totalRows / p.size ); - tsp.moveToPage(table, p); + tsp.moveToPage(table, p, true); + // update display here in case all rows are removed + tsp.updatePageDisplay(table, c, false); } }