mirror of
https://github.com/Mottie/tablesorter.git
synced 2024-11-15 23:54:22 +00:00
parent
c7d4395c85
commit
55d19b3a95
@ -253,7 +253,7 @@
|
||||
};
|
||||
|
||||
function buildParserCache( c, $tbodies ) {
|
||||
var rows, list, l, i, h, ch, np, p, e, time, tb, len,
|
||||
var rows, list, span, max, colIndex, i, h, ch, np, p, e, time, tb, len,
|
||||
table = c.table,
|
||||
j = 0,
|
||||
debug = {};
|
||||
@ -274,39 +274,48 @@
|
||||
while (j < len) {
|
||||
rows = tb[j].rows;
|
||||
if (rows.length) {
|
||||
l = c.columns; // rows[j].cells.length;
|
||||
for (i = 0; i < l; i++) {
|
||||
h = c.$headerIndexed[i];
|
||||
// get column indexed table cell
|
||||
ch = ts.getColumnData( table, c.headers, i );
|
||||
// get column parser/extractor
|
||||
e = ts.getParserById( ts.getData(h, ch, 'extractor') );
|
||||
p = ts.getParserById( ts.getData(h, ch, 'sorter') );
|
||||
np = ts.getData(h, ch, 'parser') === 'false';
|
||||
// empty cells behaviour - keeping emptyToBottom for backwards compatibility
|
||||
c.empties[i] = ( ts.getData(h, ch, 'empty') || c.emptyTo || (c.emptyToBottom ? 'bottom' : 'top' ) ).toLowerCase();
|
||||
// text strings behaviour in numerical sorts
|
||||
c.strings[i] = ( ts.getData(h, ch, 'string') || c.stringTo || 'max' ).toLowerCase();
|
||||
if (np) {
|
||||
p = ts.getParserById('no-parser');
|
||||
colIndex = 0;
|
||||
max = c.columns; // rows[j].cells.length;
|
||||
for (i = 0; i < max; i++) {
|
||||
h = c.$headerIndexed[ colIndex ];
|
||||
if ( h && h.length ) {
|
||||
// get column indexed table cell
|
||||
ch = ts.getColumnData( table, c.headers, colIndex );
|
||||
// get column parser/extractor
|
||||
e = ts.getParserById( ts.getData(h, ch, 'extractor') );
|
||||
p = ts.getParserById( ts.getData(h, ch, 'sorter') );
|
||||
np = ts.getData(h, ch, 'parser') === 'false';
|
||||
// empty cells behaviour - keeping emptyToBottom for backwards compatibility
|
||||
c.empties[colIndex] = ( ts.getData(h, ch, 'empty') || c.emptyTo || (c.emptyToBottom ? 'bottom' : 'top' ) ).toLowerCase();
|
||||
// text strings behaviour in numerical sorts
|
||||
c.strings[colIndex] = ( ts.getData(h, ch, 'string') || c.stringTo || 'max' ).toLowerCase();
|
||||
if (np) {
|
||||
p = ts.getParserById('no-parser');
|
||||
}
|
||||
if (!e) {
|
||||
// For now, maybe detect someday
|
||||
e = false;
|
||||
}
|
||||
if (!p) {
|
||||
p = detectParserForColumn(c, rows, -1, i);
|
||||
}
|
||||
if (c.debug) {
|
||||
debug[ '(' + colIndex + ') ' + h.text() ] = {
|
||||
parser : p.id,
|
||||
extractor : e ? e.id : 'none',
|
||||
string : c.strings[colIndex],
|
||||
empty : c.empties[colIndex]
|
||||
};
|
||||
}
|
||||
list.parsers[colIndex] = p;
|
||||
list.extractors[colIndex] = e;
|
||||
span = h[0].colSpan - 1;
|
||||
if ( span > 0 ) {
|
||||
colIndex += span;
|
||||
max += span;
|
||||
}
|
||||
}
|
||||
if (!e) {
|
||||
// For now, maybe detect someday
|
||||
e = false;
|
||||
}
|
||||
if (!p) {
|
||||
p = detectParserForColumn(c, rows, -1, i);
|
||||
}
|
||||
if (c.debug) {
|
||||
debug[ '(' + i + ') ' + h.text() ] = {
|
||||
parser : p.id,
|
||||
extractor : e ? e.id : 'none',
|
||||
string : c.strings[i],
|
||||
empty : c.empties[i]
|
||||
};
|
||||
}
|
||||
list.parsers[i] = p;
|
||||
list.extractors[i] = e;
|
||||
colIndex++;
|
||||
}
|
||||
}
|
||||
j += (list.parsers.length) ? len : 1;
|
||||
@ -326,8 +335,8 @@
|
||||
|
||||
/* utils */
|
||||
function buildCache(table, callback, $tbodies) {
|
||||
var cc, t, v, i, j, k, $tb, $row, cols, cacheTime,
|
||||
totalRows, rowData, prevRowData, colMax,
|
||||
var cc, t, v, i, j, k, $tb, $row, cols, cell, cacheTime,
|
||||
totalRows, rowData, prevRowData, colMax, span, cacheIndex, max,
|
||||
c = table.config,
|
||||
parsers = c.parsers;
|
||||
// update tbody variable
|
||||
@ -379,29 +388,52 @@
|
||||
t = prevRowData.child.length;
|
||||
prevRowData.child[ t ] = [];
|
||||
// child row content does not account for colspans/rowspans; so indexing may be off
|
||||
for ( j = 0; j < c.columns; j++ ) {
|
||||
prevRowData.child[ t ][ j ] = ts.getParsedText( c, v[ j ], j );
|
||||
cacheIndex = 0;
|
||||
max = c.columns;
|
||||
for ( j = 0; j < max; j++ ) {
|
||||
cell = v[ j ];
|
||||
if ( cell ) {
|
||||
prevRowData.child[ t ][ j ] = ts.getParsedText( c, cell, j );
|
||||
span = v[ j ].colSpan - 1;
|
||||
if ( span > 0 ) {
|
||||
cacheIndex += span;
|
||||
max += span
|
||||
}
|
||||
}
|
||||
cacheIndex++;
|
||||
}
|
||||
// go to the next for loop
|
||||
continue;
|
||||
}
|
||||
rowData.$row = $row;
|
||||
rowData.order = i; // add original row position to rowCache
|
||||
for ( j = 0; j < c.columns; ++j ) {
|
||||
if (typeof parsers[ j ] === 'undefined') {
|
||||
if ( c.debug ) {
|
||||
console.warn( 'No parser found for cell:', $row[ 0 ].cells[ j ], 'does it have a header?' );
|
||||
cacheIndex = 0;
|
||||
max = c.columns;
|
||||
for ( j = 0; j < max; ++j ) {
|
||||
cell = $row[ 0 ].cells[ j ];
|
||||
if ( cell ) {
|
||||
if (typeof parsers[ cacheIndex ] === 'undefined') {
|
||||
if ( c.debug ) {
|
||||
console.warn( 'No parser found for cell:', cell, 'does it have a header?' );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
t = ts.getElementText( c, cell, cacheIndex );
|
||||
rowData.raw[ cacheIndex ] = t; // save original row text
|
||||
v = ts.getParsedText( c, cell, cacheIndex, t );
|
||||
cols[ cacheIndex ] = v;
|
||||
if ( ( parsers[ cacheIndex ].type || '' ).toLowerCase() === 'numeric' ) {
|
||||
// determine column max value (ignore sign)
|
||||
colMax[ j ] = Math.max( Math.abs( v ) || 0, colMax[ cacheIndex ] || 0 );
|
||||
}
|
||||
// allow colSpan in tbody
|
||||
span = cell.colSpan - 1;
|
||||
if ( span > 0 ) {
|
||||
cacheIndex += span;
|
||||
max += span;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
t = ts.getElementText( c, $row[ 0 ].cells[j], j );
|
||||
rowData.raw.push( t ); // save original row text
|
||||
v = ts.getParsedText( c, $row[ 0 ].cells[ j ], j, t );
|
||||
cols.push( v );
|
||||
if ( ( parsers[ j ].type || '' ).toLowerCase() === 'numeric' ) {
|
||||
// determine column max value (ignore sign)
|
||||
colMax[ j ] = Math.max( Math.abs( v ) || 0, colMax[ j ] || 0 );
|
||||
}
|
||||
cacheIndex++;
|
||||
}
|
||||
// ensure rowData is always in the same location (after the last column)
|
||||
cols[ c.columns ] = rowData;
|
||||
@ -487,7 +519,9 @@
|
||||
$t = c.$headers.filter('[data-column="' + indx + '"]');
|
||||
// target sortable column cells, unless there are none, then use non-sortable cells
|
||||
// .last() added in jQuery 1.4; use .filter(':last') to maintain compatibility with jQuery v1.2.6
|
||||
c.$headerIndexed[indx] = $t.not('.sorter-false').length ? $t.not('.sorter-false').filter(':last') : $t.filter(':last');
|
||||
c.$headerIndexed[indx] = $t.length ?
|
||||
$t.not('.sorter-false').length ? $t.not('.sorter-false').filter(':last') : $t.filter(':last') :
|
||||
$();
|
||||
}
|
||||
c.$table.find(c.selectorHeaders).attr({
|
||||
scope: 'col',
|
||||
|
@ -647,71 +647,81 @@
|
||||
return parsed ? c.parsers[column].format( filter, c.table, [], column ) : filter;
|
||||
},
|
||||
buildRow: function( table, c, wo ) {
|
||||
var col, column, $header, makeSelect, disabled, name, ffxn, tmp,
|
||||
var $filter, col, column, $header, makeSelect, disabled, name, ffxn, tmp,
|
||||
// c.columns defined in computeThIndexes()
|
||||
cellFilter = wo.filter_cellFilter,
|
||||
columns = c.columns,
|
||||
arry = $.isArray( cellFilter ),
|
||||
buildFilter = '<tr role="row" class="' + tscss.filterRow + ' ' + c.cssIgnoreRow + '">';
|
||||
for ( column = 0; column < columns; column++ ) {
|
||||
buildFilter += '<td';
|
||||
if ( arry ) {
|
||||
buildFilter += ( cellFilter[ column ] ? ' class="' + cellFilter[ column ] + '"' : '' );
|
||||
} else {
|
||||
buildFilter += ( cellFilter !== '' ? ' class="' + cellFilter + '"' : '' );
|
||||
if ( c.$headerIndexed[ column ].length ) {
|
||||
buildFilter += '<td data-column="' + column + '"';
|
||||
// account for entire column set with colspan. See #1047
|
||||
tmp = c.$headerIndexed[ column ] && c.$headerIndexed[ column ][0].colSpan || 0;
|
||||
if ( tmp > 1 ) {
|
||||
buildFilter += ' colspan="' + tmp + '"';
|
||||
}
|
||||
if ( arry ) {
|
||||
buildFilter += ( cellFilter[ column ] ? ' class="' + cellFilter[ column ] + '"' : '' );
|
||||
} else {
|
||||
buildFilter += ( cellFilter !== '' ? ' class="' + cellFilter + '"' : '' );
|
||||
}
|
||||
buildFilter += '></td>';
|
||||
}
|
||||
buildFilter += '></td>';
|
||||
}
|
||||
c.$filters = $( buildFilter += '</tr>' )
|
||||
.appendTo( c.$table.children( 'thead' ).eq( 0 ) )
|
||||
.find( 'td' );
|
||||
.children( 'td' );
|
||||
// build each filter input
|
||||
for ( column = 0; column < columns; column++ ) {
|
||||
disabled = false;
|
||||
// assuming last cell of a column is the main column
|
||||
$header = c.$headerIndexed[ column ];
|
||||
ffxn = ts.getColumnData( table, wo.filter_functions, column );
|
||||
makeSelect = ( wo.filter_functions && ffxn && typeof ffxn !== 'function' ) ||
|
||||
$header.hasClass( 'filter-select' );
|
||||
// get data from jQuery data, metadata, headers option or header class name
|
||||
col = ts.getColumnData( table, c.headers, column );
|
||||
disabled = ts.getData( $header[0], col, 'filter' ) === 'false' ||
|
||||
ts.getData( $header[0], col, 'parser' ) === 'false';
|
||||
if ( $header && $header.length ) {
|
||||
$filter = c.$filters.filter( '[data-column="' + column + '"]' );
|
||||
ffxn = ts.getColumnData( table, wo.filter_functions, column );
|
||||
makeSelect = ( wo.filter_functions && ffxn && typeof ffxn !== 'function' ) ||
|
||||
$header.hasClass( 'filter-select' );
|
||||
// get data from jQuery data, metadata, headers option or header class name
|
||||
col = ts.getColumnData( table, c.headers, column );
|
||||
disabled = ts.getData( $header[0], col, 'filter' ) === 'false' ||
|
||||
ts.getData( $header[0], col, 'parser' ) === 'false';
|
||||
|
||||
if ( makeSelect ) {
|
||||
buildFilter = $( '<select>' ).appendTo( c.$filters.eq( column ) );
|
||||
} else {
|
||||
ffxn = ts.getColumnData( table, wo.filter_formatter, column );
|
||||
if ( ffxn ) {
|
||||
wo.filter_formatterCount++;
|
||||
buildFilter = ffxn( c.$filters.eq( column ), column );
|
||||
// no element returned, so lets go find it
|
||||
if ( buildFilter && buildFilter.length === 0 ) {
|
||||
buildFilter = c.$filters.eq( column ).children( 'input' );
|
||||
}
|
||||
// element not in DOM, so lets attach it
|
||||
if ( buildFilter && ( buildFilter.parent().length === 0 ||
|
||||
( buildFilter.parent().length && buildFilter.parent()[0] !== c.$filters[column] ) ) ) {
|
||||
c.$filters.eq( column ).append( buildFilter );
|
||||
}
|
||||
if ( makeSelect ) {
|
||||
buildFilter = $( '<select>' ).appendTo( $filter );
|
||||
} else {
|
||||
buildFilter = $( '<input type="search">' ).appendTo( c.$filters.eq( column ) );
|
||||
ffxn = ts.getColumnData( table, wo.filter_formatter, column );
|
||||
if ( ffxn ) {
|
||||
wo.filter_formatterCount++;
|
||||
buildFilter = ffxn( $filter, column );
|
||||
// no element returned, so lets go find it
|
||||
if ( buildFilter && buildFilter.length === 0 ) {
|
||||
buildFilter = $filter.children( 'input' );
|
||||
}
|
||||
// element not in DOM, so lets attach it
|
||||
if ( buildFilter && ( buildFilter.parent().length === 0 ||
|
||||
( buildFilter.parent().length && buildFilter.parent()[0] !== $filter[0] ) ) ) {
|
||||
$filter.append( buildFilter );
|
||||
}
|
||||
} else {
|
||||
buildFilter = $( '<input type="search">' ).appendTo( $filter );
|
||||
}
|
||||
if ( buildFilter ) {
|
||||
tmp = $header.data( 'placeholder' ) ||
|
||||
$header.attr( 'data-placeholder' ) ||
|
||||
wo.filter_placeholder.search || '';
|
||||
buildFilter.attr( 'placeholder', tmp );
|
||||
}
|
||||
}
|
||||
if ( buildFilter ) {
|
||||
tmp = $header.data( 'placeholder' ) ||
|
||||
$header.attr( 'data-placeholder' ) ||
|
||||
wo.filter_placeholder.search || '';
|
||||
buildFilter.attr( 'placeholder', tmp );
|
||||
}
|
||||
}
|
||||
if ( buildFilter ) {
|
||||
// add filter class name
|
||||
name = ( $.isArray( wo.filter_cssFilter ) ?
|
||||
( typeof wo.filter_cssFilter[column] !== 'undefined' ? wo.filter_cssFilter[column] || '' : '' ) :
|
||||
wo.filter_cssFilter ) || '';
|
||||
buildFilter.addClass( tscss.filter + ' ' + name ).attr( 'data-column', column );
|
||||
if ( disabled ) {
|
||||
buildFilter.attr( 'placeholder', '' ).addClass( tscss.filterDisabled )[0].disabled = true;
|
||||
// add filter class name
|
||||
name = ( $.isArray( wo.filter_cssFilter ) ?
|
||||
( typeof wo.filter_cssFilter[column] !== 'undefined' ? wo.filter_cssFilter[column] || '' : '' ) :
|
||||
wo.filter_cssFilter ) || '';
|
||||
buildFilter.addClass( tscss.filter + ' ' + name ).attr( 'data-column', column );
|
||||
if ( disabled ) {
|
||||
buildFilter.attr( 'placeholder', '' ).addClass( tscss.filterDisabled )[0].disabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1261,7 +1271,7 @@
|
||||
// ( '> -10' => '> -100' will ignore hidden rows )
|
||||
!( regex.isNeg1.test( val ) || regex.isNeg2.test( val ) ) &&
|
||||
// if filtering using a select without a 'filter-match' class ( exact match ) - fixes #593
|
||||
!( val !== '' && c.$filters && c.$filters.eq( indx ).find( 'select' ).length &&
|
||||
!( val !== '' && c.$filters && c.$filters.filter( '[data-column="' + indx + '"]' ).find( 'select' ).length &&
|
||||
!c.$headerIndexed[indx].hasClass( 'filter-match' ) );
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user