add jquery.tablesorter v2.17.6/2.17.7

This commit is contained in:
Peter Dave Hello
2014-08-26 00:33:09 +08:00
parent b532ac7ebd
commit 20278dba4a
173 changed files with 31155 additions and 1 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 720 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 737 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 416 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 736 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 745 B

@@ -0,0 +1,42 @@
/* pager wrapper, div */
.tablesorter-pager {
padding: 5px;
}
/* pager wrapper, in thead/tfoot */
td.tablesorter-pager {
background-color: #e6eeee;
margin: 0; /* needed for bootstrap .pager gets a 18px bottom margin */
}
/* pager navigation arrows */
.tablesorter-pager img {
vertical-align: middle;
margin-right: 2px;
cursor: pointer;
}
/* pager output text */
.tablesorter-pager .pagedisplay {
padding: 0 5px 0 5px;
width: auto;
white-space: nowrap;
text-align: center;
}
/* pager element reset (needed for bootstrap) */
.tablesorter-pager select {
margin: 0;
padding: 0;
}
/*** css used when "updateArrows" option is true ***/
/* the pager itself gets a disabled class when the number of rows is less than the size */
.tablesorter-pager.disabled {
display: none;
}
/* hide or fade out pager arrows when the first or last row is visible */
.tablesorter-pager .disabled {
/* visibility: hidden */
opacity: 0.5;
filter: alpha(opacity=50);
cursor: default;
}
@@ -0,0 +1,921 @@
/*!
* tablesorter pager plugin
* updated 8/1/2014 (v2.17.6)
*/
/*jshint browser:true, jquery:true, unused:false */
;(function($) {
"use strict";
/*jshint supernew:true */
var ts = $.tablesorter;
$.extend({ tablesorterPager: new function() {
this.defaults = {
// target the pager markup
container: null,
// use this format: "http://mydatabase.com?page={page}&size={size}&{sortList:col}&{filterList:fcol}"
// where {page} is replaced by the page number, {size} is replaced by the number of records to show,
// {sortList:col} adds the sortList to the url into a "col" array, and {filterList:fcol} adds
// the filterList to the url into an "fcol" array.
// So a sortList = [[2,0],[3,0]] becomes "&col[2]=0&col[3]=0" in the url
// and a filterList = [[2,Blue],[3,13]] becomes "&fcol[2]=Blue&fcol[3]=13" in the url
ajaxUrl: null,
// modify the url after all processing has been applied
customAjaxUrl: function(table, url) { return url; },
// modify the $.ajax object to allow complete control over your ajax requests
ajaxObject: {
dataType: 'json'
},
// set this to false if you want to block ajax loading on init
processAjaxOnInit: true,
// process ajax so that the following information is returned:
// [ total_rows (number), rows (array of arrays), headers (array; optional) ]
// example:
// [
// 100, // total rows
// [
// [ "row1cell1", "row1cell2", ... "row1cellN" ],
// [ "row2cell1", "row2cell2", ... "row2cellN" ],
// ...
// [ "rowNcell1", "rowNcell2", ... "rowNcellN" ]
// ],
// [ "header1", "header2", ... "headerN" ] // optional
// ]
ajaxProcessing: function(ajax){ return [ 0, [], null ]; },
// output default: '{page}/{totalPages}'
// possible variables: {page}, {totalPages}, {filteredPages}, {startRow}, {endRow}, {filteredRows} and {totalRows}
output: '{startRow} to {endRow} of {totalRows} rows', // '{page}/{totalPages}'
// apply disabled classname to the pager arrows when the rows at either extreme is visible
updateArrows: true,
// starting page of the pager (zero based index)
page: 0,
// reset pager after filtering; set to desired page #
// set to false to not change page at filter start
pageReset: 0,
// Number of visible rows
size: 10,
// Save pager page & size if the storage script is loaded (requires $.tablesorter.storage in jquery.tablesorter.widgets.js)
savePages: true,
// defines custom storage key
storageKey: 'tablesorter-pager',
// if true, the table will remain the same height no matter how many records are displayed. The space is made up by an empty
// table row set to a height to compensate; default is false
fixedHeight: false,
// count child rows towards the set page size? (set true if it is a visible table row within the pager)
// if true, child row(s) may not appear to be attached to its parent row, may be split across pages or
// may distort the table if rowspan or cellspans are included.
countChildRows: false,
// remove rows from the table to speed up the sort of large tables.
// setting this to false, only hides the non-visible rows; needed if you plan to add/remove rows with the pager enabled.
removeRows: false, // removing rows in larger tables speeds up the sort
// css class names of pager arrows
cssFirst: '.first', // go to first page arrow
cssPrev: '.prev', // previous page arrow
cssNext: '.next', // next page arrow
cssLast: '.last', // go to last page arrow
cssGoto: '.gotoPage', // go to page selector - select dropdown that sets the current page
cssPageDisplay: '.pagedisplay', // location of where the "output" is displayed
cssPageSize: '.pagesize', // page size selector - select dropdown that sets the "size" option
cssErrorRow: 'tablesorter-errorRow', // error information row
// class added to arrows when at the extremes (i.e. prev/first arrows are "disabled" when on the first page)
cssDisabled: 'disabled', // Note there is no period "." in front of this class name
// stuff not set by the user
totalRows: 0,
totalPages: 0,
filteredRows: 0,
filteredPages: 0,
ajaxCounter: 0,
currentFilters: [],
startRow: 0,
endRow: 0,
$size: null,
last: {}
};
var $this = this,
// hide arrows at extremes
pagerArrows = function(p, disable) {
var a = 'addClass',
r = 'removeClass',
d = p.cssDisabled,
dis = !!disable,
first = ( dis || p.page === 0 ),
tp = Math.min( p.totalPages, p.filteredPages ),
last = ( dis || (p.page === tp - 1) || tp === 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);
}
},
updatePageDisplay = function(table, p, completed) {
var i, pg, s, $out, regex,
c = table.config,
f = c.$table.hasClass('hasFilters'),
t = [],
sz = p.size || 10; // don't allow dividing by zero
t = [ (c.widgetOptions && c.widgetOptions.filter_filteredRow || 'filtered'), c.selectorRemove.replace(/^(\w+\.)/g,'') ];
if (p.countChildRows) { t.push(c.cssChildRow); }
regex = new RegExp( '(' + t.join('|') + ')' );
if (f && !p.ajaxUrl) {
if ($.isEmptyObject(c.cache)) {
// delayInit: true so nothing is in the cache
p.filteredRows = p.totalRows = c.$tbodies.eq(0).children('tr').not( p.countChildRows ? '' : '.' + c.cssChildRow ).length;
} else {
p.filteredRows = 0;
$.each(c.cache[0].normalized, function(i, el) {
p.filteredRows += p.regexRows.test(el[c.columns].$row[0].className) ? 0 : 1;
});
}
} else if (!f) {
p.filteredRows = p.totalRows;
}
p.totalPages = Math.ceil( p.totalRows / sz ); // needed for "pageSize" method
c.totalRows = p.totalRows;
c.filteredRows = p.filteredRows;
p.filteredPages = Math.ceil( p.filteredRows / sz ) || 0;
if ( Math.min( p.totalPages, p.filteredPages ) >= 0 ) {
t = (p.size * p.page > p.filteredRows);
p.startRow = (t) ? 1 : (p.filteredRows === 0 ? 0 : p.size * p.page + 1);
p.page = (t) ? 0 : p.page;
p.endRow = Math.min( p.filteredRows, p.totalRows, p.size * ( p.page + 1 ) );
$out = p.$container.find(p.cssPageDisplay);
// form the output string (can now get a new output string from the server)
s = ( p.ajaxData && p.ajaxData.output ? p.ajaxData.output || p.output : p.output )
// {page} = one-based index; {page+#} = zero based index +/- value
.replace(/\{page([\-+]\d+)?\}/gi, function(m,n){
return p.totalPages ? p.page + (n ? parseInt(n, 10) : 1) : 0;
})
// {totalPages}, {extra}, {extra:0} (array) or {extra : key} (object)
.replace(/\{\w+(\s*:\s*\w+)?\}/gi, function(m){
var len, indx,
str = m.replace(/[{}\s]/g,''),
extra = str.split(':'),
data = p.ajaxData,
// return zero for default page/row numbers
deflt = /(rows?|pages?)$/i.test(str) ? 0 : '';
if (/(startRow|page)/.test(extra[0]) && extra[1] === 'input') {
len = ('' + (extra[0] === 'page' ? p.totalPages : p.totalRows)).length;
indx = extra[0] === 'page' ? p.page + 1 : p.startRow;
return '<input type="text" class="ts-' + extra[0] + '" style="max-width:' + len + 'em" value="' + indx + '"/>';
}
return extra.length > 1 && data && data[extra[0]] ? data[extra[0]][extra[1]] : p[str] || (data ? data[str] : deflt) || deflt;
});
if ($out.length) {
$out[ ($out[0].tagName === 'INPUT') ? 'val' : 'html' ](s);
if ( p.$goto.length ) {
t = '';
pg = Math.min( p.totalPages, p.filteredPages );
for ( i = 1; i <= pg; i++ ) {
t += '<option>' + i + '</option>';
}
p.$goto.html(t).val( p.page + 1 );
}
// rebind startRow/page inputs
$out.find('.ts-startRow, .ts-page').unbind('change').bind('change', function(){
var v = $(this).val(),
pg = $(this).hasClass('ts-startRow') ? Math.floor( v/p.size ) + 1 : v;
c.$table.trigger('pageSet.pager', [ pg ]);
});
}
}
pagerArrows(p);
if (p.initialized && completed !== false) {
c.$table.trigger('pagerComplete', p);
// save pager info to storage
if (p.savePages && ts.storage) {
ts.storage(table, p.storageKey, {
page : p.page,
size : p.size
});
}
}
},
fixHeight = function(table, p) {
var d, h,
c = table.config,
$b = c.$tbodies.eq(0);
if (p.fixedHeight) {
$b.find('tr.pagerSavedHeightSpacer').remove();
h = $.data(table, 'pagerSavedHeight');
if (h) {
d = h - $b.height();
if ( d > 5 && $.data(table, 'pagerLastSize') === p.size && $b.children('tr:visible').length < p.size ) {
$b.append('<tr class="pagerSavedHeightSpacer ' + c.selectorRemove.replace(/^(\w+\.)/g,'') + '" style="height:' + d + 'px;"></tr>');
}
}
}
},
changeHeight = function(table, p) {
var $b = table.config.$tbodies.eq(0);
$b.find('tr.pagerSavedHeightSpacer').remove();
$.data(table, 'pagerSavedHeight', $b.height());
fixHeight(table, p);
$.data(table, 'pagerLastSize', p.size);
},
hideRows = function(table, p){
if (!p.ajaxUrl) {
var i,
lastIndex = 0,
c = table.config,
rows = c.$tbodies.eq(0).children('tr'),
l = rows.length,
s = ( p.page * p.size ),
e = s + p.size,
f = c.widgetOptions && c.widgetOptions.filter_filteredRow || 'filtered',
j = 0; // size counter
for ( i = 0; i < l; i++ ){
if ( !rows[i].className.match(f) ) {
if (j === s && rows[i].className.match(c.cssChildRow)) {
// hide child rows @ start of pager (if already visible)
rows[i].style.display = 'none';
} else {
rows[i].style.display = ( j >= s && j < e ) ? '' : 'none';
// don't count child rows
j += rows[i].className.match(c.cssChildRow + '|' + c.selectorRemove.replace(/^(\w+\.)/g,'')) && !p.countChildRows ? 0 : 1;
if ( j === e && rows[i].style.display !== 'none' && rows[i].className.match(ts.css.cssHasChild) ) {
lastIndex = i;
}
}
}
}
// add any attached child rows to last row of pager. Fixes part of issue #396
if ( lastIndex > 0 && rows[lastIndex].className.match(ts.css.cssHasChild) ) {
while ( ++lastIndex < l && rows[lastIndex].className.match(c.cssChildRow) ) {
rows[lastIndex].style.display = '';
}
}
}
},
hideRowsSetup = function(table, p){
p.size = parseInt( p.$size.val(), 10 ) || p.size;
$.data(table, 'pagerLastSize', p.size);
pagerArrows(p);
if ( !p.removeRows ) {
hideRows(table, p);
$(table).bind('sortEnd.pager filterEnd.pager', function(){
hideRows(table, p);
});
}
},
renderAjax = function(data, table, p, xhr, exception){
// process data
if ( typeof(p.ajaxProcessing) === "function" ) {
// ajaxProcessing result: [ total, rows, headers ]
var i, j, hsh, $f, $sh, t, th, d, l, rr_count,
c = table.config,
$t = c.$table,
tds = '',
result = p.ajaxProcessing(data, table, xhr) || [ 0, [] ],
hl = $t.find('thead th').length;
// Clean up any previous error.
ts.showError(table);
if ( exception ) {
if (c.debug) {
ts.log('Ajax Error', xhr, exception);
}
ts.showError(table,
xhr.status === 0 ? 'Not connected, verify Network' :
xhr.status === 404 ? 'Requested page not found [404]' :
xhr.status === 500 ? 'Internal Server Error [500]' :
exception === 'parsererror' ? 'Requested JSON parse failed' :
exception === 'timeout' ? 'Time out error' :
exception === 'abort' ? 'Ajax Request aborted' :
'Uncaught error: ' + xhr.statusText + ' [' + xhr.status + ']' );
c.$tbodies.eq(0).children('tr').detach();
p.totalRows = 0;
} else {
// process ajax object
if (!$.isArray(result)) {
p.ajaxData = result;
c.totalRows = p.totalRows = result.total;
c.filteredRows = p.filteredRows = typeof result.filteredRows !== 'undefined' ? result.filteredRows : result.total;
th = result.headers;
d = result.rows;
} else {
// allow [ total, rows, headers ] or [ rows, total, headers ]
t = isNaN(result[0]) && !isNaN(result[1]);
// ensure a zero returned row count doesn't fail the logical ||
rr_count = result[t ? 1 : 0];
p.totalRows = isNaN(rr_count) ? p.totalRows || 0 : rr_count;
// can't set filtered rows when returning an array
c.totalRows = c.filteredRows = p.filteredRows = p.totalRows;
d = p.totalRows === 0 ? [""] : result[t ? 0 : 1] || []; // row data
th = result[2]; // headers
}
l = d && d.length;
if (d instanceof jQuery) {
if (p.processAjaxOnInit) {
// append jQuery object
c.$tbodies.eq(0).children('tr').detach();
c.$tbodies.eq(0).append(d);
}
} else if (l) {
// build table from array
for ( i = 0; i < l; i++ ) {
tds += '<tr>';
for ( j = 0; j < d[i].length; j++ ) {
// build tbody cells; watch for data containing HTML markup - see #434
tds += /^\s*<td/.test(d[i][j]) ? $.trim(d[i][j]) : '<td>' + d[i][j] + '</td>';
}
tds += '</tr>';
}
// add rows to first tbody
if (p.processAjaxOnInit) {
c.$tbodies.eq(0).html( tds );
}
}
p.processAjaxOnInit = true;
// only add new header text if the length matches
if ( th && th.length === hl ) {
hsh = $t.hasClass('hasStickyHeaders');
$sh = hsh ? c.widgetOptions.$sticky.children('thead:first').children('tr').children() : '';
$f = $t.find('tfoot tr:first').children();
// don't change td headers (may contain pager)
c.$headers.filter('th').each(function(j){
var $t = $(this), icn;
// add new test within the first span it finds, or just in the header
if ( $t.find('.' + ts.css.icon).length ) {
icn = $t.find('.' + ts.css.icon).clone(true);
$t.find('.tablesorter-header-inner').html( th[j] ).append(icn);
if ( hsh && $sh.length ) {
icn = $sh.eq(j).find('.' + ts.css.icon).clone(true);
$sh.eq(j).find('.tablesorter-header-inner').html( th[j] ).append(icn);
}
} else {
$t.find('.tablesorter-header-inner').html( th[j] );
if (hsh && $sh.length) {
$sh.eq(j).find('.tablesorter-header-inner').html( th[j] );
}
}
$f.eq(j).html( th[j] );
});
}
}
if (c.showProcessing) {
ts.isProcessing(table); // remove loading icon
}
// make sure last pager settings are saved, prevents multiple server side calls with
// the same parameters
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);
fixHeight(table, p);
$t.trigger('updateCache', [function(){
if (p.initialized) {
// apply widgets after table has rendered & after a delay to prevent
// multiple applyWidget blocking code from blocking this trigger
setTimeout(function(){
$t
.trigger('applyWidgets')
.trigger('pagerChange', p);
}, 0);
}
}]);
}
if (!p.initialized) {
p.initialized = true;
$(table)
.trigger('applyWidgets')
.trigger('pagerInitialized', p);
}
},
getAjax = function(table, p){
var url = getAjaxUrl(table, p),
$doc = $(document),
counter,
c = table.config;
if ( url !== '' ) {
if (c.showProcessing) {
ts.isProcessing(table, true); // show loading icon
}
$doc.bind('ajaxError.pager', function(e, xhr, settings, exception) {
renderAjax(null, table, p, xhr, exception);
$doc.unbind('ajaxError.pager');
});
counter = ++p.ajaxCounter;
p.ajaxObject.url = url; // from the ajaxUrl option and modified by customAjaxUrl
p.ajaxObject.success = function(data, status, jqxhr) {
// Refuse to process old ajax commands that were overwritten by new ones - see #443
if (counter < p.ajaxCounter){
return;
}
renderAjax(data, table, p, jqxhr);
$doc.unbind('ajaxError.pager');
if (typeof p.oldAjaxSuccess === 'function') {
p.oldAjaxSuccess(data);
}
};
if (c.debug) {
ts.log('ajax initialized', p.ajaxObject);
}
$.ajax(p.ajaxObject);
}
},
getAjaxUrl = function(table, p) {
var c = table.config,
url = (p.ajaxUrl) ? p.ajaxUrl
// allow using "{page+1}" in the url string to switch to a non-zero based index
.replace(/\{page([\-+]\d+)?\}/, function(s,n){ return p.page + (n ? parseInt(n, 10) : 0); })
.replace(/\{size\}/g, p.size) : '',
sl = c.sortList,
fl = p.currentFilters || $(table).data('lastSearch') || [],
sortCol = url.match(/\{\s*sort(?:List)?\s*:\s*(\w*)\s*\}/),
filterCol = url.match(/\{\s*filter(?:List)?\s*:\s*(\w*)\s*\}/),
arry = [];
if (sortCol) {
sortCol = sortCol[1];
$.each(sl, function(i,v){
arry.push(sortCol + '[' + v[0] + ']=' + v[1]);
});
// if the arry is empty, just add the col parameter... "&{sortList:col}" becomes "&col"
url = url.replace(/\{\s*sort(?:List)?\s*:\s*(\w*)\s*\}/g, arry.length ? arry.join('&') : sortCol );
arry = [];
}
if (filterCol) {
filterCol = filterCol[1];
$.each(fl, function(i,v){
if (v) {
arry.push(filterCol + '[' + i + ']=' + encodeURIComponent(v));
}
});
// if the arry is empty, just add the fcol parameter... "&{filterList:fcol}" becomes "&fcol"
url = url.replace(/\{\s*filter(?:List)?\s*:\s*(\w*)\s*\}/g, arry.length ? arry.join('&') : filterCol );
p.currentFilters = fl;
}
if ( typeof(p.customAjaxUrl) === "function" ) {
url = p.customAjaxUrl(table, url);
}
if (c.debug) {
ts.log('Pager ajax url: ' + url);
}
return url;
},
renderTable = function(table, rows, p) {
var $tb, index, count, added,
$t = $(table),
c = table.config,
f = c.$table.hasClass('hasFilters'),
l = rows && rows.length || 0, // rows may be undefined
s = ( p.page * p.size ),
e = p.size;
if ( l < 1 ) {
if (c.debug) {
ts.log('Pager: no rows for pager to render');
}
// empty table, abort!
return;
}
if ( p.page >= p.totalPages ) {
// lets not render the table more than once
moveToLastPage(table, p);
}
p.isDisabled = false; // needed because sorting will change the page and re-enable the pager
if (p.initialized) { $t.trigger('pagerChange', p); }
if ( !p.removeRows ) {
hideRows(table, p);
} else {
ts.clearTableBody(table);
$tb = ts.processTbody(table, c.$tbodies.eq(0), true);
// not filtered, start from the calculated starting point (s)
// if filtered, start from zero
index = f ? 0 : s;
count = f ? 0 : s;
added = 0;
while (added < e && index < rows.length) {
if (!f || !/filtered/.test(rows[index][0].className)){
count++;
if (count > s && added <= e) {
added++;
$tb.append(rows[index]);
}
}
index++;
}
ts.processTbody(table, $tb, false);
}
updatePageDisplay(table, p);
if ( !p.isDisabled ) { fixHeight(table, p); }
$t.trigger('applyWidgets');
if (table.isUpdating) {
$t.trigger("updateComplete", table);
}
},
showAllRows = function(table, p){
if ( p.ajax ) {
pagerArrows(p, true);
} else {
p.isDisabled = true;
$.data(table, 'pagerLastPage', p.page);
$.data(table, 'pagerLastSize', p.size);
p.page = 0;
p.size = p.totalRows;
p.totalPages = 1;
$(table)
.addClass('pagerDisabled')
.removeAttr('aria-describedby')
.find('tr.pagerSavedHeightSpacer').remove();
renderTable(table, table.config.rowsCopy, p);
if (table.config.debug) {
ts.log('pager disabled');
}
}
// disable size selector
p.$size.add(p.$goto).add(p.$container.find('.ts-startRow, .ts-page')).each(function(){
$(this).attr('aria-disabled', 'true').addClass(p.cssDisabled)[0].disabled = true;
});
},
// updateCache if delayInit: true
updateCache = function(table) {
var c = table.config,
p = c.pager;
c.$table.trigger('updateCache', [ function(){
var i,
rows = [],
n = table.config.cache[0].normalized;
p.totalRows = n.length;
for (i = 0; i < p.totalRows; i++) {
rows.push(n[i][c.columns].$row);
}
c.rowsCopy = rows;
moveToPage(table, p, true);
} ]);
},
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 ( pageMoved !== false && p.initialized && $.isEmptyObject(table.config.cache)) {
return updateCache(table);
}
if ( p.page < 0 ) { p.page = 0; }
if ( p.page > ( pg - 1 ) && pg !== 0 ) { p.page = pg - 1; }
// fixes issue where one currentFilter is [] and the other is ['','',''],
// making the next if comparison think the filters are different (joined by commas). Fixes #202.
l.currentFilters = (l.currentFilters || []).join('') === '' ? [] : l.currentFilters;
p.currentFilters = (p.currentFilters || []).join('') === '' ? [] : p.currentFilters;
// don't allow rendering multiple times on the same page/size/totalRows/filters/sorts
if ( l.page === p.page && l.size === p.size && l.totalRows === p.totalRows &&
(l.currentFilters || []).join(',') === (p.currentFilters || []).join(',') &&
l.sortList === (c.sortList || []).join(',') ) { return; }
if (c.debug) {
ts.log('Pager changing to page ' + p.page);
}
p.last = {
page : p.page,
size : p.size,
// fixes #408; modify sortList otherwise it auto-updates
sortList : (c.sortList || []).join(','),
totalRows : p.totalRows,
currentFilters : p.currentFilters || []
};
if (p.ajax) {
getAjax(table, p);
} else if (!p.ajax) {
renderTable(table, c.rowsCopy, p);
}
$.data(table, 'pagerLastPage', p.page);
if (p.initialized && pageMoved !== false) {
$t
.trigger('pageMoved', p)
.trigger('applyWidgets');
if (table.isUpdating) {
$t.trigger('updateComplete');
}
}
},
setPageSize = function(table, size, p) {
p.size = size || p.size || 10;
p.$size.val(p.size);
$.data(table, 'pagerLastPage', p.page);
$.data(table, 'pagerLastSize', p.size);
p.totalPages = Math.ceil( p.totalRows / p.size );
p.filteredPages = Math.ceil( p.filteredRows / p.size );
moveToPage(table, p);
},
moveToFirstPage = function(table, p) {
p.page = 0;
moveToPage(table, p);
},
moveToLastPage = function(table, p) {
p.page = ( Math.min( p.totalPages, p.filteredPages ) - 1 );
moveToPage(table, p);
},
moveToNextPage = function(table, p) {
p.page++;
if ( p.page >= ( Math.min( p.totalPages, p.filteredPages ) - 1 ) ) {
p.page = ( Math.min( p.totalPages, p.filteredPages ) - 1 );
}
moveToPage(table, p);
},
moveToPrevPage = function(table, p) {
p.page--;
if ( p.page <= 0 ) {
p.page = 0;
}
moveToPage(table, p);
},
destroyPager = function(table, p){
showAllRows(table, p);
p.$container.hide(); // hide pager
table.config.appender = null; // remove pager appender function
p.initialized = false;
delete table.config.rowsCopy;
$(table).unbind('destroy.pager sortEnd.pager filterEnd.pager enable.pager disable.pager');
if (ts.storage) {
ts.storage(table, p.storageKey, '');
}
},
enablePager = function(table, p, triggered){
var info,
c = table.config;
p.$size.add(p.$goto).add(p.$container.find('.ts-startRow, .ts-page'))
.removeClass(p.cssDisabled)
.removeAttr('disabled')
.attr('aria-disabled', 'false');
p.isDisabled = false;
p.page = $.data(table, 'pagerLastPage') || p.page || 0;
p.size = $.data(table, 'pagerLastSize') || parseInt(p.$size.find('option[selected]').val(), 10) || p.size || 10;
p.$size.val(p.size); // set page size
p.totalPages = Math.ceil( Math.min( p.totalRows, p.filteredRows ) / p.size );
// if table id exists, include page display with aria info
if ( table.id ) {
info = table.id + '_pager_info';
p.$container.find(p.cssPageDisplay).attr('id', info);
c.$table.attr('aria-describedby', info);
}
if ( triggered ) {
c.$table.trigger('updateRows');
setPageSize(table, p.size, p);
hideRowsSetup(table, p);
fixHeight(table, p);
if (c.debug) {
ts.log('pager enabled');
}
}
};
$this.appender = function(table, rows) {
var c = table.config,
p = c.pager;
if ( !p.ajax ) {
c.rowsCopy = rows;
p.totalRows = p.countChildRows ? c.$tbodies.eq(0).children('tr').length : rows.length;
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);
}
};
$this.construct = function(settings) {
return this.each(function() {
// check if tablesorter has initialized
if (!(this.config && this.hasInitialized)) { return; }
var t, ctrls, fxn,
table = this,
c = table.config,
wo = c.widgetOptions,
p = c.pager = $.extend( true, {}, $.tablesorterPager.defaults, settings ),
$t = c.$table,
// added in case the pager is reinitialized after being destroyed.
pager = p.$container = $(p.container).addClass('tablesorter-pager').show();
if (c.debug) {
ts.log('Pager initializing');
}
p.oldAjaxSuccess = p.oldAjaxSuccess || p.ajaxObject.success;
c.appender = $this.appender;
if (ts.filter && $.inArray('filter', c.widgets) >= 0) {
// get any default filter settings (data-value attribute) fixes #388
p.currentFilters = c.$table.data('lastSearch') || ts.filter.setDefaults(table, c, c.widgetOptions) || [];
// set, but don't apply current filters
ts.setFilters(table, p.currentFilters, false);
}
if (p.savePages && ts.storage) {
t = ts.storage(table, p.storageKey) || {}; // fixes #387
p.page = isNaN(t.page) ? p.page : t.page;
p.size = ( isNaN(t.size) ? p.size : t.size ) || 10;
$.data(table, 'pagerLastSize', p.size);
}
// skipped rows
p.regexRows = new RegExp('(' + (wo.filter_filteredRow || 'filtered') + '|' + c.selectorRemove.replace(/^(\w+\.)/g,'') + '|' + c.cssChildRow + ')');
$t
.unbind('filterStart filterEnd sortEnd disable enable destroy update updateRows updateAll addRows pageSize '.split(' ').join('.pager '))
.bind('filterStart.pager', function(e, filters) {
p.currentFilters = filters;
// don't change page is filters are the same (pager updating, etc)
if (p.pageReset !== false && (c.lastCombinedFilter || '') !== (filters || []).join('')) {
p.page = p.pageReset; // fixes #456 & #565
}
})
// update pager after filter widget completes
.bind('filterEnd.pager sortEnd.pager', function() {
if (p.initialized) {
if (c.delayInit && c.rowsCopy && c.rowsCopy.length === 0) {
// make sure we have a copy of all table rows once the cache has been built
updateCache(table);
}
// update page display first, so we update p.filteredPages
updatePageDisplay(table, p, false);
moveToPage(table, p, false);
fixHeight(table, p);
}
})
.bind('disable.pager', function(e){
e.stopPropagation();
showAllRows(table, p);
})
.bind('enable.pager', function(e){
e.stopPropagation();
enablePager(table, p, true);
})
.bind('destroy.pager', function(e){
e.stopPropagation();
destroyPager(table, p);
})
.bind('update updateRows updateAll addRows '.split(' ').join('.pager '), function(e){
e.stopPropagation();
fixHeight(table, p);
var $rows = c.$tbodies.eq(0).children('tr');
p.totalRows = $rows.length - ( p.countChildRows ? 0 : $rows.filter('.' + c.cssChildRow).length );
p.totalPages = Math.ceil( p.totalRows / p.size );
updatePageDisplay(table, p);
hideRows(table, p);
})
.bind('pageSize.pager', function(e,v){
e.stopPropagation();
setPageSize(table, parseInt(v, 10) || 10, p);
hideRows(table, p);
updatePageDisplay(table, p, false);
if (p.$size.length) { p.$size.val(p.size); } // twice?
})
.bind('pageSet.pager', function(e,v){
e.stopPropagation();
p.page = (parseInt(v, 10) || 1) - 1;
if (p.$goto.length) { p.$goto.val(p.size); } // twice?
moveToPage(table, p, true);
updatePageDisplay(table, p, false);
});
// clicked controls
ctrls = [ p.cssFirst, p.cssPrev, p.cssNext, p.cssLast ];
fxn = [ moveToFirstPage, moveToPrevPage, moveToNextPage, moveToLastPage ];
pager.find(ctrls.join(','))
.attr("tabindex", 0)
.unbind('click.pager')
.bind('click.pager', function(e){
e.stopPropagation();
var i, $t = $(this), l = ctrls.length;
if ( !$t.hasClass(p.cssDisabled) ) {
for (i = 0; i < l; i++) {
if ($t.is(ctrls[i])) {
fxn[i](table, p);
break;
}
}
}
});
// goto selector
p.$goto = pager.find(p.cssGoto);
if ( p.$goto.length ) {
p.$goto
.unbind('change')
.bind('change', function(){
p.page = $(this).val() - 1;
moveToPage(table, p, true);
updatePageDisplay(table, p, false);
});
}
// page size selector
p.$size = pager.find(p.cssPageSize);
if ( p.$size.length ) {
// setting an option as selected appears to cause issues with initial page size
p.$size.find('option').removeAttr('selected');
p.$size.unbind('change.pager').bind('change.pager', function() {
p.$size.val( $(this).val() ); // in case there are more than one pagers
if ( !$(this).hasClass(p.cssDisabled) ) {
setPageSize(table, parseInt( $(this).val(), 10 ), p);
changeHeight(table, p);
}
return false;
});
}
// clear initialized flag
p.initialized = false;
// before initialization event
$t.trigger('pagerBeforeInitialized', p);
enablePager(table, p, false);
if ( typeof(p.ajaxUrl) === 'string' ) {
// ajax pager; interact with database
p.ajax = true;
//When filtering with ajax, allow only custom filtering function, disable default filtering since it will be done server side.
c.widgetOptions.filter_serversideFiltering = true;
c.serverSideSorting = true;
moveToPage(table, p);
} else {
p.ajax = false;
// Regular pager; all rows stored in memory
$(this).trigger("appendCache", true);
hideRowsSetup(table, p);
}
changeHeight(table, p);
// pager initialized
if (!p.ajax) {
p.initialized = true;
$(table).trigger('pagerInitialized', p);
}
});
};
}() });
// see #486
ts.showError = function(table, message){
$(table).each(function(){
var $row,
c = this.config,
errorRow = c.pager && c.pager.cssErrorRow || c.widgetOptions.pager_css && c.widgetOptions.pager_css.errorRow || 'tablesorter-errorRow';
if (c) {
if (typeof message === 'undefined') {
c.$table.find('thead').find(c.selectorRemove).remove();
} else {
$row = ( /tr\>/.test(message) ? $(message) : $('<tr><td colspan="' + c.columns + '">' + message + '</td></tr>') )
.click(function(){
$(this).remove();
})
// add error row to thead instead of tbody, or clicking on the header will result in a parser error
.appendTo( c.$table.find('thead:first') )
.addClass( errorRow + ' ' + c.selectorRemove.replace(/^(\w+\.)/g,'') )
.attr({
role : 'alert',
'aria-live' : 'assertive'
});
}
}
});
};
// extend plugin scope
$.fn.extend({
tablesorterPager: $.tablesorterPager.construct
});
})(jQuery);
File diff suppressed because one or more lines are too long
@@ -0,0 +1,183 @@
/**** Filter Formatter Elements ****/
.tablesorter .tablesorter-filter-row td {
text-align: center;
font-size: 0.9em;
font-weight: normal;
}
/**** Sliders ****/
/* shrink the sliders to look nicer inside of a table cell */
.tablesorter .ui-slider, .tablesorter input.range {
width: 90%;
margin: 2px auto 2px auto; /* add enough top margin so the tooltips will fit */
font-size: 0.8em;
}
.tablesorter .ui-slider {
top: 12px;
}
.tablesorter .ui-slider .ui-slider-handle {
width: 0.9em;
height: 0.9em;
}
.tablesorter .ui-datepicker {
font-size: 0.8em;
}
.tablesorter .ui-slider-horizontal {
height: 0.5em;
}
/* Add tooltips to slider handles */
.tablesorter .value-popup:after {
content : attr(data-value);
position: absolute;
bottom: 14px;
left: -7px;
min-width: 18px;
height: 12px;
background-color: #444;
background-image: -webkit-gradient(linear, left top, left bottom, from(#444444), to(#999999));
background-image: -webkit-linear-gradient(top, #444, #999);
background-image: -moz-linear-gradient(top, #444, #999);
background-image: -o-linear-gradient(top, #444, #999);
background-image: linear-gradient(to bottom, #444, #999);
-webkit-border-radius: 3px;
border-radius: 3px;
-webkit-background-clip: padding-box; background-clip: padding-box;
-webkit-box-shadow: 0px 0px 4px 0px #777;
box-shadow: 0px 0px 4px 0px #777;
border: #444 1px solid;
color: #fff;
font: 1em/1.1em Arial, Sans-Serif;
padding: 1px;
text-align: center;
}
.tablesorter .value-popup:before {
content: "";
position: absolute;
width: 0;
height: 0;
border-top: 8px solid #777;
border-left: 8px solid transparent;
border-right: 8px solid transparent;
top: -8px;
left: 50%;
margin-left: -8px;
margin-top: -1px;
}
/**** Date Picker ****/
.tablesorter .dateFrom, .tablesorter .dateTo {
width: 80px;
margin: 2px 5px;
}
/**** Color Picker/HTML5Number Toggle button ****/
.tablesorter .button {
width: 14px;
height: 14px;
background: #fcfff4;
background: -webkit-linear-gradient(top, #fcfff4 0%, #dfe5d7 40%, #b3bead 100%);
background: -moz-linear-gradient(top, #fcfff4 0%, #dfe5d7 40%, #b3bead 100%);
background: -o-linear-gradient(top, #fcfff4 0%, #dfe5d7 40%, #b3bead 100%);
background: -ms-linear-gradient(top, #fcfff4 0%, #dfe5d7 40%, #b3bead 100%);
background: linear-gradient(top, #fcfff4 0%, #dfe5d7 40%, #b3bead 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fcfff4', endColorstr='#b3bead', GradientType=0 );
margin: 1px 5px 1px 1px;
-webkit-border-radius: 25px;
-moz-border-radius: 25px;
border-radius: 25px;
-webkit-box-shadow: inset 0px 1px 1px white, 0px 1px 3px rgba(0,0,0,0.5);
-moz-box-shadow: inset 0px 1px 1px white, 0px 1px 3px rgba(0,0,0,0.5);
box-shadow: inset 0px 1px 1px white, 0px 1px 3px rgba(0,0,0,0.5);
position: relative;
top: 3px;
display: inline-block;
}
.tablesorter .button label {
cursor: pointer;
position: absolute;
width: 10px;
height: 10px;
-webkit-border-radius: 25px;
-moz-border-radius: 25px;
border-radius: 25px;
left: 2px;
top: 2px;
-webkit-box-shadow: inset 0px 1px 1px rgba(0,0,0,0.5), 0px 1px 0px rgba(255,255,255,1);
-moz-box-shadow: inset 0px 1px 1px rgba(0,0,0,0.5), 0px 1px 0px rgba(255,255,255,1);
box-shadow: inset 0px 1px 1px rgba(0,0,0,0.5), 0px 1px 0px rgba(255,255,255,1);
background: #45484d;
background: -webkit-linear-gradient(top, #222 0%, #45484d 100%);
background: -moz-linear-gradient(top, #222 0%, #45484d 100%);
background: -o-linear-gradient(top, #222 0%, #45484d 100%);
background: -ms-linear-gradient(top, #222 0%, #45484d 100%);
background: linear-gradient(top, #222 0%, #45484d 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#222', endColorstr='#45484d', GradientType=0 );
}
.tablesorter .button label:after {
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
filter: alpha(opacity=0);
opacity: 0;
content: '';
position: absolute;
width: 8px;
height: 8px;
background: #55f;
background: -webkit-linear-gradient(top, #aaf 0%, #55f 100%);
background: -moz-linear-gradient(top, #aaf 0%, #55f 100%);
background: -o-linear-gradient(top, #aaf 0%, #55f 100%);
background: -ms-linear-gradient(top, #aaf 0%, #55f 100%);
background: linear-gradient(top, #aaf 0%, #55f 100%);
-webkit-border-radius: 25px;
-moz-border-radius: 25px;
border-radius: 25px;
top: 1px;
left: 1px;
-webkit-box-shadow: inset 0px 1px 1px #fff, 0px 1px 3px rgba(0,0,0,0.5);
-moz-box-shadow: inset 0px 1px 1px #fff, 0px 1px 3px rgba(0,0,0,0.5);
box-shadow: inset 0px 1px 1px #fff, 0px 1px 3px rgba(0,0,0,0.5);
}
.tablesorter .button label:hover::after {
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=30)";
filter: alpha(opacity=30);
opacity: 0.3;
}
.tablesorter .button input[type=checkbox] {
visibility: hidden;
}
.tablesorter .button input[type=checkbox]:checked + label:after {
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
filter: alpha(opacity=100);
opacity: 1;
}
.tablesorter .colorpicker {
width: 30px;
height: 18px;
}
.tablesorter .ui-spinner-input {
width: 100px;
height: 18px;
}
.tablesorter .currentColor, .tablesorter .ui-spinner {
position: relative;
}
.tablesorter input.number {
position: relative;
}
/* hide filter row */
.tablesorter .tablesorter-filter-row.hideme td * {
height: 1px;
min-height: 0;
border: 0;
padding: 0;
margin: 0;
/* don't use visibility: hidden because it disables tabbing */
opacity: 0;
filter: alpha(opacity=0);
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 48 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 284 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 513 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 520 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 B

@@ -0,0 +1,186 @@
/*************
Black Ice Theme (by thezoggy)
*************/
/* overall */
.tablesorter-blackice {
width: 100%;
margin-right: auto;
margin-left: auto;
font: 11px/18px Arial, Sans-serif;
text-align: left;
background-color: #000;
border-collapse: collapse;
border-spacing: 0;
}
/* header */
.tablesorter-blackice th,
.tablesorter-blackice thead td {
padding: 4px;
font: bold 13px/20px Arial, Sans-serif;
color: #e5e5e5;
text-align: left;
text-shadow: 0 1px 0 rgba(0, 0, 0, 0.7);
background-color: #111;
border: 1px solid #232323;
}
.tablesorter-blackice .header,
.tablesorter-blackice .tablesorter-header {
padding: 4px 20px 4px 4px;
cursor: pointer;
background-image: url(data:image/gif;base64,R0lGODlhFQAJAIAAAP///////yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==);
background-position: center right;
background-repeat: no-repeat;
}
.tablesorter-blackice .headerSortUp,
.tablesorter-blackice .tablesorter-headerSortUp,
.tablesorter-blackice .tablesorter-headerAsc {
background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7);
color: #fff;
}
.tablesorter-blackice .headerSortDown,
.tablesorter-blackice .tablesorter-headerSortDown,
.tablesorter-blackice .tablesorter-headerDesc {
color: #fff;
background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7);
}
.tablesorter-blackice thead .sorter-false {
background-image: none;
cursor: default;
padding: 4px;
}
/* tfoot */
.tablesorter-blackice tfoot .tablesorter-headerSortUp,
.tablesorter-blackice tfoot .tablesorter-headerSortDown,
.tablesorter-blackice tfoot .tablesorter-headerAsc,
.tablesorter-blackice tfoot .tablesorter-headerDesc {
/* remove sort arrows from footer */
background-image: none;
}
/* tbody */
.tablesorter-blackice td {
padding: 4px;
color: #ccc;
vertical-align: top;
background-color: #333;
border: 1px solid #232323;
}
/* hovered row colors */
.tablesorter-blackice tbody > tr:hover > td,
.tablesorter-blackice tbody > tr.even:hover > td,
.tablesorter-blackice tbody > tr.odd:hover > td {
background: #000;
}
/* table processing indicator */
.tablesorter-blackice .tablesorter-processing {
background-position: center center !important;
background-repeat: no-repeat !important;
/* background-image: url(../addons/pager/icons/loading.gif) !important; */
background-image: url('data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=') !important;
}
/* Zebra Widget - row alternating colors */
.tablesorter-blackice tr.odd td {
background-color: #333;
}
.tablesorter-blackice tr.even td {
background-color: #393939;
}
/* Column Widget - column sort colors */
.tablesorter-blackice td.primary,
.tablesorter-blackice tr.odd td.primary {
background-color: #2f3a40;
}
.tablesorter-blackice tr.even td.primary {
background-color: #3f4a50;
}
.tablesorter-blackice td.secondary,
.tablesorter-blackice tr.odd td.secondary {
background-color: #3f4a50;
}
.tablesorter-blackice tr.even td.secondary {
background-color: #4f5a60;
}
.tablesorter-blackice td.tertiary,
.tablesorter-blackice tr.odd td.tertiary {
background-color: #4f5a60;
}
.tablesorter-blackice tr.even td.tertiary {
background-color: #5a646b;
}
/* caption */
caption {
background: #fff;
}
/* filter widget */
.tablesorter-blackice .tablesorter-filter-row td {
background: #222;
line-height: normal;
text-align: center; /* center the input */
-webkit-transition: line-height 0.1s ease;
-moz-transition: line-height 0.1s ease;
-o-transition: line-height 0.1s ease;
transition: line-height 0.1s ease;
}
/* optional disabled input styling */
.tablesorter-blackice .tablesorter-filter-row .disabled {
opacity: 0.5;
filter: alpha(opacity=50);
cursor: not-allowed;
}
/* hidden filter row */
.tablesorter-blackice .tablesorter-filter-row.hideme td {
/*** *********************************************** ***/
/*** change this padding to modify the thickness ***/
/*** of the closed filter row (height = padding x 2) ***/
padding: 2px;
/*** *********************************************** ***/
margin: 0;
line-height: 0;
cursor: pointer;
}
.tablesorter-blackice .tablesorter-filter-row.hideme .tablesorter-filter {
height: 1px;
min-height: 0;
border: 0;
padding: 0;
margin: 0;
/* don't use visibility: hidden because it disables tabbing */
opacity: 0;
filter: alpha(opacity=0);
}
/* filters */
.tablesorter-blackice .tablesorter-filter {
width: 98%;
height: auto;
margin: 0;
padding: 4px;
background-color: #fff;
border: 1px solid #bbb;
color: #333;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-webkit-transition: height 0.1s ease;
-moz-transition: height 0.1s ease;
-o-transition: height 0.1s ease;
transition: height 0.1s ease;
}
/* rows hidden by filtering (needed for child rows) */
.tablesorter .filtered {
display: none;
}
/* ajax error row */
.tablesorter .tablesorter-errorRow td {
text-align: center;
cursor: pointer;
background-color: #e6bf99;
}
@@ -0,0 +1,221 @@
/*************
Blue Theme
*************/
/* overall */
.tablesorter-blue {
width: 100%;
background-color: #fff;
margin: 10px 0 15px;
text-align: left;
border-spacing: 0;
border: #cdcdcd 1px solid;
border-width: 1px 0 0 1px;
}
.tablesorter-blue th,
.tablesorter-blue td {
border: #cdcdcd 1px solid;
border-width: 0 1px 1px 0;
}
/* header */
.tablesorter-blue th,
.tablesorter-blue thead td {
font: bold 12px/18px Arial, Sans-serif;
color: #000;
background-color: #99bfe6;
border-collapse: collapse;
padding: 4px;
text-shadow: 0 1px 0 rgba(204, 204, 204, 0.7);
}
.tablesorter-blue tbody td,
.tablesorter-blue tfoot th,
.tablesorter-blue tfoot td {
padding: 4px;
vertical-align: top;
}
.tablesorter-blue .header,
.tablesorter-blue .tablesorter-header {
/* black (unsorted) double arrow */
background-image: url(data:image/gif;base64,R0lGODlhFQAJAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==);
/* white (unsorted) double arrow */
/* background-image: url(data:image/gif;base64,R0lGODlhFQAJAIAAAP///////yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==); */
/* image */
/* background-image: url(images/black-unsorted.gif); */
background-repeat: no-repeat;
background-position: center right;
padding: 4px 18px 4px 4px;
white-space: normal;
cursor: pointer;
}
.tablesorter-blue .headerSortUp,
.tablesorter-blue .tablesorter-headerSortUp,
.tablesorter-blue .tablesorter-headerAsc {
background-color: #9fbfdf;
/* black asc arrow */
background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7);
/* white asc arrow */
/* background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7); */
/* image */
/* background-image: url(images/black-asc.gif); */
}
.tablesorter-blue .headerSortDown,
.tablesorter-blue .tablesorter-headerSortDown,
.tablesorter-blue .tablesorter-headerDesc {
background-color: #8cb3d9;
/* black desc arrow */
background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7);
/* white desc arrow */
/* background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7); */
/* image */
/* background-image: url(images/black-desc.gif); */
}
.tablesorter-blue thead .sorter-false {
background-image: none;
cursor: default;
padding: 4px;
}
/* tfoot */
.tablesorter-blue tfoot .tablesorter-headerSortUp,
.tablesorter-blue tfoot .tablesorter-headerSortDown,
.tablesorter-blue tfoot .tablesorter-headerAsc,
.tablesorter-blue tfoot .tablesorter-headerDesc {
/* remove sort arrows from footer */
background-image: none;
}
/* tbody */
.tablesorter-blue td {
color: #3d3d3d;
background-color: #fff;
padding: 4px;
vertical-align: top;
}
/* hovered row colors
you'll need to add additional lines for
rows with more than 2 child rows
*/
.tablesorter-blue tbody > tr:hover > td,
.tablesorter-blue tbody > tr:hover + tr.tablesorter-childRow > td,
.tablesorter-blue tbody > tr:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td,
.tablesorter-blue tbody > tr.even:hover > td,
.tablesorter-blue tbody > tr.even:hover + tr.tablesorter-childRow > td,
.tablesorter-blue tbody > tr.even:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td {
background: #d9d9d9;
}
.tablesorter-blue tbody > tr.odd:hover > td,
.tablesorter-blue tbody > tr.odd:hover + tr.tablesorter-childRow > td,
.tablesorter-blue tbody > tr.odd:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td {
background: #bfbfbf;
}
/* table processing indicator */
.tablesorter-blue .tablesorter-processing {
background-position: center center !important;
background-repeat: no-repeat !important;
/* background-image: url(../addons/pager/icons/loading.gif) !important; */
background-image: url('data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=') !important;
}
/* Zebra Widget - row alternating colors */
.tablesorter-blue tbody tr.odd td {
background-color: #ebf2fa;
}
.tablesorter-blue tbody tr.even td {
background-color: #fff;
}
/* Column Widget - column sort colors */
.tablesorter-blue td.primary,
.tablesorter-blue tr.odd td.primary {
background-color: #99b3e6;
}
.tablesorter-blue tr.even td.primary {
background-color: #c2d1f0;
}
.tablesorter-blue td.secondary,
.tablesorter-blue tr.odd td.secondary {
background-color: #c2d1f0;
}
.tablesorter-blue tr.even td.secondary {
background-color: #d6e0f5;
}
.tablesorter-blue td.tertiary,
.tablesorter-blue tr.odd td.tertiary {
background-color: #d6e0f5;
}
.tablesorter-blue tr.even td.tertiary {
background-color: #ebf0fa;
}
/* caption */
caption {
background: #fff;
}
/* filter widget */
.tablesorter-blue .tablesorter-filter-row td {
background: #eee;
line-height: normal;
text-align: center; /* center the input */
-webkit-transition: line-height 0.1s ease;
-moz-transition: line-height 0.1s ease;
-o-transition: line-height 0.1s ease;
transition: line-height 0.1s ease;
}
/* optional disabled input styling */
.tablesorter-blue .tablesorter-filter-row .disabled {
opacity: 0.5;
filter: alpha(opacity=50);
cursor: not-allowed;
}
/* hidden filter row */
.tablesorter-blue .tablesorter-filter-row.hideme td {
/*** *********************************************** ***/
/*** change this padding to modify the thickness ***/
/*** of the closed filter row (height = padding x 2) ***/
padding: 2px;
/*** *********************************************** ***/
margin: 0;
line-height: 0;
cursor: pointer;
}
.tablesorter-blue .tablesorter-filter-row.hideme .tablesorter-filter {
height: 1px;
min-height: 0;
border: 0;
padding: 0;
margin: 0;
/* don't use visibility: hidden because it disables tabbing */
opacity: 0;
filter: alpha(opacity=0);
}
/* filters */
.tablesorter-blue .tablesorter-filter {
width: 98%;
height: auto;
margin: 0;
padding: 4px;
background-color: #fff;
border: 1px solid #bbb;
color: #333;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-webkit-transition: height 0.1s ease;
-moz-transition: height 0.1s ease;
-o-transition: height 0.1s ease;
transition: height 0.1s ease;
}
/* rows hidden by filtering (needed for child rows) */
.tablesorter .filtered {
display: none;
}
/* ajax error row */
.tablesorter .tablesorter-errorRow td {
text-align: center;
cursor: pointer;
background-color: #e6bf99;
}
@@ -0,0 +1,152 @@
/*************
Bootstrap theme
*************/
/* jQuery Bootstrap Theme */
.tablesorter-bootstrap {
width: 100%;
}
.tablesorter-bootstrap thead th,
.tablesorter-bootstrap thead td,
.tablesorter-bootstrap tfoot th,
.tablesorter-bootstrap tfoot td {
font: bold 14px/20px Arial, Sans-serif;
padding: 4px;
margin: 0 0 18px;
background-color: #eee;
}
.tablesorter-bootstrap .tablesorter-header {
cursor: pointer;
}
.tablesorter-bootstrap .tablesorter-header-inner {
position: relative;
padding: 4px 18px 4px 4px;
}
/* bootstrap uses <i> for icons */
.tablesorter-bootstrap .tablesorter-header i {
font-size: 11px;
position: absolute;
right: 2px;
top: 50%;
margin-top: -7px; /* half the icon height; older IE doesn't like this */
width: 14px;
height: 14px;
background-repeat: no-repeat;
line-height: 14px;
display: inline-block;
}
/* black unsorted icon */
.tablesorter-bootstrap .bootstrap-icon-unsorted {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAOCAMAAADOvxanAAAAVFBMVEUAAABCQkJZWVkZGRnJyckgICAZGRkZGRn8/PweHh4dHR0aGhoaGhpUVFQbGxvQ0NDc3NxMTExSUlIbGxvr6+s4ODhKSkogICAtLS00NDQzMzMnJydSEPrQAAAAGHRSTlMA1ssZRLgdAQbDyisqsZo8QdXUq0r9xPepSRwiAAAAX0lEQVQI13XHSQKAIAwEwQAKxn13Ev7/T2Pu9qmarJKPXIicI4PH4hxaKNrhm2S8bJK5h4YzKHrzJNtK6yYT/TdXzpS5zuYg4MSQYF6i4IHExdw1UVRi05HPrrvT53a+qyMFC9t04gcAAAAASUVORK5CYII=);
}
/* white unsorted icon */
.tablesorter-bootstrap .icon-white.bootstrap-icon-unsorted {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAOBAMAAAALT/umAAAAKlBMVEUAAAD///////////////////////////////////////////////////+Gu8ovAAAADXRSTlMA4EXKBtQqvR0+sxmalc142gAAAFdJREFUCNdjYGDoamAAAjZbMxCVfvd6AgMDd+3du9UMDKx3hWSvMjBwXZww8RYDGuC53NB8h4GB8a617UUGBs7Yu3cjGRhYVO9eVQFKOskKOQApFmUgBwBZ+xXRTttNdAAAAABJRU5ErkJggg==);
}
/* since bootstrap (table-striped) uses nth-child(), we just use this to add a zebra stripe color */
.tablesorter-bootstrap > tbody > tr.odd > td,
.tablesorter-bootstrap > tbody > tr.tablesorter-hasChildRow.odd:hover ~ tr.tablesorter-hasChildRow.odd ~ .tablesorter-childRow.odd > td {
background-color: #f9f9f9;
}
.tablesorter-bootstrap > tbody > tr.odd:hover > td,
.tablesorter-bootstrap > tbody > tr.even:hover > td,
.tablesorter-bootstrap > tbody > tr.tablesorter-hasChildRow.odd:hover ~ .tablesorter-childRow.odd > td,
.tablesorter-bootstrap > tbody > tr.tablesorter-hasChildRow.even:hover ~ .tablesorter-childRow.even > td {
background-color: #f5f5f5;
}
.tablesorter-bootstrap > tbody > tr.even > td,
.tablesorter-bootstrap > tbody > tr.tablesorter-hasChildRow.even:hover ~ tr.tablesorter-hasChildRow.even ~ .tablesorter-childRow.even > td {
background-color: #fff;
}
/* processing icon */
.tablesorter-bootstrap .tablesorter-processing {
background-image: url('data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=');
background-position: center center !important;
background-repeat: no-repeat !important;
}
/* caption */
.caption {
background: #fff;
}
/* filter widget */
.tablesorter-bootstrap .tablesorter-filter-row .tablesorter-filter {
width: 98%;
margin: 0 auto;
padding: 4px 6px;
color: #333;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-webkit-transition: height 0.1s ease;
-moz-transition: height 0.1s ease;
-o-transition: height 0.1s ease;
transition: height 0.1s ease;
}
.tablesorter-bootstrap .tablesorter-filter-row .tablesorter-filter.disabled {
background-color: #eee;
color: #555;
cursor: not-allowed;
border: 1px solid #ccc;
border-radius: 4px;
box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.075) inset;
box-sizing: border-box;
transition: height 0.1s ease;
}
.tablesorter-bootstrap .tablesorter-filter-row td {
background: #efefef;
line-height: normal;
text-align: center;
padding: 4px 6px;
vertical-align: middle;
-webkit-transition: line-height 0.1s ease;
-moz-transition: line-height 0.1s ease;
-o-transition: line-height 0.1s ease;
transition: line-height 0.1s ease;
}
/* hidden filter row */
.tablesorter-bootstrap .tablesorter-filter-row.hideme td {
padding: 2px; /* change this to modify the thickness of the closed border row */
margin: 0;
line-height: 0;
}
.tablesorter-bootstrap .tablesorter-filter-row.hideme .tablesorter-filter {
height: 1px;
min-height: 0;
border: 0;
padding: 0;
margin: 0;
/* don't use visibility: hidden because it disables tabbing */
opacity: 0;
filter: alpha(opacity=0);
}
/* rows hidden by filtering (needed for child rows) */
.tablesorter .filtered {
display: none;
}
/* pager plugin */
.tablesorter-bootstrap .tablesorter-pager select {
padding: 4px 6px;
}
.tablesorter-bootstrap .tablesorter-pager .pagedisplay {
border: 0;
}
/* tfoot i for pager controls */
.tablesorter-bootstrap tfoot i {
font-size: 11px;
}
/* ajax error row */
.tablesorter .tablesorter-errorRow td {
text-align: center;
cursor: pointer;
background-color: #e6bf99;
}
@@ -0,0 +1,150 @@
/*************
Bootstrap 2 Theme
*************/
/* jQuery Bootstrap 2 Theme */
.tablesorter-bootstrap {
width: 100%;
}
.tablesorter-bootstrap .tablesorter-header,
.tablesorter-bootstrap tfoot th,
.tablesorter-bootstrap tfoot td {
font: bold 14px/20px Arial, Sans-serif;
position: relative;
padding: 8px;
margin: 0 0 18px;
list-style: none;
background-color: #FBFBFB;
background-image: -moz-linear-gradient(top, white, #efefef);
background-image: -ms-linear-gradient(top, white, #efefef);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(white), to(#efefef));
background-image: -webkit-linear-gradient(top, white, #efefef);
background-image: -o-linear-gradient(top, white, #efefef);
background-image: linear-gradient(to bottom, white, #efefef);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#efefef', GradientType=0);
background-repeat: repeat-x;
-webkit-box-shadow: inset 0 1px 0 white;
-moz-box-shadow: inset 0 1px 0 #ffffff;
box-shadow: inset 0 1px 0 white;
}
.tablesorter-bootstrap .tablesorter-header {
cursor: pointer;
}
.tablesorter-bootstrap .tablesorter-header-inner {
position: relative;
padding: 4px 18px 4px 4px;
}
/* bootstrap uses <i> for icons */
.tablesorter-bootstrap .tablesorter-header i {
position: absolute;
right: 2px;
top: 50%;
margin-top: -7px; /* half the icon height; older IE doesn't like this */
width: 14px;
height: 14px;
background-repeat: no-repeat;
line-height: 14px;
display: inline-block;
}
/* black unsorted icon */
.tablesorter-bootstrap .bootstrap-icon-unsorted {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAOCAYAAAD5YeaVAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAWVJREFUeNqUUL9Lw2AUTGP8mqGlpBQkNeCSRcckEBcHq1jImMElToKuDvpHFMGhU0BQcHBwLji6CE1B4uB/INQsDi4d2jQ/fPeZxo764OV6915f7lLJ81xot9tCURXqdVEUr7IsO6ffH9Q5BlEUCaLwWxWqTcbYnaIoh0Dw4gAvcWlxq1qt9hqNxg6hUGAP+uIPUrGs0qXLer2+v/pTX6QpxLtkc2U2m53ACb8sSdIDXerSEms2m6+DweAICA4d89KGbduf9MpEVdXQ9/2LVqv1CASHjjn3iq/x1xKFfxQPqGnada1W86bT6SiO42OS3qk3KPStLMvbk8nkfjwen/LLuq6blFymMB0KdUPSGhAcOualjX6/f0bCiC7NaWGPQr0BwaFjzn0gYJqmLAiCA8/zni3LmhuGkQPBoWPOPwQeaPIqD4fDruu6L6Zp5kBw6IudchmdJAkLw3DXcZwnIPjy/FuAAQCiqqWWCAFKcwAAAABJRU5ErkJggg==);
}
/* white unsorted icon */
.tablesorter-bootstrap .icon-white.bootstrap-icon-unsorted {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAOBAMAAAALT/umAAAAKlBMVEUAAAD///////////////////////////////////////////////////+Gu8ovAAAADXRSTlMA4EXKBtQqvR0+sxmalc142gAAAFdJREFUCNdjYGDoamAAAjZbMxCVfvd6AgMDd+3du9UMDKx3hWSvMjBwXZww8RYDGuC53NB8h4GB8a617UUGBs7Yu3cjGRhYVO9eVQFKOskKOQApFmUgBwBZ+xXRTttNdAAAAABJRU5ErkJggg==);
}
/* since bootstrap (table-striped) uses nth-child(), we just use this to add a zebra stripe color */
.tablesorter-bootstrap tr.odd td {
background-color: #f9f9f9;
}
.tablesorter-bootstrap tbody > .odd:hover > td,
.tablesorter-bootstrap tbody > .even:hover > td {
background-color: #f5f5f5;
}
.tablesorter-bootstrap tr.even td {
background-color: #fff;
}
/* processing icon */
.tablesorter-bootstrap .tablesorter-processing {
background-image: url('data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=');
position: absolute;
z-index: 1000;
}
/* caption */
caption {
background: #fff;
}
/* filter widget */
.tablesorter-bootstrap .tablesorter-filter-row .tablesorter-filter {
width: 98%;
margin: 0 auto;
padding: 4px 6px;
background-color: #fff;
color: #333;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-webkit-transition: height 0.1s ease;
-moz-transition: height 0.1s ease;
-o-transition: height 0.1s ease;
transition: height 0.1s ease;
}
.tablesorter-bootstrap .tablesorter-filter-row .tablesorter-filter.disabled {
background: #eee;
cursor: not-allowed;
}
.tablesorter-bootstrap .tablesorter-filter-row td {
background: #eee;
line-height: normal;
text-align: center;
padding: 4px 6px;
vertical-align: middle;
-webkit-transition: line-height 0.1s ease;
-moz-transition: line-height 0.1s ease;
-o-transition: line-height 0.1s ease;
transition: line-height 0.1s ease;
}
/* hidden filter row */
.tablesorter-bootstrap .tablesorter-filter-row.hideme td {
padding: 2px; /* change this to modify the thickness of the closed border row */
margin: 0;
line-height: 0;
}
.tablesorter-bootstrap .tablesorter-filter-row.hideme .tablesorter-filter {
height: 1px;
min-height: 0;
border: 0;
padding: 0;
margin: 0;
/* don't use visibility: hidden because it disables tabbing */
opacity: 0;
filter: alpha(opacity=0);
}
/* rows hidden by filtering (needed for child rows) */
.tablesorter .filtered {
display: none;
}
/* pager plugin */
.tablesorter-bootstrap .tablesorter-pager select {
padding: 4px 6px;
}
.tablesorter-bootstrap .tablesorter-pager .pagedisplay {
border: 0;
}
/* ajax error row */
.tablesorter .tablesorter-errorRow td {
text-align: center;
cursor: pointer;
background-color: #e6bf99;
}
@@ -0,0 +1,187 @@
/*************
Dark Theme (by thezoggy)
*************/
/* overall */
.tablesorter-dark {
width: 100%;
font: 11px/18px Arial, Sans-serif;
color: #ccc;
text-align: left;
background-color: #000;
border-spacing: 0;
}
/* header */
.tablesorter-dark th,
.tablesorter-dark thead td {
padding: 4px;
font: bold 12px/20px Arial, Sans-serif;
color: #fff;
background-color: #000;
border-collapse: collapse;
}
.tablesorter-dark thead th {
border-bottom: #333 2px solid;
}
.tablesorter-dark .header,
.tablesorter-dark .tablesorter-header {
padding: 4px 20px 4px 4px;
cursor: pointer;
background-image: url(data:image/gif;base64,R0lGODlhFQAJAIAAAP///////yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==);
background-position: center right;
background-repeat: no-repeat;
}
.tablesorter-dark thead .headerSortUp,
.tablesorter-dark thead .tablesorter-headerSortUp,
.tablesorter-dark thead .tablesorter-headerAsc {
background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7);
border-bottom: #888 1px solid;
}
.tablesorter-dark thead .headerSortDown,
.tablesorter-dark thead .tablesorter-headerSortDown,
.tablesorter-dark thead .tablesorter-headerDesc {
background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7);
border-bottom: #888 1px solid;
}
.tablesorter-dark thead .sorter-false {
background-image: none;
cursor: default;
padding: 4px;
}
/* tfoot */
.tablesorter-dark tfoot .tablesorter-headerSortUp,
.tablesorter-dark tfoot .tablesorter-headerSortDown,
.tablesorter-dark tfoot .tablesorter-headerAsc,
.tablesorter-dark tfoot .tablesorter-headerDesc {
border-top: #888 1px solid;
/* remove sort arrows from footer */
background-image: none;
}
/* tbody */
.tablesorter-dark td {
padding: 4px;
background-color: #000;
border-bottom: #333 1px solid;
color: #ccc;
}
/* hovered row colors */
.tablesorter-dark tbody > tr:hover > td,
.tablesorter-dark tbody > tr.even:hover > td,
.tablesorter-dark tbody > tr.odd:hover > td {
background: #000;
}
/* table processing indicator */
.tablesorter-dark .tablesorter-processing {
background-position: center center !important;
background-repeat: no-repeat !important;
/* background-image: url(../addons/pager/icons/loading.gif) !important; */
background-image: url('data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=') !important;
}
/* Zebra Widget - row alternating colors */
.tablesorter-dark tr.odd td {
background-color: #202020;
}
.tablesorter-dark tr.even td {
background-color: #101010;
}
/* Column Widget - column sort colors */
.tablesorter-dark td.primary,
.tablesorter-dark tr.odd td.primary {
background-color: #0a0a0a;
}
.tablesorter-dark tr.even td.primary {
background-color: #050505;
}
.tablesorter-dark td.secondary,
.tablesorter-dark tr.odd td.secondary {
background-color: #0f0f0f;
}
.tablesorter-dark tr.even td.secondary {
background-color: #0a0a0a;
}
.tablesorter-dark td.tertiary,
.tablesorter-dark tr.odd td.tertiary {
background-color: #191919;
}
.tablesorter-dark tr.even td.tertiary {
background-color: #0f0f0f;
}
/* caption */
caption {
background: #202020;
}
/* filter widget */
.tablesorter-dark .tablesorter-filter-row td {
background: #202020;
line-height: normal;
text-align: center; /* center the input */
-webkit-transition: line-height 0.1s ease;
-moz-transition: line-height 0.1s ease;
-o-transition: line-height 0.1s ease;
transition: line-height 0.1s ease;
}
/* optional disabled input styling */
.tablesorter-dark .tablesorter-filter-row .disabled {
opacity: 0.5;
filter: alpha(opacity=50);
cursor: not-allowed;
}
/* hidden filter row */
.tablesorter-dark .tablesorter-filter-row.hideme td {
/*** *********************************************** ***/
/*** change this padding to modify the thickness ***/
/*** of the closed filter row (height = padding x 2) ***/
padding: 2px;
/*** *********************************************** ***/
margin: 0;
line-height: 0;
cursor: pointer;
}
.tablesorter-dark .tablesorter-filter-row.hideme .tablesorter-filter {
height: 1px;
min-height: 0;
border: 0;
padding: 0;
margin: 0;
/* don't use visibility: hidden because it disables tabbing */
opacity: 0;
filter: alpha(opacity=0);
}
/* filters */
.tablesorter-dark .tablesorter-filter {
width: 98%;
height: auto;
margin: 4px;
padding: 4px;
background-color: #111;
border: 1px solid #222;
color: #ddd;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-webkit-transition: height 0.1s ease;
-moz-transition: height 0.1s ease;
-o-transition: height 0.1s ease;
transition: height 0.1s ease;
}
/* rows hidden by filtering (needed for child rows) */
.tablesorter .filtered {
display: none;
}
/* ajax error row */
.tablesorter .tablesorter-errorRow td {
text-align: center;
cursor: pointer;
background-color: #e6bf99;
}
@@ -0,0 +1,189 @@
/*************
Default Theme
*************/
/* overall */
.tablesorter-default {
width: 100%;
font: 12px/18px Arial, Sans-serif;
color: #333;
background-color: #fff;
border-spacing: 0;
margin: 10px 0 15px;
text-align: left;
}
/* header */
.tablesorter-default th,
.tablesorter-default thead td {
font: bold 12px/18px Arial, Sans-serif;
color: #000;
background-color: #fff;
border-collapse: collapse;
border-bottom: #ccc 2px solid;
padding: 0;
}
.tablesorter-default tfoot th,
.tablesorter-default tfoot td {
border: 0;
}
.tablesorter-default .header,
.tablesorter-default .tablesorter-header {
background-image: url(data:image/gif;base64,R0lGODlhFQAJAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==);
background-position: center right;
background-repeat: no-repeat;
cursor: pointer;
white-space: normal;
padding: 4px 20px 4px 4px;
}
.tablesorter-default thead .headerSortUp,
.tablesorter-default thead .tablesorter-headerSortUp,
.tablesorter-default thead .tablesorter-headerAsc {
background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7);
border-bottom: #000 2px solid;
}
.tablesorter-default thead .headerSortDown,
.tablesorter-default thead .tablesorter-headerSortDown,
.tablesorter-default thead .tablesorter-headerDesc {
background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7);
border-bottom: #000 2px solid;
}
.tablesorter-default thead .sorter-false {
background-image: none;
cursor: default;
padding: 4px;
}
/* tfoot */
.tablesorter-default tfoot .tablesorter-headerSortUp,
.tablesorter-default tfoot .tablesorter-headerSortDown,
.tablesorter-default tfoot .tablesorter-headerAsc,
.tablesorter-default tfoot .tablesorter-headerDesc {
border-top: #000 2px solid;
}
/* tbody */
.tablesorter-default td {
background-color: #fff;
border-bottom: #ccc 1px solid;
padding: 4px;
vertical-align: top;
}
/* hovered row colors */
.tablesorter-default tbody > tr:hover > td,
.tablesorter-default tbody > tr.even:hover > td,
.tablesorter-default tbody > tr.odd:hover > td {
background: #fff;
color: #000;
}
/* table processing indicator */
.tablesorter-default .tablesorter-processing {
background-position: center center !important;
background-repeat: no-repeat !important;
/* background-image: url(../addons/pager/icons/loading.gif) !important; */
background-image: url('data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=') !important;
}
/* Zebra Widget - row alternating colors */
.tablesorter-default tr.odd td {
background-color: #dfdfdf;
}
.tablesorter-default tr.even td {
background-color: #efefef;
}
/* Column Widget - column sort colors */
.tablesorter-default tr.odd td.primary {
background-color: #bfbfbf;
}
.tablesorter-default td.primary,
.tablesorter-default tr.even td.primary {
background-color: #d9d9d9;
}
.tablesorter-default tr.odd td.secondary {
background-color: #d9d9d9;
}
.tablesorter-default td.secondary,
.tablesorter-default tr.even td.secondary {
background-color: #e6e6e6;
}
.tablesorter-default tr.odd td.tertiary {
background-color: #e6e6e6;
}
.tablesorter-default td.tertiary,
.tablesorter-default tr.even td.tertiary {
background-color: #f2f2f2;
}
/* caption */
caption {
background: #fff;
}
/* filter widget */
.tablesorter-default .tablesorter-filter-row td {
background: #eee;
border-bottom: #ccc 1px solid;
line-height: normal;
text-align: center; /* center the input */
-webkit-transition: line-height 0.1s ease;
-moz-transition: line-height 0.1s ease;
-o-transition: line-height 0.1s ease;
transition: line-height 0.1s ease;
}
/* optional disabled input styling */
.tablesorter-default .tablesorter-filter-row .disabled {
opacity: 0.5;
filter: alpha(opacity=50);
cursor: not-allowed;
}
/* hidden filter row */
.tablesorter-default .tablesorter-filter-row.hideme td {
/*** *********************************************** ***/
/*** change this padding to modify the thickness ***/
/*** of the closed filter row (height = padding x 2) ***/
padding: 2px;
/*** *********************************************** ***/
margin: 0;
line-height: 0;
cursor: pointer;
}
.tablesorter-default .tablesorter-filter-row.hideme .tablesorter-filter {
height: 1px;
min-height: 0;
border: 0;
padding: 0;
margin: 0;
/* don't use visibility: hidden because it disables tabbing */
opacity: 0;
filter: alpha(opacity=0);
}
/* filters */
.tablesorter-default .tablesorter-filter {
width: 95%;
height: auto;
margin: 4px;
padding: 4px;
background-color: #fff;
border: 1px solid #bbb;
color: #333;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-webkit-transition: height 0.1s ease;
-moz-transition: height 0.1s ease;
-o-transition: height 0.1s ease;
transition: height 0.1s ease;
}
/* rows hidden by filtering (needed for child rows) */
.tablesorter .filtered {
display: none;
}
/* ajax error row */
.tablesorter .tablesorter-errorRow td {
text-align: center;
cursor: pointer;
background-color: #e6bf99;
}
@@ -0,0 +1,212 @@
/*************
Dropbox Theme (by thezoggy)
*************/
/* overall */
.tablesorter-dropbox {
width: 100%;
font: 13px/32px "Open Sans","lucida grande","Segoe UI",arial,verdana,"lucida sans unicode",tahoma,sans-serif;
color: #555;
text-align: left;
background-color: #fff;
border-collapse: collapse;
border-top: 1px solid #82cffa;
border-spacing: 0;
}
/* header */
.tablesorter-dropbox th,
.tablesorter-dropbox thead td,
.tablesorter-dropbox tfoot th,
.tablesorter-dropbox tfoot td {
background-color: #f0f9ff;
border-color: #82cffa #e7f2fb #96c4ea;
border-style: solid;
border-width: 1px;
padding: 3px 6px;
font-size: 13px;
font-weight: normal;
line-height: 29px;
color: #2281CF;
text-align: left;
}
.tablesorter-dropbox .header,
.tablesorter-dropbox thead tr,
.tablesorter-dropbox .tablesorter-headerRow {
background-color: #f0f9ff;
border-bottom: 1px solid #96c4ea;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.12), 0 0 0 #000000 inset;
white-space: normal;
}
.tablesorter-dropbox .tablesorter-headerSortUp,
.tablesorter-dropbox .tablesorter-headerSortDown,
.tablesorter-dropbox .tablesorter-headerAsc,
.tablesorter-dropbox .tablesorter-headerDesc {
font-weight: 600;
}
.tablesorter-dropbox .tablesorter-header {
cursor: pointer;
}
.tablesorter-dropbox .tablesorter-header i {
width: 9px;
height: 9px;
padding: 0 10px 0 4px;
display: inline-block;
background-position: center right;
background-repeat: no-repeat;
content: "";
}
.tablesorter-dropbox .tablesorter-headerSortUp i,
.tablesorter-dropbox .tablesorter-headerAsc i {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAALhJREFUeNpi/P//PwMhwILMiexYx8bIxNTy/9+/muUVQb9g4kzIitg4edI4+YRLQTSyOCPMupjerUI8whK3OXgEhH58+fDuy9sXqkuKvd+hmMTOxdvCxS8sxMUvxACiQXwU6+Im7DDg5BNKY+fiY2BmYWMA0SA+SByuiJ2bbzIHrwAzMxsb0AGMDCAaxAeJg+SZ7wtaqfAISfQAdTIwMUM8ywhUyMTEzPD/71+5FXvPLWUkJpwAAgwAZqYvvHStbD4AAAAASUVORK5CYII=');
/* background-image: url(images/dropbox-asc.png); */
}
.tablesorter-dropbox .tablesorter-headerSortUp:hover i,
.tablesorter-dropbox .tablesorter-headerAsc:hover i {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAALVJREFUeNpi/P//PwMhwILMCc+qZGNkYmr5/+9fzcpp7b9g4kzIitjYOdM4uXlLQTSyOCPMuqi8OiEefsHbHFzcQj++fX335eN71WWTmt6hmMTOwdXCycMnBDSJAUSD+CjWxRQ0GHBw86Sxc3AyMDOzMIBoEB8kDlfEzsk1mYOLByjPCnQAIwOIBvFB4iB55rsfmVS4+QV7QNYwMTNDHApUyMTExPDv/z+5Feu3L2UkJpwAAgwA244u+I9CleAAAAAASUVORK5CYII=');
/* background-image: url(images/dropbox-asc-hovered.png); */
}
.tablesorter-dropbox .tablesorter-headerSortDown i,
.tablesorter-dropbox .tablesorter-headerDesc i {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAALdJREFUeNpi/P//PwMhwBLdtVGFhZ3zNhMzC4bkv79/GP78/K7KCDIpZ9mVw+xcfDaMTExwBf///WP4+e3TkSlROrZg7UxMLLns3HxnmFnZmGGK/v7+9ff3j2+5YHkQMSlC48Kv719m/f//D2IKkAbxQeJwRSDw4/OHmr+/fr0DqmAA0SA+TA6uaEq0zjugG+r//vkFcks9iA/3HbJvvn18O+vf379yP758mMXAoAAXZyQmnAACDADX316BiTFbMQAAAABJRU5ErkJggg==');
/* background-image: url(images/dropbox-desc.png); */
}
.tablesorter-dropbox .tablesorter-headerSortDown:hover i,
.tablesorter-dropbox .tablesorter-headerDesc:hover i {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAALNJREFUeNpi/P//PwMhwBJf3uP879e3PUzMzBiS//7+ZWBi43JhBJmU2z7nIzMzEx8jIyNcAUj8799/nyZXpvCzgARYuXjTWBkZVjCzIEz7++cvw+//DGkgNiPMTWVT1l5hZvynDTINbMp/pqtdOcE6IDkmmM5fv3/5//v37z9QBQOIBvFhcnBFEwoj7/5jZFnz9+8fBhAN4sN9h+ybH9++JrGxscr/+vE1CVmckZhwAggwANvlUyq5Dd1wAAAAAElFTkSuQmCC');
/* background-image: url(images/dropbox-desc-hovered.png); */
}
.tablesorter-dropbox thead .sorter-false {
cursor: default;
}
.tablesorter-dropbox thead .sorter-false i,
.tablesorter-dropbox thead .sorter-false:hover i {
background-image: none;
padding: 4px;
}
/* tbody */
.tablesorter-dropbox td {
padding: 5px 6px;
line-height: 32px;
color: #555;
text-align: left;
border-top: 1px solid #edf1f5;
border-bottom: 1px solid #edf1f5;
}
/* hovered row colors */
.tablesorter-dropbox tbody > tr:hover > td,
.tablesorter-dropbox tbody > tr.even:hover > td,
.tablesorter-dropbox tbody > tr.odd:hover > td {
background-color: rgba(230, 245, 255, 0.3);
border-right: 0;
border-left: 0;
border-color: #c6d8e4;
/* trick to do border-top and bottom colors */
border-style: double;
}
/* table processing indicator */
.tablesorter-dropbox .tablesorter-processing {
background-position: center center !important;
background-repeat: no-repeat !important;
/* background-image: url(../addons/pager/icons/loading.gif) !important; */
background-image: url('data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=') !important;
}
/* Zebra Widget - row alternating colors */
.tablesorter-dropbox tr.odd td {
}
.tablesorter-dropbox tr.even td {
}
/* Column Widget - column sort colors */
.tablesorter-dropbox td.primary,
.tablesorter-dropbox tr.odd td.primary {
}
.tablesorter-dropbox tr.even td.primary {
}
.tablesorter-dropbox td.secondary,
.tablesorter-dropbox tr.odd td.secondary {
}
.tablesorter-dropbox tr.even td.secondary {
}
.tablesorter-dropbox td.tertiary,
.tablesorter-dropbox tr.odd td.tertiary {
}
.tablesorter-dropbox tr.even td.tertiary {
}
/* caption */
caption {
background: #fff;
}
/* Filter Widget */
.tablesorter-dropbox .tablesorter-filter-row td {
background: #fff;
line-height: normal;
text-align: center; /* center the input */
-webkit-transition: line-height 0.1s ease;
-moz-transition: line-height 0.1s ease;
-o-transition: line-height 0.1s ease;
transition: line-height 0.1s ease;
}
/* optional disabled input styling */
.tablesorter-dropbox .tablesorter-filter-row .disabled {
opacity: 0.5;
filter: alpha(opacity=50);
cursor: not-allowed;
}
/* hidden filter row */
.tablesorter-dropbox .tablesorter-filter-row.hideme td {
/*** *********************************************** ***/
/*** change this padding to modify the thickness ***/
/*** of the closed filter row (height = padding x 2) ***/
padding: 2px;
/*** *********************************************** ***/
margin: 0;
line-height: 0;
cursor: pointer;
}
.tablesorter-dropbox .tablesorter-filter-row.hideme .tablesorter-filter {
height: 1px;
min-height: 0;
border: 0;
padding: 0;
margin: 0;
/* don't use visibility: hidden because it disables tabbing */
opacity: 0;
filter: alpha(opacity=0);
}
/* filters */
.tablesorter-dropbox .tablesorter-filter {
width: 98%;
height: auto;
margin: 4px;
background-color: #fff;
border: 1px solid #bbb;
color: #333;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-webkit-transition: height 0.1s ease;
-moz-transition: height 0.1s ease;
-o-transition: height 0.1s ease;
transition: height 0.1s ease;
}
/* rows hidden by filtering (needed for child rows) */
.tablesorter .filtered {
display: none;
}
/* ajax error row */
.tablesorter .tablesorter-errorRow td {
text-align: center;
cursor: pointer;
background-color: #e6bf99;
}
@@ -0,0 +1,203 @@
/*************
Green Theme
*************/
/* overall */
.tablesorter-green {
width: 100%;
text-align: left;
border-spacing: 0;
border: #cdcdcd 1px solid;
border-width: 1px 0 0 1px;
}
.tablesorter-green th,
.tablesorter-green td {
font: 12px/18px Arial, Sans-serif;
border: #cdcdcd 1px solid;
border-width: 0 1px 1px 0;
}
/* header */
.tablesorter-green thead tr .tablesorter-header,
.tablesorter-green tfoot tr {
background: center center repeat-x;
background-image: url(data:image/gif;base64,R0lGODlhAQBkAOYAAN/e39XU1fX19tTU1eXm5uTl5ePk5OLj4+Hi4vX29fT19PP08/Lz8vHy8fDx8O/w7+7v7uzt7Orr6ufo5/T08/Pz8ufn5uLi4eDg39/f3t3d3Nzc29HR0NDQz8/Pzuvq6urp6eno6Ojn5+fm5tfW1tbV1dTT09PS0tLR0dHQ0NDPz/f39/b29vX19fT09PPz8/Ly8vHx8e/v7+7u7u3t7ezs7Ovr6+rq6unp6ejo6Ofn5+bm5uXl5eTk5OPj4+Li4uHh4eDg4N/f397e3t3d3dzc3Nvb29ra2tnZ2djY2NfX19XV1dPT09LS0tHR0dDQ0M/Pz8rKysXFxf///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAFMALAAAAAABAGQAAAdegCsrLC0tLi+ILi6FCSwsCS0KkhQVDA0OMjM0NTYfICEiIzw9P0AYGUQaG0ZHSEoDTU9Qs08pTk1MSyRJR0VDQT8+PTw7Ojg3NTMyMTAvi4WOhC0vMTI1OT9GTlFSgQA7);
/* background-image: url(images/green-header.gif); */
}
.tablesorter-green th,
.tablesorter-green thead td {
font-weight: bold;
border-right: #cdcdcd 1px solid;
border-collapse: collapse;
padding: 6px;
}
.tablesorter-green .header,
.tablesorter-green .tablesorter-header-inner {
background: no-repeat 5px center;
background-image: url(data:image/gif;base64,R0lGODlhEAAQAOYAAA5NDBBYDlWWUzRUM5DVjp7inJ/fnQ1ECiCsGhyYFxqKFRFdDhBXDQxCCiO8HSK2HCCqGh2aGByUFxuPFhqNFhmHFRZ2EhVvERRpEBBVDSS8HiGyHB+mGh6fGRuTFxiAFBd5Eww/Cgs5CRp7Fiu+JRx8GCy/JjHAKyynKCuhJzXCMDbCMDnDMyNuHz3EODy9N0LFPSl7JkvIRjycOFDKS1LKTVPLT1XLUFTCT17OWTBkLmbQYnDTbHXVcXnWdoXago/djGmUZ112XCJEIEdjRf///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAEUALAAAAAAQABAAAAdlgEWCg4SFhoIvh4cVLECKhCMeJjwFj0UlEwgaMD4Gii0WFAkRHQ47BIY6IQAZDAwBCyAPOJa1toRBGBAwNTY3OT0/AoZCDQoOKi4yNDOKRCIfGycrKZYDBxIkKLZDFxy3RTHgloEAOw==);
/* background-image: url(images/green-unsorted.gif); */
border-collapse: collapse;
white-space: normal;
cursor: pointer;
}
.tablesorter-green thead .headerSortUp .tablesorter-header-inner,
.tablesorter-green thead .tablesorter-headerSortUp .tablesorter-header-inner,
.tablesorter-green thead .tablesorter-headerAsc .tablesorter-header-inner {
background-image: url(data:image/gif;base64,R0lGODlhEAAQANUAAA5NDBBYDpDVjp7inJ/fnSCsGhyYFxFdDhBXDSO8HSK2HB2aGBuPFhqNFhmHFRZ2EhBVDSS8Hh6fGRuTFxd5Eww/Chp7Fhx8GCy/JjnDMyNuHzy9N0LFPVTCTzBkLmbQYnDTbHnWdo/djP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAACMALAAAAAAQABAAAAY4wJFwSCwaj8ikcslMbpojR0bEtEwwoIHywihEOCECUvNoGBaSxEdg9FQAEAQicKAoOtC8fs8fBgEAOw==)
/* background-image: url(images/green-asc.gif); */
}
.tablesorter-green thead .headerSortDown .tablesorter-header-inner,
.tablesorter-green thead .tablesorter-headerSortDown .tablesorter-header-inner,
.tablesorter-green thead .tablesorter-headerDesc .tablesorter-header-inner {
background-image: url(data:image/gif;base64,R0lGODlhEAAQANUAAFWWUzRUMw1EChqKFQxCCiO8HSCqGhyUFxVvERRpECGyHB+mGhiAFAs5CSu+JTHAKyynKCuhJzXCMDbCMD3EOELFPSl7JkvIRjycOFDKS1LKTVPLT1XLUF7OWXXVcYXagmmUZ112XCJEIEdjRf///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAACQALAAAAAAQABAAAAY4QJJwSCwaj8ikcskkghKGimbD6Xg+AGOIMChIKJcMBjlqMBSPSUQZEBwcEKYIsWiSLPa8fs9HBgEAOw==)
/* background-image: url(images/green-desc.gif); */
}
.tablesorter-green th.tablesorter-header .tablesorter-header-inner,
.tablesorter-green td.tablesorter-header .tablesorter-header-inner {
padding-left: 23px;
}
.tablesorter-green thead .tablesorter-header.sorter-false .tablesorter-header-inner {
background-image: none;
cursor: default;
padding-left: 6px;
}
/* tfoot */
.tablesorter-green tbody td,
.tablesorter-green tfoot th {
padding: 6px;
vertical-align: top;
}
/* tbody */
.tablesorter-green td {
color: #3d3d3d;
padding: 6px;
}
/* hovered row colors
you'll need to add additional lines for
rows with more than 2 child rows
*/
.tablesorter-green tbody > tr:hover > td,
.tablesorter-green tbody > tr:hover + tr.tablesorter-childRow > td,
.tablesorter-green tbody > tr:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td,
.tablesorter-green tbody > tr.even:hover > td,
.tablesorter-green tbody > tr.even:hover + tr.tablesorter-childRow > td,
.tablesorter-green tbody > tr.even:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td {
background: #d9d9d9;
}
.tablesorter-green tbody > tr.odd:hover > td,
.tablesorter-green tbody > tr.odd:hover + tr.tablesorter-childRow > td,
.tablesorter-green tbody > tr.odd:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td {
background: #bfbfbf;
}
/* table processing indicator */
.tablesorter-green .tablesorter-processing {
background-position: center center !important;
background-repeat: no-repeat !important;
/* background-image: url(../addons/pager/icons/loading.gif) !important; */
background-image: url('data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=') !important;
}
/* Zebra Widget - row alternating colors */
.tablesorter-green tr.odd td {
background-color: #ebfaeb;
}
.tablesorter-green tr.even td {
background-color: #fff;
}
/* Column Widget - column sort colors */
.tablesorter-green td.primary,
.tablesorter-green tr.odd td.primary {
background-color: #99e6a6;
}
.tablesorter-green tr.even td.primary {
background-color: #c2f0c9;
}
.tablesorter-green td.secondary,
.tablesorter-green tr.odd td.secondary {
background-color: #c2f0c9;
}
.tablesorter-green tr.even td.secondary {
background-color: #d6f5db;
}
.tablesorter-green td.tertiary,
.tablesorter-green tr.odd td.tertiary {
background-color: #d6f5db;
}
.tablesorter-green tr.even td.tertiary {
background-color: #ebfaed;
}
/* caption */
caption {
background: #fff;
}
/* filter widget */
.tablesorter-green .tablesorter-filter-row td {
background: #eee;
line-height: normal;
text-align: center; /* center the input */
-webkit-transition: line-height 0.1s ease;
-moz-transition: line-height 0.1s ease;
-o-transition: line-height 0.1s ease;
transition: line-height 0.1s ease;
}
/* optional disabled input styling */
.tablesorter-green .tablesorter-filter-row .disabled {
opacity: 0.5;
filter: alpha(opacity=50);
cursor: not-allowed;
}
/* hidden filter row */
.tablesorter-green .tablesorter-filter-row.hideme td {
/*** *********************************************** ***/
/*** change this padding to modify the thickness ***/
/*** of the closed filter row (height = padding x 2) ***/
padding: 2px;
/*** *********************************************** ***/
margin: 0;
line-height: 0;
cursor: pointer;
}
.tablesorter-green .tablesorter-filter-row.hideme .tablesorter-filter {
height: 1px;
min-height: 0;
border: 0;
padding: 0;
margin: 0;
/* don't use visibility: hidden because it disables tabbing */
opacity: 0;
filter: alpha(opacity=0);
}
/* filters */
.tablesorter-green .tablesorter-filter {
width: 98%;
height: auto;
margin: 4px;
padding: 4px;
background-color: #fff;
border: 1px solid #bbb;
color: #333;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-webkit-transition: height 0.1s ease;
-moz-transition: height 0.1s ease;
-o-transition: height 0.1s ease;
transition: height 0.1s ease;
}
/* rows hidden by filtering (needed for child rows) */
.tablesorter .filtered {
display: none;
}
/* ajax error row */
.tablesorter .tablesorter-errorRow td {
text-align: center;
cursor: pointer;
background-color: #e6bf99;
}
@@ -0,0 +1,245 @@
/*************
Grey Theme
*************/
/* overall */
.tablesorter-grey {
width: 100%;
margin: 10px 0 15px;
text-align: left;
border-spacing: 0;
border-left: #555 1px solid;
}
/* header */
.tablesorter-grey th,
.tablesorter-grey thead td {
font: bold 12px/18px Arial, Sans-serif;
color: #c8c8c8;
background-color: #3c3c3c;
background-image: -moz-linear-gradient(top, #555, #3c3c3c);
background-image: -ms-linear-gradient(top, #555, #3c3c3c);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#555), to(#3c3c3c));
background-image: -webkit-linear-gradient(top, #555, #3c3c3c);
background-image: -o-linear-gradient(top, #555, #3c3c3c);
background-image: linear-gradient(to bottom, #555,#3c3c3c);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#555555', endColorstr='#3c3c3c',GradientType=0 );
background-repeat: repeat-x;
border-right: #555 1px solid;
text-shadow: 0 1px 0 rgba(128, 128, 128, 0.7);
-webkit-box-shadow: inset 0 1px 0 #222;
-moz-box-shadow: inset 0 1px 0 #222;
box-shadow: inset 0 1px 0 #222;
padding: 4px;
}
.tablesorter-grey .tablesorter-header-inner,
.tablesorter-grey .tablesorter-header-inner {
position: relative;
padding: 4px 15px 4px 4px;
}
.tablesorter-grey .header,
.tablesorter-grey .tablesorter-header {
cursor: pointer;
}
.tablesorter-grey .header i,
.tablesorter-grey .tablesorter-header i {
width: 18px;
height: 10px;
position: absolute;
right: 2px;
top: 50%;
margin-top: -10px;
/* white (unsorted) double arrow */
background-image: url(data:image/gif;base64,R0lGODlhFQAJAIAAAP///////yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==);
background-repeat: no-repeat;
background-position: center right;
padding: 4px;
white-space: normal;
}
.tablesorter-grey th.headerSortUp,
.tablesorter-grey th.tablesorter-headerSortUp,
.tablesorter-grey th.headerSortDown,
.tablesorter-grey th.tablesorter-headerSortDown {
color: #ddd;
background-color: #135185;
background-image: -moz-linear-gradient(top, #195c93, #0e4776);
background-image: -ms-linear-gradient(top, #195c93, #0e4776);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#195c93), to(#0e4776));
background-image: -webkit-linear-gradient(top, #195c93, #0e4776);
background-image: -o-linear-gradient(top, #195c93, #0e4776);
background-image: linear-gradient(to bottom, #195c93, #0e4776);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#195c93', endColorstr='#0e4776',GradientType=0 );
}
.tablesorter-grey .headerSortUp i,
.tablesorter-grey .tablesorter-headerSortUp i,
.tablesorter-grey .tablesorter-headerAsc i {
/* white asc arrow */
background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7);
}
.tablesorter-grey .headerSortDown i,
.tablesorter-grey .tablesorter-headerSortDown i,
.tablesorter-grey .tablesorter-headerDesc i {
/* white desc arrow */
background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7);
}
.tablesorter-grey thead .sorter-false {
cursor: default;
}
.tablesorter-grey thead .sorter-false i {
background-image: none;
padding: 4px;
}
/* tfoot */
.tablesorter-grey tbody td,
.tablesorter-grey tfoot th,
.tablesorter-grey tfoot td {
padding: 4px;
vertical-align: top;
border-right: #555 1px solid;
}
.tablesorter-grey tfoot th,
.tablesorter-grey tfoot td {
padding: 8px;
}
/* tbody */
.tablesorter-grey td {
color: #eee;
background-color: #6d6d6d;
padding: 4px;
vertical-align: top;
}
/* hovered row colors
you'll need to add additional lines for
rows with more than 2 child rows
*/
.tablesorter-grey tbody > tr:hover > td,
.tablesorter-grey tbody > tr:hover + tr.tablesorter-childRow > td,
.tablesorter-grey tbody > tr:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td,
.tablesorter-grey tbody > tr.even:hover > td,
.tablesorter-grey tbody > tr.even:hover + tr.tablesorter-childRow > td,
.tablesorter-grey tbody > tr.even:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td {
background: #134b78;
}
.tablesorter-grey tbody > tr.odd:hover > td,
.tablesorter-grey tbody > tr.odd:hover + tr.tablesorter-childRow > td,
.tablesorter-grey tbody > tr.odd:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td {
background: #134b78;
}
/* table processing indicator */
.tablesorter-grey .tablesorter-processing {
background-position: center center !important;
background-repeat: no-repeat !important;
/* background-image: url(../addons/pager/icons/loading.gif) !important; */
background-image: url('data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=') !important;
}
/* Zebra Widget - row alternating colors */
.tablesorter-grey tbody tr.odd td {
background-color: #5e5e5e;
}
.tablesorter-grey tbody tr.even td {
background-color: #6d6d6d;
}
/* Column Widget - column sort colors */
.tablesorter-grey td.primary,
.tablesorter-grey tr.odd td.primary {
color: #ddd;
background-color: #165388;
}
.tablesorter-grey tr.even td.primary {
color: #ddd;
background-color: #195c93;
}
.tablesorter-grey td.secondary,
.tablesorter-grey tr.odd td.secondary {
color: #ddd;
background-color: #185C9A;
}
.tablesorter-grey tr.even td.secondary {
color: #ddd;
background-color: #1D67A5;
}
.tablesorter-grey td.tertiary,
.tablesorter-grey tr.odd td.tertiary {
color: #ddd;
background-color: #1B67AD;
}
.tablesorter-grey tr.even td.tertiary {
color: #ddd;
background-color: #2073B7;
}
/* caption */
caption {
background: #fff;
}
/* filter widget */
.tablesorter-grey .tablesorter-filter-row td {
background: #3c3c3c;
line-height: normal;
text-align: center; /* center the input */
-webkit-transition: line-height 0.1s ease;
-moz-transition: line-height 0.1s ease;
-o-transition: line-height 0.1s ease;
transition: line-height 0.1s ease;
}
/* optional disabled input styling */
.tablesorter-grey .tablesorter-filter-row .disabled {
opacity: 0.5;
filter: alpha(opacity=50);
cursor: not-allowed;
}
/* hidden filter row */
.tablesorter-grey .tablesorter-filter-row.hideme td {
/*** *********************************************** ***/
/*** change this padding to modify the thickness ***/
/*** of the closed filter row (height = padding x 2) ***/
padding: 2px;
/*** *********************************************** ***/
margin: 0;
line-height: 0;
cursor: pointer;
}
.tablesorter-grey .tablesorter-filter-row.hideme .tablesorter-filter {
height: 1px;
min-height: 0;
border: 0;
padding: 0;
margin: 0;
/* don't use visibility: hidden because it disables tabbing */
opacity: 0;
filter: alpha(opacity=0);
}
/* filters */
.tablesorter-grey .tablesorter-filter {
width: 98%;
height: auto;
margin: 0;
padding: 4px;
background-color: #6d6d6d;
border: 1px solid #555;
color: #ddd;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-webkit-transition: height 0.1s ease;
-moz-transition: height 0.1s ease;
-o-transition: height 0.1s ease;
transition: height 0.1s ease;
}
/* rows hidden by filtering (needed for child rows) */
.tablesorter .filtered {
display: none;
}
/* ajax error row */
.tablesorter .tablesorter-errorRow td {
text-align: center;
cursor: pointer;
background-color: #e6bf99;
}
@@ -0,0 +1,201 @@
/*************
Ice Theme (by thezoggy)
*************/
/* overall */
.tablesorter-ice {
width: 100%;
background-color: #fff;
margin: 10px 0 15px;
text-align: left;
border-spacing: 0;
border: #ccc 1px solid;
border-width: 1px 0 0 1px;
}
.tablesorter-ice th,
.tablesorter-ice td {
border: #ccc 1px solid;
border-width: 0 1px 1px 0;
}
/* header */
.tablesorter-ice th,
.tablesorter-ice thead td {
font: 12px/18px Arial, Sans-serif;
color: #555;
background-color: #f6f8f9;
border-collapse: collapse;
padding: 4px;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);
}
.tablesorter-ice tbody td,
.tablesorter-ice tfoot th,
.tablesorter-ice tfoot td {
padding: 4px;
vertical-align: top;
}
.tablesorter-ice .header,
.tablesorter-ice .tablesorter-header {
background: #f6f8f9 no-repeat center right;
background-image: url(data:image/gif;base64,R0lGODlhDAAMAMQAAAJEjAJCiwJBigJAiANFjgNGjgNEjQRIkQRHkANIkAVMlAVQmAZWnQZUnAdYoAhdpAhZoAlhqQlepQliqQppsApmrQxutgtutQtutAxwtwxwtg1yug1zugxtsw1yuP8A/yH5BAEAAB8ALAAAAAAMAAwAAAUx4Cd+3GiOW4ado2d9VMVm1xg9ptadTsP+QNZEcjoQTBDGCAFgLRSfQgCYMAiCn8EvBAA7);
/* background-image: url(images/ice-unsorted.gif) */
padding: 4px 20px 4px 4px;
white-space: normal;
cursor: pointer;
}
.tablesorter-ice .headerSortUp,
.tablesorter-ice .tablesorter-headerSortUp,
.tablesorter-ice .tablesorter-headerAsc {
color: #333;
background: #ebedee no-repeat center right;
background-image: url(data:image/gif;base64,R0lGODlhDAAMANUAAAJCiwNHkANFjgNEjQRIkQNJkQRMlARKkwRKkgVPlwZSmgdaogdYnwhfpghcowlhqgliqglgqAlgpwljqwporwpmrQplrAtsswtqsgtrsgtqsQxttAtvtQtttAxyuQxwtwxxtwxvtg10uw1zuQ1xuP8A/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAACUALAAAAAAMAAwAAAY6wJKwJBoahyNQ6Dj0fDoZCpPEuWgqk4jxs8FQLI+Gg8Esm5kQydFQMC7IwkOAqUiUCAIzIjA4lwBlQQA7);
/* background-image: url(images/ice-desc.gif) */
}
.tablesorter-ice .headerSortDown,
.tablesorter-ice .tablesorter-headerSortDown,
.tablesorter-ice .tablesorter-headerDesc {
color: #333;
background: #ebedee no-repeat center right;
background-image: url(data:image/gif;base64,R0lGODlhDAAMANUAAAE/iAJBigNFjgNEjQNFjQNDiwRHkQRHjwNHjwROlgRMlQRMlARJkgRKkgZQmAVPlgZWnQZSmgZRmAdXoAdXnwdUnAdbogdZoQhbowlhqAlepglkrAliqQtstAtqsQxyugxyuQxwuAxxuAxxtwxwtgxvtQ10vA12vA10u/8A/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAACkALAAAAAAMAAwAAAY6wJQwdRoah6bP6DhEiVIdDxNEGm4yxlDpiJkwv2AmR2OhVCSJBsJ4gUQeCwOB6VAwBAXwYRAIpwBfQQA7);
/* background-image: url(images/ice-asc.gif); */
}
.tablesorter-ice thead .sorter-false {
background-image: none;
cursor: default;
padding: 4px;
}
/* tfoot */
.tablesorter-ice tfoot .tablesorter-headerSortUp,
.tablesorter-ice tfoot .tablesorter-headerSortDown,
.tablesorter-ice tfoot .tablesorter-headerAsc,
.tablesorter-ice tfoot .tablesorter-headerDesc {
background: #ebedee;
}
/* tbody */
.tablesorter-ice td {
color: #333;
}
/* hovered row colors */
.tablesorter-ice tbody > tr:hover > td,
.tablesorter-ice tbody > tr.even:hover > td,
.tablesorter-ice tbody > tr.odd:hover > td {
background: #ebf2fa;
}
/* table processing indicator */
.tablesorter-ice .tablesorter-processing {
background-position: center center !important;
background-repeat: no-repeat !important;
/* background-image: url(../addons/pager/icons/loading.gif) !important; */
background-image: url('data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=') !important;
}
/* Zebra Widget - row alternating colors */
.tablesorter-ice tr.odd td {
background-color: #dfdfdf;
}
.tablesorter-ice tr.even td {
background-color: #efefef;
}
/* Column Widget - column sort colors */
.tablesorter-ice td.primary,
.tablesorter-ice tr.odd td.primary {
background-color: #9ae5e5;
}
.tablesorter-ice tr.even td.primary {
background-color: #c2f0f0;
}
.tablesorter-ice td.secondary,
.tablesorter-ice tr.odd td.secondary {
background-color: #c2f0f0;
}
.tablesorter-ice tr.even td.secondary {
background-color: #d5f5f5;
}
.tablesorter-ice td.tertiary,
.tablesorter-ice tr.odd td.tertiary {
background-color: #d5f5f5;
}
.tablesorter-ice tr.even td.tertiary {
background-color: #ebfafa;
}
/* sticky headers */
.tablesorter-ice.containsStickyHeaders thead tr:nth-child(1) th,
.tablesorter-ice.containsStickyHeaders thead tr:nth-child(1) td {
border-top: #ccc 1px solid;
}
/* caption */
caption {
background: #fff;
}
/* filter widget */
.tablesorter-ice .tablesorter-filter-row td {
background: #eee;
line-height: normal;
text-align: center; /* center the input */
-webkit-transition: line-height 0.1s ease;
-moz-transition: line-height 0.1s ease;
-o-transition: line-height 0.1s ease;
transition: line-height 0.1s ease;
}
/* optional disabled input styling */
.tablesorter-ice .tablesorter-filter-row .disabled {
opacity: 0.5;
filter: alpha(opacity=50);
cursor: not-allowed;
}
/* hidden filter row */
.tablesorter-ice .tablesorter-filter-row.hideme td {
/*** *********************************************** ***/
/*** change this padding to modify the thickness ***/
/*** of the closed filter row (height = padding x 2) ***/
padding: 2px;
/*** *********************************************** ***/
margin: 0;
line-height: 0;
cursor: pointer;
}
.tablesorter-ice .tablesorter-filter-row.hideme .tablesorter-filter {
height: 1px;
min-height: 0;
border: 0;
padding: 0;
margin: 0;
/* don't use visibility: hidden because it disables tabbing */
opacity: 0;
filter: alpha(opacity=0);
}
/* filters */
.tablesorter-ice .tablesorter-filter {
width: 98%;
height: auto;
margin: 4px;
padding: 4px;
background-color: #fff;
border: 1px solid #bbb;
color: #333;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-webkit-transition: height 0.1s ease;
-moz-transition: height 0.1s ease;
-o-transition: height 0.1s ease;
transition: height 0.1s ease;
}
/* rows hidden by filtering (needed for child rows) */
.tablesorter .filtered {
display: none;
}
/* ajax error row */
.tablesorter .tablesorter-errorRow td {
text-align: center;
cursor: pointer;
background-color: #e6bf99;
}
@@ -0,0 +1,156 @@
/*************
jQuery UI Theme
*************/
/* overall */
.tablesorter-jui {
width: 100%;
border-collapse: separate;
border-spacing: 2px; /* adjust spacing between table cells */
margin: 10px 0 15px;
padding: 5px;
font-size: 0.8em;
}
/* header */
.tablesorter-jui thead th,
.tablesorter-jui thead td,
.tablesorter-jui tfoot th,
.tablesorter-jui tfoot td {
position: relative;
background-repeat: no-repeat;
background-position: right center;
/* UI hover and active states make the font normal and the table resizes, this fixes it */
font-weight: bold !important;
border-width: 1px !important;
text-align: left;
padding: 8px; /* wider than the icon */
}
.tablesorter-jui .header,
.tablesorter-jui .tablesorter-header {
cursor: pointer;
white-space: normal;
}
.tablesorter-jui .tablesorter-header-inner {
padding-right: 20px;
}
.tablesorter-jui thead tr th .ui-icon {
position: absolute;
right: 3px;
top: 50%;
margin-top: -8px; /* half the icon height; older IE doesn't like this */
}
.tablesorter-jui thead .sorter-false {
cursor: default;
}
/* tfoot */
.tablesorter-jui tfoot th,
.tablesorter-jui tfoot td {
font-weight: normal !important;
font-size: .9em;
padding: 2px;
}
/* tbody */
.tablesorter-jui td {
padding: 4px;
vertical-align: top;
}
/* hovered row colors */
.tablesorter-jui tbody > tr:hover td {
opacity: 0.7;
filter: alpha(opacity=70);
}
/* table processing indicator */
.tablesorter-jui .tablesorter-processing .tablesorter-header-inner {
background-position: center center !important;
background-repeat: no-repeat !important;
/* background-image: url(../addons/pager/icons/loading.gif) !important; */
background-image: url('data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=') !important;
}
/* Zebra widget - This allows you to use ui-state-default as the zebra stripe color */
.tablesorter-jui tr.ui-state-default {
background-image: none;
font-weight: normal;
}
/* processing background color */
.tablesorter-jui .tablesorter-processing {
background-color: #ddd; /* older browsers that don't support rgba */
background-color: rgba(255,255,255,0.8);
}
/* caption */
.tablesorter-jui caption {
border: 0;
}
/* filter widget */
.tablesorter-jui .tablesorter-filter-row td {
background: transparent;
line-height: normal;
text-align: center; /* center the input */
-webkit-transition: line-height 0.1s ease;
-moz-transition: line-height 0.1s ease;
-o-transition: line-height 0.1s ease;
transition: line-height 0.1s ease;
}
/* optional disabled input styling */
.tablesorter-jui .tablesorter-filter-row .disabled {
opacity: 0.5;
filter: alpha(opacity=50);
cursor: not-allowed;
}
/* hidden filter row */
.tablesorter-jui .tablesorter-filter-row.hideme td {
/*** *********************************************** ***/
/*** change this padding to modify the thickness ***/
/*** of the closed filter row (height = padding x 2) ***/
padding: 2px;
/*** *********************************************** ***/
margin: 0;
line-height: 0;
cursor: pointer;
}
.tablesorter-jui .tablesorter-filter-row.hideme .tablesorter-filter {
height: 1px;
min-height: 0;
border: 0;
padding: 0;
margin: 0;
/* don't use visibility: hidden because it disables tabbing */
opacity: 0;
filter: alpha(opacity=0);
}
/* filters */
.tablesorter-jui .tablesorter-filter {
width: 98%;
height: auto;
margin: 0;
padding: 4px;
background-color: #fff;
border: 1px solid #bbb;
color: #333;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-webkit-transition: height 0.1s ease;
-moz-transition: height 0.1s ease;
-o-transition: height 0.1s ease;
transition: height 0.1s ease;
}
/* rows hidden by filtering (needed for child rows) */
.tablesorter .filtered {
display: none;
}
/* ajax error row */
.tablesorter .tablesorter-errorRow td {
text-align: center;
cursor: pointer;
background-color: #e6bf99;
}
@@ -0,0 +1,192 @@
/*************
Metro Dark Theme
*************/
/* overall */
.tablesorter-metro-dark {
width: 100%;
font: 12px/18px 'Segoe UI Semilight', 'Open Sans', Verdana, Arial, Helvetica, sans-serif;
color: #000;
background-color: #333;
border-spacing: 0;
margin: 10px 0 15px;
text-align: left;
}
.tablesorter-metro-dark tr.dark-row th, .tablesorter-metro-dark tr.dark-row td {
background-color: #222;
color: #fff;
padding: 2px;
text-align: left;
font-size: 14px;
}
/* header/footer */
.tablesorter-metro-dark caption,
.tablesorter-metro-dark th,
.tablesorter-metro-dark thead td,
.tablesorter-metro-dark tfoot th,
.tablesorter-metro-dark tfoot td {
font-weight: 300;
font-size: 15px;
color: #ddd;
background-color: #333;
padding: 4px;
}
.tablesorter-metro-dark .header,
.tablesorter-metro-dark .tablesorter-header {
background-image: url(data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAQBAMAAADQT4M0AAAAGFBMVEUAAADu7u7u7u7u7u7u7u7u7u7u7u7u7u5jNePWAAAACHRSTlMAMxIHKwEgMWD59H4AAABSSURBVAjXY2BgYFJgAAHzYhDJ6igSAKTYBAUTgJSioKAQAwNzoaCguAFDiCAQuDIkgigxBgiA8cJAVCpQt6AgSL+JoKAzA0gjUBsQqBcBCYhFAAE/CV4zeSzxAAAAAElFTkSuQmCC);
background-position: center right;
background-repeat: no-repeat;
cursor: pointer;
white-space: normal;
}
.tablesorter-metro-dark .tablesorter-header-inner {
padding: 0 18px 0 4px;
}
.tablesorter-metro-dark thead .headerSortUp,
.tablesorter-metro-dark thead .tablesorter-headerSortUp,
.tablesorter-metro-dark thead .tablesorter-headerAsc {
background-image: url(data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAQBAMAAADQT4M0AAAAIVBMVEUAAADu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u5meJAOAAAACnRSTlMAMwsqXt+gIBUGxGoDMAAAAFlJREFUCNctzC0SQAAUReEzGNQ3AlHRiSRZFCVZYgeswRL8hLdK7834wj3tAlGP6y7fYHpKS6w6WwbVG0I1NZVnZPG8/DYxOYlnhUYkA06R1s9ESsxR4NIdPhkPFDFYuEnMAAAAAElFTkSuQmCC);
}
.tablesorter-metro-dark thead .headerSortDown,
.tablesorter-metro-dark thead .tablesorter-headerSortDown,
.tablesorter-metro-dark thead .tablesorter-headerDesc {
background-image: url(data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAQBAMAAADQT4M0AAAALVBMVEUAAADu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7i0NViAAAADnRSTlMAMiweCQITTvDctZZqaTlM310AAABcSURBVAjXY2BgYEtgAAFHERDJqigUAKSYBQUNgFSioKAYAwOLIBA4MASBKFUGQxAlzAAF+94BwWuGKBC1lIFl3rt3Lx0YGCzevWsGSjK9e6cAUlT3HKyW9wADAwDRrBiDy6bKzwAAAABJRU5ErkJggg==);
}
.tablesorter-metro-dark thead .sorter-false {
background-image: none;
cursor: default;
padding: 4px;
}
/* tbody */
.tablesorter-metro-dark td {
background-color: #fff;
padding: 4px;
vertical-align: top;
}
/* hovered row colors */
.tablesorter-metro-dark tbody > tr:hover > td,
.tablesorter-metro-dark tbody > tr.even:hover > td,
.tablesorter-metro-dark tbody > tr.odd:hover > td {
background: #bbb;
color: #000;
}
/* table processing indicator */
.tablesorter-metro-dark .tablesorter-processing {
background-position: center center !important;
background-repeat: no-repeat !important;
/* background-image: url(../addons/pager/icons/loading.gif) !important; */
background-image: url(data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=) !important;
}
/* pager */
.tablesorter-metro-dark .tablesorter-pager button {
background-color: #444;
color: #eee;
border: #555 1px solid;
cursor: pointer;
}
.tablesorter-metro-dark .tablesorter-pager button:hover {
background-color: #555;
}
/* Zebra Widget - row alternating colors */
.tablesorter-metro-dark tr.odd td {
background-color: #eee;
}
.tablesorter-metro-dark tr.even td {
background-color: #fff;
}
/* Column Widget - column sort colors */
.tablesorter-metro-dark tr.odd td.primary {
background-color: #bfbfbf;
}
.tablesorter-metro-dark td.primary,
.tablesorter-metro-dark tr.even td.primary {
background-color: #d9d9d9;
}
.tablesorter-metro-dark tr.odd td.secondary {
background-color: #d9d9d9;
}
.tablesorter-metro-dark td.secondary,
.tablesorter-metro-dark tr.even td.secondary {
background-color: #e6e6e6;
}
.tablesorter-metro-dark tr.odd td.tertiary {
background-color: #e6e6e6;
}
.tablesorter-metro-dark td.tertiary,
.tablesorter-metro-dark tr.even td.tertiary {
background-color: #f2f2f2;
}
/* filter widget */
.tablesorter-metro-dark .tablesorter-filter-row td {
background: #eee;
line-height: normal;
text-align: center; /* center the input */
-webkit-transition: line-height 0.1s ease;
-moz-transition: line-height 0.1s ease;
-o-transition: line-height 0.1s ease;
transition: line-height 0.1s ease;
}
/* optional disabled input styling */
.tablesorter-metro-dark .tablesorter-filter-row .disabled {
opacity: 0.5;
filter: alpha(opacity=50);
cursor: not-allowed;
}
/* hidden filter row */
.tablesorter-metro-dark .tablesorter-filter-row.hideme td {
/*** *********************************************** ***/
/*** change this padding to modify the thickness ***/
/*** of the closed filter row (height = padding x 2) ***/
padding: 2px;
/*** *********************************************** ***/
margin: 0;
line-height: 0;
cursor: pointer;
}
.tablesorter-metro-dark .tablesorter-filter-row.hideme .tablesorter-filter {
height: 1px;
min-height: 0;
border: 0;
padding: 0;
margin: 0;
/* don't use visibility: hidden because it disables tabbing */
opacity: 0;
filter: alpha(opacity=0);
}
/* filters */
.tablesorter-metro-dark .tablesorter-filter {
width: 95%;
height: auto;
margin: 4px;
padding: 4px;
background-color: #fff;
border: 1px solid #bbb;
color: #333;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-webkit-transition: height 0.1s ease;
-moz-transition: height 0.1s ease;
-o-transition: height 0.1s ease;
transition: height 0.1s ease;
}
/* rows hidden by filtering (needed for child rows) */
.tablesorter .filtered {
display: none;
}
/* ajax error row */
.tablesorter .tablesorter-errorRow td {
text-align: center;
cursor: pointer;
background-color: #e6bf99;
}
@@ -0,0 +1,191 @@
/* jQuery Quicksearch plugin
by riklomas https://github.com/riklomas/quicksearch
Modified to include childRows (for tablesorter)
See http://stackoverflow.com/q/20342203/145346 for
more details
*/
(function($, window, document, undefined) {
$.fn.quicksearch = function (target, opt) {
var timeout, cache, rowcache, jq_results, val = '', e = this, options = $.extend({
delay: 100,
selector: null,
stripeRows: null,
loader: null,
noResults: '',
childRow: 'tablesorter-childRow', // include child row with search results
matchedResultsCount: 0,
bind: 'keyup',
onBefore: function () {
return;
},
onAfter: function () {
return;
},
show: function () {
this.style.display = "";
},
hide: function () {
this.style.display = "none";
},
prepareQuery: function (val) {
return val.toLowerCase().split(' ');
},
testQuery: function (query, txt, _row) {
for (var i = 0; i < query.length; i += 1) {
if (txt.indexOf(query[i]) === -1) {
return false;
}
}
return true;
}
}, opt);
this.go = function () {
var i = 0,
numMatchedRows = 0,
noresults = true,
query = options.prepareQuery(val),
val_empty = (val.replace(' ', '').length === 0);
for (var i = 0, len = rowcache.length; i < len; i++) {
if (val_empty || options.testQuery(query, cache[i], rowcache[i]) ||
($(rowcache[i]).hasClass(options.childRow) && $(rowcache[i > 1 ? i - 1 : 0]).is(':visible'))) {
options.show.apply(rowcache[i]);
noresults = false;
numMatchedRows++;
} else {
options.hide.apply(rowcache[i]);
}
}
if (noresults) {
this.results(false);
} else {
this.results(true);
this.stripe();
}
this.matchedResultsCount = numMatchedRows;
this.loader(false);
options.onAfter();
return this;
};
/*
* External API so that users can perform search programatically.
* */
this.search = function (submittedVal) {
val = submittedVal;
e.trigger();
};
/*
* External API to get the number of matched results as seen in
* https://github.com/ruiz107/quicksearch/commit/f78dc440b42d95ce9caed1d087174dd4359982d6
* */
this.currentMatchedResults = function() {
return this.matchedResultsCount;
};
this.stripe = function () {
if (typeof options.stripeRows === "object" && options.stripeRows !== null)
{
var joined = options.stripeRows.join(' ');
var stripeRows_length = options.stripeRows.length;
jq_results.not(':hidden').each(function (i) {
$(this).removeClass(joined).addClass(options.stripeRows[i % stripeRows_length]);
});
}
return this;
};
this.strip_html = function (input) {
var output = input.replace(new RegExp('<[^<]+\>', 'g'), "");
output = $.trim(output.toLowerCase());
return output;
};
this.results = function (bool) {
if (typeof options.noResults === "string" && options.noResults !== "") {
if (bool) {
$(options.noResults).hide();
} else {
$(options.noResults).show();
}
}
return this;
};
this.loader = function (bool) {
if (typeof options.loader === "string" && options.loader !== "") {
(bool) ? $(options.loader).show() : $(options.loader).hide();
}
return this;
};
this.cache = function () {
jq_results = $(target);
if (typeof options.noResults === "string" && options.noResults !== "") {
jq_results = jq_results.not(options.noResults);
}
var t = (typeof options.selector === "string") ?
jq_results.find(options.selector) : $(target).not(options.noResults);
cache = t.map(function () {
return e.strip_html(this.innerHTML);
});
rowcache = jq_results.map(function () {
return this;
});
/*
* Modified fix for sync-ing "val".
* Original fix https://github.com/michaellwest/quicksearch/commit/4ace4008d079298a01f97f885ba8fa956a9703d1
* */
val = val || this.val() || "";
return this.go();
};
this.trigger = function () {
this.loader(true);
options.onBefore();
window.clearTimeout(timeout);
timeout = window.setTimeout(function () {
e.go();
}, options.delay);
return this;
};
this.cache();
this.results(true);
this.stripe();
this.loader(false);
return this.each(function () {
/*
* Changed from .bind to .on.
* */
$(this).on(options.bind, function () {
val = $(this).val();
e.trigger();
});
});
};
}(jQuery, this, document));
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,116 @@
/*
* Metadata - jQuery plugin for parsing metadata from elements
*
* Copyright (c) 2006 John Resig, Yehuda Katz, Jörn Zaefferer, Paul McLanahan
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
*/
/**
* Sets the type of metadata to use. Metadata is encoded in JSON, and each property
* in the JSON will become a property of the element itself.
*
* There are three supported types of metadata storage:
*
* attr: Inside an attribute. The name parameter indicates *which* attribute.
*
* class: Inside the class attribute, wrapped in curly braces: { }
*
* elem: Inside a child element (e.g. a script tag). The
* name parameter indicates *which* element.
*
* The metadata for an element is loaded the first time the element is accessed via jQuery.
*
* As a result, you can define the metadata type, use $(expr) to load the metadata into the elements
* matched by expr, then redefine the metadata type and run another $(expr) for other elements.
*
* @name $.metadata.setType
*
* @example <p id="one" class="some_class {item_id: 1, item_label: 'Label'}">This is a p</p>
* @before $.metadata.setType("class")
* @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label"
* @desc Reads metadata from the class attribute
*
* @example <p id="one" class="some_class" data="{item_id: 1, item_label: 'Label'}">This is a p</p>
* @before $.metadata.setType("attr", "data")
* @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label"
* @desc Reads metadata from a "data" attribute
*
* @example <p id="one" class="some_class"><script>{item_id: 1, item_label: 'Label'}</script>This is a p</p>
* @before $.metadata.setType("elem", "script")
* @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label"
* @desc Reads metadata from a nested script element
*
* @param String type The encoding type
* @param String name The name of the attribute to be used to get metadata (optional)
* @cat Plugins/Metadata
* @descr Sets the type of encoding to be used when loading metadata for the first time
* @type undefined
* @see metadata()
*/
(function($) {
$.extend({
metadata : {
defaults : {
type: 'class',
name: 'metadata',
cre: /(\{.*\})/,
single: 'metadata'
},
setType: function( type, name ){
this.defaults.type = type;
this.defaults.name = name;
},
get: function( elem, opts ){
var data, m, e, attr,
settings = $.extend({},this.defaults,opts);
// check for empty string in single property
if ( !settings.single.length ) { settings.single = 'metadata'; }
data = $.data(elem, settings.single);
// returned cached data if it already exists
if ( data ) { return data; }
data = "{}";
if ( settings.type === "class" ) {
m = settings.cre.exec( elem.className );
if ( m ) { data = m[1]; }
} else if ( settings.type === "elem" ) {
if( !elem.getElementsByTagName ) { return undefined; }
e = elem.getElementsByTagName(settings.name);
if ( e.length ) { data = $.trim(e[0].innerHTML); }
} else if ( elem.getAttribute !== undefined ) {
attr = elem.getAttribute( settings.name );
if ( attr ) { data = attr; }
}
if ( data.indexOf( '{' ) <0 ) { data = "{" + data + "}"; }
data = eval("(" + data + ")");
$.data( elem, settings.single, data );
return data;
}
}
});
/**
* Returns the metadata object for the first member of the jQuery object.
*
* @name metadata
* @descr Returns element's metadata object
* @param Object opts An object contianing settings to override the defaults
* @type jQuery
* @cat Plugins/Metadata
*/
$.fn.metadata = function( opts ){
return $.metadata.get( this[0], opts );
};
})(jQuery);
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,138 @@
/*! Filter widget select2 formatter function - updated 7/17/2014 (v2.17.5)
* requires: jQuery 1.7.2+, tableSorter 2.16+, filter widget 2.16+ and select2 v3.4.6+ plugin
*/
/*jshint browser:true, jquery:true, unused:false */
/*global jQuery: false */
;(function($){
"use strict";
var ts = $.tablesorter || {};
ts.filterFormatter = ts.filterFormatter || {};
/************************\
Select2 Filter Formatter
\************************/
ts.filterFormatter.select2 = function($cell, indx, select2Def) {
var o = $.extend({
// select2 filter formatter options
cellText : '', // Text (wrapped in a label element)
match : true, // adds "filter-match" to header
value : '',
// include ANY select2 options below
multiple : true,
width : '100%'
}, select2Def ),
arry, data,
c = $cell.closest('table')[0].config,
wo = c.widgetOptions,
// Add a hidden input to hold the range values
$input = $('<input class="filter" type="hidden">')
.appendTo($cell)
// hidden filter update namespace trigger by filter widget
.bind('change' + c.namespace + 'filter', function(){
var val = this.value;
val = val.replace(/[/()$^]/g, '').split('|');
$cell.find('.select2').select2('val', val);
updateSelect2();
}),
$header = c.$headers.filter('[data-column="' + indx + '"]:last'),
onlyAvail = $header.hasClass(wo.filter_onlyAvail),
$shcell = [],
matchPrefix = o.match ? '' : '^',
matchSuffix = o.match ? '' : '$',
// this function updates the hidden input and adds the current values to the header cell text
updateSelect2 = function() {
var v = $cell.find('.select2').select2('val') || o.value || '';
$input
// add regex, so we filter exact numbers
.val( $.isArray(v) && v.length && v.join('') !== '' ? '/(' + matchPrefix + (v || []).join(matchSuffix + '|' + matchPrefix) + matchSuffix + ')/' : '' )
.trigger('search').end()
.find('.select2').select2('val', v);
// update sticky header cell
if ($shcell.length) {
$shcell
.find('.select2').select2('val', v);
}
},
// get options from table cell content or filter_selectSource (v2.16)
updateOptions = function(){
data = [];
arry = ts.filter.getOptionSource(c.$table[0], indx, onlyAvail) || [];
// build select2 data option
$.each(arry, function(i,v){
data.push({id: v, text: v});
});
o.data = data;
};
// get filter-match class from option
$header.toggleClass('filter-match', o.match);
if (o.cellText) {
$cell.prepend('<label>' + o.cellText + '</label>');
}
// don't add default in table options if either ajax or
// data options are already defined
if (!(o.ajax && !$.isEmptyObject(o.ajax)) && !o.data) {
updateOptions();
if (onlyAvail) {
c.$table.bind('filterEnd', function(){
updateOptions();
$cell.add($shcell).find('.select2').select2(o);
});
}
}
// add a select2 hidden input!
$('<input class="select2 select2-' + indx + '" type="hidden" />')
.val(o.value)
.appendTo($cell)
.select2(o)
.bind('change', function(){
updateSelect2();
});
// update select2 from filter hidden input, in case of saved filters
c.$table.bind('filterFomatterUpdate', function(){
// value = '/(^x$|^y$)/' => 'x,y'
var val = c.$table.data('lastSearch')[indx] || '';
val = val.replace(/[/()$^]/g, '').split('|');
$cell.find('.select2').select2('val', val);
updateSelect2();
ts.filter.formatterUpdated($cell, indx);
});
// has sticky headers?
c.$table.bind('stickyHeadersInit', function(){
$shcell = c.widgetOptions.$sticky.find('.tablesorter-filter-row').children().eq(indx).empty();
// add a select2!
$('<input class="select2 select2-' + indx + '" type="hidden">')
.val(o.value)
.appendTo($shcell)
.select2(o)
.bind('change', function(){
$cell.find('.select2').select2('val', $shcell.find('.select2').select2('val') );
updateSelect2();
});
if (o.cellText) {
$shcell.prepend('<label>' + o.cellText + '</label>');
}
});
// on reset
c.$table.bind('filterReset', function(){
$cell.find('.select2').select2('val', o.value || '');
setTimeout(function(){
updateSelect2();
}, 0);
});
updateSelect2();
return $input;
};
})(jQuery);
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,81 @@
/*!
* Extract out date parsers
*/
/*jshint jquery:true */
;(function($){
"use strict";
/*! extract US Long Date (ignore any other text)
* e.g. "Sue's Birthday! Jun 26, 2004 7:22 AM (8# 2oz)"
* demo: http://jsfiddle.net/abkNM/2293/
*/
$.tablesorter.addParser({
id: "extractUSLongDate",
is: function (s) {
// don't auto detect this parser
return false;
},
format: function (s, table) {
var date = s.match(/[A-Z]{3,10}\.?\s+\d{1,2},?\s+(?:\d{4})(?:\s+\d{1,2}:\d{2}(?::\d{2})?(?:\s+[AP]M)?)?/i);
return date ? $.tablesorter.formatFloat((new Date(date[0]).getTime() || ''), table) || s : s;
},
type: "numeric"
});
/*! extract MMDDYYYY (ignore any other text)
* demo: http://jsfiddle.net/Mottie/abkNM/2418/
*/
$.tablesorter.addParser({
id: "extractMMDDYYYY",
is: function (s) {
// don't auto detect this parser
return false;
},
format: function (s, table) {
var date = s.replace(/\s+/g," ").replace(/[\-.,]/g, "/").match(/(\d{1,2}[\/\s]\d{1,2}[\/\s]\d{4}(\s+\d{1,2}:\d{2}(:\d{2})?(\s+[AP]M)?)?)/i);
return date ? $.tablesorter.formatFloat((new Date(date[0]).getTime() || ''), table) || s : s;
},
type: "numeric"
});
/*! extract DDMMYYYY (ignore any other text)
* demo: http://jsfiddle.net/Mottie/abkNM/2419/
*/
$.tablesorter.addParser({
id: "extractDDMMYYYY",
is: function (s) {
// don't auto detect this parser
return false;
},
format: function (s, table) {
var date = s.replace(/\s+/g," ").replace(/[\-.,]/g, "/").match(/(\d{1,2}[\/\s]\d{1,2}[\/\s]\d{4}(\s+\d{1,2}:\d{2}(:\d{2})?(\s+[AP]M)?)?)/i);
if (date) {
date = date[0].replace(/(\d{1,2})[\/\s](\d{1,2})[\/\s](\d{4})/, "$2/$1/$3");
return $.tablesorter.formatFloat((new Date(date).getTime() || ''), table) || s;
}
return s;
},
type: "numeric"
});
/*! extract YYYYMMDD (ignore any other text)
* demo: http://jsfiddle.net/Mottie/abkNM/2420/
*/
$.tablesorter.addParser({
id: "extractYYYYMMDD",
is: function (s) {
// don't auto detect this parser
return false;
},
format: function (s, table) {
var date = s.replace(/\s+/g," ").replace(/[\-.,]/g, "/").match(/(\d{4}[\/\s]\d{1,2}[\/\s]\d{1,2}(\s+\d{1,2}:\d{2}(:\d{2})?(\s+[AP]M)?)?)/i);
if (date) {
date = date[0].replace(/(\d{4})[\/\s](\d{1,2})[\/\s](\d{1,2})/, "$2/$3/$1");
return $.tablesorter.formatFloat((new Date(date).getTime() || ''), table) || s;
}
return s;
},
type: "numeric"
});
})(jQuery);
@@ -0,0 +1,34 @@
/*! ISO-8601 date parser
* This parser will work with dates in ISO8601 format
* 2013-02-18T18:18:44+00:00
* Written by Sean Ellingham :https://github.com/seanellingham
* See https://github.com/Mottie/tablesorter/issues/247
*/
/*global jQuery: false */
;(function($){
"use strict";
var iso8601date = /^([0-9]{4})(-([0-9]{2})(-([0-9]{2})(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?$/;
$.tablesorter.addParser({
id : 'iso8601date',
is : function(s) {
return s.match(iso8601date);
},
format : function(s) {
var result = s.match(iso8601date);
if (result) {
var date = new Date(result[1], 0, 1);
if (result[3]) { date.setMonth(result[3] - 1); }
if (result[5]) { date.setDate(result[5]); }
if (result[7]) { date.setHours(result[7]); }
if (result[8]) { date.setMinutes(result[8]); }
if (result[10]) { date.setSeconds(result[10]); }
if (result[12]) { date.setMilliseconds(Number('0.' + result[12]) * 1000); }
return date;
}
return s;
},
type : 'numeric'
});
})(jQuery);
@@ -0,0 +1,33 @@
/*! Month parser
* Demo: http://jsfiddle.net/Mottie/abkNM/477/
*/
/*jshint jquery:true */
;(function($){
"use strict";
var ts = $.tablesorter;
ts.dates = $.extend({}, ts.dates, {
// *** modify this array to change match the language ***
monthCased : [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
});
ts.dates.monthLower = ts.dates.monthCased.join(',').toLocaleLowerCase().split(',');
ts.addParser({
id: "month",
is: function(){
return false;
},
format: function(s, table) {
var j = -1, c = table.config,
n = c.ignoreCase ? s.toLocaleLowerCase() : s;
$.each(ts.dates[ 'month' + (c.ignoreCase ? 'Lower' : 'Cased') ], function(i,v){
if (j < 0 && n.match(v)) { j = i; }
});
// return s (original string) if there isn't a match
// (non-weekdays will sort separately and empty cells will sort as expected)
return j < 0 ? s : j;
},
type: "numeric"
});
})(jQuery);
@@ -0,0 +1,74 @@
/*! Two digit year parser
* Demo: http://jsfiddle.net/Mottie/abkNM/427/
*/
/*jshint jquery:true */
;(function($){
"use strict";
var ts = $.tablesorter,
// Make the date be within +/- range of the 2 digit year
// so if the current year is 2020, and the 2 digit year is 80 (2080 - 2020 > 50), it becomes 1980
// if the 2 digit year is 50 (2050 - 2020 < 50), then it becomes 2050.
range = 50;
ts.dates = $.extend({}, ts.dates, {
regxxxxyy: /(\d{1,2})[\/\s](\d{1,2})[\/\s](\d{2})/,
regyyxxxx: /(\d{2})[\/\s](\d{1,2})[\/\s](\d{1,2})/
});
ts.formatDate = function(s, regex, format, table){
var n = s
// replace separators
.replace(/\s+/g," ").replace(/[-.,]/g, "/")
// reformat xx/xx/xx to mm/dd/19yy;
.replace(regex, format),
d = new Date(n),
y = d.getFullYear(),
rng = table && table.config.dateRange || range,
now = new Date().getFullYear();
// if date > 50 years old (set range), add 100 years
// this will work when people start using "50" and mean "2050"
while (now - y > rng) {
y += 100;
}
return d.setFullYear(y) || s;
};
$.tablesorter.addParser({
id: "ddmmyy",
is: function() {
return false;
},
format: function(s, table) {
// reformat dd/mm/yy to mm/dd/19yy;
return ts.formatDate(s, ts.dates.regxxxxyy, "$2/$1/19$3", table);
},
type: "numeric"
});
$.tablesorter.addParser({
id: "mmddyy",
is: function() {
return false;
},
format: function(s, table) {
// reformat mm/dd/yy to mm/dd/19yy
return ts.formatDate(s, ts.dates.regxxxxyy, "$1/$2/19$3", table);
},
type: "numeric"
});
$.tablesorter.addParser({
id: "yymmdd",
is: function() {
return false;
},
format: function(s, table) {
// reformat yy/mm/dd to mm/dd/19yy
return ts.formatDate(s, ts.dates.regyyxxxx, "$2/$3/19$1", table);
},
type: "numeric"
});
})(jQuery);
@@ -0,0 +1,33 @@
/*! Weekday parser
* Demo: http://jsfiddle.net/Mottie/abkNM/477/
*/
/*jshint jquery:true */
;(function($){
"use strict";
var ts = $.tablesorter;
ts.dates = $.extend({}, ts.dates, {
// *** modify this array to change match the language ***
weekdayCased : [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ]
});
ts.dates.weekdayLower = ts.dates.weekdayCased.join(',').toLocaleLowerCase().split(',');
ts.addParser({
id: "weekday",
is: function(){
return false;
},
format: function(s, table) {
var j = -1, c = table.config;
s = c.ignoreCase ? s.toLocaleLowerCase() : s;
$.each(ts.dates[ 'weekday' + (c.ignoreCase ? 'Lower' : 'Cased') ], function(i,v){
if (j < 0 && s.match(v)) { j = i; }
});
// return s (original string) if there isn't a match
// (non-weekdays will sort separately and empty cells will sort as expected)
return j < 0 ? s : j;
},
type: "numeric"
});
})(jQuery);
@@ -0,0 +1,36 @@
/*!
* Extract dates using popular natural language date parsers
*/
/*jshint jquery:true */
;(function($){
"use strict";
/*! Sugar (http://sugarjs.com/dates#comparing_dates)
* demo: http://jsfiddle.net/Mottie/abkNM/551/
*/
$.tablesorter.addParser({
id: "sugar",
is: function() {
return false;
},
format: function(s) {
return Date.create ? Date.create(s).getTime() || s : new Date(s).getTime() || s;
},
type: "numeric"
});
/*! Datejs (http://www.datejs.com/)
* demo: http://jsfiddle.net/Mottie/abkNM/550/
*/
$.tablesorter.addParser({
id: "datejs",
is: function() {
return false;
},
format: function(s) {
return Date.parse && Date.parse(s) || s;
},
type: "numeric"
});
})(jQuery);
@@ -0,0 +1,63 @@
/*! Distance parser
* This parser will parser numbers like 5'10" (5 foot 10 inches)
* and 31½ into sortable values.
* Demo: http://jsfiddle.net/Mottie/abkNM/154/
*/
/*global jQuery: false */
;(function($){
"use strict";
var ts = $.tablesorter;
ts.symbolRegex = /[\u215b\u215c\u215d\u215e\u00bc\u00bd\u00be]/g;
ts.processFractions = function(n, table) {
if (n) {
var t, p = 0;
n = $.trim(n.replace(/\"/,''));
// look for a space in the first part of the number: "10 3/4" and save the "10"
if (/\s/.test(n)) {
p = ts.formatFloat(n.split(' ')[0], table);
// remove stuff to the left of the space
n = $.trim(n.substring(n.indexOf(' '), n.length));
}
// look for a "/" to calculate fractions
if (/\//g.test(n)) {
t = n.split('/');
// turn 3/4 into .75; make sure we don't divide by zero
n = p + parseInt(t[0], 10) / parseInt(t[1] || 1, 10);
// look for fraction symbols
} else if (ts.symbolRegex.test(n)) {
n = p + n.replace(ts.symbolRegex, function(m){
return {
'\u215b' : '.125', // 1/8
'\u215c' : '.375', // 3/8
'\u215d' : '.625', // 5/8
'\u215e' : '.875', // 7/8
'\u00bc' : '.25', // 1/4
'\u00bd' : '.5', // 1/2
'\u00be' : '.75' // 3/4
}[m];
});
}
}
return n || 0;
};
$.tablesorter.addParser({
id: 'distance',
is: function() {
// return false so this parser is not auto detected
return false;
},
format: function(s, table) {
if (s === '') { return ''; }
// look for feet symbol = '
// very generic test to catch 1.1', 1 1/2' and 1½'
var d = (/^\s*\S*(\s+\S+)?\s*\'/.test(s)) ? s.split("'") : [0,s],
f = ts.processFractions(d[0], table), // feet
i = ts.processFractions(d[1], table); // inches
return (/[\'\"]/).test(s) ? parseFloat(f) + (parseFloat(i)/12 || 0) : parseFloat(f) + parseFloat(i);
},
type: 'numeric'
});
})(jQuery);
@@ -0,0 +1,73 @@
/*! File Type parser
* When a file type extension is found, the equivalent name is
* prefixed into the parsed data, so sorting occurs in groups
*/
/*global jQuery: false */
;(function($){
"use strict";
// basic list from http://en.wikipedia.org/wiki/List_of_file_formats
// To add a custom equivalent, define:
// $.tablesorter.fileTypes.equivalents['xx'] = "A|B|C";
$.tablesorter.fileTypes = {
// divides filetype extensions in the equivalent list below
separator : '|',
equivalents : {
"3D Image" : "3dm|3ds|dwg|max|obj",
"Audio" : "aif|aac|ape|flac|la|m4a|mid|midi|mp2|mp3|ogg|ra|raw|rm|wav|wma",
"Compressed" : "7z|bin|cab|cbr|gz|gzip|iso|lha|lz|rar|tar|tgz|zip|zipx|zoo",
"Database" : "csv|dat|db|dbf|json|ldb|mdb|myd|pdb|sql|tsv|wdb|wmdb|xlr|xls|xlsx|xml",
"Development" : "asm|c|class|cls|cpp|cc|cs|cxx|cbp|cs|dba|fla|h|java|lua|pl|py|pyc|pyo|sh|sln|r|rb|vb",
"Document" : "doc|docx|odt|ott|pages|pdf|rtf|tex|wpd|wps|wrd|wri",
"Executable" : "apk|app|com|exe|gadget|lnk|msi",
"Fonts" : "eot|fnt|fon|otf|ttf|woff",
"Icons" : "ani|cur|icns|ico",
"Images" : "bmp|gif|jpg|jpeg|jpe|jp2|pic|png|psd|tga|tif|tiff|wmf|webp",
"Presentation" : "pps|ppt",
"Published" : "chp|epub|lit|pub|ppp|fm|mobi",
"Script" : "as|bat|cgi|cmd|jar|js|lua|scpt|scptd|sh|vbs|vb|wsf",
"Styles" : "css|less|sass",
"Text" : "info|log|md|markdown|nfo|tex|text|txt",
"Vectors" : "awg|ai|eps|cdr|ps|svg",
"Video" : "asf|avi|flv|m4v|mkv|mov|mp4|mpe|mpeg|mpg|ogg|rm|rv|swf|vob|wmv",
"Web" : "asp|aspx|cer|cfm|htm|html|php|url|xhtml"
}
};
$.tablesorter.addParser({
id: 'filetype',
is: function() {
return false;
},
format: function(s, table) {
var t,
c = table.config,
wo = c.widgetOptions,
i = s.lastIndexOf('.'),
sep = $.tablesorter.fileTypes.separator,
m = $.tablesorter.fileTypes.matching,
types = $.tablesorter.fileTypes.equivalents;
if (!m) {
// make a string to "quick" match the existing equivalents
var t = [];
$.each(types, function(i,v){
t.push(v);
});
m = $.tablesorter.fileTypes.matching = sep + t.join(sep) + sep;
}
if (i >= 0) {
t = sep + s.substring(i + 1, s.length) + sep;
if (m.indexOf(t) >= 0) {
for (i in types) {
if ((sep + types[i] + sep).indexOf(t) >= 0) {
return i + (wo.group_separator ? wo.group_separator : '-') + s;
}
}
}
}
return s;
},
type: 'text'
});
})(jQuery);
@@ -0,0 +1,47 @@
/*! Title parser
* This parser will remove "The", "A" and "An" from the beginning of a book
* or movie title, so it sorts by the second word or number
* Demo: http://jsfiddle.net/Mottie/abkNM/5/
*/
/*global jQuery: false */
;(function($){
"use strict";
// basic list from http://en.wikipedia.org/wiki/Article_%28grammar%29
$.tablesorter.ignoreArticles = {
"en" : "the, a, an",
"de" : "der, die, das, des, dem, den, ein, eine, einer, eines, einem, einen",
"nl" : "de, het, de, een",
"es" : "el, la, lo, los, las, un, una, unos, unas",
"pt" : "o, a, os, as, um, uma, uns, umas",
"fr" : "le, la, l'_, les, un, une, des",
"it" : "il, lo, la, l'_, i, gli, le, un', uno, una, un",
"hu" : "a, az, egy"
};
// To add a custom parser, define:
// $.tablesorter.ignoreArticles['xx'] = "A, B, C";
// and then set the language id 'xx' in the headers option
// ignoreArticles : 'xx'
$.tablesorter.addParser({
id: 'ignoreArticles',
is: function() {
return false;
},
format: function(s, table, cell, cellIndex) {
var c = table.config, art, lang;
if ( !(c.headers && c.headers[cellIndex] && c.headers[cellIndex].ignoreArticlesRegex) ) {
// initialize - save regex in c.headers[cellIndex].ignoreArticles
if (!c.headers) { c.headers = {}; }
if (!c.headers[cellIndex]) { c.headers[cellIndex] = {}; }
lang = $.tablesorter.getData(c.$headers.eq(cellIndex), c.headers[cellIndex], 'ignoreArticles');
art = ($.tablesorter.ignoreArticles[lang] || "the, a, an" ) + "";
c.headers[cellIndex].ignoreArticlesRegex = new RegExp('^(' + $.trim( art.split(/\s*\,\s*/).join('\\s|') + "\\s" ).replace("_\\s","") + ')', 'i');
}
return (s || '').replace(c.headers[cellIndex].ignoreArticlesRegex, '');
},
type: 'text'
});
})(jQuery);
@@ -0,0 +1,20 @@
/*! image alt attribute parser for jQuery 1.7+ & tablesorter 2.7.11+
* New 7/17/2014 (v2.17.5)
*/
/*jshint jquery:true, unused:false */
;(function($){
"use strict";
$.tablesorter.addParser({
id: "image",
is: function(){
return false;
},
format: function(s, table, cell) {
return $(cell).find('img').attr(table.config.imgAttr || 'alt') || s;
},
parsed : true, // filter widget flag
type: "text"
});
})(jQuery);
@@ -0,0 +1,157 @@
/*! input & select parsers for jQuery 1.7+ & tablesorter 2.7.11+
* Updated 8/1/2014 (v2.17.6)
* Demo: http://mottie.github.com/tablesorter/docs/example-widget-grouping.html
*/
/*jshint browser: true, jquery:true, unused:false */
;(function($){
"use strict";
var resort = true, // resort table after update
updateServer = function(event, $table, $input){
// do something here to update your server, if needed
// event = change event object
// $table = jQuery object of the table that was just updated
// $input = jQuery object of the input or select that was modified
};
// Custom parser for parsing input values
// updated dynamically using the "change" function below
$.tablesorter.addParser({
id: "inputs",
is: function(){
return false;
},
format: function(s, table, cell) {
return $(cell).find('input').val() || s;
},
parsed : true, // filter widget flag
type: "text"
});
// Custom parser for including checkbox status if using the grouping widget
// updated dynamically using the "change" function below
$.tablesorter.addParser({
id: "checkbox",
is: function(){
return false;
},
format: function(s, table, cell, cellIndex) {
var $c = $(cell),
$input = $c.find('input[type="checkbox"]'),
isChecked = $input.length ? $input[0].checked : '';
// adding class to row, indicating that a checkbox is checked; includes
// a column index in case more than one checkbox happens to be in a row
$c.closest('tr').toggleClass('checked-' + cellIndex, isChecked);
// returning plain language here because this is what is shown in the
// group headers - change it as desired
return $input.length ? isChecked ? 'checked' : 'unchecked' : s;
},
parsed : true, // filter widget flag
type: "text"
});
// Custom parser which returns the currently selected options
// updated dynamically using the "change" function below
$.tablesorter.addParser({
id: "select",
is: function(){
return false;
},
format: function(s, table, cell) {
return $(cell).find('select').val() || s;
},
parsed : true, // filter widget flag
type: "text"
});
// Select parser to get the selected text
$.tablesorter.addParser({
id: "select-text",
is: function(){
return false;
},
format: function(s, table, cell) {
var $s = $(cell).find('select');
return $s.length ? $s.find('option:selected').text() || '' : s;
},
parsed : true, // filter widget flag
type: "text"
});
// Custom parser for parsing textarea values
// updated dynamically using the "change" function below
$.tablesorter.addParser({
id: "textarea",
is: function(){
return false;
},
format: function(s, table, cell) {
return $(cell).find('textarea').val() || s;
},
parsed : true, // filter widget flag
type: "text"
});
// update select and all input types in the tablesorter cache when the change event fires.
// This method only works with jQuery 1.7+
// you can change it to use delegate (v1.4.3+) or live (v1.3+) as desired
// if this code interferes somehow, target the specific table $('#mytable'), instead of $('table')
$(function(){
$('table').on('tablesorter-initialized', function(){
// this flag prevents the updateCell event from being spammed
// it happens when you modify input text and hit enter
var focused = false,
restoreValue = function(){
// focused = false; // uncomment this line to prevent auto-accepting changes
// make sure we restore original values
$(':focus').blur();
return;
};
// bind to .tablesorter (default class name)
$(this).children('tbody')
.on('mouseleave', function(){
restoreValue();
})
.on('focus', 'select, input, textarea', function(){
focused = true;
$(this).data('ts-original-value', this.value);
})
.on('blur', 'input, textarea', function(){
// restore input value;
// "change" is triggered before "blur" so this doesn't replace the new update with the original
this.value = $(this).data('ts-original-value');
})
.on('change keyup', 'select, input, textarea', function(e){
if ( e.which === 27 ) {
// escape: restore original value
this.value = $(this).data('ts-original-value');
return;
}
// Update cell cache using... select: change, input: enter or textarea: alt + enter
if ( ( e.type === 'change' && focused ) ||
( e.type === 'keyup' && e.which === 13 && ( e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA' && e.altKey ) ) ) {
var $tar = $(e.target),
$cell = $tar.closest('td'),
$table = $cell.closest('table'),
indx = $cell[0].cellIndex,
c = $table[0].config || false,
$hdr = c && c.$headers && c.$headers.eq(indx);
// abort if not a tablesorter table, or
// don't use updateCell if column is set to "sorter-false" and "filter-false", or column is set to "parser-false"
if ( !c || ( $hdr && $hdr.length && ( $hdr.hasClass('parser-false') || ( $hdr.hasClass('sorter-false') && $hdr.hasClass('filter-false') ) ) ) ) {
return restoreValue();
}
// ignore change event if nothing changed
if ($tar.val() !== $tar.data('ts-original-value')) {
$tar.data('ts-original-value', $tar.val());
$table.trigger('updateCell', [ $tar.closest('td'), resort, function(){
updateServer(e, $table, $tar);
setTimeout(function(){ focused = false; }, 10);
} ]);
}
}
});
});
});
})(jQuery);
@@ -0,0 +1,76 @@
/*! IPv6 Address parser (WIP)
* IPv6 Address (ffff:0000:0000:0000:0000:0000:0000:0000)
* needs to support short versions like "::8" or "1:2::7:8"
* and "::00:192.168.10.184" (embedded IPv4 address)
* see http://www.intermapper.com/support/tools/IPV6-Validator.aspx
*/
/*global jQuery: false */
;(function($){
"use strict";
var ts = $.tablesorter;
$.extend( ts.regex, {}, {
ipv4Validate : /((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})/,
ipv4Extract : /([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})/,
// simplified regex from http://www.intermapper.com/support/tools/IPV6-Validator.aspx
// (specifically from http://download.dartware.com/thirdparty/ipv6validator.js)
ipv6Validate : /^\s*((([0-9a-f]{1,4}:){7}([0-9a-f]{1,4}|:))|(([0-9a-f]{1,4}:){6}(:[0-9a-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){5}(((:[0-9a-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){4}(((:[0-9a-f]{1,4}){1,3})|((:[0-9a-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){3}(((:[0-9a-f]{1,4}){1,4})|((:[0-9a-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){2}(((:[0-9a-f]{1,4}){1,5})|((:[0-9a-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){1}(((:[0-9a-f]{1,4}){1,6})|((:[0-9a-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9a-f]{1,4}){1,7})|((:[0-9a-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/i
});
ts.addParser({
id: "ipv6Address",
is: function(s) {
return ts.regex.ipv6Validate.test(s);
},
format: function(address, table) {
// code modified from http://forrst.com/posts/JS_Expand_Abbreviated_IPv6_Addresses-1OR
var i, t, sides, groups, groupsPresent,
hex = table ? (typeof table === "boolean" ? table : table && table.config.ipv6HexFormat || false) : false,
fullAddress = '',
expandedAddress = '',
validGroupCount = 8,
validGroupSize = 4;
// remove any extra spaces
address = address.replace(/\s*/g, '');
// look for embedded ipv4
if (ts.regex.ipv4Validate.test(address)) {
groups = address.match(ts.regex.ipv4Extract);
t = '';
for (i = 1; i < groups.length; i++){
t += ('00' + (parseInt(groups[i], 10).toString(16)) ).slice(-2) + ( i === 2 ? ':' : '' );
}
address = address.replace( ts.regex.ipv4Extract, t );
}
if (address.indexOf("::") == -1) {
// All eight groups are present
fullAddress = address;
} else {
// Consecutive groups of zeroes have been collapsed with "::".
sides = address.split("::");
groupsPresent = 0;
for (i = 0; i < sides.length; i++) {
groupsPresent += sides[i].split(":").length;
}
fullAddress += sides[0] + ":";
for (i = 0; i < validGroupCount - groupsPresent; i++) {
fullAddress += "0000:";
}
fullAddress += sides[1];
}
groups = fullAddress.split(":");
for (i = 0; i < validGroupCount; i++) {
// it's fastest & easiest for tablesorter to sort decimal values (vs hex)
groups[i] = hex ? ('0000' + groups[i]).slice(-4) :
('00000' + (parseInt(groups[i], 16) || 0)).slice(-5);
expandedAddress += ( i != validGroupCount-1) ? groups[i] + ':' : groups[i];
}
return hex ? expandedAddress : expandedAddress.replace(/:/g, '');
},
// uses natural sort hex compare
type: "numeric"
});
})(jQuery);
@@ -0,0 +1,77 @@
/*! Metric parser
* Demo: http://jsfiddle.net/Mottie/abkNM/382/
* Set the metric name in the header (defaults to "m|meter"), e.g.
* <th data-metric-name="b|byte">HDD Size</th>
* <th data-metric-name="m|meter">Distance</th>
*/
/*jshint jquery:true */
;(function($){
"use strict";
var prefixes = {
// "prefix" : [ base 10, base 2 ]
// skipping IEEE 1541 defined prefixes: kibibyte, mebibyte, etc, for now.
"Y|Yotta|yotta" : [ 1e24, Math.pow(1024, 8) ], // 1024^8
"Z|Zetta|zetta" : [ 1e21, Math.pow(1024, 7) ], // 1024^7
"E|Exa|exa" : [ 1e18, Math.pow(1024, 6) ], // 1024^6
"P|Peta|peta" : [ 1e15, Math.pow(1024, 5) ], // 1024^5
"T|Tera|tera" : [ 1e12, Math.pow(1024, 4) ], // 1024^4
"G|Giga|giga" : [ 1e9, Math.pow(1024, 3) ], // 1024^3
"M|Mega|mega" : [ 1e6, Math.pow(1024, 2) ], // 1024^2
"k|Kilo|kilo" : [ 1e3, 1024 ], // 1024
// prefixes below here are rarely, if ever, used in binary
"h|hecto" : [ 1e2, 1e2 ],
"da|deka" : [ 1e1, 1e1 ],
"d|deci" : [ 1e-1, 1e-1 ],
"c|centi" : [ 1e-2, 1e-2],
"m|milli" : [ 1e-3, 1e-3 ],
"µ|micro" : [ 1e-6, 1e-6 ],
"n|nano" : [ 1e-9, 1e-9 ],
"p|pico" : [ 1e-12, 1e-12 ],
"f|femto" : [ 1e-15, 1e-15 ],
"a|atto" : [ 1e-18, 1e-18 ],
"z|zepto" : [ 1e-21, 1e-21 ],
"y|yocto" : [ 1e-24, 1e-24 ]
},
// the \\d+ will not catch digits with spaces, commas or decimals; so use the value from n instead
RegLong = "(\\d+)(\\s+)?([Zz]etta|[Ee]xa|[Pp]eta|[Tt]era|[Gg]iga|[Mm]ega|kilo|hecto|deka|deci|centi|milli|micro|nano|pico|femto|atto|zepto|yocto)(",
RegAbbr = "(\\d+)(\\s+)?(Z|E|P|T|G|M|k|h|da|d|c|m|µ|n|p|f|a|z|y)(";
$.tablesorter.addParser({
id: 'metric',
is: function() {
return false;
},
format: function(s, table, cell, cellIndex) {
var v = 'm|meter',
b, t,
// process number here to get a numerical format (us or eu)
n = $.tablesorter.formatFloat(s.replace(/[^\w,. \-()]/g, ""), table),
$t = table.config.$headers.filter('[data-column="' + cellIndex + '"]'),
m = $t.data('metric');
if (!m) {
// stored values
t = ($t.attr('data-metric-name') || v).split('|');
m = [ t[1] || t[0].substring(1), t[0] ];
m[2] = new RegExp(RegLong + m[0] + "|" + m[1] + ")");
m[3] = new RegExp(RegAbbr + m[1] + ")");
$t.data('metric', m);
}
// find match to full name or abbreviation
t = s.match(m[2]) || s.match(m[3]);
if (t) {
for (v in prefixes) {
if (t[3].match(v)) {
// exception when using binary prefix
// change base for binary use
b = /^[b|bit|byte|o|octet]/.test(t[4]) ? 1 : 0;
return n * prefixes[v][b];
}
}
}
return n;
},
type: 'numeric'
});
})(jQuery);
@@ -0,0 +1,117 @@
/*! Roman numeral parsers
* code modified from both:
* Steven Levithan @ http://blog.stevenlevithan.com/archives/javascript-roman-numeral-converter
* Jonathan Snook comment @ http://blog.stevenlevithan.com/archives/javascript-roman-numeral-converter#comment-16140
*/
/*jshint jquery:true, unused:false */
;(function($){
"use strict";
// allow lower case roman numerals, since lists use i, ii, iii, etc.
var validator = /^M*(?:D?C{0,3}|C[MD])(?:L?X{0,3}|X[CL])(?:V?I{0,3}|I[XV])$/i,
matcher = /\b([MCDLXVI]+\b)/gi,
lookup = { I:1, V:5, X:10, L:50, C:100, D:500, M:1000 };
$.tablesorter.addParser({
id: 'roman',
is: function(){
return false;
},
format: function(s) {
var val,
roman = s.toUpperCase().split(''),
num = 0;
// roman numerals not found!
if ( !(s && validator.test(s)) ) {
return s;
}
while (roman.length) {
val = lookup[roman.shift()];
num += val * (val < lookup[roman[0]] ? -1 : 1);
}
return num;
},
type: "numeric"
});
$.tablesorter.addParser({
id: 'roman-ignore',
is: function(){
return false;
},
format: function(s, table, cell, column) {
var val, orig,
c = table.config,
ignore = $.isArray(c.roman_ignore) ? c.roman_ignore[column] : 0,
// find roman numerals
roman = ( isNaN(ignore) ?
// ignore can be a regex or string
$.trim( s.replace(ignore, '') ) :
// or a number to ignore the last x letters...
$.trim( s.substring(0, s.length - ignore) )
).match(matcher),
v = validator.test(roman),
num = 0;
// roman numerals not found!
if ( !(v) ) {
return s;
}
// save roman numeral for replacement
orig = roman[0];
roman = orig.toUpperCase().split('');
while (roman.length) {
val = lookup[roman.shift()];
// ignore non-roman numerals
if (val) {
num += val * (val < lookup[roman[0]] ? -1 : 1);
}
}
return num ? s.replace(orig, num) : s;
},
type: "text"
});
$.tablesorter.addParser({
id: 'roman-extract',
is: function(){
return false;
},
format: function(s) {
var val,
// find roman numerals
roman = $.grep(s.split(/\b/), function(v, i){
return validator.test(v) ? v : '';
}).join('').match(matcher),
v = roman ? validator.test(roman) : 0,
num = 0;
// roman numerals not found!
if ( !(v) ) {
return s;
}
// save roman numeral for replacement
roman = roman[0].toUpperCase().split('');
while (roman.length) {
val = lookup[roman.shift()];
// ignore non-roman numerals
if (val) {
num += val * (val < lookup[roman[0]] ? -1 : 1);
}
}
return num ? num : s;
},
type: "numeric"
});
})(jQuery);
@@ -0,0 +1,145 @@
/*! tablesorter Align Character widget - updated 3/12/2014 (core v2.15.8)
* Requires tablesorter v2.8+ and jQuery 1.7+
* by Rob Garrison
*/
/*jshint browser:true, jquery:true, unused:false */
/*global jQuery: false */
;(function($){
"use strict";
var ts = $.tablesorter;
ts.alignChar = {
init : function(table, c, wo) {
c.$headers.filter('[' + wo.alignChar_charAttrib + ']').each(function(){
var $this = $(this),
vars = {
column : this.column,
align : $this.attr(wo.alignChar_charAttrib),
alignIndex : parseInt( $this.attr(wo.alignChar_indexAttrib) || 0, 10),
adjust : parseFloat($this.attr(wo.alignChar_adjustAttrib)) || 0,
};
vars.regex = new RegExp('\\' + vars.align, 'g');
if (typeof vars.align !== 'undefined') {
wo.alignChar_savedVars[this.column] = vars;
ts.alignChar.setup(table, c, wo, vars);
}
});
},
setup: function(table, c, wo, v){
// do nothing for empty tables
if ($.isEmptyObject(c.cache)) { return; }
var tbodyIndex, rowIndex, start, end, last, index, rows, val, count,
len, wLeft, wRight, alignChar, $row,
left = [],
right = [];
for (tbodyIndex = 0; tbodyIndex < c.$tbodies.length; tbodyIndex++){
rows = c.cache[tbodyIndex];
len = rows.normalized.length;
for (rowIndex = 0; rowIndex < len; rowIndex++) {
// set up to work with modified cache v2.16.0+
$row = rows.row ? rows.row[rowIndex] : rows.normalized[rowIndex][c.columns].$row;
val = $row.find('td').eq(v.column).text().replace(/[ ]/g, "\u00a0");
// count how many "align" characters are in the string
count = (val.match( v.regex ) || []).length;
// set alignment @ alignIndex (one-based index)
if (count > 0 && v.alignIndex > 0) {
end = Math.min(v.alignIndex, count);
start = 0;
index = 0;
last = 0;
// find index of nth align character based on alignIndex (data-align-index)
while (start++ < end) {
last = val.indexOf(v.align, last + 1);
index = last < 0 ? index : last;
}
} else {
index = val.indexOf(v.align);
}
if ( index >= 0 ) {
left.push( val.substring(0, index) || '' );
right.push( val.substring(index, val.length) || '' );
} else {
// no align character found!
// put val in right or left based on the align index
left.push( (count >= 1 && v.alignIndex >= count) ? '' : val || '' );
right.push( (count >= 1 && v.alignIndex >= count) ? val || '' : '' );
}
}
}
// find widest segments
wLeft = ($.extend([], left)).sort(function(a,b){ return b.length - a.length; })[0];
wRight = ($.extend([], right)).sort(function(a,b){ return b.length - a.length; })[0];
// calculate percentage widths
v.width = v.width || ( Math.floor(wLeft.length / (wLeft.length + wRight.length) * 100) + v.adjust );
wLeft = 'min-width:' + v.width + '%';
wRight = 'min-width:' + (100 - v.width) + '%';
for (tbodyIndex = 0; tbodyIndex < c.$tbodies.length; tbodyIndex++){
rows = c.cache[tbodyIndex];
len = rows.normalized.length;
for (rowIndex = 0; rowIndex < len; rowIndex++) {
alignChar = $(wo.alignChar_wrap).length ? $(wo.alignChar_wrap).html(v.align)[0].outerHTML : v.align;
$row = rows.row ? rows.row[rowIndex] : rows.normalized[rowIndex][c.columns].$row;
$row.find('td').eq(v.column).html(
'<span class="ts-align-wrap"><span class="ts-align-left" style="' + wLeft + '">' + left[rowIndex] + '</span>' +
'<span class="ts-align-right" style="' + wRight + '">' + alignChar +
right[rowIndex].slice(v.align.length) + '</span></span>'
);
}
}
wo.alignChar_initialized = true;
},
remove: function(table, c, column){
if ($.isEmptyObject(c.cache)) { return; }
var tbodyIndex, rowIndex, len, rows, $row, $cell;
for (tbodyIndex = 0; tbodyIndex < c.$tbodies.length; tbodyIndex++){
rows = c.cache[tbodyIndex];
len = rows.normalized.length;
for (rowIndex = 0; rowIndex < len; rowIndex++) {
$row = rows.row ? rows.row[rowIndex] : rows.normalized[rowIndex][c.columns].$row;
$cell = $row.find('td').eq(column);
$cell.html( $cell.text().replace(/\s/g, ' ') );
}
}
}
};
ts.addWidget({
id: 'alignChar',
priority: 100,
options: {
alignChar_wrap : '',
alignChar_charAttrib : 'data-align-char',
alignChar_indexAttrib : 'data-align-index',
alignChar_adjustAttrib : 'data-align-adjust' // percentage width adjustments
},
init: function(table, thisWidget, c, wo){
wo.alignChar_initialized = false;
wo.alignChar_savedVars = [];
ts.alignChar.init(table, c, wo);
c.$table.on('pagerEnd refreshAlign', function(){
c.$headers.filter('[' + wo.alignChar_charAttrib + ']').each(function(){
ts.alignChar.remove(table, c, this.column);
});
ts.alignChar.init(table, c, wo);
});
},
format : function(table, c, wo){
// reinitialize in case table is empty when first initialized
if (!wo.alignChar_initialized) {
c.$table.trigger('refreshAlign');
}
},
remove : function(table, c, wo){
c.$headers.filter('[' + wo.alignChar_charAttrib + ']').each(function(){
ts.alignChar.remove(table, c, this.column);
});
wo.alignChar_initialized = false;
}
});
})(jQuery);
@@ -0,0 +1,453 @@
/*! Build Table widget for tableSorter v2.16.0 (4/23/2014)
* by Rob Garrison
*/
/*jshint browser:true, jquery:true, unused:false */
/*global jQuery: false */
;(function($){
"use strict";
var ts = $.tablesorter = $.tablesorter || {},
// build a table from data (requires existing <table> tag)
// data.header contains an array of header titles
// data.rows contains an array of rows which contains an array of cells
bt = ts.buildTable = function(tar, c){
// add table if one doesn't exist
var $tbl = tar.tagName === 'TABLE' ? $(tar) : $('<table>').appendTo(tar),
table = $tbl[0],
wo = c.widgetOptions = $.extend( true, {}, bt.defaults, c.widgetOptions ),
p = wo.build_processing,
typ = wo.build_type,
d = wo.build_source || c.data,
// determine type: html, json, array, csv, object
runType = function(d){
var t = $.type(d),
jq = d instanceof jQuery;
// run any processing if set
if ( typeof p === 'function' ) { d = p(d, wo); }
// store processed data in table.config.data
c.data = d;
// String (html or unprocessed json) or jQuery object
if ( jq || t === 'string' ) {
// look for </tr> closing tag, then we have an HTML string
if ( jq || /<\s*\/tr\s*>/.test(d) ) {
return bt.html( table, d, wo );
}
try {
d = $.parseJSON(d);
if (d) {
// valid JSON!
return bt.object( table, d, wo );
}
} catch(ignore) {}
// fall through in case it's a csv string
}
// Array
if (t === 'array' || t === 'string' || typ === 'array' || typ === 'csv') {
// build table using an array (csv & array combined script)
return bt.csv( table, d, wo );
}
// if we got here, it's an object, or nothing
return bt.object( table, d, wo );
};
// store config
table.config = c;
// even if wo.build_type is undefined, we can try to figure out the type
if ( !ts.buildTable.hasOwnProperty(typ) && typ !== '' ) {
if (c.debug) { ts.log('aborting build table widget, incorrect build type'); }
return false;
}
if ( d instanceof jQuery ) {
// get data from within a jQuery object (csv)
runType( $.trim( d.html() ) );
} else if ( d && ( d.hasOwnProperty('url') || typ === 'json' ) ) {
// load data via ajax
$.ajax( wo.build_source )
.done(function(data) {
runType(data);
})
.fail(function( jqXHR, textStatus, errorThrown) {
if (c.debug) { ts.log('aborting build table widget, failed ajax load'); }
$tbl.html('<tr><td class="error">' + jqXHR.status + ' ' + textStatus + '</td></tr>');
});
} else {
runType(d);
}
};
bt.defaults = {
// *** build widget core ***
build_type : '', // array, csv, object, json, html
build_source : '', // array, object, jQuery Object or ajaxObject { url: '', dataType: 'json' },
build_processing : null, // function that returns a useable build_type (e.g. string to array)
build_complete : 'tablesorter-build-complete', // triggered event when build completes
// *** CSV & Array ***
build_headers : {
rows : 1, // Number of header rows from the csv
classes : [], // Header classes to apply to cells
text : [], // Header cell text
widths : [] // set header cell widths (set in colgroup)
},
build_footers : {
rows : 1, // Number of header rows from the csv
classes : [], // Footer classes to apply to cells
text : [] // Footer cell text
},
build_numbers : {
addColumn : false, // include row numbering column?
sortable : false // make column sortable?
},
// *** CSV only options ***
build_csvStartLine : 0, // line within the csv to start adding to table
build_csvSeparator : ",", // csv separator
// *** build object options ***
build_objectRowKey : 'rows', // object key containing table rows
build_objectCellKey : 'cells', // object key containing table cells (within the rows object)
build_objectHeaderKey : 'headers', // object key containing table headers
build_objectFooterKey : 'footers' // object key containing table footers
};
bt.build = {
colgroup : function(widths) {
var t = '';
// add colgroup if widths set
if (widths && widths.length) {
t += '<colgroup>';
$.each(widths, function(i, w){
t += '<col' + ( w ? ' style="width:' + w + '"' : '' ) + '>';
});
t += '</colgroup>';
}
return t;
},
// d = cell data; typ = 'th' or 'td'; first = save widths from first header row only
cell : function(d, wo, typ, col, first){
var j, $td,
$col = first ? $('<col>') : '',
cls = wo.build_headers.classes,
cw = wo.build_headers.widths;
// d is just an array
if (/string|number/.test(typeof d)) {
// add classes from options, but not text
$td = $('<' + typ + (cls && cls[col] ? ' class="' + cls[col] + '"' : '') + '>' + d + '</' + typ + '>');
// get widths from options (only from first row)
if (first && cw && cw[col]) {
$col.width(cw[col] || '');
}
} else {
// assume we have an object
$td = $('<' + typ + '>');
for (j in d) {
if (d.hasOwnProperty(j)){
if (j === 'text' || j === 'html') {
$td[j]( d[j] );
} else if (first && j === 'width') {
// set column width, but only from first row
$col.width(d[j] || '');
} else {
$td.attr(j, d[j]);
}
}
}
}
return [ $td, $col ];
},
// h1 = header text from data
header : function(h1, wo){
var h2 = wo.build_headers.text,
cls = wo.build_headers.classes,
t = '<tr>' + (wo.build_numbers.addColumn ? '<th' + (wo.build_numbers.sortable ? '' :
' class="sorter-false"') + '>' + wo.build_numbers.addColumn + '</th>' : '');
$.each(h1, function(i, h) {
if (/<\s*\/t(d|h)\s*>/.test(h)) {
t += h;
} else {
t += '<th' + (cls && cls[i] ? ' class="' + cls[i] + '"' : '') + '>' +
(h2 && h2[i] ? h2[i] : h) + '</th>';
}
});
return t + '</tr>';
},
rows : function(items, txt, c, wo, num, ftr){
var h = (ftr ? 'th' : 'td'),
t = '<tr>' + (wo.build_numbers.addColumn ? '<' + h + '>' + (ftr ? '' : num) + '</' + h + '>' : '');
$.each(items, function(i, item) {
// test if HTML is already included; look for closing </td>
if (/<\s*\/t(d|h)\s*>/.test(item)) {
t += item;
} else {
t += '<' + (ftr ? h + (c && c[i] ? ' class="' + c[i] + '"' : '') : h) + '>' +
(ftr && txt && txt.length && txt[i] ? txt[i] : item) + '</' + h + '>';
}
});
return t + '</tr>';
}
};
bt.buildComplete = function(table, wo){
$(table).trigger(wo.build_complete);
ts.setup(table, table.config);
};
/* ==== Array example ====
[
[ "header1", "header2", ... "headerN" ],
[ "row1cell1", "row1cell2", ... "row1cellN" ],
[ "row2cell1", "row2cell2", ... "row2cellN" ],
...
[ "rowNcell1", "rowNcell2", ... "rowNcellN" ]
]
*/
bt.array = function(table, data, wo) {
return bt.csv(table, data, wo);
};
/* ==== CSV example ====
ID, Name, Age, Date
A42b, Parker, 28, "Jul 6, 2006 8:14 AM"
A255, Hood, 33, "Dec 10, 2002 5:14 AM"
A33, Kent, 18, "Jan 12, 2003 11:14 AM"
A1, Franklin, 45, "Jan 18, 2001 9:12 AM"
A102, Evans, 22, "Jan 18, 2007 9:12 AM"
A42a, Everet, 22, "Jan 18, 2007 9:12 AM"
ID, Name, Age, Date
*/
// Adapted & modified from csvToTable.js by Steve Sobel
// MIT license: https://code.google.com/p/jquerycsvtotable/
bt.csv = function(table, data, wo) {
var c, h,
csv = wo.build_type === 'csv' || typeof data === 'string',
$t = $(table),
lines = csv ? data.replace('\r','').split('\n') : data,
len = lines.length,
printedLines = 0,
infooter = false,
r = wo.build_headers.rows + (csv ? wo.build_csvStartLine : 0),
f = wo.build_footers.rows,
headerCount = 0,
error = '',
items,
tableHTML = bt.build.colgroup( wo.build_headers.widths ) + '<thead>';
$.each(lines, function(n, line) {
if ( n >= len - f ) { infooter = true; }
// build header
if ( (csv ? n >= wo.build_csvStartLine : true) && ( n < r ) ) {
h = csv ? bt.splitCSV( line, wo.build_csvSeparator ) : line;
headerCount = h.length;
tableHTML += bt.build.header(h, wo);
} else if ( n >= r ) {
// build tbody & tfoot rows
if (n === r) {
tableHTML += '</thead><tbody>';
}
items = csv ? bt.splitCSV( line, wo.build_csvSeparator ) : line;
if (infooter && f > 0) {
tableHTML += (n === len - f ? '</tbody><tfoot>' : '') +
(n === len ? '</tfoot>' : '');
}
if (items.length > 1) {
printedLines++;
if ( items.length !== headerCount ) {
error += 'error on line ' + n + ': Item count (' + items.length +
') does not match header count (' + headerCount + ') \n';
}
c = infooter ? wo.build_footers.classes : '';
tableHTML += bt.build.rows(items, wo.build_footers.text, c, wo, printedLines, infooter);
}
}
});
tableHTML += (f > 0 ? '' : '</tbody>');
if (error) {
$t.html(error);
} else {
$t.html(tableHTML);
bt.buildComplete(table, wo);
}
};
// CSV Parser by Brian Huisman (http://www.greywyvern.com/?post=258)
bt.splitCSV = function(str, sep) {
var x, tl,
thisCSV = $.trim(str).split(sep = sep || ",");
for ( x = thisCSV.length - 1; x >= 0; x-- ) {
if ( thisCSV[x].replace(/\"\s+$/, '"').charAt(thisCSV[x].length - 1) === '"' ) {
if ( (tl = thisCSV[x].replace(/^\s+\"/, '"')).length > 1 && tl.charAt(0) === '"' ) {
thisCSV[x] = thisCSV[x].replace(/^\s*"|"\s*$/g, '').replace(/""/g, '"');
} else if (x) {
thisCSV.splice(x - 1, 2, [thisCSV[x - 1], thisCSV[x]].join(sep));
} else {
thisCSV = thisCSV.shift().split(sep).concat(thisCSV);
}
} else {
thisCSV[x].replace(/""/g, '"');
}
}
return thisCSV;
};
// data may be a jQuery object after processing
bt.html = function(table, data, wo) {
var $t = $(table);
if ( data instanceof jQuery ) {
$t.empty().append(data);
} else {
$t.html(data);
}
bt.buildComplete(table, wo);
};
/* ==== Object example ====
data : {
headers : [
[
{ text: 'First Name', class: 'fname', width: '20%' }, // row 1 cell 1
'Last Name',
{ text: 'Age', class: 'age', 'data-sorter' : false },
'Total',
{ text: 'Discount', class : 'sorter-false' },
{ text: 'Date', class : 'date' } // row 1 cell 6
]
],
footers : 'clone', // clone headers or assign array like headers
rows : [
// TBODY 1
[ 'Peter', 'Parker', 28, '$9.99', '20%', 'Jul 6, 2006 8:14 AM' ], // row 1
[ 'John', 'Hood', 33, '$19.99', '25%', 'Dec 10, 2002 5:14 AM' ], // row 2
[ 'Clark', 'Kent', 18, '$15.89', '44%', 'Jan 12, 2003 11:14 AM' ], // row 3
// TBODY 2
{ newTbody: true, class: 'tablesorter-infoOnly' },
{ cells : [ { text: 'Info Row', colSpan: 6 } ] }, // row 4
// TBODY 3
{ newTbody: true },
[ 'Bruce', 'Evans', 22, '$13.19', '11%', 'Jan 18, 2007 9:12 AM' ], // row 5
[ 'Brice', 'Almighty', 45, '$153.19', '44%', 'Jan 18, 2001 9:12 AM' ], // row 6
{ class: 'specialRow', // row 7
cells: [
{ text: 'Fred', class: 'fname' },
{ text: 'Smith', class: 'lname' },
{ text: 18, class: 'age', 'data-info': 'fake ID!, he is really 16' },
{ text: '$22.44', class: 'total' },
{ text: '8%', class: 'discount' },
{ text: 'Aug 20, 2012 10:15 AM', class: 'date' }
],
'data-info' : 'This row likes turtles'
}
]
}
*/
bt.object = function(table, data, wo) {
// "rows"
var j, l, t, $c, $t, $tb, $tr,
c = table.config,
kh = wo.build_objectHeaderKey,
kr = wo.build_objectRowKey,
h = data.hasOwnProperty(kh) && !$.isEmptyObject(data.kh) ? data.kh : data.hasOwnProperty('headers') ? data.headers : false,
r = data.hasOwnProperty(kr) && !$.isEmptyObject(data.kr) ? data.kr : data.hasOwnProperty('rows') ? data.rows : false;
if (!h || !r || h.length === 0 || r.length === 0) {
if (c.debug) { ts.log('aborting build table widget, missing data for object build'); }
return false;
}
$c = $('<colgroup>');
$t = $('<table><thead/></table>');
// Build thead
// h = [ ['headerRow1Cell1', 'headerRow1Cell2', ... 'headerRow1CellN' ], ['headerRow2Cell1', ... ] ]
// or h = [ [ { text: 'firstCell', class: 'fc', width: '20%' }, ..., { text: 'last Cell' } ], [ /* second row */ ] ]
$.each(h, function(i, d){
$tr = $('<tr>').appendTo( $t.find('thead') );
l = d.length; // header row
for ( j = 0; j < l; j++ ) {
// cell(cellData, widgetOptions, 'th', first row)
t = bt.build.cell(d[j], wo, 'th', j, i === 0);
if (t[0] && t[0].length) { t[0].appendTo( $tr ); } // add cell
if (i === 0 && t[1]) { t[1].appendTo( $c ); } // add col to colgroup
}
});
if ($c.find('col[style]').length) {
// add colgroup if it contains col elements
$t.prepend( $c );
}
$tb = $('<tbody>');
// Build tbody
$.each(r, function(i, d){
var j;
t = $.type(d) === 'object';
// add new tbody
if (t && d.newTbody) {
$tb = $('<tbody>').appendTo( $t );
for (j in d) {
if (d.hasOwnProperty(j) && j !== 'newTbody'){
$tb.attr(j, d[j]);
}
}
} else {
if (i === 0) {
// add tbody, if the first item in the object isn't a call for a new tbody
$tb.appendTo( $t );
}
$tr = $('<tr>').appendTo( $tb );
if (t) {
// row defined by object
for (j in d) {
if (d.hasOwnProperty(j) && j !== wo.build_objectCellKey){
$tr.attr(j, d[j]);
}
}
if (d.hasOwnProperty(wo.build_objectCellKey)) {
// cells contains each cell info
d = d.cells;
}
}
l = d.length;
for ( j = 0; j < l; j++ ) {
// cell(cellData, widgetOptions, 'td')
$c = bt.build.cell(d[j], wo, 'td', j);
if ($c[0] && $c[0].length) { $c[0].appendTo( $tr ); } // add cell
}
}
});
// add footer
if (data.hasOwnProperty(wo.build_objectFooterKey)) {
t = data[wo.build_objectFooterKey];
if (t === 'clone') {
$c = $t.find('thead').html();
$t.append('<tfoot>' + $c + '</tfoot>');
} else {
$c = $('<tfoot>').appendTo( $t );
$.each(t, function(i, d) {
$tr = $('<tr>').appendTo( $c );
l = d.length; // footer cells
for ( j = 0; j < l; j++ ) {
// cell(cellData, widgetOptions, 'th')
$tb = bt.build.cell(d[j], wo, 'th', j);
if ($tb[0] && $tb[0].length) { $tb[0].appendTo( $tr ); } // add cell
}
});
}
}
$(table).html( $t.html() );
bt.buildComplete(table, wo);
};
bt.ajax = bt.json = function(table, data, wo) {
return bt.object(table, data, wo);
};
})(jQuery);
@@ -0,0 +1,317 @@
/* Column Selector/Responsive table widget (beta) for TableSorter 5/22/2014 (v2.17.0)
* Requires tablesorter v2.8+ and jQuery 1.7+
* by Justin Hallett & Rob Garrison
*/
/*jshint browser:true, jquery:true, unused:false */
/*global jQuery: false */
;(function($){
"use strict";
var ts = $.tablesorter,
namespace = '.tscolsel',
tsColSel = ts.columnSelector = {
queryAll : '@media only all { [columns] { display: none; } }',
queryBreak : '@media all and (min-width: [size]) { [columns] { display: table-cell; } }',
init: function(table, c, wo) {
var $t, colSel;
// abort if no input is contained within the layout
$t = $(wo.columnSelector_layout);
if (!$t.find('input').add( $t.filter('input') ).length) {
if (c.debug) {
ts.log('*** ERROR: Column Selector aborting, no input found in the layout! ***');
}
return;
}
// unique table class name
c.tableId = 'tablesorter' + new Date().getTime();
c.$table.addClass( c.tableId );
// build column selector/state array
colSel = c.selector = { $container : $(wo.columnSelector_container || '<div>') };
colSel.$style = $('<style></style>').prop('disabled', true).appendTo('head');
colSel.$breakpoints = $('<style></style>').prop('disabled', true).appendTo('head');
colSel.isInitializing = true;
tsColSel.setupSelector(table, c, wo);
if (wo.columnSelector_mediaquery) {
tsColSel.setupBreakpoints(c, wo);
}
colSel.isInitializing = false;
if (colSel.$container.length) {
tsColSel.updateCols(c, wo);
}
c.$table
.off('refreshColumnSelector' + namespace)
.on('refreshColumnSelector' + namespace, function(){
// make sure we're using current config settings
var c = this.config;
tsColSel.updateBreakpoints(c, c.widgetOptions);
tsColSel.updateCols(c, c.widgetOptions);
});
},
setupSelector: function(table, c, wo) {
var name,
colSel = c.selector,
$container = colSel.$container,
useStorage = wo.columnSelector_saveColumns && ts.storage,
// get stored column states
saved = useStorage ? ts.storage( table, 'tablesorter-columnSelector' ) : [],
state = useStorage ? ts.storage( table, 'tablesorter-columnSelector-auto') : {};
// initial states
colSel.auto = $.isEmptyObject(state) || $.type(state.auto) !== "boolean" ? wo.columnSelector_mediaqueryState : state.auto;
colSel.states = [];
colSel.$column = [];
colSel.$wrapper = [];
colSel.$checkbox = [];
// populate the selector container
c.$table.children('thead').find('tr:first th', table).each(function() {
var $this = $(this),
// if no data-priority is assigned, default to 1, but don't remove it from the selector list
priority = $this.attr(wo.columnSelector_priority) || 1,
colId = $this.attr('data-column'),
state = ts.getData(this, c.headers[colId], 'columnSelector');
// if this column not hidable at all
// include getData check (includes "columnSelector-false" class, data attribute, etc)
if ( isNaN(priority) && priority.length > 0 || state === 'disable' ||
( wo.columnSelector_columns[colId] && wo.columnSelector_columns[colId] === 'disable') ) {
return true; // goto next
}
// set default state; storage takes priority
colSel.states[colId] = saved && typeof(saved[colId]) !== 'undefined' ?
saved[colId] : typeof(wo.columnSelector_columns[colId]) !== 'undefined' ?
wo.columnSelector_columns[colId] : (state === 'true' || !(state === 'false'));
colSel.$column[colId] = $(this);
// set default col title
name = $this.attr(wo.columnSelector_name) || $this.text();
if ($container.length) {
colSel.$wrapper[colId] = $(wo.columnSelector_layout.replace(/\{name\}/g, name)).appendTo($container);
colSel.$checkbox[colId] = colSel.$wrapper[colId]
// input may not be wrapped within the layout template
.find('input').add( colSel.$wrapper[colId].filter('input') )
.attr('data-column', colId)
.prop('checked', colSel.states[colId])
.on('change', function(){
colSel.states[colId] = this.checked;
tsColSel.updateCols(c, wo);
}).change();
}
});
},
setupBreakpoints: function(c, wo){
var colSel = c.selector;
// add responsive breakpoints
if (wo.columnSelector_mediaquery) {
// used by window resize function
colSel.lastIndex = -1;
wo.columnSelector_breakpoints.sort();
tsColSel.updateBreakpoints(c, wo);
c.$table
.off('updateAll' + namespace)
.on('updateAll' + namespace, function(){
tsColSel.updateBreakpoints(c, wo);
tsColSel.updateCols(c, wo);
});
}
if (colSel.$container.length) {
// Add media queries toggle
if (wo.columnSelector_mediaquery) {
colSel.$auto = $( wo.columnSelector_layout.replace(/\{name\}/g, wo.columnSelector_mediaqueryName) ).prependTo(colSel.$container);
colSel.$auto
// needed in case the input in the layout is not wrapped
.find('input').add( colSel.$auto.filter('input') )
.attr('data-column', 'auto')
.prop('checked', colSel.auto)
.on('change', function(){
colSel.auto = this.checked;
$.each( colSel.$checkbox, function(i, $cb){
if ($cb) {
$cb[0].disabled = colSel.auto;
colSel.$wrapper[i].toggleClass('disabled', colSel.auto);
}
});
if (wo.columnSelector_mediaquery) {
tsColSel.updateBreakpoints(c, wo);
}
tsColSel.updateCols(c, wo);
// copy the column selector to a popup/tooltip
if (c.selector.$popup) {
c.selector.$popup.find('.tablesorter-column-selector')
.html( colSel.$container.html() )
.find('input').each(function(){
var indx = $(this).attr('data-column');
$(this).prop( 'checked', indx === 'auto' ? colSel.auto : colSel.states[indx] );
});
}
if (wo.columnSelector_saveColumns && ts.storage) {
ts.storage( c.$table[0], 'tablesorter-columnSelector-auto', { auto : colSel.auto } );
}
}).change();
}
// Add a bind on update to re-run col setup
c.$table.off('update' + namespace).on('update' + namespace, function() {
tsColSel.updateCols(c, wo);
});
}
},
updateBreakpoints: function(c, wo) {
var priority, column, breaks,
colSel = c.selector,
prefix = '.' + c.tableId,
mediaAll = [],
breakpts = '';
if (wo.columnSelector_mediaquery && !colSel.auto) {
colSel.$breakpoints.prop('disabled', true);
colSel.$style.prop('disabled', false);
return;
}
// only 6 breakpoints (same as jQuery Mobile)
for (priority = 0; priority < 6; priority++){
/*jshint loopfunc:true */
breaks = [];
c.$headers.filter('[' + wo.columnSelector_priority + '=' + (priority + 1) + ']').each(function(){
column = parseInt($(this).attr('data-column'), 10) + 1;
breaks.push(prefix + ' tr th:nth-child(' + column + ')');
breaks.push(prefix + ' tr td:nth-child(' + column + ')');
});
if (breaks.length) {
mediaAll = mediaAll.concat( breaks );
breakpts += tsColSel.queryBreak
.replace(/\[size\]/g, wo.columnSelector_breakpoints[priority])
.replace(/\[columns\]/g, breaks.join(','));
}
}
if (colSel.$style) {
colSel.$style.prop('disabled', true);
}
colSel.$breakpoints
.prop('disabled', false)
.html( tsColSel.queryAll.replace(/\[columns\]/g, mediaAll.join(',')) + breakpts );
},
updateCols: function(c, wo) {
if (wo.columnSelector_mediaquery && c.selector.auto || c.selector.isInitializing) {
return;
}
var column,
colSel = c.selector,
styles = [],
prefix = '.' + c.tableId;
colSel.$container.find('input[data-column]').filter('[data-column!="auto"]').each(function(){
if (!this.checked) {
column = parseInt( $(this).attr('data-column'), 10 ) + 1;
styles.push(prefix + ' tr th:nth-child(' + column + ')');
styles.push(prefix + ' tr td:nth-child(' + column + ')');
}
});
if (wo.columnSelector_mediaquery){
colSel.$breakpoints.prop('disabled', true);
}
if (colSel.$style) {
colSel.$style.prop('disabled', false).html( styles.length ? styles.join(',') + ' { display: none; }' : '' );
}
if (wo.columnSelector_saveColumns && ts.storage) {
ts.storage( c.$table[0], 'tablesorter-columnSelector', colSel.states );
}
},
attachTo : function(table, elm) {
table = $(table)[0];
var colSel, wo, indx,
c = table.config,
$popup = $(elm);
if ($popup.length && c) {
if (!$popup.find('.tablesorter-column-selector').length) {
// add a wrapper to add the selector into, in case the popup has other content
$popup.append('<span class="tablesorter-column-selector"></span>');
}
colSel = c.selector;
wo = c.widgetOptions;
$popup.find('.tablesorter-column-selector')
.html( colSel.$container.html() )
.find('input').each(function(){
var indx = $(this).attr('data-column');
$(this).prop( 'checked', indx === 'auto' ? colSel.auto : colSel.states[indx] );
});
colSel.$popup = $popup.on('change', 'input', function(){
// data input
indx = $(this).attr('data-column');
// update original popup
colSel.$container.find('input[data-column="' + indx + '"]')
.prop('checked', this.checked)
.trigger('change');
});
}
}
};
ts.addWidget({
id: "columnSelector",
priority: 10,
options: {
// target the column selector markup
columnSelector_container : null,
// column status, true = display, false = hide
// disable = do not display on list
columnSelector_columns : {},
// remember selected columns
columnSelector_saveColumns: true,
// container layout
columnSelector_layout : '<label><input type="checkbox">{name}</label>',
// data attribute containing column name to use in the selector container
columnSelector_name : 'data-selector-name',
/* Responsive Media Query settings */
// enable/disable mediaquery breakpoints
columnSelector_mediaquery: true,
// toggle checkbox name
columnSelector_mediaqueryName: 'Auto: ',
// breakpoints checkbox initial setting
columnSelector_mediaqueryState: true,
// responsive table hides columns with priority 1-6 at these breakpoints
// see http://view.jquerymobile.com/1.3.2/dist/demos/widgets/table-column-toggle/#Applyingapresetbreakpoint
// *** set to false to disable ***
columnSelector_breakpoints : [ '20em', '30em', '40em', '50em', '60em', '70em' ],
// data attribute containing column priority
// duplicates how jQuery mobile uses priorities:
// http://view.jquerymobile.com/1.3.2/dist/demos/widgets/table-column-toggle/
columnSelector_priority : 'data-priority'
},
init: function(table, thisWidget, c, wo) {
tsColSel.init(table, c, wo);
},
remove: function(table, c){
var csel = c.selector;
csel.$container.empty();
if (csel.$popup) { csel.$popup.empty(); }
csel.$style.remove();
csel.$breakpoints.remove();
c.$table.off('updateAll' + namespace + ' update' + namespace);
}
});
})(jQuery);
@@ -0,0 +1,70 @@
/*! tablesorter CSS Sticky Headers widget - updated 5/5/2014 (v2.16.4)
* Requires a modern browser, tablesorter v2.8+
*/
/*jshint jquery:true, unused:false */
;(function($){
"use strict";
$.tablesorter.addWidget({
id: "cssStickyHeaders",
priority: 10,
options: {
cssStickyHeaders_offset : 0,
cssStickyHeaders_addCaption : false,
cssStickyHeaders_attachTo : null,
cssStickyHeaders_filteredToTop : true,
cssStickyHeaders_zIndex : 10
},
init : function(table, thisWidget, c, wo) {
var $attach = $(wo.cssStickyHeaders_attachTo),
namespace = '.cssstickyheader',
$thead = c.$table.children('thead'),
$caption = c.$table.find('caption'),
$win = $attach.length ? $attach : $(window);
$win.bind('scroll resize '.split(' ').join(namespace + ' '), function() {
var top = $attach.length ? $attach.offset().top : $win.scrollTop(),
// add caption height; include table padding top & border-spacing or text may be above the fold (jQuery UI themes)
// border-spacing needed in Firefox, but not webkit... not sure if I should account for that
captionTop = wo.cssStickyHeaders_addCaption ? $caption.outerHeight(true) +
(parseInt(c.$table.css('padding-top'), 10) || 0) + (parseInt(c.$table.css('border-spacing'), 10) || 0) : 0,
bottom = c.$table.height() - $thead.height() - (c.$table.find('tfoot').height() || 0) - captionTop,
deltaY = top - $thead.offset().top + (parseInt(c.$table.css('border-top-width'), 10) || 0) +
(wo.cssStickyHeaders_offset || 0) + captionTop,
finalY = (deltaY > 0 && deltaY <= bottom ? deltaY : 0),
// IE can only transform header cells - fixes #447 thanks to @gakreol!
$cells = $thead.children().children();
if (wo.cssStickyHeaders_addCaption) {
$cells = $cells.add($caption);
}
$cells.css({
"position" : "relative",
"z-index" : wo.cssStickyHeaders_zIndex,
"transform" : finalY === 0 ? "" : "translate(0px," + finalY + "px)",
"-ms-transform" : finalY === 0 ? "" : "translate(0px," + finalY + "px)",
"-webkit-transform" : finalY === 0 ? "" : "translate(0px," + finalY + "px)"
});
});
c.$table.bind('filterEnd', function() {
if (wo.cssStickyHeaders_filteredToTop) {
// scroll top of table into view
window.scrollTo(0, c.$table.position().top);
}
});
},
remove: function(table, c, wo){
var namespace = '.cssstickyheader';
$(window).unbind('scroll resize '.split(' ').join(namespace + ' '));
c.$table
.unbind('update updateAll '.split(' ').join(namespace + ' '))
.children('thead, caption').css({
"position" : "",
"z-index" : "",
"transform" : "",
"-ms-transform" : "",
"-webkit-transform" : ""
});
}
});
})(jQuery);
@@ -0,0 +1,113 @@
/*! tablesorter Editable Content widget - updated 8/1/2014 (core v2.17.6)
* Requires tablesorter v2.8+ and jQuery 1.7+
* by Rob Garrison
*/
/*jshint browser:true, jquery:true, unused:false */
/*global jQuery: false */
;(function($){
"use strict";
$.tablesorter.addWidget({
id: 'editable',
options : {
editable_columns : [],
editable_enterToAccept : true,
editable_autoAccept : true,
editable_autoResort : false,
editable_validate : null, // function(text, originalText){ return text; }
editable_noEdit : 'no-edit',
editable_editComplete : 'editComplete'
},
init: function(table, thisWidget, c, wo){
if ( !wo.editable_columns.length ) { return; }
var indx, tmp, $t,
cols = [];
if ( $.type(wo.editable_columns) === "string" && wo.editable_columns.indexOf('-') >= 0 ) {
// editable_columns can contain a range string (i.e. "2-4" )
tmp = wo.editable_columns.split('-');
indx = parseInt(tmp[0],10) || 0;
tmp = parseInt(tmp[1],10) || (c.columns - 1);
if ( tmp > c.columns ) { tmp = c.columns - 1; }
for ( ; indx <= tmp; indx++ ) {
cols.push('td:nth-child(' + (indx + 1) + ')');
}
} else if ( $.isArray(wo.editable_columns) ) {
$.each(wo.editable_columns, function(i, col){
if ( col < c.columns ) {
cols.push('td:nth-child(' + (col + 1) + ')');
}
});
}
// IE does not allow making TR/TH/TD cells directly editable (issue #404)
// so add a div or span inside ( it's faster than using wrapInner() )
c.$tbodies.find( cols.join(',') ).not( '.' + wo.editable_noEdit ).each(function(){
// test for children, if they exist, then make the children editable
$t = $(this);
( $t.children().length ? $t.children() : $t ).prop( 'contenteditable', true );
});
c.$tbodies
.on('mouseleave.tseditable', function(){
if ( c.$table.data('contentFocused') ) {
// change to "true" instead of element to allow focusout to process
c.$table.data( 'contentFocused', true );
$(':focus').trigger('blur');
}
})
.on('focus.tseditable', '[contenteditable]', function(e){
c.$table.data( 'contentFocused', e.target );
var $this = $(this),
v = $this.html();
if (wo.editable_enterToAccept) {
// prevent enter from adding into the content
$this.on('keydown.tseditable', function(e){
if ( e.which === 13 ) {
e.preventDefault();
}
});
}
$this.data({ before : v, original: v });
})
.on('blur focusout keydown '.split(' ').join('.tseditable '), '[contenteditable]', function(e){
if ( !c.$table.data('contentFocused') ) { return; }
var t,
valid = false,
$this = $(e.target);
if ( e.which === 27 ) {
// user cancelled
$this.html( $this.data('original') ).trigger('blur.tseditable');
c.$table.data( 'contentFocused', false );
return false;
}
t = e.which === 13 && ( wo.editable_enterToAccept || e.altKey ) || wo.editable_autoAccept && e.type !== 'keydown';
// change if new or user hits enter (if option set)
if ( t && $this.data('before') !== $this.html() ) {
valid = $.isFunction(wo.editable_validate) ? wo.editable_validate( $this.html(), $this.data('original') ) : $this.html();
if ( t && valid !== false ) {
$this
.html( valid )
.data('before', valid)
.trigger('change');
c.$table.trigger('updateCell', [ $this.closest('td'), wo.editable_autoResort, function(table){
$this.trigger( wo.editable_editComplete, [c] );
$this.data( 'original', $this.html() );
if ( wo.editable_autoResort && c.sortList.length ) {
c.$table.trigger('applyWidgets');
}
// restore focus last cell after updating
setTimeout(function(){
var t = c.$table.data('contentFocused');
if ( t instanceof HTMLElement ) { t.focus(); }
}, 50);
} ]);
return false;
}
}
if ( !valid && e.type !== 'keydown' ) {
// restore original content on blur
$this.html( $this.data('original') );
}
});
}
});
})(jQuery);
@@ -0,0 +1,249 @@
/*! tablesorter Grouping widget - updated 3/7/2014 (core v2.15.6)
* Requires tablesorter v2.8+ and jQuery 1.7+
* by Rob Garrison
*/
/*jshint browser:true, jquery:true, unused:false */
/*global jQuery: false */
;(function($){
"use strict";
var ts = $.tablesorter;
ts.grouping = {
types : {
number : function(c, $column, txt, num, group){
var value, word;
if (num > 1 && txt !== '') {
if ($column.hasClass(ts.css.sortAsc)) {
value = Math.floor(parseFloat(txt)/num) * num;
return value > parseFloat(group || 0) ? value : parseFloat(group || 0);
} else {
value = Math.ceil(parseFloat(txt)/num) * num;
return value < parseFloat(group || num) - value ? parseFloat(group || num) - value : value;
}
} else {
word = (txt + '').match(/\d+/g);
return word && word.length >= num ? word[num - 1] : txt || '';
}
},
separator : function(c, $column, txt, num){
var word = (txt + '').split(c.widgetOptions.group_separator);
return $.trim(word && num > 0 && word.length >= num ? word[(num || 1) - 1] : '');
},
word : function(c, $column, txt, num){
var word = (txt + ' ').match(/\w+/g);
return word && word.length >= num ? word[num - 1] : txt || '';
},
letter : function(c, $column, txt, num){
return txt ? (txt + ' ').substring(0, num) : '';
},
date : function(c, $column, txt, part, group){
var wo = c.widgetOptions,
time = new Date(txt || ''),
hours = time.getHours();
return part === 'year' ? time.getFullYear() :
part === 'month' ? wo.group_months[time.getMonth()] :
part === 'day' ? wo.group_months[time.getMonth()] + ' ' + time.getDate() :
part === 'week' ? wo.group_week[time.getDay()] :
part === 'time' ? ('00' + (hours > 12 ? hours - 12 : hours === 0 ? hours + 12 : hours)).slice(-2) + ':' +
('00' + time.getMinutes()).slice(-2) + ' ' + ('00' + wo.group_time[hours >= 12 ? 1 : 0]).slice(-2) :
wo.group_dateString(time);
}
},
update : function(table, c, wo){
if ($.isEmptyObject(c.cache)) { return; }
var rowIndex, tbodyIndex, currentGroup, $rows, groupClass, grouping, time, cache, saveName, direction,
lang = wo.grouping_language,
group = '',
savedGroup = false,
column = c.sortList[0] ? c.sortList[0][0] : -1;
c.$table
.find('tr.group-hidden').removeClass('group-hidden').end()
.find('tr.group-header').remove();
if (wo.group_collapsible) {
// clear pager saved spacer height (in case the rows are collapsed)
c.$table.data('pagerSavedHeight', 0);
}
if (column >= 0 && !c.$headers.filter('[data-column="' + column + '"]:last').hasClass('group-false')) {
if (c.debug){ time = new Date(); }
wo.group_currentGroup = ''; // save current groups
wo.group_currentGroups = {};
// group class finds "group-{word/separator/letter/number/date/false}-{optional:#/year/month/day/week/time}"
groupClass = (c.$headers.filter('[data-column="' + column + '"]:last').attr('class') || '').match(/(group-\w+(-\w+)?)/g);
// grouping = [ 'group', '{word/separator/letter/number/date/false}', '{#/year/month/day/week/time}' ]
grouping = groupClass ? groupClass[0].split('-') : ['group','letter',1]; // default to letter 1
// save current grouping
if (wo.group_collapsible && wo.group_saveGroups && ts.storage) {
wo.group_currentGroups = ts.storage( table, 'tablesorter-groups' ) || {};
// include direction when grouping numbers > 1 (reversed direction shows different range values)
direction = (grouping[1] === 'number' && grouping[2] > 1) ? 'dir' + c.sortList[0][1] : '';
// combine column, sort direction & grouping as save key
saveName = wo.group_currentGroup = '' + column + direction + grouping.join('');
if (!wo.group_currentGroups[saveName]) {
wo.group_currentGroups[saveName] = [];
} else {
savedGroup = true;
}
}
for (tbodyIndex = 0; tbodyIndex < c.$tbodies.length; tbodyIndex++) {
cache = c.cache[tbodyIndex].normalized;
group = ''; // clear grouping across tbodies
$rows = c.$tbodies.eq(tbodyIndex).children('tr').not('.' + c.cssChildRow);
for (rowIndex = 0; rowIndex < $rows.length; rowIndex++) {
if ( $rows.eq(rowIndex).is(':visible') ) {
// fixes #438
if (ts.grouping.types[grouping[1]]) {
currentGroup = cache[rowIndex] ?
ts.grouping.types[grouping[1]]( c, c.$headers.filter('[data-column="' + column + '"]:last'), cache[rowIndex][column], /date/.test(groupClass) ?
grouping[2] : parseInt(grouping[2] || 1, 10) || 1, group, lang ) : currentGroup;
if (group !== currentGroup) {
group = currentGroup;
// show range if number > 1
if (grouping[1] === 'number' && grouping[2] > 1 && currentGroup !== '') {
currentGroup += ' - ' + (parseInt(currentGroup, 10) +
((parseInt(grouping[2],10) - 1) * (c.$headers.filter('[data-column="' + column + '"]:last').hasClass(ts.css.sortAsc) ? 1 : -1)));
}
if ($.isFunction(wo.group_formatter)) {
currentGroup = wo.group_formatter((currentGroup || '').toString(), column, table, c, wo) || currentGroup;
}
$rows.eq(rowIndex).before('<tr class="group-header ' + c.selectorRemove.slice(1) +
'" unselectable="on"><td colspan="' +
c.columns + '">' + (wo.group_collapsible ? '<i/>' : '') + '<span class="group-name">' +
currentGroup + '</span><span class="group-count"></span></td></tr>');
if (wo.group_saveGroups && !savedGroup && wo.group_collapsed && wo.group_collapsible) {
// all groups start collapsed
wo.group_currentGroups[wo.group_currentGroup].push(currentGroup);
}
}
}
}
}
}
c.$table.find('tr.group-header')
.bind('selectstart', false)
.each(function(){
var isHidden, $label, name,
$row = $(this),
$rows = $row.nextUntil('tr.group-header').filter(':visible');
if (wo.group_count || $.isFunction(wo.group_callback)) {
$label = $row.find('.group-count');
if ($label.length) {
if (wo.group_count) {
$label.html( wo.group_count.replace(/\{num\}/g, $rows.length) );
}
if ($.isFunction(wo.group_callback)) {
wo.group_callback($row.find('td'), $rows, column, table);
}
}
}
if (wo.group_saveGroups && wo.group_currentGroups[wo.group_currentGroup].length) {
name = $row.find('.group-name').text().toLowerCase();
isHidden = $.inArray( name, wo.group_currentGroups[wo.group_currentGroup] ) > -1;
$row.toggleClass('collapsed', isHidden);
$rows.toggleClass('group-hidden', isHidden);
} else if (wo.group_collapsed && wo.group_collapsible) {
$row.addClass('collapsed');
$rows.addClass('group-hidden');
}
});
c.$table.trigger(wo.group_complete);
if (c.debug) {
$.tablesorter.benchmark("Applying groups widget: ", time);
}
}
},
bindEvents : function(table, c, wo){
if (wo.group_collapsible) {
wo.group_currentGroups = [];
// .on() requires jQuery 1.7+
c.$table.on('click toggleGroup', 'tr.group-header', function(event){
event.stopPropagation();
var isCollapsed, $groups, indx,
$this = $(this),
name = $this.find('.group-name').text().toLowerCase();
// use shift-click to toggle ALL groups
if (event.type === 'click' && event.shiftKey) {
$this.siblings('.group-header').trigger('toggleGroup');
}
$this.toggleClass('collapsed');
// nextUntil requires jQuery 1.4+
$this.nextUntil('tr.group-header').toggleClass('group-hidden', $this.hasClass('collapsed') );
// save collapsed groups
if (wo.group_saveGroups && ts.storage) {
$groups = c.$table.find('.group-header');
isCollapsed = $this.hasClass('collapsed');
if (!wo.group_currentGroups[wo.group_currentGroup]) {
wo.group_currentGroups[wo.group_currentGroup] = [];
}
if (isCollapsed && wo.group_currentGroup) {
wo.group_currentGroups[wo.group_currentGroup].push( name );
} else if (wo.group_currentGroup) {
indx = $.inArray( name, wo.group_currentGroups[wo.group_currentGroup] );
if (indx > -1) {
wo.group_currentGroups[wo.group_currentGroup].splice( indx, 1 );
}
}
ts.storage( table, 'tablesorter-groups', wo.group_currentGroups );
}
});
}
$(wo.group_saveReset).on('click', function(){
ts.grouping.clearSavedGroups(table);
});
c.$table.on('pagerChange.tsgrouping', function(){
ts.grouping.update(table, c, wo);
});
},
clearSavedGroups: function(table){
if (table && ts.storage) {
ts.storage(table, 'tablesorter-groups', '');
ts.grouping.update(table, table.config, table.config.widgetOptions);
}
}
};
ts.addWidget({
id: 'group',
priority: 100,
options: {
group_collapsible : true, // make the group header clickable and collapse the rows below it.
group_collapsed : false, // start with all groups collapsed
group_saveGroups : true, // remember collapsed groups
group_saveReset : null, // element to clear saved collapsed groups
group_count : ' ({num})', // if not false, the "{num}" string is replaced with the number of rows in the group
group_separator : '-', // group name separator; used when group-separator-# class is used.
group_formatter : null, // function(txt, column, table, c, wo) { return txt; }
group_callback : null, // function($cell, $rows, column, table){}, callback allowing modification of the group header labels
group_complete : 'groupingComplete', // event triggered on the table when the grouping widget has finished work
// change these default date names based on your language preferences
group_months : [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ],
group_week : [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ],
group_time : [ 'AM', 'PM' ],
// this function is used when "group-date" is set to create the date string
// you can just return date, date.toLocaleString(), date.toLocaleDateString() or d.toLocaleTimeString()
// reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date#Conversion_getter
group_dateString : function(date) { return date.toLocaleString(); }
},
init: function(table, thisWidget, c, wo){
ts.grouping.bindEvents(table, c, wo);
},
format: function(table, c, wo) {
ts.grouping.update(table, c, wo);
},
remove : function(table, c, wo){
c.$table
.off('click', 'tr.group-header')
.off('pagerChange.tsgrouping')
.find('.group-hidden').removeClass('group-hidden').end()
.find('tr.group-header').remove();
}
});
})(jQuery);
@@ -0,0 +1,91 @@
/*! tablesorter headerTitles widget - updated 3/5/2014 (core v2.15.6)
* Requires tablesorter v2.8+ and jQuery 1.7+
* by Rob Garrison
*/
/*jshint browser:true, jquery:true, unused:false */
/*global jQuery: false */
;(function($){
"use strict";
var ts = $.tablesorter;
ts.addWidget({
id: 'headerTitles',
options: {
// use aria-label text
// e.g. "First Name: Ascending sort applied, activate to apply a descending sort"
headerTitle_useAria : false,
// add tooltip class
headerTitle_tooltip : '',
// custom titles [ ascending, descending, unsorted ]
headerTitle_cur_text : [ ' sort: A - Z', ' sort: Z - A', 'ly unsorted' ],
headerTitle_cur_numeric : [ ' sort: 0 - 9', ' sort: 9 - 0', 'ly unsorted' ],
headerTitle_nxt_text : [ ' sort: A - Z', ' sort: Z - A', 'remove sort' ],
headerTitle_nxt_numeric : [ ' sort: 0 - 9', ' sort: 9 - 0', 'remove sort' ],
// title display; {prefix} adds above prefix
// {type} adds the current sort order from above (text or numeric)
// {next} adds the next sort direction using the sort order above
headerTitle_output_sorted : 'current{current}; activate to {next}',
headerTitle_output_unsorted : 'current{current}; activate to {next} ',
headerTitle_output_nosort : 'No sort available',
// use this type to override the parser detection result
// e.g. use for numerically parsed columns (e.g. dates), but you
// want the user to see a text sort, e.g. [ 'text', 'numeric' ]
headerTitle_type : [],
// manipulate the title as desired
headerTitle_callback : null // function($cell, txt) { return txt; }
},
init: function(table, thisWidget, c, wo){
// force refresh
c.$table.on('refreshHeaderTitle', function(){
thisWidget.format(table, c, wo);
});
// add tooltip class
if ($.isArray(wo.headerTitle_tooltip)) {
c.$headers.each(function(){
$(this).addClass( wo.headerTitle_tooltip[this.column] || '' );
});
} else if (wo.headerTitle_tooltip !== '') {
c.$headers.addClass( wo.headerTitle_tooltip );
}
},
format: function (table, c, wo) {
var txt;
c.$headers.each(function(){
var t = this,
$this = $(this),
sortType = wo.headerTitle_type[t.column] || c.parsers[ t.column ].type || 'text',
sortDirection = $this.hasClass(ts.css.sortAsc) ? 0 : $this.hasClass(ts.css.sortDesc) ? 1 : 2,
sortNext = t.order[(t.count + 1) % (c.sortReset ? 3 : 2)];
if (wo.headerTitle_useAria) {
txt = $this.hasClass('sorter-false') ? wo.headerTitle_output_nosort : $this.attr('aria-label') || '';
} else {
txt = (wo.headerTitle_prefix || '') + // now deprecated
($this.hasClass('sorter-false') ? wo.headerTitle_output_nosort :
ts.isValueInArray( t.column, c.sortList ) >= 0 ? wo.headerTitle_output_sorted : wo.headerTitle_output_unsorted);
txt = txt.replace(/\{(current|next|name)\}/gi, function(m){
return {
'{name}' : $this.text(),
'{current}' : wo[ 'headerTitle_cur_' + sortType ][ sortDirection ] || '',
'{next}' : wo[ 'headerTitle_nxt_' + sortType ][ sortNext ] || ''
}[m.toLowerCase()];
});
}
$this.attr('title', $.isFunction(wo.headerTitle_callback) ? wo.headerTitle_callback($this, txt) : txt);
});
},
remove: function (table, c, wo) {
c.$headers.attr('title', '');
c.$table.off('refreshHeaderTitle');
// remove tooltip class
if ($.isArray(wo.headerTitle_tooltip)) {
c.$headers.each(function(){
$(this).removeClass( wo.headerTitle_tooltip[this.column] || '' );
});
} else if (wo.headerTitle_tooltip !== '') {
c.$headers.removeClass( wo.headerTitle_tooltip );
}
}
});
})(jQuery);
@@ -0,0 +1,413 @@
/*! tablesorter math widget - beta - updated 5/28/2014 (v2.17.1)
* Requires tablesorter v2.16+ and jQuery 1.7+
* by Rob Garrison
*/
/*jshint browser:true, jquery:true, unused:false */
/*global jQuery: false */
;(function($){
"use strict";
var ts = $.tablesorter,
math = {
// get all of the row numerical values in an arry
getRow : function(table, wo, $el, dataAttrib) {
var $t, txt,
c = table.config,
arry = [],
$row = $el.closest('tr'),
$cells = $row.children();
if (!$row.hasClass(wo.filter_filteredRow || 'filtered')) {
if (wo.math_ignore.length) {
$cells = $cells.not('[' + dataAttrib + '=ignore]').not('[data-column=' + wo.math_ignore.join('],[data-column=') + ']');
}
arry = $cells.not($el).map(function(){
$t = $(this);
txt = $t.attr(c.textAttribute);
if (typeof txt === "undefined") {
txt = this.textContent || $t.text();
}
txt = ts.formatFloat(txt.replace(/[^\w,. \-()]/g, ""), table);
return isNaN(txt) ? 0 : txt;
}).get();
}
return arry;
},
// get all of the column numerical values in an arry
getColumn : function(table, wo, $el, type, dataAttrib){
var i, txt, $t, len, mathAbove,
arry = [],
c = table.config,
filtered = wo.filter_filteredRow || 'filtered',
cIndex = parseInt( $el.attr('data-column'), 10 ),
$rows = c.$table.children('tbody').children(),
$row = $el.closest('tr');
// make sure tfoot rows are AFTER the tbody rows
// $rows.add( c.$table.children('tfoot').children() );
if (type === 'above') {
len = $rows.index($row);
i = len;
while (i >= 0) {
$t = $rows.eq(i).children().filter('[data-column=' + cIndex + ']');
mathAbove = $t.filter('[' + dataAttrib + '^=above]').length;
// ignore filtered rows & rows with data-math="ignore" (and starting row)
if ( ( !$rows.eq(i).hasClass(filtered) && $rows.eq(i).not('[' + dataAttrib + '=ignore]').length && i !== len ) || mathAbove && i !== len ) {
// stop calculating "above", when encountering another "above"
if (mathAbove) {
i = 0;
} else if ($t.length) {
txt = $t.attr(c.textAttribute);
if (typeof txt === "undefined") {
txt = $t[0].textContent || $t.text();
}
txt = ts.formatFloat(txt.replace(/[^\w,. \-()]/g, ""), table);
arry.push(isNaN(txt) ? 0 : txt);
}
}
i--;
}
} else {
$rows.each(function(){
$t = $(this).children().filter('[data-column=' + cIndex + ']');
if (!$(this).hasClass(filtered) && $t.not('[' + dataAttrib + '^=above],[' + dataAttrib + '^=col]').length && !$t.is($el)) {
txt = $t.attr(c.textAttribute);
if (typeof txt === "undefined") {
txt = ($t[0] ? $t[0].textContent : '') || $t.text();
}
txt = ts.formatFloat(txt.replace(/[^\w,. \-()]/g, ""), table);
arry.push(isNaN(txt) ? 0 : txt);
}
});
}
return arry;
},
// get all of the column numerical values in an arry
getAll : function(table, wo, dataAttrib){
var txt, $t, col,
arry = [],
c = table.config,
filtered = wo.filter_filteredRow || 'filtered',
$rows = c.$table.children('tbody').children();
$rows.each(function(){
if (!$(this).hasClass(filtered)) {
$(this).children().each(function(){
$t = $(this);
col = parseInt( $t.attr('data-column'), 10);
if (!$t.filter('[' + dataAttrib + ']').length && $.inArray(col, wo.math_ignore) < 0) {
txt = $t.attr(c.textAttribute);
if (typeof txt === "undefined") {
txt = ($t[0] ? $t[0].textContent : '') || $t.text();
}
txt = ts.formatFloat(txt.replace(/[^\w,. \-()]/g, ""), table);
arry.push(isNaN(txt) ? 0 : txt);
}
});
}
});
return arry;
},
recalculate : function(table, c, wo, init){
if (c && (!wo.math_isUpdating || init)) {
// add data-column attributes to all table cells
if (init) {
ts.computeColumnIndex( c.$table.children('tbody').children() );
}
// data-attribute name (defaults to data-math)
var dataAttrib = 'data-' + (wo.math_data || 'math'),
// all non-info tbody cells
$mathCells = c.$tbodies.find('[' + dataAttrib + ']');
math.mathType( table, wo, $mathCells, wo.math_priority, dataAttrib );
// only info tbody cells
$mathCells = c.$table.find('.' + c.cssInfoBlock + ', tfoot').find('[' + dataAttrib + ']');
math.mathType( table, wo, $mathCells, wo.math_priority, dataAttrib );
// find the "all" total
math.mathType( table, wo, c.$table.find('[' + dataAttrib + '^=all]'), ['all'], dataAttrib );
wo.math_isUpdating = true;
c.$table.trigger('update');
}
},
mathType : function(table, wo, $cells, priority, dataAttrib) {
if ($cells.length) {
var formula, t, $t, arry, getAll,
eq = ts.equations;
if (priority[0] === 'all') {
// no need to get all cells more than once
getAll = math.getAll(table, wo, dataAttrib);
}
$.each( priority, function(i, type) {
$cells.filter('[' + dataAttrib + '^=' + type + ']').each(function(){
$t = $(this);
formula = ($t.attr(dataAttrib) || '').replace(type + '-', '');
arry = (type === "row") ? math.getRow(table, wo, $t, dataAttrib) :
(type === "all") ? getAll : math.getColumn(table, wo, $t, type, dataAttrib);
if (eq[formula]) {
t = eq[formula](arry);
if (table.config.debug && console && console.log) {
console.log($t.attr(dataAttrib), arry, '=', t);
}
math.output( $t, wo, t, arry );
}
});
});
}
},
output : function($cell, wo, value, arry) {
// get mask from cell data-attribute: data-math-mask="#,##0.00"
var result = ts.formatMask( $cell.attr('data-' + wo.math_data + '-mask') || wo.math_mask, value, wo.math_wrapPrefix, wo.math_wrapSuffix );
if ($.isFunction(wo.math_complete)) {
result = wo.math_complete($cell, wo, result, value, arry);
}
if (result !== false) {
$cell.html(result);
}
}
};
// Modified from https://code.google.com/p/javascript-number-formatter/
/**
* @preserve IntegraXor Web SCADA - JavaScript Number Formatter
* http:// www.integraxor.com/
* author: KPL, KHL
* (c)2011 ecava
* Dual licensed under the MIT or GPL Version 2 licenses.
*/
ts.formatMask = function(m, v, tmpPrefix, tmpSuffix){
if ( !m || isNaN(+v) ) {
return v; // return as it is.
}
var isNegative, result, decimal, group, posLeadZero, posTrailZero, posSeparator, part, szSep,
integer, str, offset, i, l, len, start, tmp, end, inv,
prefix = '',
suffix = '';
// find prefix/suffix
len = m.length;
start = m.search( /[0-9\-\+#]/ );
tmp = start > 0 ? m.substring(0, start) : '';
prefix = tmp;
if ( start > 0 && tmpPrefix ) {
if ( /\{content\}/.test(tmpPrefix || '') ) {
prefix = (tmpPrefix || '').replace(/\{content\}/g, tmp || '');
} else {
prefix = (tmpPrefix || '') + tmp;
}
}
// reverse string: not an ideal method if there are surrogate pairs
inv = m.split('').reverse().join('');
end = inv.search( /[0-9\-\+#]/ );
i = len - end;
i += (m.substring( i, i + 1 ) === '.') ? 1 : 0;
tmp = end > 0 ? m.substring( i, len) : '';
suffix = tmp;
if (tmp !== '' && tmpSuffix) {
if ( /\{content\}/.test(tmpSuffix || '') ) {
suffix = (tmpSuffix || '').replace(/\{content\}/g, tmp || '');
} else {
suffix = tmp + (tmpSuffix || '');
}
}
m = m.substring(start, i);
// convert any string to number according to formation sign.
v = m.charAt(0) == '-' ? -v : +v;
isNegative = v < 0 ? v = -v : 0; // process only abs(), and turn on flag.
// search for separator for grp & decimal, anything not digit, not +/- sign, not #.
result = m.match( /[^\d\-\+#]/g );
decimal = ( result && result[result.length-1] ) || '.'; // treat the right most symbol as decimal
group = ( result && result[1] && result[0] ) || ','; // treat the left most symbol as group separator
// split the decimal for the format string if any.
m = m.split( decimal );
// Fix the decimal first, toFixed will auto fill trailing zero.
v = v.toFixed( m[1] && m[1].length );
v = +(v) + ''; // convert number to string to trim off *all* trailing decimal zero(es)
// fill back any trailing zero according to format
posTrailZero = m[1] && m[1].lastIndexOf('0'); // look for last zero in format
part = v.split('.');
// integer will get !part[1]
if ( !part[1] || ( part[1] && part[1].length <= posTrailZero ) ) {
v = (+v).toFixed( posTrailZero + 1 );
}
szSep = m[0].split( group ); // look for separator
m[0] = szSep.join(''); // join back without separator for counting the pos of any leading 0.
posLeadZero = m[0] && m[0].indexOf('0');
if ( posLeadZero > -1 ) {
while ( part[0].length < ( m[0].length - posLeadZero ) ) {
part[0] = '0' + part[0];
}
} else if ( +part[0] === 0 ) {
part[0] = '';
}
v = v.split('.');
v[0] = part[0];
// process the first group separator from decimal (.) only, the rest ignore.
// get the length of the last slice of split result.
posSeparator = ( szSep[1] && szSep[ szSep.length - 1 ].length );
if ( posSeparator ) {
integer = v[0];
str = '';
offset = integer.length % posSeparator;
l = integer.length;
for ( i = 0; i < l; i++ ) {
str += integer.charAt(i); // ie6 only support charAt for sz.
// -posSeparator so that won't trail separator on full length
/*jshint -W018 */
if ( !( ( i - offset + 1 ) % posSeparator ) && i < l - posSeparator ) {
str += group;
}
}
v[0] = str;
}
v[1] = ( m[1] && v[1] ) ? decimal + v[1] : "";
// put back any negation, combine integer and fraction, and add back prefix & suffix
return prefix + ( ( isNegative ? '-' : '' ) + v[0] + v[1] ) + suffix;
};
ts.equations = {
count : function(arry) {
return arry.length;
},
sum : function(arry) {
var total = 0;
$.each( arry, function(i) {
total += arry[i];
});
return total;
},
mean : function(arry) {
var total = ts.equations.sum( arry );
return total / arry.length;
},
median : function(arry) {
// https://gist.github.com/caseyjustus/1166258
arry.sort( function(a,b){ return a - b; } );
var half = Math.floor( arry.length / 2 );
return (arry.length % 2) ? arry[half] : ( arry[half - 1] + arry[half] ) / 2.0;
},
mode : function(arry) {
// http://stackoverflow.com/a/3451640/145346
if ( arry.length === 0 ) { return 'none'; }
var i, el,
modeMap = {},
maxCount = 1,
modes = [arry[0]];
for (i = 0; i < arry.length; i++) {
el = arry[i];
modeMap[el] = modeMap[el] ? modeMap[el] + 1 : 1;
if ( modeMap[el] > maxCount ) {
modes = [el];
maxCount = modeMap[el];
} else if (modeMap[el] === maxCount) {
modes.push(el);
maxCount = modeMap[el];
}
}
// returns arry of modes if there is a tie
return modes.sort( function(a,b){ return a - b; } );
},
max : function(arry) {
return Math.max.apply( Math, arry );
},
min : function(arry) {
return Math.min.apply( Math, arry );
},
range: function(arry) {
var v = arry.sort(function(a,b){ return a - b; });
return v[ arry.length - 1 ] - v[0];
},
// common variance equation
// (not accessible via data-attribute setting)
variance: function(arry, population) {
var avg = ts.equations.mean( arry ),
v = 0,
i = arry.length;
while (i--) {
v += Math.pow( ( arry[i] - avg ), 2 );
}
v /= ( arry.length - (population ? 0 : 1) );
return v;
},
// variance (population)
varp : function(arry) {
return ts.equations.variance(arry, true);
},
// variance (sample)
vars : function(arry) {
return ts.equations.variance(arry);
},
// standard deviation (sample)
stdevs : function(arry) {
var vars = ts.equations.variance(arry);
return Math.sqrt( vars );
},
// standard deviation (population)
stdevp : function(arry){
var varp = ts.equations.variance(arry, true);
return Math.sqrt( varp );
}
};
// add new widget called repeatHeaders
// ************************************
ts.addWidget({
id: "math",
priority: 100,
options: {
math_data : 'math',
// column index to ignore
math_ignore : [],
// mask info: https://code.google.com/p/javascript-number-formatter/
math_mask : '#,##0.00',
// complete executed after each fucntion
math_complete : null, // function($cell, wo, result, value, arry){ return result; },
// order of calculation; "all" is last
math_priority : [ 'row', 'above', 'col' ],
// template for or just prepend the mask prefix & suffix with this HTML
// e.g. '<span class="red">{content}</span>'
math_prefix : '',
math_suffix : ''
},
init : function(table, thisWidget, c, wo){
c.$table
.bind('tablesorter-initialized update updateRows addRows updateCell filterReset filterEnd '.split(' ').join('.tsmath '), function(e){
var init = e.type === 'tablesorter-initialized';
if (!wo.math_isUpdating || init) {
math.recalculate( table, c, wo, init );
}
})
.bind('updateComplete.tsmath', function(){
setTimeout(function(){
wo.math_isUpdating = false;
}, 500);
});
wo.math_isUpdating = false;
},
// this remove function is called when using the refreshWidgets method or when destroying the tablesorter plugin
// this function only applies to tablesorter v2.4+
remove: function(table, c, wo){
$(table)
.unbind('tablesorter-initialized update updateRows addRows updateCell filterReset filterEnd '.split(' ').join('.tsmath '))
.find('[data-' + wo.math_data + ']').empty();
}
});
})(jQuery);
@@ -0,0 +1,316 @@
/* Output widget (beta) for TableSorter 7/17/2014 (v2.17.5)
* Requires tablesorter v2.8+ and jQuery 1.7+
* Modified from:
* HTML Table to CSV: http://www.kunalbabre.com/projects/table2CSV.php (License unknown?)
* Download-File-JS: https://github.com/PixelsCommander/Download-File-JS (http://www.apache.org/licenses/LICENSE-2.0)
*/
/*jshint browser:true, jquery:true, unused:false */
/*global jQuery: false */
;(function($){
"use strict";
var ts = $.tablesorter,
output = ts.output = {
event : 'outputTable',
// wrap line breaks & tabs in quotes
regexQuote : /([\n\t]|<[^<]+>)/, // test
regexBR : /(<br([\s\/])?>|\n)/g, // replace
regexIMG : /<img[^>]+alt\s*=\s*['"]([^'"]+)['"][^>]*>/i, // match
regexHTML : /<[^<]+>/g, // replace
replaceCR : '\\n',
replaceTab : '\\t',
popupTitle : 'Output',
popupStyle : 'width:100%;height:100%;', // for textarea
message : 'Your device does not support downloading. Please try again in desktop browser.',
init : function(c) {
c.$table
.off(output.event)
.on(output.event, function(){
// explicitly use table.config.widgetOptions because we want
// the most up-to-date values; not the "wo" from initialization
output.process(c, c.widgetOptions);
});
},
processRow: function(c, $rows, isHeader, isJSON) {
var $this, row, col, rowlen, collen, txt,
wo = c.widgetOptions,
tmpRow = [],
dupe = wo.output_duplicateSpans,
addSpanIndex = isHeader && isJSON && wo.output_headerRows && $.isFunction(wo.output_callbackJSON),
cellIndex = 0;
$rows.each(function(rowIndex) {
if (!tmpRow[rowIndex]) { tmpRow[rowIndex] = []; }
cellIndex = 0;
$(this).children().each(function(){
$this = $(this);
// process rowspans
if ($this.filter('[rowspan]').length) {
rowlen = parseInt( $this.attr('rowspan'), 10) - 1;
txt = output.formatData( wo, $this.attr(wo.output_dataAttrib) || $this.html(), isHeader );
for (row = 1; row <= rowlen; row++) {
if (!tmpRow[rowIndex + row]) { tmpRow[rowIndex + row] = []; }
tmpRow[rowIndex + row][cellIndex] = isHeader ? txt : dupe ? txt : '';
}
}
// process colspans
if ($this.filter('[colspan]').length) {
collen = parseInt( $this.attr('colspan'), 10) - 1;
txt = output.formatData( wo, $this.attr(wo.output_dataAttrib) || $this.html(), isHeader );
for (col = 1; col <= collen; col++) {
// if we're processing the header & making JSON, the header names need to be unique
if ($this.filter('[rowspan]').length) {
rowlen = parseInt( $this.attr('rowspan'), 10);
for (row = 0; row < rowlen; row++) {
if (!tmpRow[rowIndex + row]) { tmpRow[rowIndex + row] = []; }
tmpRow[rowIndex + row][cellIndex + col] = addSpanIndex ?
wo.output_callbackJSON($this, txt, cellIndex + col) || txt + '(' + (cellIndex + col) + ')' : isHeader ? txt : dupe ? txt : '';
}
} else {
tmpRow[rowIndex][cellIndex + col] = addSpanIndex ?
wo.output_callbackJSON($this, txt, cellIndex + col) || txt + '(' + (cellIndex + col) + ')' : isHeader ? txt : dupe ? txt : '';
}
}
}
// don't include hidden columns
if ( $this.css('display') !== 'none' ) {
// skip column if already defined
while (typeof tmpRow[rowIndex][cellIndex] !== 'undefined') { cellIndex++; }
tmpRow[rowIndex][cellIndex] = tmpRow[rowIndex][cellIndex] ||
output.formatData( wo, $this.attr(wo.output_dataAttrib) || $this.html(), isHeader );
cellIndex++;
}
});
});
return tmpRow;
},
ignoreColumns : function(wo, data) {
// ignore columns -> remove data from built array (because we've already processed any rowspan/colspan)
$.each( data, function(indx, val){
data[indx] = $.grep(val, function(v, cellIndx){
return $.inArray(cellIndx, wo.output_ignoreColumns) < 0;
});
});
return data;
},
process : function(c, wo) {
var mydata, $this, $rows, headers, csvData, len,
hasStringify = window.JSON && JSON.hasOwnProperty('stringify'),
indx = 0,
tmpData = (wo.output_separator || ',').toLowerCase(),
outputJSON = tmpData === 'json',
outputArray = tmpData === 'array',
separator = outputJSON || outputArray ? ',' : wo.output_separator,
$el = c.$table;
// regex to look for the set separator or HTML
wo.output_regex = new RegExp('(' + (/\\/.test(separator) ? '\\' : '' ) + separator + ')' );
// get header cells
$this = $el.find('thead tr:visible').not('.' + (ts.css.filterRow || 'tablesorter-filter-row') );
headers = output.processRow(c, $this, true, outputJSON);
// all tbody rows
$rows = $el.children('tbody').children('tr');
// get (f)iltered, (v)isible or all rows (look for the first letter only)
$rows = /f/.test(wo.output_saveRows) ? $rows.not('.' + (wo.filter_filteredRow || 'filtered') ) :
/v/.test(wo.output_saveRows) ? $rows.filter(':visible') : $rows;
// process to array of arrays
csvData = output.processRow(c, $rows);
len = headers.length;
if (wo.output_ignoreColumns.length) {
headers = output.ignoreColumns(wo, headers);
csvData = output.ignoreColumns(wo, csvData);
}
if (outputJSON) {
tmpData = [];
$.each( csvData, function(indx, val){
// multiple header rows & output_headerRows = true, pick the last row...
tmpData.push( output.row2Hash( headers[ (len > 1 && wo.output_headerRows) ? indx % len : len - 1], val ) );
});
// requires JSON stringify; if it doesn't exist, the output will show [object Object],... in the output window
mydata = hasStringify ? JSON.stringify(tmpData) : tmpData;
} else {
tmpData = output.row2CSV(wo, wo.output_headerRows ? headers : [ headers[ (len > 1 && wo.output_headerRows) ? indx % len : len - 1] ], outputArray)
.concat( output.row2CSV(wo, csvData, outputArray) );
// stringify the array; if stringify doesn't exist the array will be flattened
mydata = outputArray && hasStringify ? JSON.stringify(tmpData) : tmpData.join('\n');
}
// callback; if true returned, continue processing
if ($.isFunction(wo.output_callback) && !wo.output_callback(c, mydata)) { return; }
if ( /p/.test( (wo.output_delivery || '').toLowerCase() ) ) {
output.popup(mydata, wo.output_popupStyle, outputJSON || outputArray);
} else {
output.download(wo, mydata);
}
}, // end process
row2CSV : function(wo, tmpRow, outputArray) {
var tmp, rowIndex,
csvData = [],
rowLen = tmpRow.length;
for (rowIndex = 0; rowIndex < rowLen; rowIndex++) {
// remove any blank rows
tmp = tmpRow[rowIndex].join('').replace(/\"/g,'');
if (tmpRow[rowIndex].length > 0 && tmp !== '') {
csvData[csvData.length] = outputArray ? tmpRow[rowIndex] : tmpRow[rowIndex].join(wo.output_separator);
}
}
return csvData;
},
row2Hash : function(keys, values) {
var json = {};
$.each(values, function(indx, val) {
if ( indx < keys.length ) {
json[ keys[indx] ] = val;
}
});
return json;
},
formatData : function(wo, input, isHeader) {
var txt,
quotes = (wo.output_separator || ',').toLowerCase(),
separator = quotes === 'json' || quotes === 'array',
// replace " with “ if undefined
result = input.replace(/\"/g, wo.output_replaceQuote || '\u201c');
// replace line breaks with \\n & tabs with \\t
result = result.replace(output.regexBR, output.replaceCR).replace(/\t/g, output.replaceTab);
// extract img alt text
txt = result.match(output.regexIMG);
if (!wo.output_includeHTML && txt !== null) {
result = txt[1];
}
// replace/remove html
result = wo.output_includeHTML && !isHeader ? result : result.replace(output.regexHTML, '');
result = wo.output_trimSpaces || isHeader ? $.trim(result) : result;
// JSON & array outputs don't need quotes
quotes = separator ? false : wo.output_wrapQuotes || wo.output_regex.test(result) || output.regexQuote.test(result);
return quotes ? '"' + result + '"' : result;
},
popup : function(data, style, wrap) {
var generator = window.open('', output.popupTitle, style);
generator.document.write(
'<html><head><title>' + output.popupTitle + '</title></head><body>' +
'<textarea wrap="' + (wrap ? 'on' : 'off') + '" style="' + output.popupStyle + '">' + data + '\n</textarea>' +
'</body></html>'
);
generator.document.close();
generator.focus();
// select all text and focus within the textarea in the popup
// $(generator.document).find('textarea').select().focus();
return true;
},
// modified from https://github.com/PixelsCommander/Download-File-JS
// & http://html5-demos.appspot.com/static/a.download.html
download : function (wo, data){
var e, blob, gotBlob,
nav = window.navigator,
link = document.createElement('a');
// iOS devices do not support downloading. We have to inform user about this.
if (/(iP)/g.test(nav.userAgent)) {
alert(output.message);
return false;
}
// test for blob support
try {
gotBlob = !!new Blob();
} catch (err) {
gotBlob = false;
}
// Use HTML5 Blob if browser supports it
if ( gotBlob ) {
window.URL = window.webkitURL || window.URL;
blob = new Blob([data], {type: wo.output_encoding});
if (nav.msSaveBlob) {
// IE 10+
nav.msSaveBlob(blob, wo.output_saveFileName);
} else {
// all other browsers
link.href = window.URL.createObjectURL(blob);
link.download = wo.output_saveFileName;
// Dispatching click event; using $(link).trigger() won't work
if (document.createEvent) {
e = document.createEvent('MouseEvents');
// event.initMouseEvent(type, canBubble, cancelable, view, detail, screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget);
e.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
link.dispatchEvent(e);
}
}
return false;
}
// fallback to force file download (whether supported by server).
// not sure if this actually works in IE9 and older...
window.open( wo.output_encoding + encodeURIComponent(data) + '?download' , '_self');
return true;
},
remove : function(c) {
c.$table.off(output.event);
}
};
ts.addWidget({
id: "output",
options: {
output_separator : ',', // set to "json", "array" or any separator
output_ignoreColumns : [], // columns to ignore [0, 1,... ] (zero-based index)
output_dataAttrib : 'data-name', // header attrib containing modified header name
output_headerRows : false, // if true, include multiple header rows (JSON only)
output_delivery : 'popup', // popup, download
output_saveRows : 'filtered', // all, visible or filtered
output_duplicateSpans: true, // duplicate output data in tbody colspan/rowspan
output_replaceQuote : '\u201c;', // left double quote
output_includeHTML : false,
output_trimSpaces : true,
output_wrapQuotes : false,
output_popupStyle : 'width=500,height=300',
output_saveFileName : 'mytable.csv',
// callback executed when processing completes
// return true to continue download/output
// return false to stop delivery & do something else with the data
output_callback : function(config, data){ return true; },
// JSON callback executed when a colspan is encountered in the header
output_callbackJSON : function($cell, txt, cellIndex) { return txt + '(' + (cellIndex) + ')'; },
// the need to modify this for Excel no longer exists
output_encoding : 'data:application/octet-stream;charset=utf8,'
},
init: function(table, thisWidget, c) {
output.init(c);
},
remove: function(table, c){
output.remove(c);
}
});
})(jQuery);
@@ -0,0 +1,964 @@
/* Pager widget for TableSorter 8/1/2014 (v2.17.6) */
/*jshint browser:true, jquery:true, unused:false */
;(function($){
"use strict";
var tsp,
ts = $.tablesorter;
ts.addWidget({
id: "pager",
priority: 55, // load pager after filter widget
options : {
// output default: '{page}/{totalPages}'
// possible variables: {page}, {totalPages}, {filteredPages}, {startRow}, {endRow}, {filteredRows} and {totalRows}
pager_output: '{startRow} to {endRow} of {totalRows} rows', // '{page}/{totalPages}'
// apply disabled classname to the pager arrows when the rows at either extreme is visible
pager_updateArrows: true,
// starting page of the pager (zero based index)
pager_startPage: 0,
// reset pager after filtering; set to desired page #
// set to false to not change page at filter start
pager_pageReset: 0,
// Number of visible rows
pager_size: 10,
// Save pager page & size if the storage script is loaded (requires $.tablesorter.storage in jquery.tablesorter.widgets.js)
pager_savePages: true,
//defines custom storage key
pager_storageKey: 'tablesorter-pager',
// if true, the table will remain the same height no matter how many records are displayed. The space is made up by an empty
// table row set to a height to compensate; default is false
pager_fixedHeight: false,
// count child rows towards the set page size? (set true if it is a visible table row within the pager)
// if true, child row(s) may not appear to be attached to its parent row, may be split across pages or
// may distort the table if rowspan or cellspans are included.
pager_countChildRows: false,
// remove rows from the table to speed up the sort of large tables.
// setting this to false, only hides the non-visible rows; needed if you plan to add/remove rows with the pager enabled.
pager_removeRows: false, // removing rows in larger tables speeds up the sort
// use this format: "http://mydatabase.com?page={page}&size={size}&{sortList:col}&{filterList:fcol}"
// where {page} is replaced by the page number, {size} is replaced by the number of records to show,
// {sortList:col} adds the sortList to the url into a "col" array, and {filterList:fcol} adds
// the filterList to the url into an "fcol" array.
// So a sortList = [[2,0],[3,0]] becomes "&col[2]=0&col[3]=0" in the url
// and a filterList = [[2,Blue],[3,13]] becomes "&fcol[2]=Blue&fcol[3]=13" in the url
pager_ajaxUrl: null,
// modify the url after all processing has been applied
pager_customAjaxUrl: function(table, url) { return url; },
// modify the $.ajax object to allow complete control over your ajax requests
pager_ajaxObject: {
dataType: 'json'
},
// set this to false if you want to block ajax loading on init
pager_processAjaxOnInit: true,
// process ajax so that the following information is returned:
// [ total_rows (number), rows (array of arrays), headers (array; optional) ]
// example:
// [
// 100, // total rows
// [
// [ "row1cell1", "row1cell2", ... "row1cellN" ],
// [ "row2cell1", "row2cell2", ... "row2cellN" ],
// ...
// [ "rowNcell1", "rowNcell2", ... "rowNcellN" ]
// ],
// [ "header1", "header2", ... "headerN" ] // optional
// ]
pager_ajaxProcessing: function(ajax){ return [ 0, [], null ]; },
// css class names of pager arrows
pager_css: {
container : 'tablesorter-pager',
errorRow : 'tablesorter-errorRow', // error information row (don't include period at beginning)
disabled : 'disabled' // class added to arrows @ extremes (i.e. prev/first arrows "disabled" on first page)
},
// jQuery selectors
pager_selectors: {
container : '.pager', // target the pager markup
first : '.first', // go to first page arrow
prev : '.prev', // previous page arrow
next : '.next', // next page arrow
last : '.last', // go to last page arrow
gotoPage : '.gotoPage', // go to page selector - select dropdown that sets the current page
pageDisplay : '.pagedisplay', // location of where the "output" is displayed
pageSize : '.pagesize' // page size selector - select dropdown that sets the "size" option
}
},
init: function(table){
tsp.init(table);
},
// only update to complete sorter initialization
format: function(table, c){
if (!(c.pager && c.pager.initialized)){
return tsp.initComplete(table, c);
}
tsp.moveToPage(table, c.pager, false);
},
remove: function(table, c){
tsp.destroyPager(table, c);
}
});
/* pager widget functions */
tsp = ts.pager = {
init: function(table) {
// check if tablesorter has initialized
if (table.hasInitialized && table.config.pager.initialized) { return; }
var t,
c = table.config,
wo = c.widgetOptions,
s = wo.pager_selectors,
// save pager variables
p = c.pager = $.extend({
totalPages: 0,
filteredRows: 0,
filteredPages: 0,
currentFilters: [],
page: wo.pager_startPage,
startRow: 0,
endRow: 0,
ajaxCounter: 0,
$size: null,
last: {}
}, c.pager);
// pager initializes multiple times before table has completed initialization
if (p.isInitializing) { return; }
p.isInitializing = true;
if (c.debug) {
ts.log('Pager initializing');
}
p.size = $.data(table, 'pagerLastSize') || wo.pager_size;
// added in case the pager is reinitialized after being destroyed.
p.$container = $(s.container).addClass(wo.pager_css.container).show();
// goto selector
p.$goto = p.$container.find(s.gotoPage); // goto is a reserved word #657
// page size selector
p.$size = p.$container.find(s.pageSize);
p.totalRows = c.$tbodies.eq(0).children('tr').not( c.widgetOptions.pager_countChildRows ? '' : '.' + c.cssChildRow ).length;
p.oldAjaxSuccess = p.oldAjaxSuccess || wo.pager_ajaxObject.success;
c.appender = tsp.appender;
if (ts.filter && $.inArray('filter', c.widgets) >= 0) {
// get any default filter settings (data-value attribute) fixes #388
p.currentFilters = c.$table.data('lastSearch') || ts.filter.setDefaults(table, c, wo) || [];
// set, but don't apply current filters
ts.setFilters(table, p.currentFilters, false);
}
if (wo.pager_savePages && ts.storage) {
t = ts.storage(table, wo.pager_storageKey) || {}; // fixes #387
p.page = isNaN(t.page) ? p.page : t.page;
p.size = ( isNaN(t.size) ? p.size : t.size ) || 10;
$.data(table, 'pagerLastSize', p.size);
}
// skipped rows
p.regexRows = new RegExp('(' + (wo.filter_filteredRow || 'filtered') + '|' + c.selectorRemove.replace(/^(\w+\.)/g,'') + '|' + c.cssChildRow + ')');
// clear initialized flag
p.initialized = false;
// before initialization event
c.$table.trigger('pagerBeforeInitialized', c);
tsp.enablePager(table, c, false);
if ( typeof(wo.pager_ajaxUrl) === 'string' ) {
// ajax pager; interact with database
p.ajax = true;
// When filtering with ajax, allow only custom filtering function, disable default filtering since it will be done server side.
wo.filter_serversideFiltering = true;
c.serverSideSorting = true;
tsp.moveToPage(table, p);
} else {
p.ajax = false;
// Regular pager; all rows stored in memory
c.$table.trigger("appendCache", [{}, true]);
tsp.hideRowsSetup(table, c);
}
},
initComplete: function(table, c){
var p = c.pager;
tsp.changeHeight(table, c);
tsp.bindEvents(table, c);
tsp.setPageSize(table, 0, c); // page size 0 is ignored
// pager initialized
p.initialized = true;
p.isInitializing = false;
c.$table.trigger('pagerInitialized', c);
tsp.updatePageDisplay(table, c);
},
bindEvents: function(table, c){
var ctrls, fxn,
p = c.pager,
wo = c.widgetOptions,
s = wo.pager_selectors;
c.$table
.unbind('filterStart filterEnd sortEnd disable enable destroy update updateRows updateAll addRows pageSize '.split(' ').join('.pager '))
.bind('filterStart.pager', function(e, filters) {
p.currentFilters = filters;
// don't change page is filters are the same (pager updating, etc)
if (wo.pager_pageReset !== false && (c.lastCombinedFilter || '') !== (filters || []).join('')) {
p.page = wo.pager_pageReset; // fixes #456 & #565
}
})
// update pager after filter widget completes
.bind('filterEnd.pager sortEnd.pager', function() {
if (p.initialized) {
if (c.delayInit && c.rowsCopy && c.rowsCopy.length === 0) {
// make sure we have a copy of all table rows once the cache has been built
tsp.updateCache(table);
}
// update page display first, so we update p.filteredPages
tsp.updatePageDisplay(table, c, false);
tsp.moveToPage(table, p, false);
tsp.fixHeight(table, c);
}
})
.bind('disable.pager', function(e){
e.stopPropagation();
tsp.showAllRows(table, c);
})
.on('enable.pager', function(e){
e.stopPropagation();
tsp.enablePager(table, c, true);
})
.on('destroy.pager', function(e){
e.stopPropagation();
tsp.destroyPager(table, c);
})
.on('update updateRows updateAll addRows '.split(' ').join('.pager '), function(e){
e.stopPropagation();
tsp.fixHeight(table, c);
var $rows = c.$tbodies.eq(0).children('tr');
p.totalRows = $rows.length - ( c.widgetOptions.pager_countChildRows ? 0 : $rows.filter('.' + c.cssChildRow).length );
p.totalPages = Math.ceil( p.totalRows / p.size );
tsp.updatePageDisplay(table, c);
tsp.hideRows(table, c);
// make sure widgets are applied - fixes #450
c.$table.trigger('applyWidgets');
})
.on('pageSize.pager', function(e,v){
e.stopPropagation();
tsp.setPageSize(table, parseInt(v, 10) || 10, c);
tsp.hideRows(table, c);
tsp.updatePageDisplay(table, c, false);
if (p.$size.length) { p.$size.val(p.size); } // twice?
})
.on('pageSet.pager', function(e,v){
e.stopPropagation();
p.page = (parseInt(v, 10) || 1) - 1;
if (p.$goto.length) { p.$goto.val(c.size); } // twice?
tsp.moveToPage(table, p, true);
tsp.updatePageDisplay(table, c, false);
});
// clicked controls
ctrls = [ s.first, s.prev, s.next, s.last ];
fxn = [ 'moveToFirstPage', 'moveToPrevPage', 'moveToNextPage', 'moveToLastPage' ];
p.$container.find(ctrls.join(','))
.attr("tabindex", 0)
.unbind('click.pager')
.bind('click.pager', function(e){
e.stopPropagation();
var i,
$c = $(this),
l = ctrls.length;
if ( !$c.hasClass(wo.pager_css.disabled) ) {
for (i = 0; i < l; i++) {
if ($c.is(ctrls[i])) {
tsp[fxn[i]](table, p);
break;
}
}
}
});
if ( p.$goto.length ) {
p.$goto
.unbind('change')
.bind('change', function(){
p.page = $(this).val() - 1;
tsp.moveToPage(table, p, true);
tsp.updatePageDisplay(table, c, false);
});
}
if ( p.$size.length ) {
// setting an option as selected appears to cause issues with initial page size
p.$size.find('option').removeAttr('selected');
p.$size
.unbind('change.pager')
.bind('change.pager', function() {
p.$size.val( $(this).val() ); // in case there are more than one pagers
if ( !$(this).hasClass(wo.pager_css.disabled) ) {
tsp.setPageSize(table, parseInt( $(this).val(), 10 ), c);
tsp.changeHeight(table, c);
}
return false;
});
}
},
// hide arrows at extremes
pagerArrows: function(c, disable) {
var p = c.pager,
dis = !!disable,
first = dis || p.page === 0,
tp = Math.min( p.totalPages, p.filteredPages ),
last = dis || p.page === tp - 1 || tp === 0,
wo = c.widgetOptions,
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);
}
},
updatePageDisplay: function(table, c, completed) {
var i, pg, s, $out, regex,
wo = c.widgetOptions,
p = c.pager,
f = c.$table.hasClass('hasFilters'),
t = [],
sz = p.size || 10; // don't allow dividing by zero
t = [ wo && wo.filter_filteredRow || 'filtered', c.selectorRemove.replace(/^(\w+\.)/g,'') ];
if (wo.pager_countChildRows) { t.push(c.cssChildRow); }
regex = new RegExp( '(' + t.join('|') + ')' );
p.$size.add(p.$goto).removeClass(wo.pager_css.disabled).removeAttr('disabled').attr('aria-disabled', 'false');
if (f && !wo.pager_ajaxUrl) {
if ($.isEmptyObject(c.cache)) {
// delayInit: true so nothing is in the cache
p.filteredRows = p.totalRows = c.$tbodies.eq(0).children('tr').not( c.widgetOptions.pager_countChildRows ? '' : '.' + c.cssChildRow ).length;
} else {
p.filteredRows = 0;
$.each(c.cache[0].normalized, function(i, el) {
p.filteredRows += p.regexRows.test(el[c.columns].$row[0].className) ? 0 : 1;
});
}
} else if (!f) {
p.filteredRows = p.totalRows;
}
p.totalPages = Math.ceil( p.totalRows / sz ); // needed for "pageSize" method
c.totalRows = p.totalRows;
c.filteredRows = p.filteredRows;
p.filteredPages = Math.ceil( p.filteredRows / sz ) || 0;
if ( Math.min( p.totalPages, p.filteredPages ) >= 0 ) {
t = (p.size * p.page > p.filteredRows);
p.startRow = (t) ? 1 : (p.filteredRows === 0 ? 0 : p.size * p.page + 1);
p.page = (t) ? 0 : p.page;
p.endRow = Math.min( p.filteredRows, p.totalRows, p.size * ( p.page + 1 ) );
$out = p.$container.find(wo.pager_selectors.pageDisplay);
// form the output string (can now get a new output string from the server)
s = ( p.ajaxData && p.ajaxData.output ? p.ajaxData.output || wo.pager_output : wo.pager_output )
// {page} = one-based index; {page+#} = zero based index +/- value
.replace(/\{page([\-+]\d+)?\}/gi, function(m,n){
return p.totalPages ? p.page + (n ? parseInt(n, 10) : 1) : 0;
})
// {totalPages}, {extra}, {extra:0} (array) or {extra : key} (object)
.replace(/\{\w+(\s*:\s*\w+)?\}/gi, function(m){
var len, indx,
str = m.replace(/[{}\s]/g,''),
extra = str.split(':'),
data = p.ajaxData,
// return zero for default page/row numbers
deflt = /(rows?|pages?)$/i.test(str) ? 0 : '';
if (/(startRow|page)/.test(extra[0]) && extra[1] === 'input') {
len = ('' + (extra[0] === 'page' ? p.totalPages : p.totalRows)).length;
indx = extra[0] === 'page' ? p.page + 1 : p.startRow;
return '<input type="text" class="ts-' + extra[0] + '" style="max-width:' + len + 'em" value="' + indx + '"/>';
}
return extra.length > 1 && data && data[extra[0]] ? data[extra[0]][extra[1]] : p[str] || (data ? data[str] : deflt) || deflt;
});
if ($out.length) {
$out[ ($out[0].tagName === 'INPUT') ? 'val' : 'html' ](s);
if ( p.$goto.length ) {
t = '';
pg = Math.min( p.totalPages, p.filteredPages );
for ( i = 1; i <= pg; i++ ) {
t += '<option>' + i + '</option>';
}
p.$goto.html(t).val( p.page + 1 );
}
// rebind startRow/page inputs
$out.find('.ts-startRow, .ts-page').unbind('change').bind('change', function(){
var v = $(this).val(),
pg = $(this).hasClass('ts-startRow') ? Math.floor( v/p.size ) + 1 : v;
c.$table.trigger('pageSet.pager', [ pg ]);
});
}
}
tsp.pagerArrows(c);
if (p.initialized && completed !== false) {
c.$table.trigger('pagerComplete', c);
// save pager info to storage
if (wo.pager_savePages && ts.storage) {
ts.storage(table, wo.pager_storageKey, {
page : p.page,
size : p.size
});
}
}
},
fixHeight: function(table, c) {
var d, h,
p = c.pager,
wo = c.widgetOptions,
$b = c.$tbodies.eq(0);
if (wo.pager_fixedHeight) {
$b.find('tr.pagerSavedHeightSpacer').remove();
h = $.data(table, 'pagerSavedHeight');
if (h) {
d = h - $b.height();
if ( d > 5 && $.data(table, 'pagerLastSize') === p.size && $b.children('tr:visible').length < p.size ) {
$b.append('<tr class="pagerSavedHeightSpacer ' + wo.pager_selectors.remove.replace(/^(\w+\.)/g,'') + '" style="height:' + d + 'px;"></tr>');
}
}
}
},
changeHeight: function(table, c) {
var $b = c.$tbodies.eq(0);
$b.find('tr.pagerSavedHeightSpacer').remove();
$.data(table, 'pagerSavedHeight', $b.height());
tsp.fixHeight(table, c);
$.data(table, 'pagerLastSize', c.pager.size);
},
hideRows: function(table, c){
if (!c.widgetOptions.pager_ajaxUrl) {
var i,
lastIndex = 0,
p = c.pager,
wo = c.widgetOptions,
rows = c.$tbodies.eq(0).children('tr'),
l = rows.length,
s = ( p.page * p.size ),
e = s + p.size,
f = wo && wo.filter_filteredRow || 'filtered',
j = 0; // size counter
for ( i = 0; i < l; i++ ){
if ( !rows[i].className.match(f) ) {
if (j === s && rows[i].className.match(c.cssChildRow)) {
// hide child rows @ start of pager (if already visible)
rows[i].style.display = 'none';
} else {
rows[i].style.display = ( j >= s && j < e ) ? '' : 'none';
// don't count child rows
j += rows[i].className.match(c.cssChildRow + '|' + c.selectorRemove.replace(/^(\w+\.)/g,'')) && !wo.pager_countChildRows ? 0 : 1;
if ( j === e && rows[i].style.display !== 'none' && rows[i].className.match(ts.css.cssHasChild) ) {
lastIndex = i;
}
}
}
}
// add any attached child rows to last row of pager. Fixes part of issue #396
if ( lastIndex > 0 && rows[lastIndex].className.match(ts.css.cssHasChild) ) {
while ( ++lastIndex < l && rows[lastIndex].className.match(c.cssChildRow) ) {
rows[lastIndex].style.display = '';
}
}
}
},
hideRowsSetup: function(table, c){
var p = c.pager;
p.size = parseInt( p.$size.val(), 10 ) || p.size;
$.data(table, 'pagerLastSize', p.size);
tsp.pagerArrows(c);
if ( !c.widgetOptions.pager_removeRows ) {
tsp.hideRows(table, c);
c.$table.on('sortEnd.pager filterEnd.pager', function(){
tsp.hideRows(table, c);
});
}
},
renderAjax: function(data, table, c, xhr, exception){
var p = c.pager,
wo = c.widgetOptions;
// process data
if ( $.isFunction(wo.pager_ajaxProcessing) ) {
// ajaxProcessing result: [ total, rows, headers ]
var i, j, t, hsh, $f, $sh, th, d, l, rr_count,
$t = c.$table,
tds = '',
result = wo.pager_ajaxProcessing(data, table, xhr) || [ 0, [] ],
hl = $t.find('thead th').length;
// Clean up any previous error.
ts.showError(table);
if ( exception ) {
if (c.debug) {
ts.log('Ajax Error', xhr, exception);
}
ts.showError(table, exception.message + ' (' + xhr.status + ')');
c.$tbodies.eq(0).children('tr').detach();
p.totalRows = 0;
} else {
// process ajax object
if (!$.isArray(result)) {
p.ajaxData = result;
c.totalRows = p.totalRows = result.total;
c.filteredRows = p.filteredRows = typeof result.filteredRows !== 'undefined' ? result.filteredRows : result.total;
th = result.headers;
d = result.rows;
} else {
// allow [ total, rows, headers ] or [ rows, total, headers ]
t = isNaN(result[0]) && !isNaN(result[1]);
// ensure a zero returned row count doesn't fail the logical ||
rr_count = result[t ? 1 : 0];
p.totalRows = isNaN(rr_count) ? p.totalRows || 0 : rr_count;
// can't set filtered rows when returning an array
c.totalRows = c.filteredRows = p.filteredRows = p.totalRows;
d = p.totalRows === 0 ? [""] : result[t ? 0 : 1] || []; // row data
th = result[2]; // headers
}
l = d && d.length;
if (d instanceof jQuery) {
if (wo.pager_processAjaxOnInit) {
// append jQuery object
c.$tbodies.eq(0).children('tr').detach();
c.$tbodies.eq(0).append(d);
}
} else if (l) {
// build table from array
for ( i = 0; i < l; i++ ) {
tds += '<tr>';
for ( j = 0; j < d[i].length; j++ ) {
// build tbody cells; watch for data containing HTML markup - see #434
tds += /^\s*<td/.test(d[i][j]) ? $.trim(d[i][j]) : '<td>' + d[i][j] + '</td>';
}
tds += '</tr>';
}
// add rows to first tbody
if (wo.pager_processAjaxOnInit) {
c.$tbodies.eq(0).html( tds );
}
}
wo.pager_processAjaxOnInit = true;
// only add new header text if the length matches
if ( th && th.length === hl ) {
hsh = $t.hasClass('hasStickyHeaders');
$sh = hsh ? wo.$sticky.children('thead:first').children('tr').children() : '';
$f = $t.find('tfoot tr:first').children();
// don't change td headers (may contain pager)
c.$headers.filter('th').each(function(j){
var $t = $(this), icn;
// add new test within the first span it finds, or just in the header
if ( $t.find('.' + ts.css.icon).length ) {
icn = $t.find('.' + ts.css.icon).clone(true);
$t.find('.tablesorter-header-inner').html( th[j] ).append(icn);
if ( hsh && $sh.length ) {
icn = $sh.eq(j).find('.' + ts.css.icon).clone(true);
$sh.eq(j).find('.tablesorter-header-inner').html( th[j] ).append(icn);
}
} else {
$t.find('.tablesorter-header-inner').html( th[j] );
if (hsh && $sh.length) {
$sh.eq(j).find('.tablesorter-header-inner').html( th[j] );
}
}
$f.eq(j).html( th[j] );
});
}
}
if (c.showProcessing) {
ts.isProcessing(table); // remove loading icon
}
// make sure last pager settings are saved, prevents multiple server side calls with
// the same parameters
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);
tsp.fixHeight(table, c);
$t.trigger('updateCache', [function(){
if (p.initialized) {
// apply widgets after table has rendered & after a delay to prevent
// multiple applyWidget blocking code from blocking this trigger
setTimeout(function(){
$t
.trigger('applyWidgets')
.trigger('pagerChange', p);
}, 0);
}
}]);
}
if (!p.initialized) {
c.$table.trigger('applyWidgets');
}
},
getAjax: function(table, c){
var counter,
url = tsp.getAjaxUrl(table, c),
$doc = $(document),
wo = c.widgetOptions,
p = c.pager;
if ( url !== '' ) {
if (c.showProcessing) {
ts.isProcessing(table, true); // show loading icon
}
$doc.on('ajaxError.pager', function(e, xhr, settings, exception) {
tsp.renderAjax(null, table, c, xhr, exception);
$doc.unbind('ajaxError.pager');
});
counter = ++p.ajaxCounter;
wo.pager_ajaxObject.url = url; // from the ajaxUrl option and modified by customAjaxUrl
wo.pager_ajaxObject.success = function(data, status, jqxhr) {
// Refuse to process old ajax commands that were overwritten by new ones - see #443
if (counter < p.ajaxCounter){
return;
}
tsp.renderAjax(data, table, c, jqxhr);
$doc.unbind('ajaxError.pager');
if (typeof p.oldAjaxSuccess === 'function') {
p.oldAjaxSuccess(data);
}
};
if (c.debug) {
ts.log('ajax initialized', wo.pager_ajaxObject);
}
$.ajax(wo.pager_ajaxObject);
}
},
getAjaxUrl: function(table, c) {
var p = c.pager,
wo = c.widgetOptions,
url = (wo.pager_ajaxUrl) ? wo.pager_ajaxUrl
// allow using "{page+1}" in the url string to switch to a non-zero based index
.replace(/\{page([\-+]\d+)?\}/, function(s,n){ return p.page + (n ? parseInt(n, 10) : 0); })
.replace(/\{size\}/g, p.size) : '',
sl = c.sortList,
fl = p.currentFilters || $(table).data('lastSearch') || [],
sortCol = url.match(/\{\s*sort(?:List)?\s*:\s*(\w*)\s*\}/),
filterCol = url.match(/\{\s*filter(?:List)?\s*:\s*(\w*)\s*\}/),
arry = [];
if (sortCol) {
sortCol = sortCol[1];
$.each(sl, function(i,v){
arry.push(sortCol + '[' + v[0] + ']=' + v[1]);
});
// if the arry is empty, just add the col parameter... "&{sortList:col}" becomes "&col"
url = url.replace(/\{\s*sort(?:List)?\s*:\s*(\w*)\s*\}/g, arry.length ? arry.join('&') : sortCol );
arry = [];
}
if (filterCol) {
filterCol = filterCol[1];
$.each(fl, function(i,v){
if (v) {
arry.push(filterCol + '[' + i + ']=' + encodeURIComponent(v));
}
});
// if the arry is empty, just add the fcol parameter... "&{filterList:fcol}" becomes "&fcol"
url = url.replace(/\{\s*filter(?:List)?\s*:\s*(\w*)\s*\}/g, arry.length ? arry.join('&') : filterCol );
p.currentFilters = fl;
}
if ( $.isFunction(wo.pager_customAjaxUrl) ) {
url = wo.pager_customAjaxUrl(table, url);
}
if (c.debug) {
ts.log('Pager ajax url: ' + url);
}
return url;
},
renderTable: function(table, rows) {
var $tb, index, count, added,
c = table.config,
p = c.pager,
wo = c.widgetOptions,
f = c.$table.hasClass('hasFilters'),
l = rows && rows.length || 0, // rows may be undefined
s = ( p.page * p.size ),
e = p.size;
if ( l < 1 ) {
if (c.debug) {
ts.log('Pager: no rows for pager to render');
}
// empty table, abort!
return;
}
if ( p.page >= p.totalPages ) {
// lets not render the table more than once
return tsp.moveToLastPage(table, p);
}
p.isDisabled = false; // needed because sorting will change the page and re-enable the pager
if (p.initialized) { c.$table.trigger('pagerChange', c); }
if ( !wo.pager_removeRows ) {
tsp.hideRows(table, c);
} else {
ts.clearTableBody(table);
$tb = ts.processTbody(table, c.$tbodies.eq(0), true);
// not filtered, start from the calculated starting point (s)
// if filtered, start from zero
index = f ? 0 : s;
count = f ? 0 : s;
added = 0;
while (added < e && index < rows.length) {
if (!f || !/filtered/.test(rows[index][0].className)){
count++;
if (count > s && added <= e) {
added++;
$tb.append(rows[index]);
}
}
index++;
}
ts.processTbody(table, $tb, false);
}
tsp.updatePageDisplay(table, c);
if ( !p.isDisabled ) { tsp.fixHeight(table, c); }
wo.pager_startPage = p.page;
wo.pager_size = p.size;
c.$table.trigger('applyWidgets');
if (table.isUpdating) {
c.$table.trigger('updateComplete');
}
},
showAllRows: function(table, c){
var p = c.pager,
wo = c.widgetOptions;
if ( p.ajax ) {
tsp.pagerArrows(c, true);
} else {
p.isDisabled = true;
$.data(table, 'pagerLastPage', p.page);
$.data(table, 'pagerLastSize', p.size);
p.page = 0;
p.size = p.totalRows;
p.totalPages = 1;
c.$table
.addClass('pagerDisabled')
.removeAttr('aria-describedby')
.find('tr.pagerSavedHeightSpacer').remove();
tsp.renderTable(table, c.rowsCopy);
if (c.debug) {
ts.log('pager disabled');
}
}
// disable size selector
p.$size.add(p.$goto).each(function(){
$(this).attr('aria-disabled', 'true').addClass(wo.pager_css.disabled)[0].disabled = true;
});
},
// updateCache if delayInit: true
// this is normally done by "appendToTable" function in the tablesorter core AFTER a sort
updateCache: function(table) {
var c = table.config,
p = c.pager;
c.$table.trigger('updateCache', [ function(){
if ( !$.isEmptyObject(table.config.cache) ) {
var i,
rows = [],
n = table.config.cache[0].normalized;
p.totalRows = n.length;
for (i = 0; i < p.totalRows; i++) {
rows.push(n[i][c.columns].$row);
}
c.rowsCopy = rows;
tsp.moveToPage(table, p, true);
// clear out last search to force an update
p.last.currentFilters = [' '];
}
} ]);
},
moveToPage: function(table, p, pageMoved) {
if ( p.isDisabled ) { return; }
if ( pageMoved !== false && p.initialized && $.isEmptyObject(table.config.cache)) {
return tsp.updateCache(table);
}
var c = table.config,
l = p.last,
pg = Math.min( p.totalPages, p.filteredPages );
if ( p.page < 0 ) { p.page = 0; }
if ( p.page > ( pg - 1 ) && pg !== 0 ) { p.page = pg - 1; }
// fixes issue where one current filter is [] and the other is ['','',''],
// making the next if comparison think the filters as different. Fixes #202.
l.currentFilters = (l.currentFilters || []).join('') === '' ? [] : l.currentFilters;
p.currentFilters = (p.currentFilters || []).join('') === '' ? [] : p.currentFilters;
// don't allow rendering multiple times on the same page/size/totalRows/filters/sorts
if ( l.page === p.page && l.size === p.size && l.totalRows === p.totalRows &&
(l.currentFilters || []).join(',') === (p.currentFilters || []).join(',') &&
l.sortList === (c.sortList || []).join(',') ) {
return;
}
if (c.debug) {
ts.log('Pager changing to page ' + p.page);
}
p.last = {
page : p.page,
size : p.size,
// fixes #408; modify sortList otherwise it auto-updates
sortList : (c.sortList || []).join(','),
totalRows : p.totalRows,
currentFilters : p.currentFilters || []
};
if (p.ajax) {
tsp.getAjax(table, c);
} else if (!p.ajax) {
tsp.renderTable(table, c.rowsCopy);
}
$.data(table, 'pagerLastPage', p.page);
if (p.initialized && pageMoved !== false) {
c.$table.trigger('pageMoved', c);
if (!p.ajax && table.isUpdating) {
c.$table.trigger('updateComplete');
}
}
},
setPageSize: function(table, size, c) {
var p = c.pager;
p.size = size || p.size || 10;
p.$size.val(p.size);
$.data(table, 'pagerLastPage', p.page);
$.data(table, 'pagerLastSize', p.size);
p.totalPages = Math.ceil( p.totalRows / p.size );
p.filteredPages = Math.ceil( p.filteredRows / p.size );
tsp.moveToPage(table, p, true);
},
moveToFirstPage: function(table, p) {
p.page = 0;
tsp.moveToPage(table, p, true);
},
moveToLastPage: function(table, p) {
p.page = ( Math.min( p.totalPages, p.filteredPages ) - 1 );
tsp.moveToPage(table, p, true);
},
moveToNextPage: function(table, p) {
p.page++;
if ( p.page >= ( Math.min( p.totalPages, p.filteredPages ) - 1 ) ) {
p.page = ( Math.min( p.totalPages, p.filteredPages ) - 1 );
}
tsp.moveToPage(table, p, true);
},
moveToPrevPage: function(table, p) {
p.page--;
if ( p.page <= 0 ) {
p.page = 0;
}
tsp.moveToPage(table, p, true);
},
destroyPager: function(table, c){
var p = c.pager;
tsp.showAllRows(table, c);
p.$container.hide(); // hide pager
c.appender = null; // remove pager appender function
p.initialized = false;
delete table.config.rowsCopy;
c.$table.unbind('destroy.pager sortEnd.pager filterEnd.pager enable.pager disable.pager');
if (ts.storage) {
ts.storage(table, c.widgetOptions.pager_storageKey, '');
}
},
enablePager: function(table, c, triggered){
var info, p = c.pager;
p.isDisabled = false;
p.page = $.data(table, 'pagerLastPage') || p.page || 0;
p.size = $.data(table, 'pagerLastSize') || parseInt(p.$size.find('option[selected]').val(), 10) || p.size || 10;
p.$size.val(p.size); // set page size
p.totalPages = Math.ceil( Math.min( p.totalRows, p.filteredRows ) / p.size );
c.$table.removeClass('pagerDisabled');
// if table id exists, include page display with aria info
if ( table.id ) {
info = table.id + '_pager_info';
p.$container.find(c.widgetOptions.pager_selectors.pageDisplay).attr('id', info);
c.$table.attr('aria-describedby', info);
}
if ( triggered ) {
c.$table.trigger('updateRows');
tsp.setPageSize(table, p.size, c);
tsp.hideRowsSetup(table, c);
tsp.fixHeight(table, c);
if (c.debug) {
ts.log('pager enabled');
}
}
},
appender: function(table, rows) {
var c = table.config,
wo = c.widgetOptions,
p = c.pager;
if ( !p.ajax ) {
c.rowsCopy = rows;
p.totalRows = c.widgetOptions.pager_countChildRows ? c.$tbodies.eq(0).children('tr').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);
// update display here in case all rows are removed
tsp.updatePageDisplay(table, c, false);
} else {
tsp.moveToPage(table, p, true);
}
}
};
// see #486
ts.showError = function(table, message){
$(table).each(function(){
var $row,
c = this.config,
errorRow = c.pager && c.pager.cssErrorRow || c.widgetOptions.pager_css && c.widgetOptions.pager_css.errorRow || 'tablesorter-errorRow';
if (c) {
if (typeof message === 'undefined') {
c.$table.find('thead').find(c.selectorRemove).remove();
} else {
$row = ( /tr\>/.test(message) ? $(message) : $('<tr><td colspan="' + c.columns + '">' + message + '</td></tr>') )
.click(function(){
$(this).remove();
})
// add error row to thead instead of tbody, or clicking on the header will result in a parser error
.appendTo( c.$table.find('thead:first') )
.addClass( errorRow + ' ' + c.selectorRemove.replace(/^(\w+\.)/g,'') )
.attr({
role : 'alert',
'aria-live' : 'assertive'
});
}
}
});
};
})(jQuery);
@@ -0,0 +1,123 @@
/* Print widget (beta) for TableSorter 6/18/2014 (v2.17.2)
* Requires tablesorter v2.8+ and jQuery 1.2.6+
*/
/*jshint browser:true, jquery:true, unused:false */
/*global jQuery: false */
;(function($){
"use strict";
var ts = $.tablesorter,
printTable = ts.printTable = {
event : 'printTable',
basicStyle : 'table, tr, td, th { border : solid 1px black; border-collapse : collapse; } td, th { padding: 2px; }',
init : function(c) {
c.$table
.unbind(printTable.event)
.bind(printTable.event, function(){
// explicitly use table.config.widgetOptions because we want
// the most up-to-date values; not the "wo" from initialization
printTable.process(c, c.widgetOptions);
});
},
process : function(c, wo) {
var $this,
$table = $('<div/>').append(c.$table.clone()),
printStyle = printTable.basicStyle + 'table { width: 100% }' +
// hide filter row
'.tablesorter-filter-row { display: none }' +
// hide sort arrows
'.tablesorter-header { background-image: none !important; }';
// replace content with data-attribute content
$table.find('[' + wo.print_dataAttrib + ']').each(function(){
$this = $(this);
$this.text( $this.attr(wo.print_dataAttrib) );
});
// === rows ===
// Assume "visible" means rows hidden by the pager (rows set to "display:none")
// or hidden by a class name which is added to the wo.print_extraCSS definition
if (/a/i.test(wo.print_rows)) {
// force show of all rows
printStyle += 'tbody tr { display: table-row !important; }';
} else if (/f/i.test(wo.print_rows)) {
// add definition to show all non-filtered rows (cells hidden by the pager)
printStyle += 'tbody tr:not(.' + (wo.filter_filteredRow || 'filtered') + ') { display: table-row !important; }';
}
// === columns ===
// columnSelector -> c.selector.$style
// Assume "visible" means hidden columns have a "display:none" style, or a class name
// add the definition to the wo.print_extraCSS option
if (/s/i.test(wo.print_columns) && c.selector && c.widgets.indexOf('columnSelector') >= 0) {
// show selected (visible) columns; make a copy of the columnSelector widget css (not media queries)
printStyle += c.selector.auto ? '' : c.selector.$style.text();
} else if (/a/i.test(wo.print_columns)) {
// force show all cells
printStyle += 'td, th { display: table-cell !important; }';
}
printStyle += wo.print_extraCSS;
// callback function
if ( $.isFunction(wo.print_callback) ) {
wo.print_callback( c, $table, printStyle );
} else {
printTable.printOutput(c, $table.html(), printStyle);
}
}, // end process
printOutput : function(c, data, style) {
var wo = c.widgetOptions,
generator = window.open('', wo.print_title, 'width=500,height=300'),
t = wo.print_title || c.$table.find('caption').text() || c.$table[0].id || document.title || 'table';
generator.document.write(
'<html><head><title>' + t + '</title>' +
( wo.print_styleSheet ? '<link rel="stylesheet" href="' + wo.print_styleSheet + '">' : '' ) +
'<style>' + style + '</style>' +
'</head><body>' + data + '</body></html>'
);
generator.document.close();
generator.print();
generator.close();
return true;
},
remove : function(c) {
c.$table.off(printTable.event);
}
};
ts.addWidget({
id: 'print',
options: {
print_title : '', // this option > caption > table id > "table"
print_dataAttrib : 'data-name', // header attrib containing modified header name
print_rows : 'filtered', // (a)ll, (v)isible or (f)iltered
print_columns : 'selected', // (a)ll or (s)elected (if columnSelector widget is added)
print_extraCSS : '', // add any extra css definitions for the popup window here
print_styleSheet : '', // add the url of your print stylesheet
// callback executed when processing completes
// to continue printing, use the following function:
// function( config, $table, printStyle ) {
// // do something to the table or printStyle string
// $.tablesorter.printTable.printOutput( config, $table.html(), printStyle );
// }
print_callback : null
},
init: function(table, thisWidget, c) {
printTable.init(c);
},
remove: function(table, c){
printTable.remove(c);
}
});
})(jQuery);
@@ -0,0 +1,179 @@
/* table reflow widget (beta) for TableSorter 3/22/2014 (v2.16.0)
* Requires tablesorter v2.8+ and jQuery 1.7+
* Also, this widget requires the following default css (modify as desired)
/ * REQUIRED CSS: change your reflow breakpoint here (35em below) * /
@media ( max-width: 35em ) {
.ui-table-reflow td,
.ui-table-reflow th {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
float: right;
/ * if not using the stickyHeaders widget (not the css3 version)
* the "!important" flag, and "height: auto" can be removed * /
width: 100% !important;
height: auto !important;
}
/ * reflow widget * /
.ui-table-reflow tbody td[data-title]:before {
color: #469;
font-size: .9em;
content: attr(data-title);
float: left;
width: 50%;
white-space: pre-wrap;
text-align: bottom;
display: inline-block;
}
/ * reflow2 widget * /
table.ui-table-reflow .ui-table-cell-label.ui-table-cell-label-top {
display: block;
padding: .4em 0;
margin: .4em 0;
text-transform: uppercase;
font-size: .9em;
font-weight: 400;
}
table.ui-table-reflow .ui-table-cell-label {
padding: .4em;
min-width: 30%;
display: inline-block;
margin: -.4em 1em -.4em -.4em;
}
}
.ui-table-reflow .ui-table-cell-label {
display: none;
}
*/
/*jshint browser:true, jquery:true, unused:false */
/*global jQuery: false */
;(function($){
"use strict";
var ts = $.tablesorter,
tablereflow = {
// simple reflow
// add data-attribute to each cell which shows when media query is active
// this widget DOES NOT WORK on a table with multiple thead rows
init : function(table, c, wo) {
var $this,
title = wo.reflow_dataAttrib,
header = wo.reflow_headerAttrib,
headers = [];
c.$table
.addClass(wo.reflow_className)
.off('refresh.tsreflow updateComplete.tsreflow2')
// emulate jQuery Mobile refresh
// https://api.jquerymobile.com/table-reflow/#method-refresh
.on('refresh.tsreflow updateComplete.tsreflow2', function(){
tablereflow.init(table, c, wo);
});
c.$headers.each(function(){
$this = $(this);
headers.push( $this.attr(header) || $this.text() );
});
c.$tbodies.children().each(function(){
$(this).children().each(function(i){
$(this).attr(title, headers[i]);
});
});
},
init2: function(table, c, wo) {
var $this, $tbody, i, $hdr, txt, len,
cols = c.columns,
header = wo.reflow2_headerAttrib,
headers = [];
c.$table
.addClass(wo.reflow2_className)
.off('refresh.tsreflow2 updateComplete.tsreflow2')
// emulate jQuery Mobile refresh
// https://api.jquerymobile.com/table-reflow/#method-refresh
.on('refresh.tsreflow2 updateComplete.tsreflow2', function(){
tablereflow.init2(table, c, wo);
});
// add <b> to every table cell with thead cell contents
for (i = 0; i < cols; i++) {
$hdr = c.$headers.filter('[data-column="' + i + '"]');
if ($hdr.length > 1) {
txt = [];
$hdr.each(function(){
$this = $(this);
if (!$this.hasClass(wo.reflow2_classIgnore)) {
txt.push( $this.attr(header) || $this.text() );
}
});
} else {
txt = [ $hdr.attr(header) || $hdr.text() ];
}
headers.push( txt );
}
// include "remove-me" class so these additional elements are removed before updating
txt = '<b class="' + c.selectorRemove.slice(1) + ' ' + wo.reflow2_labelClass;
c.$tbodies.children().each(function(){
$tbody = ts.processTbody(table, $(this), true);
$tbody.children().each(function(j){
$this = $(this);
len = headers[j].length
i = len - 1;
while (i >= 0) {
$this.prepend(txt + (i === 0 && len > 1 ? ' ' + wo.reflow2_labelTop : '') + '">' + headers[j][i] + '</b>');
i--;
}
});
ts.processTbody(table, $tbody, false);
});
},
remove : function(table, c, wo) {
c.$table.removeClass(wo.reflow_className);
},
remove2 : function(table, c, wo) {
c.$table.removeClass(wo.reflow2_className);
}
};
ts.addWidget({
id: "reflow",
options: {
// class name added to make it responsive (class name within media query)
reflow_className : 'ui-table-reflow',
// header attribute containing modified header name
reflow_headerAttrib : 'data-name',
// data attribute added to each tbody cell
reflow_dataAttrib : 'data-title'
},
init: function(table, thisWidget, c, wo) {
tablereflow.init(table, c, wo);
},
remove: function(table, c, wo){
tablereflow.remove(table, c, wo);
}
});
ts.addWidget({
id: "reflow2",
options: {
// class name added to make it responsive (class name within media query)
reflow2_className : 'ui-table-reflow',
// ignore header cell content with this class name
reflow2_classIgnore : 'ui-table-reflow-ignore',
// header attribute containing modified header name
reflow2_headerAttrib : 'data-name',
// class name applied to thead labels
reflow2_labelClass : 'ui-table-cell-label',
// class name applied to first row thead label
reflow2_labelTop : 'ui-table-cell-label-top'
},
init: function(table, thisWidget, c, wo) {
tablereflow.init2(table, c, wo);
},
remove: function(table, c, wo){
tablereflow.remove2(table, c, wo);
}
});
})(jQuery);
@@ -0,0 +1,50 @@
/*! tablesorter repeatHeaders widget - updated 4/12/2013
* Requires tablesorter v2.8+ and jQuery 1.7+
* Original by Christian Bach from the example-widgets.html demo
*/
/*global jQuery: false */
;(function($){
"use strict";
$.tablesorter.addWidget({
id: "repeatHeaders",
priority: 10,
options: {
rowsToSkip : 4
},
// format is called on init and when a sorting has finished
format: function(table, c, wo) {
var h = '', i, $tr, l, skip;
// cache and collect all TH headers
if (!wo.repeatHeaders) {
h = '<tr class="repeated-header remove-me">';
$.each(c.headerContent, function(i,t) {
h += '<th>' + t + '</th>';
});
// "remove-me" class was added in case the table needs to be updated, the "remove-me" rows will be
// removed prior to the update to prevent including the rows in the update - see "selectorRemove" option
wo.repeatHeaders = h + '</tr>';
}
// number of rows to skip
skip = wo && wo.rowsToSkip || 4;
// remove appended headers by classname
c.$table.find("tr.repeated-header").remove();
$tr = c.$tbodies.find('tr');
l = $tr.length;
// loop all tr elements and insert a copy of the "headers"
for (i = skip; i < l; i += skip) {
// insert a copy of the table head every X rows
$tr.eq(i).before(wo.repeatHeaders);
}
},
// this remove function is called when using the refreshWidgets method or when destroying the tablesorter plugin
// this function only applies to tablesorter v2.4+
remove: function(table, c){
c.$table.find("tr.repeated-header").remove();
}
});
})(jQuery);
@@ -0,0 +1,218 @@
/*!
Copyright (C) 2011 T. Connell & Associates, Inc.
Dual-licensed under the MIT and GPL licenses
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Resizable scroller widget for the jQuery tablesorter plugin
Version 2.0 - modified by Rob Garrison 4/12/2013; updated 6/28/2014 (v2.17.3)
Requires jQuery v1.7+
Requires the tablesorter plugin, v2.8+, available at http://mottie.github.com/tablesorter/docs/
Usage:
$(function() {
$('table.tablesorter').tablesorter({
widgets: ['zebra', 'scroller'],
widgetOptions : {
scroller_height : 300, // height of scroll window
scroller_barWidth : 18, // scroll bar width
scroller_jumpToHeader : true, // header snap to browser top when scrolling the tbody
scroller_idPrefix : 's_' // cloned thead id prefix (random number added to end)
}
});
});
Website: www.tconnell.com
*/
/*jshint browser:true, jquery:true, unused:false */
;(function($){
"use strict";
$.fn.hasScrollBar = function(){
return this.get(0).scrollHeight > this.height();
};
var ts = $.tablesorter;
ts.window_resize = function(){
if (this.resize_timer) {
clearTimeout(this.resize_timer);
}
this.resize_timer = setTimeout(function(){
$(this).trigger('resizeEnd');
}, 250);
};
// Add extra scroller css
$(function(){
var s = '<style>' +
'.tablesorter-scroller-reset { width: auto !important; } ' +
'.tablesorter-scroller { text-align: left; overflow: hidden; }' +
'.tablesorter-scroller-header { overflow: hidden; }' +
'.tablesorter-scroller-header table.tablesorter { margin-bottom: 0; }' +
'.tablesorter-scroller-table { overflow-y: scroll; }' +
'.tablesorter-scroller-table table.tablesorter { margin-top: 0; overflow: scroll; } ' +
'.tablesorter-scroller-table .tablesorter-filter-row, .tablesorter-scroller-table tfoot { display: none; }' +
'.tablesorter-scroller-table table.tablesorter thead tr.tablesorter-headerRow * {' +
'line-height:0;height:0;border:none;background-image:none;padding-top:0;padding-bottom:0;margin-top:0;margin-bottom:0;overflow:hidden;' +
'}</style>';
$(s).appendTo('body');
});
ts.addWidget({
id: 'scroller',
priority: 60, // run after the filter widget
options: {
scroller_height : 300,
scroller_barWidth : 18,
scroller_jumpToHeader: true,
scroller_upAfterSort: true,
scroller_idPrefix : 's_'
},
init: function(table, thisWidget, c, wo){
var $win = $(window);
// Setup window.resizeEnd event
$win
.bind('resize', ts.window_resize)
.bind('resizeEnd', function() {
// init is run before format, so scroller_resizeWidth
// won't be defined within the "c" or "wo" parameters
if (typeof table.config.widgetOptions.scroller_resizeWidth === 'function') {
// IE calls resize when you modify content, so we have to unbind the resize event
// so we don't end up with an infinite loop. we can rebind after we're done.
$win.unbind('resize', ts.window_resize);
table.config.widgetOptions.scroller_resizeWidth();
$win.bind('resize', ts.window_resize);
}
});
},
format: function(table, c, wo) {
var h, $hdr, id, t, resize, $cells,
$win = $(window),
$tbl = c.$table;
if (!c.isScrolling) {
h = wo.scroller_height || 300;
t = $tbl.find('tbody').height();
if (t !== 0 && h > t) { h = t + 10; } // Table is less than h px
id = wo.scroller_id = wo.scroller_idPrefix + Math.floor(Math.random() * 1001);
$hdr = $('<table class="' + $tbl.attr('class') + '" cellpadding=0 cellspacing=0><thead>' + $tbl.find('thead:first').html() + '</thead></table>');
$tbl
.wrap('<div id="' + id + '" class="tablesorter-scroller" />')
.before($hdr)
.find('.tablesorter-filter-row').addClass('hideme');
$cells = $hdr
.wrap('<div class="tablesorter-scroller-header" style="width:' + $tbl.width() + ';" />')
.find('.' + ts.css.header);
$tbl.wrap('<div class="tablesorter-scroller-table" style="height:' + h + 'px;width:' + $tbl.width() + ';" />');
// make scroller header sortable
ts.bindEvents(table, $cells);
// look for filter widget
if ($tbl.hasClass('hasFilters')) {
ts.filter.bindSearch( $tbl, $hdr.find('.' + ts.css.filter) );
}
resize = function(){
var d, b, $h, $th, w,
// Hide other scrollers so we can resize
$div = $('div.scroller[id != "' + id + '"]').hide();
$tbl.find('thead').show();
// Reset sizes so parent can resize.
$tbl
.addClass('tablesorter-scroller-reset')
.find('thead').find('.tablesorter-header-inner').addClass('tablesorter-scroller-reset');
d = $tbl.parent();
d.addClass('tablesorter-scroller-reset');
d.parent().trigger('resize');
// Shrink a bit to accommodate scrollbar
d.width( d.parent().innerWidth() - ( d.parent().hasScrollBar() ? wo.scroller_barWidth : 0 ) );
w = d.innerWidth() - ( d.hasScrollBar() ? wo.scroller_barWidth : 0 );
$tbl.width( w );
$hdr.width( w );
$hdr.parent().width( w );
$tbl.closest('.tablesorter-scroller').find('.tablesorter-scroller-reset').removeClass('tablesorter-scroller-reset');
// include left & right border widths
b = parseInt( $tbl.css('border-left-width'), 10 ) + parseInt( $tbl.css('border-right-width'), 10 );
$h = $hdr.find('thead').children().children();
// adjust cloned header to match original table width - includes wrappers, headers, and header inner div
$tbl.find('thead').children().children().each(function(i, c){
$th = $(c).find('.tablesorter-header-inner');
if ($th.length) {
// I have no idea why this is in here anymore LOL
w = parseInt( $th.css('min-width').replace('auto', '0').replace(/(px|em)/, ''), 10 );
if ( $th.width() < w ) {
$th.width(w);
} else {
w = $th.width();
}
$h.eq(i)
.find('.tablesorter-header-inner').width(w - b)
// set inner width first
.parent()
.width( $th.parent().width() - b );
}
});
$div.show();
};
// Expose to external calls
wo.scroller_resizeWidth = resize;
resize();
$tbl.find('thead').css('visibility', 'hidden');
c.isScrolling = true;
t = $tbl.parent().parent().height();
// The header will always jump into view if scrolling the table body
$tbl.parent().bind('scroll', function(){
if (wo.scroller_jumpToHeader) {
var pos = $win.scrollTop() - $hdr.offset().top;
if ($(this).scrollTop() !== 0 && pos < t && pos > 0) {
$win.scrollTop( $hdr.offset().top );
}
}
$hdr.parent().scrollLeft( $(this).scrollLeft() );
});
}
// Sorting, so scroll to top
if (wo.scroller_upAfterSort) {
$tbl.parent().animate({ scrollTop: 0 }, 'fast');
}
},
remove : function(table, c, wo){
var $table = c.$table;
$table.closest('.tablesorter-scroller').find('.tablesorter-scroller-header').remove();
$table
.unwrap()
.find('.tablesorter-filter-row').removeClass('hideme').end()
.find('thead').show().css('visibility', 'visible');
c.isScrolling = false;
}
});
})(jQuery);
@@ -0,0 +1,124 @@
/*
* StaticRow widget for jQuery TableSorter 2.0
* Version 1.2 - modified by Rob Garrison (6/28/2014 for tablesorter v2.16.1-beta+)
* Requires:
* jQuery v1.4+
* tablesorter plugin, v2.8+, available at http://mottie.github.com/tablesorter/docs/
*
* Copyright (c) 2011 Nils Luxton
* Licensed under the MIT license:
* http://www.opensource.org/licenses/mit-license.php
*
*/
/*jshint browser:true, jquery:true, unused:false */
/*global jQuery: false */
;(function($){
"use strict";
var ts = $.tablesorter,
// events triggered on the table that update this widget
events = 'staticRowsRefresh updateComplete '.split(' ').join('.tsstaticrows '),
// add/refresh row indexes
addIndexes = function(table){
var $tr, wo, v, indx, rows,
c = table.config;
// "Index" the static rows, saving their current (starting) position in the
// table inside a data() param on the <tr> element itself for later use.
if (c) {
wo = c.widgetOptions;
c.$tbodies.each(function(){
$tr = $(this).children();
rows = $tr.length;
$tr.filter(wo.staticRow_class).each(function() {
$tr = $(this);
indx = $tr.data(wo.staticRow_index);
if (typeof indx !== "undefined") {
v = parseFloat(indx);
// percentage of total rows
indx = (/%/.test(indx)) ? Math.round(v/100 * rows) : v;
} else {
indx = $tr.index();
}
// row indexing starts over within each tbody
$tr.data( wo.staticRow_data, indx );
});
});
}
};
ts.addWidget({
// Give the new Widget an ID to be used in the tablesorter() call, as follows:
// $('#myElement').tablesorter({ widgets: ['zebra', 'staticRow'] });
id: 'staticRow',
options: {
staticRow_class : '.static',
staticRow_data : 'static-index',
staticRow_index : 'row-index'
},
init: function(table, thisWidget, c, wo){
addIndexes(table);
// refresh static rows after updates
c.$table
.unbind(events)
.bind(events, function(){
addIndexes(table);
c.$table.trigger('applyWidgets');
});
},
format: function(table, c, wo) {
// Loop thru static rows, moving them to their original "indexed" position,
// & repeat until no more re-shuffling is needed
var targetIndex, $thisRow, indx, numRows, $tbody, hasShuffled, $rows, max;
c.$tbodies.each(function(){
$tbody = $.tablesorter.processTbody(table, $(this), true); // remove tbody
hasShuffled = true;
indx = 0;
$rows = $tbody.children(wo.staticRow_class);
numRows = $tbody.children('tr').length - 1;
max = $rows.length;
// don't allow the while loop to cycle more times than the set number of static rows
while (hasShuffled && indx < max) {
hasShuffled = false;
/*jshint loopfunc:true */
$rows.each(function() {
targetIndex = $(this).data(wo.staticRow_data);
// allow setting target index >> num rows to always make a row last
targetIndex = targetIndex >= numRows ? numRows : targetIndex < 0 ? 0 : targetIndex;
if (targetIndex !== $(this).index()) {
hasShuffled = true;
$thisRow = $(this).detach();
if (targetIndex >= numRows) {
// Are we trying to be the last row?
$thisRow.appendTo( $tbody );
} else if (targetIndex === 0) {
// Are we trying to be the first row?
$thisRow.prependTo( $tbody );
} else {
// No, we want to be somewhere in the middle!
$thisRow.insertBefore( $tbody.find('tr:eq(' + targetIndex + ')') );
}
}
});
indx++;
}
$.tablesorter.processTbody(table, $tbody, false); // restore tbody
});
c.$table.trigger('staticRowsComplete', table);
},
remove : function(table, c, wo){
c.$table.unbind(events);
}
});
})(jQuery);
Binary file not shown.

After

Width:  |  Height:  |  Size: 720 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 737 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 416 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 736 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 745 B

@@ -0,0 +1,42 @@
/* pager wrapper, div */
.tablesorter-pager {
padding: 5px;
}
/* pager wrapper, in thead/tfoot */
td.tablesorter-pager {
background-color: #e6eeee;
margin: 0; /* needed for bootstrap .pager gets a 18px bottom margin */
}
/* pager navigation arrows */
.tablesorter-pager img {
vertical-align: middle;
margin-right: 2px;
cursor: pointer;
}
/* pager output text */
.tablesorter-pager .pagedisplay {
padding: 0 5px 0 5px;
width: auto;
white-space: nowrap;
text-align: center;
}
/* pager element reset (needed for bootstrap) */
.tablesorter-pager select {
margin: 0;
padding: 0;
}
/*** css used when "updateArrows" option is true ***/
/* the pager itself gets a disabled class when the number of rows is less than the size */
.tablesorter-pager.disabled {
display: none;
}
/* hide or fade out pager arrows when the first or last row is visible */
.tablesorter-pager .disabled {
/* visibility: hidden */
opacity: 0.5;
filter: alpha(opacity=50);
cursor: default;
}
@@ -0,0 +1,921 @@
/*!
* tablesorter pager plugin
* updated 8/1/2014 (v2.17.6)
*/
/*jshint browser:true, jquery:true, unused:false */
;(function($) {
"use strict";
/*jshint supernew:true */
var ts = $.tablesorter;
$.extend({ tablesorterPager: new function() {
this.defaults = {
// target the pager markup
container: null,
// use this format: "http://mydatabase.com?page={page}&size={size}&{sortList:col}&{filterList:fcol}"
// where {page} is replaced by the page number, {size} is replaced by the number of records to show,
// {sortList:col} adds the sortList to the url into a "col" array, and {filterList:fcol} adds
// the filterList to the url into an "fcol" array.
// So a sortList = [[2,0],[3,0]] becomes "&col[2]=0&col[3]=0" in the url
// and a filterList = [[2,Blue],[3,13]] becomes "&fcol[2]=Blue&fcol[3]=13" in the url
ajaxUrl: null,
// modify the url after all processing has been applied
customAjaxUrl: function(table, url) { return url; },
// modify the $.ajax object to allow complete control over your ajax requests
ajaxObject: {
dataType: 'json'
},
// set this to false if you want to block ajax loading on init
processAjaxOnInit: true,
// process ajax so that the following information is returned:
// [ total_rows (number), rows (array of arrays), headers (array; optional) ]
// example:
// [
// 100, // total rows
// [
// [ "row1cell1", "row1cell2", ... "row1cellN" ],
// [ "row2cell1", "row2cell2", ... "row2cellN" ],
// ...
// [ "rowNcell1", "rowNcell2", ... "rowNcellN" ]
// ],
// [ "header1", "header2", ... "headerN" ] // optional
// ]
ajaxProcessing: function(ajax){ return [ 0, [], null ]; },
// output default: '{page}/{totalPages}'
// possible variables: {page}, {totalPages}, {filteredPages}, {startRow}, {endRow}, {filteredRows} and {totalRows}
output: '{startRow} to {endRow} of {totalRows} rows', // '{page}/{totalPages}'
// apply disabled classname to the pager arrows when the rows at either extreme is visible
updateArrows: true,
// starting page of the pager (zero based index)
page: 0,
// reset pager after filtering; set to desired page #
// set to false to not change page at filter start
pageReset: 0,
// Number of visible rows
size: 10,
// Save pager page & size if the storage script is loaded (requires $.tablesorter.storage in jquery.tablesorter.widgets.js)
savePages: true,
// defines custom storage key
storageKey: 'tablesorter-pager',
// if true, the table will remain the same height no matter how many records are displayed. The space is made up by an empty
// table row set to a height to compensate; default is false
fixedHeight: false,
// count child rows towards the set page size? (set true if it is a visible table row within the pager)
// if true, child row(s) may not appear to be attached to its parent row, may be split across pages or
// may distort the table if rowspan or cellspans are included.
countChildRows: false,
// remove rows from the table to speed up the sort of large tables.
// setting this to false, only hides the non-visible rows; needed if you plan to add/remove rows with the pager enabled.
removeRows: false, // removing rows in larger tables speeds up the sort
// css class names of pager arrows
cssFirst: '.first', // go to first page arrow
cssPrev: '.prev', // previous page arrow
cssNext: '.next', // next page arrow
cssLast: '.last', // go to last page arrow
cssGoto: '.gotoPage', // go to page selector - select dropdown that sets the current page
cssPageDisplay: '.pagedisplay', // location of where the "output" is displayed
cssPageSize: '.pagesize', // page size selector - select dropdown that sets the "size" option
cssErrorRow: 'tablesorter-errorRow', // error information row
// class added to arrows when at the extremes (i.e. prev/first arrows are "disabled" when on the first page)
cssDisabled: 'disabled', // Note there is no period "." in front of this class name
// stuff not set by the user
totalRows: 0,
totalPages: 0,
filteredRows: 0,
filteredPages: 0,
ajaxCounter: 0,
currentFilters: [],
startRow: 0,
endRow: 0,
$size: null,
last: {}
};
var $this = this,
// hide arrows at extremes
pagerArrows = function(p, disable) {
var a = 'addClass',
r = 'removeClass',
d = p.cssDisabled,
dis = !!disable,
first = ( dis || p.page === 0 ),
tp = Math.min( p.totalPages, p.filteredPages ),
last = ( dis || (p.page === tp - 1) || tp === 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);
}
},
updatePageDisplay = function(table, p, completed) {
var i, pg, s, $out, regex,
c = table.config,
f = c.$table.hasClass('hasFilters'),
t = [],
sz = p.size || 10; // don't allow dividing by zero
t = [ (c.widgetOptions && c.widgetOptions.filter_filteredRow || 'filtered'), c.selectorRemove.replace(/^(\w+\.)/g,'') ];
if (p.countChildRows) { t.push(c.cssChildRow); }
regex = new RegExp( '(' + t.join('|') + ')' );
if (f && !p.ajaxUrl) {
if ($.isEmptyObject(c.cache)) {
// delayInit: true so nothing is in the cache
p.filteredRows = p.totalRows = c.$tbodies.eq(0).children('tr').not( p.countChildRows ? '' : '.' + c.cssChildRow ).length;
} else {
p.filteredRows = 0;
$.each(c.cache[0].normalized, function(i, el) {
p.filteredRows += p.regexRows.test(el[c.columns].$row[0].className) ? 0 : 1;
});
}
} else if (!f) {
p.filteredRows = p.totalRows;
}
p.totalPages = Math.ceil( p.totalRows / sz ); // needed for "pageSize" method
c.totalRows = p.totalRows;
c.filteredRows = p.filteredRows;
p.filteredPages = Math.ceil( p.filteredRows / sz ) || 0;
if ( Math.min( p.totalPages, p.filteredPages ) >= 0 ) {
t = (p.size * p.page > p.filteredRows);
p.startRow = (t) ? 1 : (p.filteredRows === 0 ? 0 : p.size * p.page + 1);
p.page = (t) ? 0 : p.page;
p.endRow = Math.min( p.filteredRows, p.totalRows, p.size * ( p.page + 1 ) );
$out = p.$container.find(p.cssPageDisplay);
// form the output string (can now get a new output string from the server)
s = ( p.ajaxData && p.ajaxData.output ? p.ajaxData.output || p.output : p.output )
// {page} = one-based index; {page+#} = zero based index +/- value
.replace(/\{page([\-+]\d+)?\}/gi, function(m,n){
return p.totalPages ? p.page + (n ? parseInt(n, 10) : 1) : 0;
})
// {totalPages}, {extra}, {extra:0} (array) or {extra : key} (object)
.replace(/\{\w+(\s*:\s*\w+)?\}/gi, function(m){
var len, indx,
str = m.replace(/[{}\s]/g,''),
extra = str.split(':'),
data = p.ajaxData,
// return zero for default page/row numbers
deflt = /(rows?|pages?)$/i.test(str) ? 0 : '';
if (/(startRow|page)/.test(extra[0]) && extra[1] === 'input') {
len = ('' + (extra[0] === 'page' ? p.totalPages : p.totalRows)).length;
indx = extra[0] === 'page' ? p.page + 1 : p.startRow;
return '<input type="text" class="ts-' + extra[0] + '" style="max-width:' + len + 'em" value="' + indx + '"/>';
}
return extra.length > 1 && data && data[extra[0]] ? data[extra[0]][extra[1]] : p[str] || (data ? data[str] : deflt) || deflt;
});
if ($out.length) {
$out[ ($out[0].tagName === 'INPUT') ? 'val' : 'html' ](s);
if ( p.$goto.length ) {
t = '';
pg = Math.min( p.totalPages, p.filteredPages );
for ( i = 1; i <= pg; i++ ) {
t += '<option>' + i + '</option>';
}
p.$goto.html(t).val( p.page + 1 );
}
// rebind startRow/page inputs
$out.find('.ts-startRow, .ts-page').unbind('change').bind('change', function(){
var v = $(this).val(),
pg = $(this).hasClass('ts-startRow') ? Math.floor( v/p.size ) + 1 : v;
c.$table.trigger('pageSet.pager', [ pg ]);
});
}
}
pagerArrows(p);
if (p.initialized && completed !== false) {
c.$table.trigger('pagerComplete', p);
// save pager info to storage
if (p.savePages && ts.storage) {
ts.storage(table, p.storageKey, {
page : p.page,
size : p.size
});
}
}
},
fixHeight = function(table, p) {
var d, h,
c = table.config,
$b = c.$tbodies.eq(0);
if (p.fixedHeight) {
$b.find('tr.pagerSavedHeightSpacer').remove();
h = $.data(table, 'pagerSavedHeight');
if (h) {
d = h - $b.height();
if ( d > 5 && $.data(table, 'pagerLastSize') === p.size && $b.children('tr:visible').length < p.size ) {
$b.append('<tr class="pagerSavedHeightSpacer ' + c.selectorRemove.replace(/^(\w+\.)/g,'') + '" style="height:' + d + 'px;"></tr>');
}
}
}
},
changeHeight = function(table, p) {
var $b = table.config.$tbodies.eq(0);
$b.find('tr.pagerSavedHeightSpacer').remove();
$.data(table, 'pagerSavedHeight', $b.height());
fixHeight(table, p);
$.data(table, 'pagerLastSize', p.size);
},
hideRows = function(table, p){
if (!p.ajaxUrl) {
var i,
lastIndex = 0,
c = table.config,
rows = c.$tbodies.eq(0).children('tr'),
l = rows.length,
s = ( p.page * p.size ),
e = s + p.size,
f = c.widgetOptions && c.widgetOptions.filter_filteredRow || 'filtered',
j = 0; // size counter
for ( i = 0; i < l; i++ ){
if ( !rows[i].className.match(f) ) {
if (j === s && rows[i].className.match(c.cssChildRow)) {
// hide child rows @ start of pager (if already visible)
rows[i].style.display = 'none';
} else {
rows[i].style.display = ( j >= s && j < e ) ? '' : 'none';
// don't count child rows
j += rows[i].className.match(c.cssChildRow + '|' + c.selectorRemove.replace(/^(\w+\.)/g,'')) && !p.countChildRows ? 0 : 1;
if ( j === e && rows[i].style.display !== 'none' && rows[i].className.match(ts.css.cssHasChild) ) {
lastIndex = i;
}
}
}
}
// add any attached child rows to last row of pager. Fixes part of issue #396
if ( lastIndex > 0 && rows[lastIndex].className.match(ts.css.cssHasChild) ) {
while ( ++lastIndex < l && rows[lastIndex].className.match(c.cssChildRow) ) {
rows[lastIndex].style.display = '';
}
}
}
},
hideRowsSetup = function(table, p){
p.size = parseInt( p.$size.val(), 10 ) || p.size;
$.data(table, 'pagerLastSize', p.size);
pagerArrows(p);
if ( !p.removeRows ) {
hideRows(table, p);
$(table).bind('sortEnd.pager filterEnd.pager', function(){
hideRows(table, p);
});
}
},
renderAjax = function(data, table, p, xhr, exception){
// process data
if ( typeof(p.ajaxProcessing) === "function" ) {
// ajaxProcessing result: [ total, rows, headers ]
var i, j, hsh, $f, $sh, t, th, d, l, rr_count,
c = table.config,
$t = c.$table,
tds = '',
result = p.ajaxProcessing(data, table, xhr) || [ 0, [] ],
hl = $t.find('thead th').length;
// Clean up any previous error.
ts.showError(table);
if ( exception ) {
if (c.debug) {
ts.log('Ajax Error', xhr, exception);
}
ts.showError(table,
xhr.status === 0 ? 'Not connected, verify Network' :
xhr.status === 404 ? 'Requested page not found [404]' :
xhr.status === 500 ? 'Internal Server Error [500]' :
exception === 'parsererror' ? 'Requested JSON parse failed' :
exception === 'timeout' ? 'Time out error' :
exception === 'abort' ? 'Ajax Request aborted' :
'Uncaught error: ' + xhr.statusText + ' [' + xhr.status + ']' );
c.$tbodies.eq(0).children('tr').detach();
p.totalRows = 0;
} else {
// process ajax object
if (!$.isArray(result)) {
p.ajaxData = result;
c.totalRows = p.totalRows = result.total;
c.filteredRows = p.filteredRows = typeof result.filteredRows !== 'undefined' ? result.filteredRows : result.total;
th = result.headers;
d = result.rows;
} else {
// allow [ total, rows, headers ] or [ rows, total, headers ]
t = isNaN(result[0]) && !isNaN(result[1]);
// ensure a zero returned row count doesn't fail the logical ||
rr_count = result[t ? 1 : 0];
p.totalRows = isNaN(rr_count) ? p.totalRows || 0 : rr_count;
// can't set filtered rows when returning an array
c.totalRows = c.filteredRows = p.filteredRows = p.totalRows;
d = p.totalRows === 0 ? [""] : result[t ? 0 : 1] || []; // row data
th = result[2]; // headers
}
l = d && d.length;
if (d instanceof jQuery) {
if (p.processAjaxOnInit) {
// append jQuery object
c.$tbodies.eq(0).children('tr').detach();
c.$tbodies.eq(0).append(d);
}
} else if (l) {
// build table from array
for ( i = 0; i < l; i++ ) {
tds += '<tr>';
for ( j = 0; j < d[i].length; j++ ) {
// build tbody cells; watch for data containing HTML markup - see #434
tds += /^\s*<td/.test(d[i][j]) ? $.trim(d[i][j]) : '<td>' + d[i][j] + '</td>';
}
tds += '</tr>';
}
// add rows to first tbody
if (p.processAjaxOnInit) {
c.$tbodies.eq(0).html( tds );
}
}
p.processAjaxOnInit = true;
// only add new header text if the length matches
if ( th && th.length === hl ) {
hsh = $t.hasClass('hasStickyHeaders');
$sh = hsh ? c.widgetOptions.$sticky.children('thead:first').children('tr').children() : '';
$f = $t.find('tfoot tr:first').children();
// don't change td headers (may contain pager)
c.$headers.filter('th').each(function(j){
var $t = $(this), icn;
// add new test within the first span it finds, or just in the header
if ( $t.find('.' + ts.css.icon).length ) {
icn = $t.find('.' + ts.css.icon).clone(true);
$t.find('.tablesorter-header-inner').html( th[j] ).append(icn);
if ( hsh && $sh.length ) {
icn = $sh.eq(j).find('.' + ts.css.icon).clone(true);
$sh.eq(j).find('.tablesorter-header-inner').html( th[j] ).append(icn);
}
} else {
$t.find('.tablesorter-header-inner').html( th[j] );
if (hsh && $sh.length) {
$sh.eq(j).find('.tablesorter-header-inner').html( th[j] );
}
}
$f.eq(j).html( th[j] );
});
}
}
if (c.showProcessing) {
ts.isProcessing(table); // remove loading icon
}
// make sure last pager settings are saved, prevents multiple server side calls with
// the same parameters
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);
fixHeight(table, p);
$t.trigger('updateCache', [function(){
if (p.initialized) {
// apply widgets after table has rendered & after a delay to prevent
// multiple applyWidget blocking code from blocking this trigger
setTimeout(function(){
$t
.trigger('applyWidgets')
.trigger('pagerChange', p);
}, 0);
}
}]);
}
if (!p.initialized) {
p.initialized = true;
$(table)
.trigger('applyWidgets')
.trigger('pagerInitialized', p);
}
},
getAjax = function(table, p){
var url = getAjaxUrl(table, p),
$doc = $(document),
counter,
c = table.config;
if ( url !== '' ) {
if (c.showProcessing) {
ts.isProcessing(table, true); // show loading icon
}
$doc.bind('ajaxError.pager', function(e, xhr, settings, exception) {
renderAjax(null, table, p, xhr, exception);
$doc.unbind('ajaxError.pager');
});
counter = ++p.ajaxCounter;
p.ajaxObject.url = url; // from the ajaxUrl option and modified by customAjaxUrl
p.ajaxObject.success = function(data, status, jqxhr) {
// Refuse to process old ajax commands that were overwritten by new ones - see #443
if (counter < p.ajaxCounter){
return;
}
renderAjax(data, table, p, jqxhr);
$doc.unbind('ajaxError.pager');
if (typeof p.oldAjaxSuccess === 'function') {
p.oldAjaxSuccess(data);
}
};
if (c.debug) {
ts.log('ajax initialized', p.ajaxObject);
}
$.ajax(p.ajaxObject);
}
},
getAjaxUrl = function(table, p) {
var c = table.config,
url = (p.ajaxUrl) ? p.ajaxUrl
// allow using "{page+1}" in the url string to switch to a non-zero based index
.replace(/\{page([\-+]\d+)?\}/, function(s,n){ return p.page + (n ? parseInt(n, 10) : 0); })
.replace(/\{size\}/g, p.size) : '',
sl = c.sortList,
fl = p.currentFilters || $(table).data('lastSearch') || [],
sortCol = url.match(/\{\s*sort(?:List)?\s*:\s*(\w*)\s*\}/),
filterCol = url.match(/\{\s*filter(?:List)?\s*:\s*(\w*)\s*\}/),
arry = [];
if (sortCol) {
sortCol = sortCol[1];
$.each(sl, function(i,v){
arry.push(sortCol + '[' + v[0] + ']=' + v[1]);
});
// if the arry is empty, just add the col parameter... "&{sortList:col}" becomes "&col"
url = url.replace(/\{\s*sort(?:List)?\s*:\s*(\w*)\s*\}/g, arry.length ? arry.join('&') : sortCol );
arry = [];
}
if (filterCol) {
filterCol = filterCol[1];
$.each(fl, function(i,v){
if (v) {
arry.push(filterCol + '[' + i + ']=' + encodeURIComponent(v));
}
});
// if the arry is empty, just add the fcol parameter... "&{filterList:fcol}" becomes "&fcol"
url = url.replace(/\{\s*filter(?:List)?\s*:\s*(\w*)\s*\}/g, arry.length ? arry.join('&') : filterCol );
p.currentFilters = fl;
}
if ( typeof(p.customAjaxUrl) === "function" ) {
url = p.customAjaxUrl(table, url);
}
if (c.debug) {
ts.log('Pager ajax url: ' + url);
}
return url;
},
renderTable = function(table, rows, p) {
var $tb, index, count, added,
$t = $(table),
c = table.config,
f = c.$table.hasClass('hasFilters'),
l = rows && rows.length || 0, // rows may be undefined
s = ( p.page * p.size ),
e = p.size;
if ( l < 1 ) {
if (c.debug) {
ts.log('Pager: no rows for pager to render');
}
// empty table, abort!
return;
}
if ( p.page >= p.totalPages ) {
// lets not render the table more than once
moveToLastPage(table, p);
}
p.isDisabled = false; // needed because sorting will change the page and re-enable the pager
if (p.initialized) { $t.trigger('pagerChange', p); }
if ( !p.removeRows ) {
hideRows(table, p);
} else {
ts.clearTableBody(table);
$tb = ts.processTbody(table, c.$tbodies.eq(0), true);
// not filtered, start from the calculated starting point (s)
// if filtered, start from zero
index = f ? 0 : s;
count = f ? 0 : s;
added = 0;
while (added < e && index < rows.length) {
if (!f || !/filtered/.test(rows[index][0].className)){
count++;
if (count > s && added <= e) {
added++;
$tb.append(rows[index]);
}
}
index++;
}
ts.processTbody(table, $tb, false);
}
updatePageDisplay(table, p);
if ( !p.isDisabled ) { fixHeight(table, p); }
$t.trigger('applyWidgets');
if (table.isUpdating) {
$t.trigger("updateComplete", table);
}
},
showAllRows = function(table, p){
if ( p.ajax ) {
pagerArrows(p, true);
} else {
p.isDisabled = true;
$.data(table, 'pagerLastPage', p.page);
$.data(table, 'pagerLastSize', p.size);
p.page = 0;
p.size = p.totalRows;
p.totalPages = 1;
$(table)
.addClass('pagerDisabled')
.removeAttr('aria-describedby')
.find('tr.pagerSavedHeightSpacer').remove();
renderTable(table, table.config.rowsCopy, p);
if (table.config.debug) {
ts.log('pager disabled');
}
}
// disable size selector
p.$size.add(p.$goto).add(p.$container.find('.ts-startRow, .ts-page')).each(function(){
$(this).attr('aria-disabled', 'true').addClass(p.cssDisabled)[0].disabled = true;
});
},
// updateCache if delayInit: true
updateCache = function(table) {
var c = table.config,
p = c.pager;
c.$table.trigger('updateCache', [ function(){
var i,
rows = [],
n = table.config.cache[0].normalized;
p.totalRows = n.length;
for (i = 0; i < p.totalRows; i++) {
rows.push(n[i][c.columns].$row);
}
c.rowsCopy = rows;
moveToPage(table, p, true);
} ]);
},
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 ( pageMoved !== false && p.initialized && $.isEmptyObject(table.config.cache)) {
return updateCache(table);
}
if ( p.page < 0 ) { p.page = 0; }
if ( p.page > ( pg - 1 ) && pg !== 0 ) { p.page = pg - 1; }
// fixes issue where one currentFilter is [] and the other is ['','',''],
// making the next if comparison think the filters are different (joined by commas). Fixes #202.
l.currentFilters = (l.currentFilters || []).join('') === '' ? [] : l.currentFilters;
p.currentFilters = (p.currentFilters || []).join('') === '' ? [] : p.currentFilters;
// don't allow rendering multiple times on the same page/size/totalRows/filters/sorts
if ( l.page === p.page && l.size === p.size && l.totalRows === p.totalRows &&
(l.currentFilters || []).join(',') === (p.currentFilters || []).join(',') &&
l.sortList === (c.sortList || []).join(',') ) { return; }
if (c.debug) {
ts.log('Pager changing to page ' + p.page);
}
p.last = {
page : p.page,
size : p.size,
// fixes #408; modify sortList otherwise it auto-updates
sortList : (c.sortList || []).join(','),
totalRows : p.totalRows,
currentFilters : p.currentFilters || []
};
if (p.ajax) {
getAjax(table, p);
} else if (!p.ajax) {
renderTable(table, c.rowsCopy, p);
}
$.data(table, 'pagerLastPage', p.page);
if (p.initialized && pageMoved !== false) {
$t
.trigger('pageMoved', p)
.trigger('applyWidgets');
if (table.isUpdating) {
$t.trigger('updateComplete');
}
}
},
setPageSize = function(table, size, p) {
p.size = size || p.size || 10;
p.$size.val(p.size);
$.data(table, 'pagerLastPage', p.page);
$.data(table, 'pagerLastSize', p.size);
p.totalPages = Math.ceil( p.totalRows / p.size );
p.filteredPages = Math.ceil( p.filteredRows / p.size );
moveToPage(table, p);
},
moveToFirstPage = function(table, p) {
p.page = 0;
moveToPage(table, p);
},
moveToLastPage = function(table, p) {
p.page = ( Math.min( p.totalPages, p.filteredPages ) - 1 );
moveToPage(table, p);
},
moveToNextPage = function(table, p) {
p.page++;
if ( p.page >= ( Math.min( p.totalPages, p.filteredPages ) - 1 ) ) {
p.page = ( Math.min( p.totalPages, p.filteredPages ) - 1 );
}
moveToPage(table, p);
},
moveToPrevPage = function(table, p) {
p.page--;
if ( p.page <= 0 ) {
p.page = 0;
}
moveToPage(table, p);
},
destroyPager = function(table, p){
showAllRows(table, p);
p.$container.hide(); // hide pager
table.config.appender = null; // remove pager appender function
p.initialized = false;
delete table.config.rowsCopy;
$(table).unbind('destroy.pager sortEnd.pager filterEnd.pager enable.pager disable.pager');
if (ts.storage) {
ts.storage(table, p.storageKey, '');
}
},
enablePager = function(table, p, triggered){
var info,
c = table.config;
p.$size.add(p.$goto).add(p.$container.find('.ts-startRow, .ts-page'))
.removeClass(p.cssDisabled)
.removeAttr('disabled')
.attr('aria-disabled', 'false');
p.isDisabled = false;
p.page = $.data(table, 'pagerLastPage') || p.page || 0;
p.size = $.data(table, 'pagerLastSize') || parseInt(p.$size.find('option[selected]').val(), 10) || p.size || 10;
p.$size.val(p.size); // set page size
p.totalPages = Math.ceil( Math.min( p.totalRows, p.filteredRows ) / p.size );
// if table id exists, include page display with aria info
if ( table.id ) {
info = table.id + '_pager_info';
p.$container.find(p.cssPageDisplay).attr('id', info);
c.$table.attr('aria-describedby', info);
}
if ( triggered ) {
c.$table.trigger('updateRows');
setPageSize(table, p.size, p);
hideRowsSetup(table, p);
fixHeight(table, p);
if (c.debug) {
ts.log('pager enabled');
}
}
};
$this.appender = function(table, rows) {
var c = table.config,
p = c.pager;
if ( !p.ajax ) {
c.rowsCopy = rows;
p.totalRows = p.countChildRows ? c.$tbodies.eq(0).children('tr').length : rows.length;
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);
}
};
$this.construct = function(settings) {
return this.each(function() {
// check if tablesorter has initialized
if (!(this.config && this.hasInitialized)) { return; }
var t, ctrls, fxn,
table = this,
c = table.config,
wo = c.widgetOptions,
p = c.pager = $.extend( true, {}, $.tablesorterPager.defaults, settings ),
$t = c.$table,
// added in case the pager is reinitialized after being destroyed.
pager = p.$container = $(p.container).addClass('tablesorter-pager').show();
if (c.debug) {
ts.log('Pager initializing');
}
p.oldAjaxSuccess = p.oldAjaxSuccess || p.ajaxObject.success;
c.appender = $this.appender;
if (ts.filter && $.inArray('filter', c.widgets) >= 0) {
// get any default filter settings (data-value attribute) fixes #388
p.currentFilters = c.$table.data('lastSearch') || ts.filter.setDefaults(table, c, c.widgetOptions) || [];
// set, but don't apply current filters
ts.setFilters(table, p.currentFilters, false);
}
if (p.savePages && ts.storage) {
t = ts.storage(table, p.storageKey) || {}; // fixes #387
p.page = isNaN(t.page) ? p.page : t.page;
p.size = ( isNaN(t.size) ? p.size : t.size ) || 10;
$.data(table, 'pagerLastSize', p.size);
}
// skipped rows
p.regexRows = new RegExp('(' + (wo.filter_filteredRow || 'filtered') + '|' + c.selectorRemove.replace(/^(\w+\.)/g,'') + '|' + c.cssChildRow + ')');
$t
.unbind('filterStart filterEnd sortEnd disable enable destroy update updateRows updateAll addRows pageSize '.split(' ').join('.pager '))
.bind('filterStart.pager', function(e, filters) {
p.currentFilters = filters;
// don't change page is filters are the same (pager updating, etc)
if (p.pageReset !== false && (c.lastCombinedFilter || '') !== (filters || []).join('')) {
p.page = p.pageReset; // fixes #456 & #565
}
})
// update pager after filter widget completes
.bind('filterEnd.pager sortEnd.pager', function() {
if (p.initialized) {
if (c.delayInit && c.rowsCopy && c.rowsCopy.length === 0) {
// make sure we have a copy of all table rows once the cache has been built
updateCache(table);
}
// update page display first, so we update p.filteredPages
updatePageDisplay(table, p, false);
moveToPage(table, p, false);
fixHeight(table, p);
}
})
.bind('disable.pager', function(e){
e.stopPropagation();
showAllRows(table, p);
})
.bind('enable.pager', function(e){
e.stopPropagation();
enablePager(table, p, true);
})
.bind('destroy.pager', function(e){
e.stopPropagation();
destroyPager(table, p);
})
.bind('update updateRows updateAll addRows '.split(' ').join('.pager '), function(e){
e.stopPropagation();
fixHeight(table, p);
var $rows = c.$tbodies.eq(0).children('tr');
p.totalRows = $rows.length - ( p.countChildRows ? 0 : $rows.filter('.' + c.cssChildRow).length );
p.totalPages = Math.ceil( p.totalRows / p.size );
updatePageDisplay(table, p);
hideRows(table, p);
})
.bind('pageSize.pager', function(e,v){
e.stopPropagation();
setPageSize(table, parseInt(v, 10) || 10, p);
hideRows(table, p);
updatePageDisplay(table, p, false);
if (p.$size.length) { p.$size.val(p.size); } // twice?
})
.bind('pageSet.pager', function(e,v){
e.stopPropagation();
p.page = (parseInt(v, 10) || 1) - 1;
if (p.$goto.length) { p.$goto.val(p.size); } // twice?
moveToPage(table, p, true);
updatePageDisplay(table, p, false);
});
// clicked controls
ctrls = [ p.cssFirst, p.cssPrev, p.cssNext, p.cssLast ];
fxn = [ moveToFirstPage, moveToPrevPage, moveToNextPage, moveToLastPage ];
pager.find(ctrls.join(','))
.attr("tabindex", 0)
.unbind('click.pager')
.bind('click.pager', function(e){
e.stopPropagation();
var i, $t = $(this), l = ctrls.length;
if ( !$t.hasClass(p.cssDisabled) ) {
for (i = 0; i < l; i++) {
if ($t.is(ctrls[i])) {
fxn[i](table, p);
break;
}
}
}
});
// goto selector
p.$goto = pager.find(p.cssGoto);
if ( p.$goto.length ) {
p.$goto
.unbind('change')
.bind('change', function(){
p.page = $(this).val() - 1;
moveToPage(table, p, true);
updatePageDisplay(table, p, false);
});
}
// page size selector
p.$size = pager.find(p.cssPageSize);
if ( p.$size.length ) {
// setting an option as selected appears to cause issues with initial page size
p.$size.find('option').removeAttr('selected');
p.$size.unbind('change.pager').bind('change.pager', function() {
p.$size.val( $(this).val() ); // in case there are more than one pagers
if ( !$(this).hasClass(p.cssDisabled) ) {
setPageSize(table, parseInt( $(this).val(), 10 ), p);
changeHeight(table, p);
}
return false;
});
}
// clear initialized flag
p.initialized = false;
// before initialization event
$t.trigger('pagerBeforeInitialized', p);
enablePager(table, p, false);
if ( typeof(p.ajaxUrl) === 'string' ) {
// ajax pager; interact with database
p.ajax = true;
//When filtering with ajax, allow only custom filtering function, disable default filtering since it will be done server side.
c.widgetOptions.filter_serversideFiltering = true;
c.serverSideSorting = true;
moveToPage(table, p);
} else {
p.ajax = false;
// Regular pager; all rows stored in memory
$(this).trigger("appendCache", true);
hideRowsSetup(table, p);
}
changeHeight(table, p);
// pager initialized
if (!p.ajax) {
p.initialized = true;
$(table).trigger('pagerInitialized', p);
}
});
};
}() });
// see #486
ts.showError = function(table, message){
$(table).each(function(){
var $row,
c = this.config,
errorRow = c.pager && c.pager.cssErrorRow || c.widgetOptions.pager_css && c.widgetOptions.pager_css.errorRow || 'tablesorter-errorRow';
if (c) {
if (typeof message === 'undefined') {
c.$table.find('thead').find(c.selectorRemove).remove();
} else {
$row = ( /tr\>/.test(message) ? $(message) : $('<tr><td colspan="' + c.columns + '">' + message + '</td></tr>') )
.click(function(){
$(this).remove();
})
// add error row to thead instead of tbody, or clicking on the header will result in a parser error
.appendTo( c.$table.find('thead:first') )
.addClass( errorRow + ' ' + c.selectorRemove.replace(/^(\w+\.)/g,'') )
.attr({
role : 'alert',
'aria-live' : 'assertive'
});
}
}
});
};
// extend plugin scope
$.fn.extend({
tablesorterPager: $.tablesorterPager.construct
});
})(jQuery);
File diff suppressed because one or more lines are too long
@@ -0,0 +1,183 @@
/**** Filter Formatter Elements ****/
.tablesorter .tablesorter-filter-row td {
text-align: center;
font-size: 0.9em;
font-weight: normal;
}
/**** Sliders ****/
/* shrink the sliders to look nicer inside of a table cell */
.tablesorter .ui-slider, .tablesorter input.range {
width: 90%;
margin: 2px auto 2px auto; /* add enough top margin so the tooltips will fit */
font-size: 0.8em;
}
.tablesorter .ui-slider {
top: 12px;
}
.tablesorter .ui-slider .ui-slider-handle {
width: 0.9em;
height: 0.9em;
}
.tablesorter .ui-datepicker {
font-size: 0.8em;
}
.tablesorter .ui-slider-horizontal {
height: 0.5em;
}
/* Add tooltips to slider handles */
.tablesorter .value-popup:after {
content : attr(data-value);
position: absolute;
bottom: 14px;
left: -7px;
min-width: 18px;
height: 12px;
background-color: #444;
background-image: -webkit-gradient(linear, left top, left bottom, from(#444444), to(#999999));
background-image: -webkit-linear-gradient(top, #444, #999);
background-image: -moz-linear-gradient(top, #444, #999);
background-image: -o-linear-gradient(top, #444, #999);
background-image: linear-gradient(to bottom, #444, #999);
-webkit-border-radius: 3px;
border-radius: 3px;
-webkit-background-clip: padding-box; background-clip: padding-box;
-webkit-box-shadow: 0px 0px 4px 0px #777;
box-shadow: 0px 0px 4px 0px #777;
border: #444 1px solid;
color: #fff;
font: 1em/1.1em Arial, Sans-Serif;
padding: 1px;
text-align: center;
}
.tablesorter .value-popup:before {
content: "";
position: absolute;
width: 0;
height: 0;
border-top: 8px solid #777;
border-left: 8px solid transparent;
border-right: 8px solid transparent;
top: -8px;
left: 50%;
margin-left: -8px;
margin-top: -1px;
}
/**** Date Picker ****/
.tablesorter .dateFrom, .tablesorter .dateTo {
width: 80px;
margin: 2px 5px;
}
/**** Color Picker/HTML5Number Toggle button ****/
.tablesorter .button {
width: 14px;
height: 14px;
background: #fcfff4;
background: -webkit-linear-gradient(top, #fcfff4 0%, #dfe5d7 40%, #b3bead 100%);
background: -moz-linear-gradient(top, #fcfff4 0%, #dfe5d7 40%, #b3bead 100%);
background: -o-linear-gradient(top, #fcfff4 0%, #dfe5d7 40%, #b3bead 100%);
background: -ms-linear-gradient(top, #fcfff4 0%, #dfe5d7 40%, #b3bead 100%);
background: linear-gradient(top, #fcfff4 0%, #dfe5d7 40%, #b3bead 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fcfff4', endColorstr='#b3bead', GradientType=0 );
margin: 1px 5px 1px 1px;
-webkit-border-radius: 25px;
-moz-border-radius: 25px;
border-radius: 25px;
-webkit-box-shadow: inset 0px 1px 1px white, 0px 1px 3px rgba(0,0,0,0.5);
-moz-box-shadow: inset 0px 1px 1px white, 0px 1px 3px rgba(0,0,0,0.5);
box-shadow: inset 0px 1px 1px white, 0px 1px 3px rgba(0,0,0,0.5);
position: relative;
top: 3px;
display: inline-block;
}
.tablesorter .button label {
cursor: pointer;
position: absolute;
width: 10px;
height: 10px;
-webkit-border-radius: 25px;
-moz-border-radius: 25px;
border-radius: 25px;
left: 2px;
top: 2px;
-webkit-box-shadow: inset 0px 1px 1px rgba(0,0,0,0.5), 0px 1px 0px rgba(255,255,255,1);
-moz-box-shadow: inset 0px 1px 1px rgba(0,0,0,0.5), 0px 1px 0px rgba(255,255,255,1);
box-shadow: inset 0px 1px 1px rgba(0,0,0,0.5), 0px 1px 0px rgba(255,255,255,1);
background: #45484d;
background: -webkit-linear-gradient(top, #222 0%, #45484d 100%);
background: -moz-linear-gradient(top, #222 0%, #45484d 100%);
background: -o-linear-gradient(top, #222 0%, #45484d 100%);
background: -ms-linear-gradient(top, #222 0%, #45484d 100%);
background: linear-gradient(top, #222 0%, #45484d 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#222', endColorstr='#45484d', GradientType=0 );
}
.tablesorter .button label:after {
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
filter: alpha(opacity=0);
opacity: 0;
content: '';
position: absolute;
width: 8px;
height: 8px;
background: #55f;
background: -webkit-linear-gradient(top, #aaf 0%, #55f 100%);
background: -moz-linear-gradient(top, #aaf 0%, #55f 100%);
background: -o-linear-gradient(top, #aaf 0%, #55f 100%);
background: -ms-linear-gradient(top, #aaf 0%, #55f 100%);
background: linear-gradient(top, #aaf 0%, #55f 100%);
-webkit-border-radius: 25px;
-moz-border-radius: 25px;
border-radius: 25px;
top: 1px;
left: 1px;
-webkit-box-shadow: inset 0px 1px 1px #fff, 0px 1px 3px rgba(0,0,0,0.5);
-moz-box-shadow: inset 0px 1px 1px #fff, 0px 1px 3px rgba(0,0,0,0.5);
box-shadow: inset 0px 1px 1px #fff, 0px 1px 3px rgba(0,0,0,0.5);
}
.tablesorter .button label:hover::after {
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=30)";
filter: alpha(opacity=30);
opacity: 0.3;
}
.tablesorter .button input[type=checkbox] {
visibility: hidden;
}
.tablesorter .button input[type=checkbox]:checked + label:after {
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
filter: alpha(opacity=100);
opacity: 1;
}
.tablesorter .colorpicker {
width: 30px;
height: 18px;
}
.tablesorter .ui-spinner-input {
width: 100px;
height: 18px;
}
.tablesorter .currentColor, .tablesorter .ui-spinner {
position: relative;
}
.tablesorter input.number {
position: relative;
}
/* hide filter row */
.tablesorter .tablesorter-filter-row.hideme td * {
height: 1px;
min-height: 0;
border: 0;
padding: 0;
margin: 0;
/* don't use visibility: hidden because it disables tabbing */
opacity: 0;
filter: alpha(opacity=0);
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 48 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 284 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 B

Some files were not shown because too many files have changed in this diff Show More