mirror of
https://github.com/Mottie/tablesorter.git
synced 2024-11-15 23:54:22 +00:00
Events sortEnd & updateComplete fire on empty tables. Fixes #532
Sort events now only fire while sorting, previously they fired when updating an unsorted table Updated pager to fire appropriately when using ajax Added unit tests (non-ajax) events
This commit is contained in:
parent
c4d02b312a
commit
474e446ef8
@ -124,7 +124,7 @@
|
||||
}
|
||||
},
|
||||
|
||||
updatePageDisplay = function(table, p, flag) {
|
||||
updatePageDisplay = function(table, p, completed) {
|
||||
var i, pg, s, out,
|
||||
c = table.config,
|
||||
f = c.$table.hasClass('hasFilters') && !p.ajaxUrl,
|
||||
@ -168,7 +168,7 @@
|
||||
}
|
||||
}
|
||||
pagerArrows(p);
|
||||
if (p.initialized && flag !== false) {
|
||||
if (p.initialized && completed !== false) {
|
||||
c.$table.trigger('pagerComplete', p);
|
||||
// save pager info to storage
|
||||
if (p.savePages && ts.storage) {
|
||||
@ -331,7 +331,8 @@
|
||||
}
|
||||
// make sure last pager settings are saved, prevents multiple server side calls with
|
||||
// the same parameters
|
||||
p.last.totalPages = p.totalPages = Math.ceil( p.totalRows / ( p.size || 10 ) );
|
||||
p.totalPages = Math.ceil( p.totalRows / ( p.size || 10 ) );
|
||||
p.last.totalRows = p.totalRows;
|
||||
p.last.currentFilters = p.currentFilters;
|
||||
p.last.sortList = (c.sortList || []).join(',');
|
||||
updatePageDisplay(table, p);
|
||||
@ -339,8 +340,9 @@
|
||||
$t.trigger('updateCache', [function(){
|
||||
if (p.initialized) {
|
||||
// apply widgets after table has rendered
|
||||
$t.trigger('applyWidgets');
|
||||
$t.trigger('pagerChange', p);
|
||||
$t
|
||||
.trigger('applyWidgets')
|
||||
.trigger('pagerChange', p);
|
||||
}
|
||||
}]);
|
||||
}
|
||||
@ -429,6 +431,8 @@
|
||||
|
||||
renderTable = function(table, rows, p) {
|
||||
var i, $tb,
|
||||
$t = $(table),
|
||||
c = table.config,
|
||||
l = rows && rows.length || 0, // rows may be undefined
|
||||
s = ( p.page * p.size ),
|
||||
e = ( s + p.size );
|
||||
@ -438,7 +442,7 @@
|
||||
moveToLastPage(table, p);
|
||||
}
|
||||
p.isDisabled = false; // needed because sorting will change the page and re-enable the pager
|
||||
if (p.initialized) { $(table).trigger('pagerChange', p); }
|
||||
if (p.initialized) { $t.trigger('pagerChange', p); }
|
||||
|
||||
if ( !p.removeRows ) {
|
||||
hideRows(table, p);
|
||||
@ -447,7 +451,7 @@
|
||||
e = rows.length;
|
||||
}
|
||||
ts.clearTableBody(table);
|
||||
$tb = ts.processTbody(table, table.config.$tbodies.eq(0), true);
|
||||
$tb = ts.processTbody(table, c.$tbodies.eq(0), true);
|
||||
for ( i = s; i < e; i++ ) {
|
||||
$tb.append(rows[i]);
|
||||
}
|
||||
@ -456,7 +460,10 @@
|
||||
|
||||
updatePageDisplay(table, p);
|
||||
if ( !p.isDisabled ) { fixHeight(table, p); }
|
||||
$(table).trigger('applyWidgets');
|
||||
$t.trigger('applyWidgets');
|
||||
if (table.isUpdating) {
|
||||
$t.trigger("updateComplete", table);
|
||||
}
|
||||
},
|
||||
|
||||
showAllRows = function(table, p){
|
||||
@ -484,9 +491,10 @@
|
||||
});
|
||||
},
|
||||
|
||||
moveToPage = function(table, p, flag) {
|
||||
moveToPage = function(table, p, pageMoved) {
|
||||
if ( p.isDisabled ) { return; }
|
||||
var c = table.config,
|
||||
$t = $(table),
|
||||
l = p.last,
|
||||
pg = Math.min( p.totalPages, p.filteredPages );
|
||||
if ( p.page < 0 ) { p.page = 0; }
|
||||
@ -513,12 +521,16 @@
|
||||
if (p.ajax) {
|
||||
getAjax(table, p);
|
||||
} else if (!p.ajax) {
|
||||
renderTable(table, table.config.rowsCopy, p);
|
||||
renderTable(table, c.rowsCopy, p);
|
||||
}
|
||||
$.data(table, 'pagerLastPage', p.page);
|
||||
if (p.initialized && flag !== false) {
|
||||
c.$table.trigger('pageMoved', p);
|
||||
c.$table.trigger('applyWidgets');
|
||||
if (p.initialized && pageMoved !== false) {
|
||||
$t
|
||||
.trigger('pageMoved', p)
|
||||
.trigger('applyWidgets');
|
||||
if (table.isUpdating) {
|
||||
$t.trigger('updateComplete');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -331,7 +331,8 @@
|
||||
// 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) : '';
|
||||
return c.appender ? c.appender(table, rows) :
|
||||
table.isUpdating ? c.$table.trigger("updateComplete", table) : ''; // Fixes #532
|
||||
}
|
||||
if (c.debug) {
|
||||
appendTime = new Date();
|
||||
@ -368,9 +369,9 @@
|
||||
}
|
||||
// apply table widgets; but not before ajax completes
|
||||
if (!init && !c.appender) { ts.applyWidget(table); }
|
||||
// trigger sortend
|
||||
$(table).trigger("sortEnd", table);
|
||||
$(table).trigger("updateComplete", table);
|
||||
if (table.isUpdating) {
|
||||
c.$table.trigger("updateComplete", table);
|
||||
}
|
||||
}
|
||||
|
||||
// computeTableHeaderCellIndexes from:
|
||||
@ -682,6 +683,7 @@
|
||||
setHeadersCss(table);
|
||||
multisort(table);
|
||||
appendToTable(table);
|
||||
$table.trigger("sortEnd", table);
|
||||
}, 1);
|
||||
}
|
||||
|
||||
@ -754,8 +756,9 @@
|
||||
}
|
||||
|
||||
function resortComplete($table, callback){
|
||||
var c = $table[0].config;
|
||||
if (c.pager && !c.pager.ajax) {
|
||||
var table = $table[0],
|
||||
c = table.config;
|
||||
if (table.isUpdating) {
|
||||
$table.trigger('updateComplete');
|
||||
}
|
||||
if (typeof callback === "function") {
|
||||
@ -764,12 +767,13 @@
|
||||
}
|
||||
|
||||
function checkResort($table, flag, callback) {
|
||||
var sl = $table[0].config.sortList;
|
||||
// don't try to resort if the table is still processing
|
||||
// this will catch spamming of the updateCell method
|
||||
if (flag !== false && !$table[0].isProcessing) {
|
||||
$table.trigger("sorton", [$table[0].config.sortList, function(){
|
||||
if (flag !== false && !$table[0].isProcessing && sl.length) {
|
||||
$table.trigger("sorton", [sl, function(){
|
||||
resortComplete($table, callback);
|
||||
}]);
|
||||
}, true]);
|
||||
} else {
|
||||
resortComplete($table, callback);
|
||||
}
|
||||
@ -780,7 +784,7 @@
|
||||
$table = c.$table;
|
||||
// apply easy methods that trigger bound events
|
||||
$table
|
||||
.unbind('sortReset update updateRows updateCell updateAll addRows sorton appendCache updateCache applyWidgetId applyWidgets refreshWidgets destroy mouseup mouseleave '.split(' ').join('.tablesorter '))
|
||||
.unbind('sortReset update updateRows updateCell updateAll addRows updateComplete sorton appendCache updateCache applyWidgetId applyWidgets refreshWidgets destroy mouseup mouseleave '.split(' ').join('.tablesorter '))
|
||||
.bind("sortReset.tablesorter", function(e){
|
||||
e.stopPropagation();
|
||||
c.sortList = [];
|
||||
@ -790,6 +794,7 @@
|
||||
})
|
||||
.bind("updateAll.tablesorter", function(e, resort, callback){
|
||||
e.stopPropagation();
|
||||
table.isUpdating = true;
|
||||
ts.refreshWidgets(table, true, true);
|
||||
ts.restoreHeaders(table);
|
||||
buildHeaders(table);
|
||||
@ -799,12 +804,14 @@
|
||||
})
|
||||
.bind("update.tablesorter updateRows.tablesorter", function(e, resort, callback) {
|
||||
e.stopPropagation();
|
||||
table.isUpdating = true;
|
||||
// update sorting (if enabled/disabled)
|
||||
updateHeader(table);
|
||||
commonUpdate(table, resort, callback);
|
||||
})
|
||||
.bind("updateCell.tablesorter", function(e, cell, resort, callback) {
|
||||
e.stopPropagation();
|
||||
table.isUpdating = true;
|
||||
$table.find(c.selectorRemove).remove();
|
||||
// get position from the dom
|
||||
var l, row, icell,
|
||||
@ -826,6 +833,7 @@
|
||||
})
|
||||
.bind("addRows.tablesorter", function(e, $row, resort, callback) {
|
||||
e.stopPropagation();
|
||||
table.isUpdating = true;
|
||||
if (isEmptyObject(c.cache)) {
|
||||
// empty table, do an update instead - fixes #450
|
||||
updateHeader(table);
|
||||
@ -856,6 +864,9 @@
|
||||
checkResort($table, resort, callback);
|
||||
}
|
||||
})
|
||||
.bind("updateComplete.tablesorter", function(){
|
||||
table.isUpdating = false;
|
||||
})
|
||||
.bind("sorton.tablesorter", function(e, list, callback, init) {
|
||||
var c = table.config;
|
||||
e.stopPropagation();
|
||||
@ -870,6 +881,7 @@
|
||||
// sort the table and append it to the dom
|
||||
multisort(table);
|
||||
appendToTable(table, init);
|
||||
$table.trigger("sortEnd", this);
|
||||
if (typeof callback === "function") {
|
||||
callback(table);
|
||||
}
|
||||
@ -994,7 +1006,7 @@
|
||||
ts.applyWidget(table, true);
|
||||
// if user has supplied a sort list to constructor
|
||||
if (c.sortList.length > 0) {
|
||||
$table.trigger("sorton", [c.sortList, {}, !c.initWidgets]);
|
||||
$table.trigger("sorton", [c.sortList, {}, !c.initWidgets, true]);
|
||||
} else {
|
||||
setHeadersCss(table);
|
||||
if (c.initWidgets) {
|
||||
@ -1135,7 +1147,7 @@
|
||||
// disable tablesorter
|
||||
$t
|
||||
.removeData('tablesorter')
|
||||
.unbind('sortReset update updateAll updateRows updateCell addRows sorton appendCache updateCache applyWidgetId applyWidgets refreshWidgets destroy mouseup mouseleave keypress sortBegin sortEnd '.split(' ').join('.tablesorter '));
|
||||
.unbind('sortReset update updateAll updateRows updateCell addRows updateComplete sorton appendCache updateCache applyWidgetId applyWidgets refreshWidgets destroy mouseup mouseleave keypress sortBegin sortEnd '.split(' ').join('.tablesorter '));
|
||||
c.$headers.add($f)
|
||||
.removeClass( [ts.css.header, c.cssHeader, c.cssAsc, c.cssDesc, ts.css.sortAsc, ts.css.sortDesc, ts.css.sortNone].join(' ') )
|
||||
.removeAttr('data-column');
|
||||
|
@ -315,7 +315,7 @@ tsp = ts.pager = {
|
||||
}
|
||||
},
|
||||
|
||||
updatePageDisplay: function(table, c, flag) {
|
||||
updatePageDisplay: function(table, c, completed) {
|
||||
var i, pg, s, out,
|
||||
wo = c.widgetOptions,
|
||||
p = c.pager,
|
||||
@ -361,7 +361,7 @@ tsp = ts.pager = {
|
||||
}
|
||||
}
|
||||
tsp.pagerArrows(c);
|
||||
if (p.initialized && flag !== false) {
|
||||
if (p.initialized && completed !== false) {
|
||||
c.$table.trigger('pagerComplete', c);
|
||||
// save pager info to storage
|
||||
if (wo.pager_savePages && ts.storage) {
|
||||
@ -521,7 +521,8 @@ tsp = ts.pager = {
|
||||
}
|
||||
// make sure last pager settings are saved, prevents multiple server side calls with
|
||||
// the same parameters
|
||||
p.last.totalPages = p.totalPages = Math.ceil( p.totalRows / ( p.size || 10 ) );
|
||||
p.totalPages = Math.ceil( p.totalRows / ( p.size || 10 ) );
|
||||
p.last.totalRows = p.totalRows;
|
||||
p.last.currentFilters = p.currentFilters;
|
||||
p.last.sortList = (c.sortList || []).join(',');
|
||||
tsp.updatePageDisplay(table, c);
|
||||
@ -650,6 +651,9 @@ tsp = ts.pager = {
|
||||
wo.pager_startPage = p.page;
|
||||
wo.pager_size = p.size;
|
||||
c.$table.trigger('applyWidgets');
|
||||
if (table.isUpdating) {
|
||||
c.$table.trigger('updateComplete');
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
@ -680,7 +684,7 @@ tsp = ts.pager = {
|
||||
});
|
||||
},
|
||||
|
||||
moveToPage: function(table, p, flag) {
|
||||
moveToPage: function(table, p, pageMoved) {
|
||||
if ( p.isDisabled ) { return; }
|
||||
var c = table.config,
|
||||
l = p.last,
|
||||
@ -714,8 +718,11 @@ tsp = ts.pager = {
|
||||
tsp.renderTable(table, c.rowsCopy);
|
||||
}
|
||||
$.data(table, 'pagerLastPage', p.page);
|
||||
if (p.initialized && flag !== false) {
|
||||
if (p.initialized && pageMoved !== false) {
|
||||
c.$table.trigger('pageMoved', c);
|
||||
if (!p.ajax && table.isUpdating) {
|
||||
c.$table.trigger('updateComplete');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -804,6 +811,8 @@ tsp = ts.pager = {
|
||||
tsp.moveToPage(table, p, true);
|
||||
// update display here in case all rows are removed
|
||||
tsp.updatePageDisplay(table, c, false);
|
||||
} else {
|
||||
tsp.moveToPage(table, p, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
44
test.html
44
test.html
@ -10,8 +10,8 @@
|
||||
<script src="testing/jshint-r12.js"></script>
|
||||
<script src="testing/jquery-1.8.3.min.js"></script>
|
||||
<script src="js/jquery.tablesorter.js"></script>
|
||||
<script src="js/jquery.metadata.js"></script>
|
||||
<script src="js/parsers/parser-ipv6.js"></script>
|
||||
<script src="js/jquery.metadata.js"></script>
|
||||
<script src="testing/testing.js"></script>
|
||||
<script src="testing/testing-ipv6.js"></script>
|
||||
|
||||
@ -46,12 +46,15 @@
|
||||
*/
|
||||
|
||||
$(function(){
|
||||
// keep stuff in order; yeah I know every test needs to be atomic - bleh
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
var ts = $.tablesorter,
|
||||
$table1 = $('.tester:eq(0)'),
|
||||
$table2 = $('.tester:eq(1)'),
|
||||
$table3 = $('.tester:eq(2)'),
|
||||
$table4 = $('.tester:eq(3)'),
|
||||
$table5 = $('.tester:eq(4)'), // empty table
|
||||
table1 = $table1[0],
|
||||
table2 = $table2[0],
|
||||
table3 = $table3[0],
|
||||
@ -114,6 +117,20 @@
|
||||
}
|
||||
});
|
||||
|
||||
$table5
|
||||
.bind( events.join(' '), function(e){
|
||||
if (e.type === events[sortIndx%3]) {
|
||||
sortIndx++;
|
||||
}
|
||||
})
|
||||
.bind('updateComplete', function(){
|
||||
updateIndx++;
|
||||
})
|
||||
.tablesorter();
|
||||
|
||||
// ensure all sort events fire on an empty table
|
||||
$table5.trigger('sorton', [ [[0,0]] ]);
|
||||
|
||||
/************************************************
|
||||
JSHint testing
|
||||
************************************************/
|
||||
@ -235,8 +252,8 @@
|
||||
parserTests = 85,
|
||||
// skipping metadata parser
|
||||
sample1 = {
|
||||
'text' : { 'test': 'test', 'TesT': 'test', '\u00e1 test': 'á test' },
|
||||
'currency' : { '£1': 1, '($2.23)': -2.23, '5€': 5, '(11¤)': -11, '500¥': 500, '25¢': 25, '$1,000.50': 1000.5 },
|
||||
'text' : { 'test': 'test', 'TesT': 'test', '\u00e1 test': '\u00e1 test' },
|
||||
'currency' : { '\u00a31': 1, '($2.23)': -2.23, '5\u20ac': 5, '(11\u00a4)': -11, '500\u00a5': 500, '25\u00a2': 25, '$1,000.50': 1000.5 },
|
||||
'ipAddress' : { '255.255.255.255': 255255255255, '32.32.32.32': 32032032032, '1.1.1.1': 1001001001 },
|
||||
'url' : { 'http://google.com': 'google.com', 'ftp://fred.com': 'fred.com', 'https://github.com': 'github.com' },
|
||||
'isoDate' : { '2012/12/12': returnTime('2012/12/12'), '2012-12/12': returnTime('2012/12/12'), '2013-1-1': returnTime('2013/1/1'), '2013/1/1 12:34:56 AM': returnTime('2013/1/1 12:34:56 AM') },
|
||||
@ -249,7 +266,7 @@
|
||||
// switch ignoreCase, sortLocalCompare & shortDate "ddmmyyyy"
|
||||
sample2 = {
|
||||
'text' : { 'TesT': 'TesT', '\u00e1 test': 'a test' },
|
||||
'currency' : { '€ 123 456,78': 123456.78, '€ 123.456,78': 123456.78 },
|
||||
'currency' : { '\u20ac 123 456,78': 123456.78, '\u20ac 123.456,78': 123456.78 },
|
||||
'shortDate' : { '2/1/2001': returnTime('1/2/2001'), '2-1-2001': returnTime('1/2/2001'), '2 1,2001': returnTime('1/2/2001') }
|
||||
},
|
||||
// shortdate to "yyyymmdd"
|
||||
@ -363,8 +380,8 @@
|
||||
|
||||
test( "sort Events", function(){
|
||||
expect(1);
|
||||
// table1 sorted twice in the above test; sortIndx = 6 (3 events x 2)
|
||||
equal( sortIndx, 6, 'sortStart, sortBegin & sortComplete fired in order x2' );
|
||||
// table1 sorted twice in the above test; sortIndx = 9 then empty table5 x1 (total = 3 events x 3)
|
||||
equal( sortIndx, 9, 'sortStart, sortBegin & sortEnd fired in order x3; including empty table' );
|
||||
});
|
||||
|
||||
/************************************************
|
||||
@ -414,11 +431,17 @@
|
||||
tester.cacheCompare( table1, 'all', [ 'test3', 1, 'test2', 2, 'test1', 3, '', '', 'testc', 4, 'testb', 5, 'testa', 6 ], 'update method' );
|
||||
}]);
|
||||
|
||||
// update empty table
|
||||
$table5.trigger('update', [false, function(){
|
||||
updateCallback++;
|
||||
}]);
|
||||
|
||||
});
|
||||
|
||||
test( "UpdateComplete Event", function(){
|
||||
expect(1);
|
||||
// table1 updated 4x in the above test
|
||||
// table5 updated 1x
|
||||
equal( updateIndx, updateCallback, 'updatedComplete and update callback functions working properly' );
|
||||
});
|
||||
|
||||
@ -615,5 +638,14 @@
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- empty table -->
|
||||
<table class="tester">
|
||||
<thead>
|
||||
<tr><th>1</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,4 +1,5 @@
|
||||
var ipv6parser = $.tablesorter.getParserById('ipv6Address').format,
|
||||
var ipv6parser = $.tablesorter.getParserById('ipv6Address').format,
|
||||
ipv6regex = $.tablesorter.regex.ipv6Validate,
|
||||
ipv6test = function(result, str, expect){
|
||||
if (result) {
|
||||
// ok( $.tablesorter.regex.ipv6Validate.test(str), "valid: " + str );
|
||||
@ -6,7 +7,7 @@ ipv6test = function(result, str, expect){
|
||||
var t = ipv6parser(str, true);
|
||||
equal( t, expect, 'valid: ' + t + ' \u2190 "' + str + '"' );
|
||||
} else {
|
||||
ok( !$.tablesorter.regex.ipv6Validate.test(str), 'invalid: "' + str + '"' );
|
||||
ok( !ipv6regex.test(str), 'invalid: "' + str + '"' );
|
||||
}
|
||||
},
|
||||
ipv6tests = function(){
|
||||
|
Loading…
Reference in New Issue
Block a user