Merge branch 'master' into gh-pages

This commit is contained in:
Rob Garrison 2016-09-01 11:47:27 -05:00
commit b730aefdd3
25 changed files with 391 additions and 166 deletions

View File

@ -101,6 +101,27 @@ If you would like to contribute, please...
View the [complete change log here](https://github.com/Mottie/tablesorter/wiki/Changes).
#### <a name="v2.27.6">Version 2.27.6</a> (9/1/2016)
* Core: `textSorter` option now accepts class names. See [Stackoverflow](http://stackoverflow.com/q/39259954/145346).
* Docs:
* Update `emptyTo` demo. See [issue #1278](https://github.com/Mottie/tablesorter/issues/1278).
* Add `$.tablesorter.defaults` variable.
* Grouping: Add `"group-date-hour"` group type; added to demo.
* Mark:
* Apply marks after pager completes. See [issue #1243](https://github.com/Mottie/tablesorter/issues/1243).
* Add `mark_tsIgnore` option. See [issue #1243](https://github.com/Mottie/tablesorter/issues/1243).
* Parser: Header checkbox remains unchecked when table is hidden. Fixes [issue #1090](https://github.com/Mottie/tablesorter/issues/1090).
* Pager Custom Controls (beta)
* Prevent out-of-range page numbers. Fixes [issue #1276](https://github.com/Mottie/tablesorter/issues/1276).
* Allow settings `ends` and/or `aroundCurrent` to zero. See [issue #1276](https://github.com/Mottie/tablesorter/issues/1276).
* Spacer settings now include wrapper element (a `<span>` by default).
* Keyboard use changes.
* A pager element must now be focused before keyboard keys work.
* Keyboard keys now include left, right, up, down, pageUp, pageDown,
home, or end.
* `pageKeyStep` option added. Number of pages to skip with pageUp or pageDown.
#### <a name="v2.27.5">Version 2.27.5</a> (8/22/2016)
* Readme: Update IRC link to a free client.
@ -112,13 +133,3 @@ View the [complete change log here](https://github.com/Mottie/tablesorter/wiki/C
* Docs & parser: Update Sugar library v2.0+. Fixes [issue #1275](https://github.com/Mottie/tablesorter/issues/1275).
* Docs: Add `sortStable` example.
#### <a name="v2.27.3">Version 2.27.3</a> (8/17/2016)
* Core: `getColumnData` now allows falsy values.
* Filter:
* Add delay to "filterFormatterUpdate". See [issue #1237](https://github.com/Mottie/tablesorter/issues/1237).
* `filter_liveSearch` now accepts an object.
* Pager: use ajax flag when calculating filtered rows.
* Readme: Fix date of last release.
* Testing: Update QUnit.

View File

@ -63,9 +63,10 @@
aroundCurrent : 1, // number of pages surrounding the current page
link : '<a href="#">{page}</a>', // page element; use {page} to include the page number
currentClass : 'current', // current page class name
adjacentSpacer : ' | ', // spacer for page numbers next to each other
distanceSpacer : ' \u2026 ', // spacer for page numbers away from each other (ellipsis &amp;hellip;)
addKeyboard : true // add left/right keyboard arrows to change current page
adjacentSpacer : '<span> | </span>', // spacer for page numbers next to each other
distanceSpacer : '<span> &#133; <span>', // spacer for page numbers away from each other (ellipsis = &amp;#133;)
addKeyboard : true, // use left,right,up,down,pageUp,pageDown,home, or end to change current page
pageKeyStep : 10 // page step to use for pageUp and pageDown
});
// initialize tablesorter & pager
@ -97,6 +98,20 @@
<p class="tip">
<em>NOTE!</em>
<ul>
<li>Modified in <span class="version">v2.27.6</span>
<ul>
<li>Fixed issues with page less than one being shown.</li>
<li>The <code>ends</code> and <code>aroundCurrent</code> works properly when values are set to zero.</li>
<li>Modified <code>adjacentSpacer</code> and <code>distanceSpacer</code> to include surrounding span element.</li>
<li>Using the keyboard has changed!
<ul>
<li><span class="label warning">NOTE</span> The keyboard keys will only work IF a pager element has focus.</li>
<li>The <code>addKeyboard</code> function now includes <kbd>left</kbd>, <kbd>right</kbd>, <kbd>up</kbd>, <kbd>down</kbd>, <kbd>pageUp</kbd>, <kbd>pageDown</kbd>, <kbd>Home</kbd> and <kbd>End</kbd>.</li>
<li>A new <code>pageKeyStep</code> option was added to allow setting the number of pages to skip on <kbd>pageUp</kbd> or <kbd>pageDown</kbd>.</li>
</ul>
</li>
</ul>
</li>
<li>Modified in <span class="version">v2.17.1</span> to properly work with either the pager addon or pager widget.</li>
<li>In <span class="version">v2.16.4</span>, code was updated to correctly count process pages.</li>
</ul>

View File

@ -1,5 +1,5 @@
/*!
* custom pager controls (beta) for TableSorter 9/15/2014 (v2.17.8) - updated 3/26/2015 (v2.21.3)
* custom pager controls (beta) for Tablesorter - updated 9/1/2016 (v2.27.6)
initialize custom pager script BEFORE initializing tablesorter/tablesorter pager
custom pager looks like this:
1 | 2 5 | 6 | 7 99 | 100
@ -12,7 +12,7 @@
/*jshint browser:true, jquery:true, unused:false, loopfunc:true */
/*global jQuery: false */
;(function($){
;(function($) {
"use strict";
$.tablesorter = $.tablesorter || {};
@ -27,9 +27,10 @@ $.tablesorter.customPagerControls = function(settings) {
aroundCurrent : 1, // number of pages surrounding the current page
link : '<a href="#">{page}</a>', // page element; use {page} to include the page number
currentClass : 'current', // current page class name
adjacentSpacer : ' | ', // spacer for page numbers next to each other
distanceSpacer : ' &#133; ', // spacer for page numbers away from each other (ellipsis)
addKeyboard : true // add left/right keyboard arrows to change current page
adjacentSpacer : '<span> | </span>', // spacer for page numbers next to each other
distanceSpacer : '<span> &#133; <span>', // spacer for page numbers away from each other (ellipsis)
addKeyboard : true, // use left,right,up,down,pageUp,pageDown,home, or end to change current page
pageKeyStep : 10 // page step to use for pageUp and pageDown
},
options = $.extend({}, defaults, settings),
$table = $(options.table),
@ -40,61 +41,101 @@ $.tablesorter.customPagerControls = function(settings) {
var indx,
p = c.pager ? c.pager : c, // using widget
pages = $('<div/>'),
pageArray = [],
cur = p.page + 1,
start = cur > 1 ? (p.filteredPages - cur < options.aroundCurrent ? -(options.aroundCurrent + 1) + (p.filteredPages - cur) : -options.aroundCurrent) : 0,
end = cur < options.aroundCurrent + 1 ? options.aroundCurrent + 3 - cur : options.aroundCurrent + 1;
for (indx = start; indx < end; indx++) {
if (cur + indx >= 1 && cur + indx < p.filteredPages) { pageArray.push( cur + indx ); }
pageArray = [],
max = p.filteredPages,
around = options.aroundCurrent;
for (indx = -around; indx <= around; indx++) {
if (cur + indx >= 1 && cur + indx <= max) {
pageArray.push(cur + indx);
}
}
if (pageArray.length) {
// include first and last pages (ends) in the pagination
for (indx = 0; indx < options.ends; indx++){
if ($.inArray(indx + 1, pageArray) === -1) { pageArray.push(indx + 1); }
if ($.inArray(p.filteredPages - indx, pageArray) === -1) { pageArray.push(p.filteredPages - indx); }
for (indx = 0; indx < options.ends; indx++) {
if ((indx + 1 <= max) && $.inArray(indx + 1, pageArray) === -1) {
pageArray.push(indx + 1);
}
if ((max - indx > 0) && $.inArray(max - indx, pageArray) === -1) {
pageArray.push(max - indx);
}
}
// sort the list
pageArray = pageArray.sort(function(a, b){ return a - b; });
// make links and spacers
$.each(pageArray, function(indx, value){
pages
.append( $(options.link.replace(/\{page\}/g, value)).toggleClass(options.currentClass, value === cur).attr('data-page', value) )
.append( '<span>' + (indx < pageArray.length - 1 && ( pageArray[ indx + 1 ] - 1 !== value ) ? options.distanceSpacer :
( indx >= pageArray.length - 1 ? '' : options.adjacentSpacer )) + '</span>' );
pageArray = pageArray.sort(function(a, b) { return a - b; });
// only include unique pages
pageArray = $.grep(pageArray, function(value, key) {
return $.inArray(value, pageArray) === key;
});
// make links and spacers
if (pageArray.length) {
max = pageArray.length - 1;
$.each(pageArray, function(indx, value) {
pages
.append(
$(options.link.replace(/\{page\}/g, value))
.toggleClass(options.currentClass, value === cur)
.attr('data-page', value)
)
.append((indx < max && (pageArray[ indx + 1 ] - 1 !== value) ?
options.distanceSpacer :
(indx >= max ? '' : options.adjacentSpacer)
));
});
}
}
$pager.find('.pagecount').html(pages.html());
$pager
.find('.pagecount')
.html(pages.html())
.find('.' + options.currentClass)
.focus();
});
// set up pager controls
$pager.find(options.pageSize).on('click', function () {
$(this)
.addClass(options.currentClass)
.siblings()
.removeClass(options.currentClass);
$table.trigger('pageSize', $(this).html());
return false;
}).end()
.on('click', options.currentPage, function(){
$(this)
.addClass(options.currentClass)
.siblings()
.removeClass(options.currentClass);
$table.trigger('pageSet', $(this).attr('data-page'));
return false;
});
$pager
.find(options.pageSize)
.on('click', function () {
$(this)
.addClass(options.currentClass)
.siblings()
.removeClass(options.currentClass);
$table.trigger('pageSize', $(this).html());
return false;
})
.end()
.on('click', options.currentPage, function() {
var $el = $(this);
$el
.addClass(options.currentClass)
.siblings()
.removeClass(options.currentClass);
$table.trigger('pageSet', $el.attr('data-page'));
return false;
});
// make right/left arrow keys work
if (options.addKeyboard) {
$(document).on('keydown', function(events){
$(document).on('keydown', function(events) {
// ignore arrows inside form elements
if (/input|select|textarea/i.test(events.target.nodeName)) { return; }
if (events.which === 37) {
// left
$pager.find(options.currentPage).filter('.' + options.currentClass).prevAll(':not(span):first').click();
} else if (events.which === 39) {
// right
$pager.find(options.currentPage).filter('.' + options.currentClass).nextAll(':not(span):first').click();
if (/input|select|textarea/i.test(events.target.nodeName) ||
!(events.which > 32 && events.which < 41)) {
return;
}
// only allow keyboard use if element inside of pager is focused
if ($(document.activeElement).closest(options.pager).is($pager)) {
events.preventDefault();
var key = events.which,
max = $table[0].config.totalRows,
$el = $pager.find(options.currentPage).filter('.' + options.currentClass),
page = $el.length ? parseInt($el.attr('data-page'), 10) : null;
if (page) {
if (key === 33) { page -= options.pageKeyStep; } // pageUp
if (key === 34) { page += options.pageKeyStep; } // pageDown
if (key === 35) { page = max; } // end
if (key === 36) { page = 1; } // home
if (key === 37 || key === 38) { page -= 1; } // left/up
if (key === 39 || key === 40) { page += 1; } // right/down
$table.trigger('pageSet', page);
}
}
});
}

View File

@ -1,4 +1,4 @@
/*! tablesorter (FORK) - updated 08-22-2016 (v2.27.5)*/
/*! tablesorter (FORK) - updated 09-01-2016 (v2.27.6)*/
/* Includes widgets ( storage,uitheme,columns,filter,stickyHeaders,resizable,saveSort ) */
(function(factory) {
if (typeof define === 'function' && define.amd) {
@ -10,7 +10,7 @@
}
}(function(jQuery) {
/*! TableSorter (FORK) v2.27.5 *//*
/*! TableSorter (FORK) v2.27.6 *//*
* Client-side table sorting with ease!
* @requires jQuery v1.2.6+
*
@ -34,7 +34,7 @@
'use strict';
var ts = $.tablesorter = {
version : '2.27.5',
version : '2.27.6',
parsers : [],
widgets : [],
@ -1633,8 +1633,9 @@
// sort multiple columns
multisort : function( c ) { /*jshint loopfunc:true */
var tbodyIndex, sortTime, colMax, rows,
var tbodyIndex, sortTime, colMax, rows, tmp,
table = c.table,
sorter = [],
dir = 0,
textSorter = c.textSorter || '',
sortList = c.sortList,
@ -1645,6 +1646,16 @@
return;
}
if ( c.debug ) { sortTime = new Date(); }
// cache textSorter to optimize speed
if ( typeof textSorter === 'object' ) {
colMax = c.columns;
while ( colMax-- ) {
tmp = ts.getColumnData( table, textSorter, colMax );
if ( typeof tmp === 'function' ) {
sorter[ colMax ] = tmp;
}
}
}
for ( tbodyIndex = 0; tbodyIndex < len; tbodyIndex++ ) {
colMax = c.cache[ tbodyIndex ].colMax;
rows = c.cache[ tbodyIndex ].normalized;
@ -1683,9 +1694,9 @@
if ( typeof textSorter === 'function' ) {
// custom OVERALL text sorter
sort = textSorter( x[ col ], y[ col ], dir, col, table );
} else if ( typeof textSorter === 'object' && textSorter.hasOwnProperty( col ) ) {
} else if ( typeof sorter[ col ] === 'function' ) {
// custom text sorter for a SPECIFIC COLUMN
sort = textSorter[ col ]( x[ col ], y[ col ], dir, col, table );
sort = sorter[ col ]( x[ col ], y[ col ], dir, col, table );
} else {
// fall back to natural sort
sort = ts[ 'sortNatural' + ( dir ? 'Asc' : 'Desc' ) ]( a[ col ], b[ col ], col, c );

File diff suppressed because one or more lines are too long

View File

@ -8,7 +8,7 @@
}
}(function(jQuery) {
/*! TableSorter (FORK) v2.27.5 *//*
/*! TableSorter (FORK) v2.27.6 *//*
* Client-side table sorting with ease!
* @requires jQuery v1.2.6+
*
@ -32,7 +32,7 @@
'use strict';
var ts = $.tablesorter = {
version : '2.27.5',
version : '2.27.6',
parsers : [],
widgets : [],
@ -1631,8 +1631,9 @@
// sort multiple columns
multisort : function( c ) { /*jshint loopfunc:true */
var tbodyIndex, sortTime, colMax, rows,
var tbodyIndex, sortTime, colMax, rows, tmp,
table = c.table,
sorter = [],
dir = 0,
textSorter = c.textSorter || '',
sortList = c.sortList,
@ -1643,6 +1644,16 @@
return;
}
if ( c.debug ) { sortTime = new Date(); }
// cache textSorter to optimize speed
if ( typeof textSorter === 'object' ) {
colMax = c.columns;
while ( colMax-- ) {
tmp = ts.getColumnData( table, textSorter, colMax );
if ( typeof tmp === 'function' ) {
sorter[ colMax ] = tmp;
}
}
}
for ( tbodyIndex = 0; tbodyIndex < len; tbodyIndex++ ) {
colMax = c.cache[ tbodyIndex ].colMax;
rows = c.cache[ tbodyIndex ].normalized;
@ -1681,9 +1692,9 @@
if ( typeof textSorter === 'function' ) {
// custom OVERALL text sorter
sort = textSorter( x[ col ], y[ col ], dir, col, table );
} else if ( typeof textSorter === 'object' && textSorter.hasOwnProperty( col ) ) {
} else if ( typeof sorter[ col ] === 'function' ) {
// custom text sorter for a SPECIFIC COLUMN
sort = textSorter[ col ]( x[ col ], y[ col ], dir, col, table );
sort = sorter[ col ]( x[ col ], y[ col ], dir, col, table );
} else {
// fall back to natural sort
sort = ts[ 'sortNatural' + ( dir ? 'Asc' : 'Desc' ) ]( a[ col ], b[ col ], col, c );

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
/*! tablesorter (FORK) - updated 08-22-2016 (v2.27.5)*/
/*! tablesorter (FORK) - updated 09-01-2016 (v2.27.6)*/
/* Includes widgets ( storage,uitheme,columns,filter,stickyHeaders,resizable,saveSort ) */
(function(factory) {
if (typeof define === 'function' && define.amd) {

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
/*! Parser: input & select - updated 4/29/2016 (v2.25.9) */
!function(a){"use strict";var b=function(a,b,c){};a.tablesorter.addParser({id:"inputs",is:function(){return!1},format:function(b,c,d){var e=a(d).find("input");return e.length?e.val():b},parsed:!0,type:"text"}),a.tablesorter.addParser({id:"inputs-numeric",is:function(){return!1},format:function(b,c,d){var e=a(d).find("input"),f=e.length?e.val():b,g=a.tablesorter.formatFloat((f||"").replace(/[^\w,. \-()]/g,""),c);return b&&"number"==typeof g?g:b?a.trim(b&&c.config.ignoreCase?b.toLocaleLowerCase():b):b},parsed:!0,type:"numeric"}),a.tablesorter.addParser({id:"checkbox",is:function(){return!1},format:function(b,c,d){var e=a(d),f=c.config.widgetOptions,g=f.group_checkbox?f.group_checkbox:["checked","unchecked"],h=e.find('input[type="checkbox"]'),i=h.length?h[0].checked:"";return h.length?g[i?0:1]:b},parsed:!0,type:"text"}),a.tablesorter.addParser({id:"select",is:function(){return!1},format:function(b,c,d){var e=a(d).find("select");return e.length?e.val():b},parsed:!0,type:"text"}),a.tablesorter.addParser({id:"select-text",is:function(){return!1},format:function(b,c,d){var e=a(d).find("select");return e.length?e.find("option:selected").text()||"":b},parsed:!0,type:"text"}),a.tablesorter.addParser({id:"textarea",is:function(){return!1},format:function(b,c,d){var e=a(d).find("textarea");return e.length?e.val():b},parsed:!0,type:"text"}),a(function(){if(a.fn.on){var c=function(a,b,c,d){a.toggleClass(b+"-"+c,d),(a[0].className||"").match(b+"-")?a.addClass(b):a.removeClass(b)},d=function(b,c){var d=window.navigator.userAgent,e=b.children("tbody").children(":visible"),f=e.length;b.children("thead").find('input[type="checkbox"]').each(function(){var b=a(this).closest("td, th").attr("data-column"),g=e.filter("."+c+"-"+b).length,h=g===f;0===g||h?(this.checked=h,this.indeterminate=!1):(this.checked=!(d.indexOf("Trident/")>-1||d.indexOf("Edge/")>-1),this.indeterminate=!0)})};a("table").on("tablesorter-initialized updateComplete",function(){this.tablesorterBusy=!1;var e=".parser-forms";a(this).children("tbody").off(e).on("mouseleave"+e,function(b){"TBODY"===b.target.nodeName&&a(":focus").blur()}).on("focus"+e,"select, input:not([type=checkbox]), textarea",function(){a(this).data("ts-original-value",this.value)}).on("blur"+e,"input:not([type=checkbox]), textarea",function(){this.value=a(this).data("ts-original-value")}).on("change keyup ".split(" ").join(e+" "),"select, input, textarea",function(e){if(27===e.which&&("INPUT"!==this.nodeName||"checkbox"!==this.type))return void(this.value=a(this).data("ts-original-value"));if("change"===e.type||"keyup"===e.type&&13===e.which&&("INPUT"===e.target.nodeName||"TEXTAREA"===e.target.nodeName&&e.altKey)){var f,g,h=a(e.target),i="checkbox"===e.target.type,j=h.closest("td"),k=j.closest("table"),l=j[0].cellIndex,m=k[0].config||!1,n=k.length&&k[0].tablesorterBusy,o=m&&m.$headerIndexed&&m.$headerIndexed[l]||[],p=i?e.target.checked:h.val();if(a.isEmptyObject(m)||n!==!1)return;if(i&&(g=m.checkboxClass||"checked",c(j.closest("tr"),g,l,p),d(k,g)),o.length&&(o.hasClass("parser-false")||o.hasClass("sorter-false")&&o.hasClass("filter-false"))||"change"===e.type&&m.table.isUpdating)return;(m&&p!==h.data("ts-original-value")||i)&&(h.data("ts-original-value",p),k[0].tablesorterBusy=!0,a.tablesorter.updateCell(m,j,f,function(){b(e,k,h),k[0].tablesorterBusy=!1}))}}),a(this).children("thead").find('input[type="checkbox"]')&&a(this).off(e).on("tablesorter-ready"+e,function(){var b,c=a(this),e=c.length&&c[0].config;a.isEmptyObject(e)||(this.tablesorterBusy=!0,b=e&&e.checkboxClass||"checked",d(c,b),this.tablesorterBusy=!1)}).children("thead").off(e).on("click"+e+" change"+e,'input[type="checkbox"]',function(e){var f,g,h,i,j,k,l=a(this),m=l.closest("table"),n=m.length&&m[0].config,o=this.checked;return!(!m.length||!n||m[0].tablesorterBusy)&&(h=parseInt(l.closest("td, th").attr("data-column"),10),j="checkbox"===n.parsers[h].id,g=m.length&&n.checkboxVisible,m[0].tablesorterBusy=!0,i=m.children("tbody").children("tr"+("undefined"==typeof g||g===!0?":visible":"")).children(":nth-child("+(h+1)+")").find('input[type="checkbox"]').prop("checked",o),k=n.checkboxClass||"checked",i.each(function(){c(a(this).closest("tr"),k,h,o)}),d(m,k),j?a.tablesorter.update(n,f,function(){b(e,m,i),m[0].tablesorterBusy=!1}):(b(e,m,i),m[0].tablesorterBusy=!1),!0)})})}})}(jQuery);
/*! Parser: input & select - updated 9/1/2016 (v2.27.6) */
!function(a){"use strict";var b=function(a,b,c){};a.tablesorter.addParser({id:"inputs",is:function(){return!1},format:function(b,c,d){var e=a(d).find("input");return e.length?e.val():b},parsed:!0,type:"text"}),a.tablesorter.addParser({id:"inputs-numeric",is:function(){return!1},format:function(b,c,d){var e=a(d).find("input"),f=e.length?e.val():b,g=a.tablesorter.formatFloat((f||"").replace(/[^\w,. \-()]/g,""),c);return b&&"number"==typeof g?g:b?a.trim(b&&c.config.ignoreCase?b.toLocaleLowerCase():b):b},parsed:!0,type:"numeric"}),a.tablesorter.addParser({id:"checkbox",is:function(){return!1},format:function(b,c,d){var e=a(d),f=c.config.widgetOptions,g=f.group_checkbox?f.group_checkbox:["checked","unchecked"],h=e.find('input[type="checkbox"]'),i=h.length?h[0].checked:"";return h.length?g[i?0:1]:b},parsed:!0,type:"text"}),a.tablesorter.addParser({id:"select",is:function(){return!1},format:function(b,c,d){var e=a(d).find("select");return e.length?e.val():b},parsed:!0,type:"text"}),a.tablesorter.addParser({id:"select-text",is:function(){return!1},format:function(b,c,d){var e=a(d).find("select");return e.length?e.find("option:selected").text()||"":b},parsed:!0,type:"text"}),a.tablesorter.addParser({id:"textarea",is:function(){return!1},format:function(b,c,d){var e=a(d).find("textarea");return e.length?e.val():b},parsed:!0,type:"text"}),a(function(){if(a.fn.on){var c=function(a,b,c,d){a.toggleClass(b+"-"+c,d),(a[0].className||"").match(b+"-")?a.addClass(b):a.removeClass(b)},d=function(b,c){var d=window.navigator.userAgent,e=b.children("tbody").children(":visible"),f=e.length;b.children("thead").find('input[type="checkbox"]').each(function(){var b=a(this).closest("td, th").attr("data-column"),g=e.filter("."+c+"-"+b).length,h=g===f&&f>0;0===g||h?(this.checked=h,this.indeterminate=!1):(this.checked=!(d.indexOf("Trident/")>-1||d.indexOf("Edge/")>-1),this.indeterminate=!0)})};a("table").on("tablesorter-initialized updateComplete",function(){this.tablesorterBusy=!1;var e=".parser-forms";a(this).children("tbody").off(e).on("mouseleave"+e,function(b){"TBODY"===b.target.nodeName&&a(":focus").blur()}).on("focus"+e,"select, input:not([type=checkbox]), textarea",function(){a(this).data("ts-original-value",this.value)}).on("blur"+e,"input:not([type=checkbox]), textarea",function(){this.value=a(this).data("ts-original-value")}).on("change keyup ".split(" ").join(e+" "),"select, input, textarea",function(e){if(27===e.which&&("INPUT"!==this.nodeName||"checkbox"!==this.type))return void(this.value=a(this).data("ts-original-value"));if("change"===e.type||"keyup"===e.type&&13===e.which&&("INPUT"===e.target.nodeName||"TEXTAREA"===e.target.nodeName&&e.altKey)){var f,g,h=a(e.target),i="checkbox"===e.target.type,j=h.closest("td"),k=j.closest("table"),l=j[0].cellIndex,m=k[0].config||!1,n=k.length&&k[0].tablesorterBusy,o=m&&m.$headerIndexed&&m.$headerIndexed[l]||[],p=i?e.target.checked:h.val();if(a.isEmptyObject(m)||n!==!1)return;if(i&&(g=m.checkboxClass||"checked",c(j.closest("tr"),g,l,p),d(k,g)),o.length&&(o.hasClass("parser-false")||o.hasClass("sorter-false")&&o.hasClass("filter-false"))||"change"===e.type&&m.table.isUpdating)return;(m&&p!==h.data("ts-original-value")||i)&&(h.data("ts-original-value",p),k[0].tablesorterBusy=!0,a.tablesorter.updateCell(m,j,f,function(){b(e,k,h),k[0].tablesorterBusy=!1}))}}),a(this).children("thead").find('input[type="checkbox"]')&&a(this).off(e).on("tablesorter-ready"+e,function(){var b,c=a(this),e=c.length&&c[0].config;a.isEmptyObject(e)||(this.tablesorterBusy=!0,b=e&&e.checkboxClass||"checked",d(c,b),this.tablesorterBusy=!1)}).children("thead").off(e).on("click"+e+" change"+e,'input[type="checkbox"]',function(e){var f,g,h,i,j,k,l=a(this),m=l.closest("table"),n=m.length&&m[0].config,o=this.checked;return!(!m.length||!n||m[0].tablesorterBusy)&&(h=parseInt(l.closest("td, th").attr("data-column"),10),j="checkbox"===n.parsers[h].id,g=m.length&&n.checkboxVisible,m[0].tablesorterBusy=!0,i=m.children("tbody").children("tr"+("undefined"==typeof g||g===!0?":visible":"")).children(":nth-child("+(h+1)+")").find('input[type="checkbox"]').prop("checked",o),k=n.checkboxClass||"checked",i.each(function(){c(a(this).closest("tr"),k,h,o)}),d(m,k),j?a.tablesorter.update(n,f,function(){b(e,m,i),m[0].tablesorterBusy=!1}):(b(e,m,i),m[0].tablesorterBusy=!1),!0)})})}})}(jQuery);

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
/*! Widget: mark.js - updated 8/1/2016 (v2.27.2) */
!function(a){"use strict";var b=a.tablesorter;b.mark={init:function(c){if("function"==typeof a.fn.mark){var d,e=c.widgetOptions.mark_tsUpdate;c.$table.on("filterEnd.tsmark"+(e?" "+e:""),function(a,d){b.mark.update(c,"filterEnd"===a.type?"":d)}),d="(?:<|=|>|\\||\"|\\'|\\s+(?:&&|-|"+(b.language.and||"and")+"|"+(b.language.or||"or")+"|"+(b.language.to||"to")+")\\s+)",b.mark.regex.filter=new RegExp(d,"gim")}else console.warn('Widget-mark not initialized: missing "jquery.mark.js"')},regex:{mark:/^mark_(.+)$/,pure:/^\/((?:\\\/|[^\/])+)\/([mig]{0,3})?$/},checkRegex:function(a){if(a instanceof RegExp){var b="".match(a);return null===b||b.length<5}return!1},cleanMatches:function(a){for(var b=[],c=a&&a.length||0;c--;)""!==a[c]&&(b[b.length]=a[c]);return b},update:function(c,d){var e={},f=c.widgetOptions,g="undefined"==typeof f.filter_ignoreCase||f.filter_ignoreCase,h=b.mark.regex,i=c.$table.find("tbody tr").unmark().not("."+(c.widgetOptions.filter_filteredRow||"filtered"));d=d||a.tablesorter.getFilters(c.$table),a.each(c.widgetOptions,function(a,b){var c=a.match(h.mark);c&&"undefined"!=typeof c[1]&&(e[c[1]]=b)}),a.each(d,function(a,d){if(d){var f=null,j=d,k=!1,l=a===c.columns?"":":nth-child("+(a+1)+")";if(h.pure.test(d)){j=h.pure.exec(d),".*"===j[1]&&(j[1]="");try{f=new RegExp(j[1],"gim"),j=new RegExp(j[1],j[2])}catch(a){j=null}return void(b.mark.checkRegex(f)&&i.children(l).markRegExp(j,e))}0===d.indexOf("~")?(k=!0,j=d.replace(/~/g,"").split("")):(d.indexOf("?")>-1&&(k=!0,d=d.replace(/\?/g,"\\S{1}")),d.indexOf("*")>-1&&(k=!0,d=d.replace(/\*/g,"\\S*")),j=d.split(h.filter)),k&&j&&j.length?(j=new RegExp(b.mark.cleanMatches(j).join(".*"),"gm"+(g?"i":"")),b.mark.checkRegex(j)&&i.children(l).markRegExp(j,e)):i.children(l).mark(b.mark.cleanMatches(j),e)}})}},b.addWidget({id:"mark",options:{mark_tsUpdate:"markUpdate"},init:function(a,c,d,e){b.mark.init(d,e)},remove:function(a,b){var c=b.widgetOptions.mark_tsUpdate;b.$table.off("filterEnd.tsmark"+(c?" "+c:""))}})}(jQuery);
/*! Widget: mark.js - updated 9/1/2016 (v2.27.6) */
!function(a){"use strict";var b=a.tablesorter;b.mark={init:function(c){if("function"==typeof a.fn.mark){var d,e=c.widgetOptions.mark_tsUpdate;c.$table.on("filterEnd.tsmark pagerComplete.tsmark"+(e?" "+e:""),function(a,d){b.mark.update(c,a.type===e?d:"")}),d="(?:<|=|>|\\||\"|\\'|\\s+(?:&&|-|"+(b.language.and||"and")+"|"+(b.language.or||"or")+"|"+(b.language.to||"to")+")\\s+)",b.mark.regex.filter=new RegExp(d,"gim")}else console.warn('Widget-mark not initialized: missing "jquery.mark.js"')},regex:{mark:/^mark_(.+)$/,pure:/^\/((?:\\\/|[^\/])+)\/([mig]{0,3})?$/},checkRegex:function(a){if(a instanceof RegExp){var b="".match(a);return null===b||b.length<5}return!1},cleanMatches:function(a){for(var b=[],c=a&&a.length||0;c--;)""!==a[c]&&(b[b.length]=a[c]);return b},ignoreColumns:function(b){for(var c=b.widgetOptions,d=b.columns,e=[];d--;)(c.mark_tsIgnore[d]||a(b.$headerIndexed[d]).hasClass("mark-ignore"))&&(e[e.length]=":nth-child("+(d+1)+")");return e.length?":not("+e.join(",")+")":""},update:function(c,d){var e={},f=c.widgetOptions,g="undefined"==typeof f.filter_ignoreCase||f.filter_ignoreCase,h=b.mark.regex,i=c.$table.find("tbody tr").unmark().not("."+(c.widgetOptions.filter_filteredRow||"filtered"));d=d||a.tablesorter.getFilters(c.$table),a.each(c.widgetOptions,function(a,b){var c=a.match(h.mark);c&&"undefined"!=typeof c[1]&&(e[c[1]]=b)}),a.each(d,function(d,j){if(j&&!a(c.$headerIndexed[d]).hasClass("mark-ignore")&&!f.mark_tsIgnore[d]){var k=null,l=j,m=!1,n=d===c.columns?b.mark.ignoreColumns(c):":nth-child("+(d+1)+")";if(h.pure.test(j)){l=h.pure.exec(j),".*"===l[1]&&(l[1]="");try{k=new RegExp(l[1],"gim"),l=new RegExp(l[1],l[2])}catch(a){l=null}return void(b.mark.checkRegex(k)&&i.children(n).markRegExp(l,e))}0===j.indexOf("~")?(m=!0,l=j.replace(/~/g,"").split("")):(j.indexOf("?")>-1&&(m=!0,j=j.replace(/\?/g,"\\S{1}")),j.indexOf("*")>-1&&(m=!0,j=j.replace(/\*/g,"\\S*")),l=j.split(h.filter)),m&&l&&l.length?(l=new RegExp(b.mark.cleanMatches(l).join(".*"),"gm"+(g?"i":"")),b.mark.checkRegex(l)&&i.children(n).markRegExp(l,e)):i.children(n).mark(b.mark.cleanMatches(l),e)}})}},b.addWidget({id:"mark",options:{mark_tsUpdate:"markUpdate",mark_tsIgnore:{}},init:function(a,c,d,e){b.mark.init(d,e)},remove:function(a,b){var c=b.widgetOptions.mark_tsUpdate;b.$table.off("filterEnd.tsmark pagerComplete.tsmark"+(c?" "+c:""))}})}(jQuery);

View File

@ -53,8 +53,10 @@ $(function(){
<ul>
<li>Set the <code>emptyTo</code> selector below:
<ul>
<li><code>top</code> - sort empty table cells to the top.</li>
<li><code>bottom</code> - sort empty table cells to the bottom.</li>
<li><code>top</code> - sort empty table cells to the top.</li>
<li><code>emptyMax</code> - sort empty table cells as having a value greater than the <em>max</em> (more positive) value (added v2.16.2)</li>
<li><code>emptyMin</code> - sort empty table cells as having a value greater than the <em>min</em> (more negative) value (added v2.16.2)</li>
<li><code>none</code> or <code>zero</code>
<ul>
<li>Sort empty table cells as if the cell has the value equal to zero</li>
@ -83,6 +85,8 @@ $(function(){
Set <code>emptyTo</code> option: <select>
<option>bottom</option>
<option>top</option>
<option>emptyMax</option>
<option>emptyMin</option>
<option value="zero">none/zero</option>
</select>

View File

@ -165,6 +165,7 @@ tr.group-header.collapsed td i {
<li>This widget will <strong>only work</strong> in tablesorter version 2.8+ and jQuery version 1.7+.</li>
<li>Please do not use this widget in very large tables (it might be really slow) <del>or when your table includes multiple tbodies</del>.<br><br></li>
<li>In <span class="version updated">v2.27.6</span>, added <code>group-date-hour</code> group type to the Header Class Names.</li>
<li>In <span class="version updated">v2.25.4</span>, the zebra widget is reapplied to the table after opening a collapsed group.</li>
<li>In <span class="version">v2.24.1</span>
<ul>
@ -563,33 +564,37 @@ group_dateString : function(date, config, $header ) {
</tr>
<tr>
<td rowspan="7">Date</td>
<td rowspan="8">Date</td>
<td><code>&quot;group-date&quot;</code></td>
<td>Group the rows by full date (this shows the current UTC time corrected for your time zone).</td>
<td>Group the rows by full date (this shows the current UTC time corrected for your time zone) - <code>&quot;sorter-shortDate&quot;</code> parser needed.</td>
</tr>
<tr>
<td><code>&quot;group-date-year&quot;</code><span class="remark">*</span></td>
<td>Group the rows by year.</td>
<td>Group the rows by year - <code>&quot;sorter-shortDate&quot;</code> parser needed.</td>
</tr>
<tr>
<td><code>&quot;group-date-month&quot;</code><span class="remark">*</span></td>
<td>Group the rows by month.</td>
<td>Group the rows by month - <code>&quot;sorter-shortDate&quot;</code> parser needed.</td>
</tr>
<tr>
<td><code>&quot;group-date-monthyear&quot;</code><span class="remark">*</span></td>
<td>Group the rows by month &amp; year.</td>
</tr>
<tr>
<td><code>&quot;group-date-week&quot;</code><span class="remark">*</span></td>
<td>Group the rows by day of the week.</td>
<td>Group the rows by month &amp; year - <code>&quot;sorter-shortDate&quot;</code> parser needed.</td>
</tr>
<tr>
<td><code>&quot;group-date-day&quot;</code><span class="remark">*</span></td>
<td>Group the rows by month/day.</td>
<td>Group the rows by month/day - <code>&quot;sorter-shortDate&quot;</code> parser needed.</td>
</tr>
<tr>
<td><code>&quot;group-date-week&quot;</code><span class="remark">*</span></td>
<td>Group the rows by day of the week - <code>&quot;sorter-weekday-index&quot;</code> parser needed.</td>
</tr>
<tr>
<td><code>&quot;group-date-time&quot;</code><span class="remark">*</span></td>
<td>Group the rows by time.</td>
<td>Group the rows by time - <code>&quot;sorter-time&quot;</code> parser needed.</td>
</tr>
<tr>
<td><code>&quot;group-date-hour&quot;</code><span class="remark">*</span></td>
<td>Group the rows by each hour - <code>&quot;sorter-time&quot;</code> parser needed.</td>
</tr>
</tbody>
@ -827,10 +832,10 @@ $(function() {
</tfoot>
<tbody>
<tr><td><input type="checkbox" checked></td><td>1</td><td>10</td><td><select><option selected>A</option><option>B</option><option>C</option></select></td><td>Koala</td><td>abc 123</td><td><input type="text" value="item: truck" /></td><td>1/13/2013 12:01 AM</td></tr>
<tr><td><input type="checkbox"></td><td>3</td><td>29</td><td><select><option>A</option><option>B</option><option selected>C</option></select></td><td>Kangaroo</td><td>abc 1</td><td><input type="text" value="item: car" /></td><td>1/15/2013</td></tr>
<tr><td><input type="checkbox"></td><td>3</td><td>29</td><td><select><option>A</option><option>B</option><option selected>C</option></select></td><td>Kangaroo</td><td>abc 1</td><td><input type="text" value="item: car" /></td><td>1/15/2013 4:20 AM</td></tr>
<tr><td><input type="checkbox"></td><td>2</td><td>10</td><td><select><option>A</option><option>B</option><option selected>C</option></select></td><td>Ant</td><td>abc 9</td><td><input type="text" value="item: motorcycle" /></td><td>1/13/2013</td></tr>
<tr><td><input type="checkbox"></td><td>3</td><td>81</td><td><select><option>A</option><option selected>B</option><option>C</option></select></td><td>Bee</td><td>zyx 24</td><td><input type="text" value="item: golf cart" /></td><td>1/11/2013</td></tr>
<tr><td><input type="checkbox" checked></td><td>3</td><td>21</td><td><select><option>A</option><option selected>B</option><option>C</option></select></td><td>Aardwolf</td><td>zyx 55</td><td><input type="text" value="item: scooter" /></td><td>1/13/2013 03:30 AM</td></tr>
<tr><td><input type="checkbox"></td><td>3</td><td>81</td><td><select><option>A</option><option selected>B</option><option>C</option></select></td><td>Bee</td><td>zyx 24</td><td><input type="text" value="item: golf cart" /></td><td>1/11/2013 12:45 AM</td></tr>
<tr><td><input type="checkbox" checked></td><td>3</td><td>21</td><td><select><option>A</option><option selected>B</option><option>C</option></select></td><td>Aardwolf</td><td>zyx 55</td><td><input type="text" value="item: scooter" /></td><td>1/13/2013 3:30 AM</td></tr>
<tr><td><input type="checkbox"></td><td>1</td><td>3</td><td><select><option selected>A</option><option>B</option><option>C</option></select></td><td>Bear</td><td>abc 11</td><td><input type="text" /></td><td>1/15/2013</td></tr>
<tr><td><input type="checkbox"></td><td>4</td><td>12</td><td><select><option>A</option><option selected>B</option><option>C</option></select></td><td>Armadillo</td><td>zyx 2</td><td><input type="text" /></td><td>1/15/2013 12:30 PM</td></tr>
<tr><td><input type="checkbox" checked></td><td>2</td><td>56</td><td><select><option selected>A</option><option>B</option><option>C</option></select></td><td>Aardvark</td><td>abc 2</td><td><input type="text" value="item: skateboard" /></td><td>1/22/2013</td></tr>
@ -881,7 +886,7 @@ $(function() {
numcol = 2,
letcol = 4,
datecol = 7,
dateGroups = [ '', 'year', 'month', 'monthyear', 'day', 'week', 'time' ];
dateGroups = [ '', 'year', 'month', 'monthyear', 'day', 'week', 'time', 'hour' ];
// Numeric column slider
$( "#slider0" ).slider({
value: startBlock,
@ -941,7 +946,7 @@ $(function() {
if ( dateGroups[ui.value] === 'week' ) {
$h.addClass('sorter-weekday-index');
$groups.trigger('update', [ [[datecol,0]] ]);
} else if ( dateGroups[ui.value] === 'time' ) {
} else if ( dateGroups[ui.value] === 'time' || dateGroups[ui.value] === 'hour' ) {
$h.addClass('sorter-time');
$groups.trigger('update', [ [[datecol,0]] ]);
} else {

View File

@ -21,14 +21,18 @@
tr td:nth-child(1) mark { background: #aa0000; color: #fff; }
tr td:nth-child(2) mark { background: #00aa00; color: #fff; }
tr td:nth-child(3) mark { background: #0000aa; color: #fff; }
tr td:nth-child(4) mark { background: #aaaa00; color: #fff; }
/* tr td:nth-child(4) mark { background: #aaaa00; color: #fff; } Age column not highlighted */
tr td:nth-child(5) mark { background: #00aaaa; color: #fff; }
tr td:nth-child(6) mark { background: #aa00aa; color: #fff; }
/* column will not be highlighted */
th.tablesorter-header.mark-ignore,
th.tablesorter-header.ignore, .ignore { background-color: #e6bf99; }
</style>
<script src="../js/jquery.tablesorter.js"></script>
<script src="../js/widgets/widget-filter.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mark.js/7.0.2/jquery.mark.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.0.0/jquery.mark.js"></script>
<script src="../js/widgets/widget-mark.js"></script>
<script id="js">$(function() {
@ -46,22 +50,33 @@ tr td:nth-child(6) mark { background: #aa00aa; color: #fff; }
filter_external: 'input[name="keyword"]',
filter_reset: 'button.reset',
// default settings
// *** mark widget only settings
mark_tsUpdate : 'markUpdate',
mark_tsIgnore : {
// don't highlight the age column
3: true
},
// *** default settings for non-regular expression searches only
mark_accuracy: 'partially',
mark_diacritics: true,
mark_separateWordSearch: true,
mark_synonyms: {},
// *** settings that apply to regex & non-regular expression searches
mark_acrossElements: false,
mark_className: '',
mark_debug: false,
mark_diacritics: true,
mark_element: 'mark',
mark_exclude: [],
mark_iframes: false,
mark_log: console,
mark_separateWordSearch: true,
mark_synonyms: {},
// callback functions
mark_done: function(totalMatches) {},
mark_each: function(element) {},
mark_filter: function(node, term, counter, totalCounter) { return true; },
mark_noMatch: function(keyword) {}
mark_filter: function(node, term, totalMatches, matches) {
// "matches" parameter is not defined for regular expression searches
return true;
},
mark_noMatch: function(termNotFound) {}
}
});
@ -86,22 +101,11 @@ tr td:nth-child(6) mark { background: #aa00aa; color: #fff; }
sortLocaleCompare: true,
widgets: ['zebra', 'mark'],
widgetOptions : {
// default settings
mark_accuracy: 'partially',
mark_className: '',
mark_debug: false,
mark_diacritics: true,
mark_element: 'mark',
mark_exclude: [],
mark_iframes: false,
mark_log: console,
mark_separateWordSearch: true,
mark_synonyms: {},
// callback functions
mark_done: function(totalMatches) {},
mark_each: function(element) {},
mark_filter: function(node, term, counter, totalCounter) { return true; },
mark_noMatch: function(keyword) {}
// using mark.js default settings
mark_tsIgnore : {
// don't highlight the age column
// 3: true // done by adding "mark-ignore" class to header
}
}
});
@ -144,6 +148,13 @@ tr td:nth-child(6) mark { background: #aa00aa; color: #fff; }
<h3 id="notes"><a href="#">Notes</a></h3>
<div>
<ul>
<li>Updated <span class="verison">v2.27.6</span>
<ul>
<li>The mark widget properly applies after a pager change has occured.</li>
<li>Added <code>mark_tsIgnore</code> option as well as support of adding a "mark-ignore" class to the header. These columns will not be highlighted - see <span class="ignore">Age</span> column below.</li>
<li>Included mark.js v8.0.0's new option as <code>mark_acrossElements</code>. This widget does not however apply the search across table cells.</li>
</ul>
</li>
<li>Added <span class="verison">v2.27.0</span> for use with the <a href="https://markjs.io/">mark.js</a> plugin.</li>
<li>Notable Issues:
<ul>
@ -152,14 +163,14 @@ tr td:nth-child(6) mark { background: #aa00aa; color: #fff; }
I may fix this in future updates.
</li>
<li><button class="bad" type="button" data-filter-column="all">/.*/</button> or <button class="bad" type="button" data-filter-column="all">/(|)/</button> - When a regular expression matches everything, the regex is ignored by the mark widget otherwise, <a href="https://github.com/julmot/mark.js/issues/55">mark.js does bad things</a>; but this regex is okay: <button type="button" data-filter-column="all">/.+/</button>.</li>
<li><button class="bad" type="button" data-filter-column="3"><=22</button> or <button class="bad" type="button" data-filter-column="5">10 - 20</button> - Operators &amp; ranges are not fully supported (these are not supported at all by the filter widget in an "all" columns match - see the documentation on <a href="example-widget-filter-any-match.html#limitations">any match limitations</a>).</li>
<li><button class="bad" type="button" data-filter-column="3">&lt;=22</button> or <button class="bad" type="button" data-filter-column="5">10 - 20</button> - Operators &amp; ranges are not fully supported (these are not supported at all by the filter widget in an "all" columns match - see the documentation on <a href="example-widget-filter-any-match.html#limitations">any match limitations</a>).</li>
<li><button class="bad" type="button" data-filter-column="all">!aaron</button> - There is nothing to highlight for not matches.</li>
</ul>
</li>
<li>The <a href="https://markjs.io/#mark"><code>mark</code> function</a> is used for the following filter queries:
<ul>
<li>Plain text</li>
<li>Logical AND (<code>&nbsp;and&nbsp;</code> or <code>&nbsp;&&&nbsp;</code>) &amp; logical OR (<code>&nbsp;or&nbsp;</code> or <code>|</code>) searches.</li>
<li>Logical AND (<code>&nbsp;and&nbsp;</code> or <code>&nbsp;&amp;&amp;&nbsp;</code>) &amp; logical OR (<code>&nbsp;or&nbsp;</code> or <code>|</code>) searches.</li>
<li>Invalid regex (e.g. <code>/(|)/</code>).</li>
<li>Operator, range, exact and not searches.</li>
</ul>
@ -210,6 +221,28 @@ $('button.update').click(function(){
</div>
</td>
</tr>
<tr id="mark-tsignore">
<td><a href="#" class="permalink">mark_tsIgnore</a></td>
<td>{}</td>
<td>This option sets which columns in the table to ignore when searching.
<div class="collapsible">
<br>
Use it as follows:
<pre class="prettyprint lang-js">$('table').tablesorter({
widgets: ['mark'],
widgetOptions: {
mark_tsIgnore: {
// ignore second column (zero-based index)
1: true
}
}
});</pre>
You can also add a <code>"mark-ignore"</code> class name to the table header to accomplish the same thing.
</div>
</td>
</tr>
</tbody>
<tbody class="tablesorter-infoOnly">
<tr>
@ -218,6 +251,15 @@ $('button.update').click(function(){
</tbody>
<tbody>
<tr id="mark-acrossElements">
<td><span class="permalink">mark_acrossElements</span></td>
<td>false</td>
<td>
Set to <code>true</code> to search for matches across elements (added in mark.js v8.0.0).<br>
This option does not apply to content across table cells as this widget targets individual cells while
performing an "any" match.
</td>
</tr>
<tr id="mark-element">
<td><span class="permalink">mark_element</span></td>
<td>"mark"</td>
@ -321,14 +363,14 @@ $('button.update').click(function(){
<button type="button" data-filter-column="all">br?n</button>
<button type="button" data-filter-column="all">br*n</button>
<button type="button" data-filter-column="all">aaron|bruce</button>
<button type="button" data-filter-column="all">aaron && 2</button>
<button type="button" data-filter-column="all">aaron &amp;&amp; 2</button>
<table id="table" class="tablesorter">
<thead>
<tr>
<th>Rank</th>
<th class="filter-match">First Name</th>
<th>Last Name</th>
<th>Age</th>
<th class="ignore" title="no highlighting">Age</th>
<th>Total</th>
<th>Discount</th>
<th>Date</th>
@ -360,7 +402,7 @@ $('button.update').click(function(){
<button class="table2" type="button">br?n</button>
<button class="table2" type="button">br*n</button>
<button class="table2" type="button">aaron|bruce</button>
<button class="table2" type="button">aaron && 2</button>
<button class="table2" type="button">aaron &amp;&amp; 2</button>
<table id="table2" class="tablesorter">
<thead>
@ -368,7 +410,7 @@ $('button.update').click(function(){
<th>Rank</th>
<th class="filter-match">First Name</th>
<th>Last Name</th>
<th>Age</th>
<th class="mark-ignore" title="no highlighting">Age</th>
<th>Total</th>
<th>Discount</th>
<th>Date</th>

View File

@ -478,13 +478,13 @@
<li><span class="label label-info">Beta</span> <a href="example-widget-formatter.html">Formatter widget</a> (<span class="version">v2.19.1</span>).</li>
<li>Grouping rows widget:
<ul>
<li><a href="example-widget-grouping.html">basic</a> (v2.8; <span class="version updated">v2.27.0</span>).</li>
<li><a href="example-widget-grouping.html">basic</a> (v2.8; <span class="version updated">v2.27.6</span>).</li>
<li><a href="example-widget-grouping-filter-childrows.html">Grouping + filter + child rows</a> (<span class="updated version">v2.15.12</span>).</li>
</ul>
</li>
<li><a href="example-widget-header-titles.html">Header titles widget</a> (v2.15.6; <span class="version updated">v2.24.4</span>).</li>
<li><span class="label label-info">Beta</span> <a href="example-widget-lazyload.html">Lazyload widget</a> (<span class="version">v2.24.0</span>; <span class="version updated">v2.25.7</span>).</li>
<li><a href="example-widget-mark.html">Mark widget</a> (<span class="version">v2.27.2</span>).</li>
<li><a href="example-widget-mark.html">Mark widget</a> (<span class="version">v2.27.6</span>).</li>
<li><a href="example-widget-math.html">Math widget</a> (<span class="version">v2.16</span>; <span class="version updated">v2.27.0</span>).</li>
<li>
<a href="example-widget-output.html">Output widget</a> (<span class="version">v2.16</span>; <span class="version updated">v2.27.0</span>).
@ -1758,7 +1758,7 @@ $(function(){
<td>Function</td>
<td>null</td>
<td>
Replace the default sorting algorithm with a custom one using this option (<span class="version updated">v2.12</span>) - <span class="label label-warning">*NOTE*</span> The parameters have changed!!.
Replace the default sorting algorithm with a custom one using this option (<span class="version updated">v2.27.6</span>) - <span class="label label-warning">*NOTE*</span> The parameters have changed!!.
<div class="collapsible">
<br>
Include a script like <a class="external" href="https://github.com/overset/javascript-natural-sort">naturalSort.js</a> as follows:
@ -1778,7 +1778,7 @@ $(function(){
return a.localeCompare(b);
}
});
});</pre>In <span class="version updated">v2.12</span>, the <code>textSorter</code> option will now accept a text sorter per column:
});</pre>In <span class="version updated">v2.27.6</span>, the <code>textSorter</code> option will allow setting a sorter per column index or class name (column indexes were added in <span class="version updated">v2.12</span>):
<pre class="prettyprint lang-js">$(function(){
$("table").tablesorter({
textSorter : {
@ -1793,9 +1793,9 @@ $(function(){
// same as the function in column 0 above (modified in v2.12)
1 : $.tablesorter.sortText,
// renamed v2.12 from $.tablesorter.sortText - performs natural sort
2 : $.tablesorter.sortNatural,
'.nat-sort' : $.tablesorter.sortNatural,
// alphanumeric sort from sugar v2.0+ (https://sugarjs.com/docs/#/Array/getOption)
3 : Sugar.Array.getOption('sortCollate')
'.sugar-sort' : Sugar.Array.getOption('sortCollate')
}
});
});</pre>The direction parameter (boolean) is merely for informational purposes as the plugin automatically switches <code>a</code> and <code>b</code> depending on the sort direction ( i.e. there's no need to worry about reverse sorting, it's taken care of by the plugin ).
@ -6109,6 +6109,35 @@ $.tablesorter.storage( $('#myTable'), 'tablesorter-filters', '' );</pre>
</thead>
<tbody>
<tr id="variable-defaults">
<td><a href="#" class="permalink">$.tablesorter.defaults</a></td>
<td>Object</td>
<td>This object contains all of the default settings shown in the <a href="#Configuration">configuration</a> section.
<div class="collapsible">
<p>
Changing a defaults will cause all tables using the code to alter its default behavior without needing to include the options while initializing. For example, changing the default theme will cause all tables to use the new theme (make sure to include the css!).
</p>
<span class="label warning">Note</span>: If you wish to modify this object, make sure to either target the setting directly: <pre class="prettyprint lang-js">
// set the default directly
$.tablesorter.defaults.theme = 'myCustomTheme';</pre>
Or use jQuery extend (include <code>true</code> parameter for <a href="http://api.jquery.com/jQuery.extend/#jQuery-extend-deep-target-object1-objectN">more depth</a>): <pre class="prettyprint lang-js">
// Extend the object. Use `true` for more than one level of depth
$.extend( true, $.tablesorter.defaults, {
theme: 'myCustomTheme',
widgets: ['zebra', 'filter'],
widgetOptions: {
filter_placeholder: {
search: 'Find in column...',
select: 'Choose an option'
},
zebra: [ 'row-even', 'row-odd' ]
}
});</pre>
If you don't use one of the above methods, the other default settings will be removed and cause unexpected issues.
</div>
</td>
<td></td>
</tr>
<tr id="variable-parsers">
<td><a href="#" class="permalink">$.tablesorter.parsers</a></td>

View File

@ -5,13 +5,14 @@
var $t, t, v, animating, clicked,
cleanupCode = function(code){
return code.replace(/[<>\"\'\t\n]/g, function(m) { return {
return code.replace(/([<>\"\'\t\n]|&#133;)/g, function(m) { return {
'<' : '&lt;',
'>' : '&gt;',
"'" : '&#39;',
'"' : '&quot;',
'\t': ' ',
'\n': '<br/>' // needed for IE
'\n': '<br/>', // needed for IE
'&#133;' : '&amp;#133;' // pager custom controls ellipsis
}[m];});
};

View File

@ -4,7 +4,7 @@
*/
/*! tablesorter (FORK) - updated 08-22-2016 (v2.27.5)*/
/*! tablesorter (FORK) - updated 09-01-2016 (v2.27.6)*/
/* Includes widgets ( storage,uitheme,columns,filter,stickyHeaders,resizable,saveSort ) */
(function(factory) {
if (typeof define === 'function' && define.amd) {
@ -16,7 +16,7 @@
}
}(function(jQuery) {
/*! TableSorter (FORK) v2.27.5 *//*
/*! TableSorter (FORK) v2.27.6 *//*
* Client-side table sorting with ease!
* @requires jQuery v1.2.6+
*
@ -40,7 +40,7 @@
'use strict';
var ts = $.tablesorter = {
version : '2.27.5',
version : '2.27.6',
parsers : [],
widgets : [],
@ -1639,8 +1639,9 @@
// sort multiple columns
multisort : function( c ) { /*jshint loopfunc:true */
var tbodyIndex, sortTime, colMax, rows,
var tbodyIndex, sortTime, colMax, rows, tmp,
table = c.table,
sorter = [],
dir = 0,
textSorter = c.textSorter || '',
sortList = c.sortList,
@ -1651,6 +1652,16 @@
return;
}
if ( c.debug ) { sortTime = new Date(); }
// cache textSorter to optimize speed
if ( typeof textSorter === 'object' ) {
colMax = c.columns;
while ( colMax-- ) {
tmp = ts.getColumnData( table, textSorter, colMax );
if ( typeof tmp === 'function' ) {
sorter[ colMax ] = tmp;
}
}
}
for ( tbodyIndex = 0; tbodyIndex < len; tbodyIndex++ ) {
colMax = c.cache[ tbodyIndex ].colMax;
rows = c.cache[ tbodyIndex ].normalized;
@ -1689,9 +1700,9 @@
if ( typeof textSorter === 'function' ) {
// custom OVERALL text sorter
sort = textSorter( x[ col ], y[ col ], dir, col, table );
} else if ( typeof textSorter === 'object' && textSorter.hasOwnProperty( col ) ) {
} else if ( typeof sorter[ col ] === 'function' ) {
// custom text sorter for a SPECIFIC COLUMN
sort = textSorter[ col ]( x[ col ], y[ col ], dir, col, table );
sort = sorter[ col ]( x[ col ], y[ col ], dir, col, table );
} else {
// fall back to natural sort
sort = ts[ 'sortNatural' + ( dir ? 'Asc' : 'Desc' ) ]( a[ col ], b[ col ], col, c );

View File

@ -1,4 +1,4 @@
/*! TableSorter (FORK) v2.27.5 *//*
/*! TableSorter (FORK) v2.27.6 *//*
* Client-side table sorting with ease!
* @requires jQuery v1.2.6+
*
@ -22,7 +22,7 @@
'use strict';
var ts = $.tablesorter = {
version : '2.27.5',
version : '2.27.6',
parsers : [],
widgets : [],
@ -1621,8 +1621,9 @@
// sort multiple columns
multisort : function( c ) { /*jshint loopfunc:true */
var tbodyIndex, sortTime, colMax, rows,
var tbodyIndex, sortTime, colMax, rows, tmp,
table = c.table,
sorter = [],
dir = 0,
textSorter = c.textSorter || '',
sortList = c.sortList,
@ -1633,6 +1634,16 @@
return;
}
if ( c.debug ) { sortTime = new Date(); }
// cache textSorter to optimize speed
if ( typeof textSorter === 'object' ) {
colMax = c.columns;
while ( colMax-- ) {
tmp = ts.getColumnData( table, textSorter, colMax );
if ( typeof tmp === 'function' ) {
sorter[ colMax ] = tmp;
}
}
}
for ( tbodyIndex = 0; tbodyIndex < len; tbodyIndex++ ) {
colMax = c.cache[ tbodyIndex ].colMax;
rows = c.cache[ tbodyIndex ].normalized;
@ -1671,9 +1682,9 @@
if ( typeof textSorter === 'function' ) {
// custom OVERALL text sorter
sort = textSorter( x[ col ], y[ col ], dir, col, table );
} else if ( typeof textSorter === 'object' && textSorter.hasOwnProperty( col ) ) {
} else if ( typeof sorter[ col ] === 'function' ) {
// custom text sorter for a SPECIFIC COLUMN
sort = textSorter[ col ]( x[ col ], y[ col ], dir, col, table );
sort = sorter[ col ]( x[ col ], y[ col ], dir, col, table );
} else {
// fall back to natural sort
sort = ts[ 'sortNatural' + ( dir ? 'Asc' : 'Desc' ) ]( a[ col ], b[ col ], col, c );

View File

@ -4,7 +4,7 @@
*/
/*! tablesorter (FORK) - updated 08-22-2016 (v2.27.5)*/
/*! tablesorter (FORK) - updated 09-01-2016 (v2.27.6)*/
/* Includes widgets ( storage,uitheme,columns,filter,stickyHeaders,resizable,saveSort ) */
(function(factory) {
if (typeof define === 'function' && define.amd) {

View File

@ -1,4 +1,4 @@
/*! Parser: input & select - updated 4/29/2016 (v2.25.9) *//*
/*! Parser: input & select - updated 9/1/2016 (v2.27.6) *//*
* for jQuery 1.7+ & tablesorter 2.7.11+
* Demo: http://mottie.github.com/tablesorter/docs/example-widget-grouping.html
*/
@ -135,7 +135,7 @@
$table.children( 'thead' ).find( 'input[type="checkbox"]' ).each( function() {
var column = $( this ).closest( 'td, th' ).attr( 'data-column' ),
vis = $rows.filter( '.' + checkboxClass + '-' + column ).length,
allChecked = vis === len;
allChecked = vis === len && len > 0;
if ( vis === 0 || allChecked ) {
this.checked = allChecked;
this.indeterminate = false;

View File

@ -1,4 +1,4 @@
/*! Widget: grouping - updated 7/31/2016 (v2.27.0) *//*
/*! Widget: grouping - updated 9/1/2016 (v2.27.6) *//*
* Requires tablesorter v2.8+ and jQuery 1.7+
* by Rob Garrison
*/
@ -57,6 +57,7 @@
part === 'day' ? month + ' ' + time.getDate() :
part === 'week' ? tsg.findWeek( wo, time.getDay() ) :
part === 'time' ? tsg.findTime( wo, time ) :
part === 'hour' ? tsg.findTime( wo, time, 'hour' ) :
wo.group_dateString( time, c, $column );
} else {
return wo.group_dateInvalid;
@ -78,7 +79,7 @@
return wo.group_week[ cldrWeek[ day ] ];
}
},
findTime : function( wo, time ) {
findTime : function( wo, time, part ) {
var suffix,
// CLDR returns { am: "AM", pm: "PM", ... }
isObj = wo.group_time.am && wo.group_time.pm,
@ -89,6 +90,9 @@
hours = ( '00' + p24 ).slice(-2),
min = ( '00' + time.getMinutes() ).slice(-2);
suffix = wo.group_time[ isObj ? [ 'am', 'pm' ][ period ] : period ];
if ( part === 'hour' ) {
return hours;
}
return hours + ':' + min + ( wo.group_time24Hour ? '' : ' ' + ( suffix || '' ) );
},

View File

@ -1,4 +1,4 @@
/*! Widget: mark.js - updated 8/1/2016 (v2.27.2) *//*
/*! Widget: mark.js - updated 9/1/2016 (v2.27.6) *//*
* Requires tablesorter v2.8+ and jQuery 1.7+
* by Rob Garrison
*/
@ -11,9 +11,10 @@
if ( typeof $.fn.mark === 'function' ) {
var tmp,
update = c.widgetOptions.mark_tsUpdate;
c.$table.on( 'filterEnd.tsmark' + ( update ? ' ' + update : '' ), function( e, filters ) {
c.$table.on( 'filterEnd.tsmark pagerComplete.tsmark' +
( update ? ' ' + update : '' ), function( e, filters ) {
// filterEnd passes "config" as the param
ts.mark.update( c, e.type === 'filterEnd' ? '' : filters );
ts.mark.update( c, e.type === update ? filters : '' );
});
// Regex to split up a query
tmp = '(?:<|=|>|\\||\"|' + "\\'|" +
@ -33,7 +34,8 @@
},
checkRegex : function( regex ) {
if ( regex instanceof RegExp ) {
// prevent lock up of mark.js (see https://github.com/julmot/mark.js/issues/55)
// prevent lock up of mark.js
// (see https://github.com/julmot/mark.js/issues/55)
var result = '\u0001\u0002\u0003\u0004\u0005'.match( regex );
return result === null || result.length < 5;
}
@ -49,10 +51,27 @@
}
return results;
},
// used when "any" match is performed
ignoreColumns : function( c ) {
var wo = c.widgetOptions,
len = c.columns,
cols = [];
while (len--) {
if (wo.mark_tsIgnore[len] ||
$( c.$headerIndexed[len] ).hasClass( 'mark-ignore' ) ) {
cols[cols.length] = ':nth-child(' + (len + 1) + ')';
}
}
if (cols.length) {
return ':not(' + cols.join(',') + ')';
}
return '';
},
update : function( c, filters ) {
var options = {},
wo = c.widgetOptions,
setIgnoreCase = typeof wo.filter_ignoreCase === 'undefined' ? true : wo.filter_ignoreCase,
setIgnoreCase = typeof wo.filter_ignoreCase === 'undefined' ? true :
wo.filter_ignoreCase,
regex = ts.mark.regex,
$rows = c.$table
.find( 'tbody tr' )
@ -68,11 +87,16 @@
}
});
$.each( filters, function( indx, filter ) {
if ( filter ) {
if ( filter &&
!( $(c.$headerIndexed[indx]).hasClass('mark-ignore') ||
wo.mark_tsIgnore[indx]
) ) {
var testRegex = null,
matches = filter,
useRegex = false,
col = indx === c.columns ? '' : ':nth-child(' + ( indx + 1 ) + ')';
col = indx === c.columns ?
ts.mark.ignoreColumns( c ) :
':nth-child(' + ( indx + 1 ) + ')';
// regular expression entered
if ( regex.pure.test( filter ) ) {
matches = regex.pure.exec( filter );
@ -122,7 +146,10 @@
}
} else {
// pass an array of matches
$rows.children( col ).mark( ts.mark.cleanMatches( matches ), options );
$rows.children( col ).mark(
ts.mark.cleanMatches( matches ),
options
);
}
}
});
@ -132,14 +159,16 @@
ts.addWidget({
id: 'mark',
options: {
mark_tsUpdate : 'markUpdate'
mark_tsUpdate : 'markUpdate',
mark_tsIgnore : {}
},
init : function( table, thisWidget, c, wo ) {
ts.mark.init( c, wo );
},
remove : function( table, c ) {
var update = c.widgetOptions.mark_tsUpdate;
c.$table.off( 'filterEnd.tsmark' + ( update ? ' ' + update : '' ) );
c.$table.off( 'filterEnd.tsmark pagerComplete.tsmark' +
( update ? ' ' + update : '' ) );
}
});

View File

@ -1,7 +1,7 @@
{
"name": "tablesorter",
"title": "tablesorter",
"version": "2.27.5",
"version": "2.27.6",
"description": "tablesorter (FORK) is a jQuery plugin for turning a standard HTML table with THEAD and TBODY tags into a sortable table without page refreshes. tablesorter can successfully parse and sort many types of data including linked data in a cell.",
"author": {
"name": "Christian Bach",

View File

@ -1,7 +1,7 @@
{
"name": "tablesorter",
"title": "tablesorter",
"version": "2.27.5",
"version": "2.27.6",
"description": "tablesorter is a jQuery plugin for turning a standard HTML table with THEAD and TBODY tags into a sortable table without page refreshes. tablesorter can successfully parse and sort many types of data including linked data in a cell.\n\nThis forked version adds lots of new enhancements including: alphanumeric sorting, pager callback functons, multiple widgets providing column styling, ui theme application, sticky headers, column filters and resizer, as well as extended documentation with a lot more demos.",
"author": {
"name": "Christian Bach",