Add namespace option for core & filter events. Fixes #535

This commit is contained in:
Mottie 2014-03-09 17:09:23 -05:00
parent 8269d902d8
commit af8111d815
4 changed files with 75 additions and 41 deletions

View File

@ -1340,6 +1340,31 @@ $(function(){
<td><a href="example-option-text-extraction.html">Example</a></td>
</tr>
<tr id="namespace">
<td><a href="#" class="permalink">namespace</a></td>
<td>String</td>
<td>Undefined</td>
<td>
This option should contain a unique namespace for each table; it is used when binding to event listeners. <span class="version">v2.15.7</span>.
<div class="collapsible">
<br>
Notes about this namespace option:
<ul>
<li>If a namesspace is not defined, a (hopefully) unique random namespace will be generated.</li>
<li>If defined, any "non-word" characters (anything not "a-z", "0-9" or "_") within the namespace will be removed.</li>
<li>Added or not, the namespace will be saved with a leading period (e.g. ".myuniquetableid")</li>
</ul>
<pre class="prettyprint lang-js">$(function(){
$("#mytable").tablesorter({
// if table id = "mytable", this namespace is saved as ".mytable"
namespace : $('#mytable')[0];
});
});</pre>
</div>
</td>
<td></td>
</tr>
<tr id="numbersorter">
<td><a href="#" class="permalink">numberSorter</a></td>
<td>Function</td>

View File

@ -783,15 +783,15 @@
$table = c.$table;
// apply easy methods that trigger bound events
$table
.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){
.unbind('sortReset update updateRows updateCell updateAll addRows updateComplete sorton appendCache updateCache applyWidgetId applyWidgets refreshWidgets destroy mouseup mouseleave '.split(' ').join(c.namespace + ' '))
.bind("sortReset" + c.namespace, function(e){
e.stopPropagation();
c.sortList = [];
setHeadersCss(table);
multisort(table);
appendToTable(table);
})
.bind("updateAll.tablesorter", function(e, resort, callback){
.bind("updateAll" + c.namespace, function(e, resort, callback){
e.stopPropagation();
table.isUpdating = true;
ts.refreshWidgets(table, true, true);
@ -801,14 +801,14 @@
bindMethods(table);
commonUpdate(table, resort, callback);
})
.bind("update.tablesorter updateRows.tablesorter", function(e, resort, callback) {
.bind("update" + c.namespace + " updateRows" + c.namespace, 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) {
.bind("updateCell" + c.namespace, function(e, cell, resort, callback) {
e.stopPropagation();
table.isUpdating = true;
$table.find(c.selectorRemove).remove();
@ -830,7 +830,7 @@
checkResort($table, resort, callback);
}
})
.bind("addRows.tablesorter", function(e, $row, resort, callback) {
.bind("addRows" + c.namespace, function(e, $row, resort, callback) {
e.stopPropagation();
table.isUpdating = true;
if (isEmptyObject(c.cache)) {
@ -863,10 +863,10 @@
checkResort($table, resort, callback);
}
})
.bind("updateComplete.tablesorter", function(){
.bind("updateComplete" + c.namespace, function(){
table.isUpdating = false;
})
.bind("sorton.tablesorter", function(e, list, callback, init) {
.bind("sorton" + c.namespace, function(e, list, callback, init) {
var c = table.config;
e.stopPropagation();
$table.trigger("sortStart", this);
@ -885,14 +885,14 @@
callback(table);
}
})
.bind("appendCache.tablesorter", function(e, callback, init) {
.bind("appendCache" + c.namespace, function(e, callback, init) {
e.stopPropagation();
appendToTable(table, init);
if (typeof callback === "function") {
callback(table);
}
})
.bind("updateCache.tablesorter", function(e, callback){
.bind("updateCache" + c.namespace, function(e, callback){
// rebuild parsers
if (!c.parsers) {
buildParserCache(table);
@ -903,20 +903,20 @@
callback(table);
}
})
.bind("applyWidgetId.tablesorter", function(e, id) {
.bind("applyWidgetId" + c.namespace, function(e, id) {
e.stopPropagation();
ts.getWidgetById(id).format(table, c, c.widgetOptions);
})
.bind("applyWidgets.tablesorter", function(e, init) {
.bind("applyWidgets" + c.namespace, function(e, init) {
e.stopPropagation();
// apply widgets
ts.applyWidget(table, init);
})
.bind("refreshWidgets.tablesorter", function(e, all, dontapply){
.bind("refreshWidgets" + c.namespace, function(e, all, dontapply){
e.stopPropagation();
ts.refreshWidgets(table, all, dontapply);
})
.bind("destroy.tablesorter", function(e, c, cb){
.bind("destroy" + c.namespace, function(e, c, cb){
e.stopPropagation();
ts.destroy(table, c, cb);
});
@ -973,6 +973,15 @@
c.$table = $table
.addClass(ts.css.table + ' ' + c.tableClass + k)
.attr({ role : 'grid'});
// give the table a unique id, which will be used in namespace binding
if (!c.namespace) {
c.namespace = '.tablesorter' + Math.random().toString(16).slice(2);
} else {
// make sure namespace starts with a period & doesn't have weird characters
c.namespace = '.' + c.namespace.replace(/\W/g,'');
}
c.$tbodies = $table.children('tbody:not(.' + c.cssInfoBlock + ')').attr({
'aria-live' : 'polite',
'aria-relevant' : 'all'
@ -1017,8 +1026,8 @@
// show processesing icon
if (c.showProcessing) {
$table
.unbind('sortBegin.tablesorter sortEnd.tablesorter')
.bind('sortBegin.tablesorter sortEnd.tablesorter', function(e) {
.unbind('sortBegin' + c.namespace + ' sortEnd' + c.namespace)
.bind('sortBegin' + c.namespace + ' sortEnd' + c.namespace, function(e) {
ts.isProcessing(table, e.type === 'sortBegin');
});
}
@ -1084,8 +1093,8 @@
$headers
// http://stackoverflow.com/questions/5312849/jquery-find-self;
.find(c.selectorSort).add( $headers.filter(c.selectorSort) )
.unbind('mousedown.tablesorter mouseup.tablesorter sort.tablesorter keyup.tablesorter')
.bind('mousedown.tablesorter mouseup.tablesorter sort.tablesorter keyup.tablesorter', function(e, external) {
.unbind('mousedown mouseup sort keyup '.split(' ').join(c.namespace + ' '))
.bind('mousedown mouseup sort keyup '.split(' ').join(c.namespace + ' '), function(e, external) {
var cell, type = e.type;
// only recognize left clicks or enter
if ( ((e.which || e.button) !== 1 && !/sort|keyup/.test(type)) || (type === 'keyup' && e.which !== 13) ) {
@ -1146,11 +1155,11 @@
// disable tablesorter
$t
.removeData('tablesorter')
.unbind('sortReset update updateAll updateRows updateCell addRows updateComplete 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(c.namespace + ' '));
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');
$r.find(c.selectorSort).unbind('mousedown.tablesorter mouseup.tablesorter keypress.tablesorter');
$r.find(c.selectorSort).unbind('mousedown mouseup keypress '.split(' ').join(c.namespace + ' '));
ts.restoreHeaders(table);
if (removeClasses !== false) {
$t.removeClass(ts.css.table + ' ' + c.tableClass + ' tablesorter-' + c.theme);

View File

@ -1,4 +1,4 @@
/*! Filter widget formatter functions - updated 2/19/2014 (v2.15)
/*! Filter widget formatter functions - updated 3/9/2014 (v2.15.7)
* requires: tableSorter 2.15+ and jQuery 1.4.3+
*
* uiSpinner (jQuery UI spinner)
@ -73,8 +73,8 @@ tsff = ts.filterFormatter = {
// Add a hidden input to hold the range values
$input = $('<input class="filter" type="hidden">')
.appendTo($cell)
// hidden filter update (.tsfilter) namespace trigger by filter widget
.bind('change.tsfilter', function(){
// hidden filter update namespace trigger by filter widget
.bind('change' + c.namespace + 'filter', function(){
updateSpinner({ value: this.value, delayed: false });
}),
$shcell = [],
@ -230,8 +230,8 @@ tsff = ts.filterFormatter = {
// Add a hidden input to hold the range values
$input = $('<input class="filter" type="hidden">')
.appendTo($cell)
// hidden filter update (.tsfilter) namespace trigger by filter widget
.bind('change.tsfilter', function(){
// hidden filter update namespace trigger by filter widget
.bind('change' + c.namespace + 'filter', function(){
updateSlider({ value: this.value });
}),
$shcell = [],
@ -368,8 +368,8 @@ tsff = ts.filterFormatter = {
// Add a hidden input to hold the range values
$input = $('<input class="filter" type="hidden">')
.appendTo($cell)
// hidden filter update (.tsfilter) namespace trigger by filter widget
.bind('change.tsfilter', function(){
// hidden filter update namespace trigger by filter widget
.bind('change' + c.namespace + 'filter', function(){
getRange();
}),
$shcell = [],
@ -500,8 +500,8 @@ tsff = ts.filterFormatter = {
// Add a hidden input to hold the range values
$input = $('<input class="dateCompare" type="hidden">')
.appendTo($cell)
// hidden filter update (.tsfilter) namespace trigger by filter widget
.bind('change.tsfilter', function(){
// hidden filter update namespace trigger by filter widget
.bind('change' + c.namespace + 'filter', function(){
var v = this.value;
if (v) {
o.onClose(v);
@ -632,8 +632,8 @@ tsff = ts.filterFormatter = {
// Add a hidden input to hold the range values
$input = $('<input class="dateRange" type="hidden">')
.appendTo($cell)
// hidden filter update (.tsfilter) namespace trigger by filter widget
.bind('change.tsfilter', function(){
// hidden filter update namespace trigger by filter widget
.bind('change' + c.namespace + 'filter', function(){
var v = this.value;
if (v.match(' - ')) {
v = v.split(' - ');
@ -940,8 +940,8 @@ tsff = ts.filterFormatter = {
.addClass('filter-parsed') // get exact numbers from column
// add span to header for the current slider value
.find('.tablesorter-header-inner').append('<span class="curvalue" />');
// hidden filter update (.tsfilter) namespace trigger by filter widget
$input = $cell.find('input[type=hidden]').bind('change.tsfilter', function(){
// hidden filter update namespace trigger by filter widget
$input = $cell.find('input[type=hidden]').bind('change' + c.namespace + 'filter', function(){
/*jshint eqeqeq:false */
var v = this.value,
compare = ($.isArray(o.compare) ? $cell.find(compareSelect).val() || o.compare[ o.selected || 0] : o.compare) || '';
@ -1085,8 +1085,8 @@ tsff = ts.filterFormatter = {
updateColor( $cell.find('.colorpicker').val() );
});
// hidden filter update (.tsfilter) namespace trigger by filter widget
$input = $cell.find('input[type=hidden]').bind('change.tsfilter', function(){
// hidden filter update namespace trigger by filter widget
$input = $cell.find('input[type=hidden]').bind('change' + c.namespace + 'filter', function(){
updateColor( this.value );
});

View File

@ -1,4 +1,4 @@
/*! tableSorter 2.8+ widgets - updated 3/7/2014 (v2.15.6)
/*! tableSorter 2.8+ widgets - updated 3/9/2014 (v2.15.7)
*
* Column Styles
* Column Filters
@ -380,7 +380,7 @@ ts.addWidget({
$table
.removeClass('hasFilters')
// add .tsfilter namespace to all BUT search
.unbind('addRows updateCell update updateRows updateComplete appendCache filterReset filterEnd search '.split(' ').join('.tsfilter '))
.unbind('addRows updateCell update updateRows updateComplete appendCache filterReset filterEnd search '.split(' ').join(c.namespace + 'filter '))
.find('.' + ts.css.filterRow).remove();
for (tbodyIndex = 0; tbodyIndex < $tbodies.length; tbodyIndex++ ) {
$tbody = ts.processTbody(table, $tbodies.eq(tbodyIndex), true); // remove tbody
@ -558,7 +558,7 @@ ts.filter = {
ts.filter.buildRow(table, c, wo);
}
c.$table.bind('addRows updateCell update updateRows updateComplete appendCache filterReset filterEnd search '.split(' ').join('.tsfilter '), function(event, filter) {
c.$table.bind('addRows updateCell update updateRows updateComplete appendCache filterReset filterEnd search '.split(' ').join(c.namespace + 'filter '), function(event, filter) {
c.$table.find('.' + ts.css.filterRow).toggle( !(wo.filter_hideEmpty && $.isEmptyObject(c.cache)) ); // fixes #450
if ( !/(search|filter)/.test(event.type) ) {
event.stopPropagation();
@ -628,7 +628,7 @@ ts.filter = {
// show processing icon
if (c.showProcessing) {
c.$table.bind('filterStart.tsfilter filterEnd.tsfilter', function(event, columns) {
c.$table.bind('filterStart' + c.namespace + 'filter filterEnd' + c.namespace + 'filter', function(event, columns) {
// only add processing to certain columns to all columns
$header = (columns) ? c.$table.find('.' + ts.css.header).filter('[data-column]').filter(function() {
return columns[$(this).data('column')] !== '';
@ -751,9 +751,9 @@ ts.filter = {
$el
// use data attribute instead of jQuery data since the head is cloned without including the data/binding
.attr('data-lastSearchTime', new Date().getTime())
.unbind('keyup search change')
.unbind('keyup search change '.split(' ').join(c.namespace + 'filter '))
// include change for select - fixes #473
.bind('keyup search change', function(event, filters) {
.bind('keyup search change '.split(' ').join(c.namespace + 'filter '), function(event, filters) {
$(this).attr('data-lastSearchTime', new Date().getTime());
// emulate what webkit does.... escape clears the filter
if (event.which === 27) {