mirror of
https://github.com/Mottie/tablesorter.git
synced 2024-11-15 23:54:22 +00:00
Filter: selectSource option now accepts an array of objects
This commit is contained in:
parent
d1ba6178d7
commit
f51b39388a
2
dist/js/widgets/widget-filter.min.js
vendored
2
dist/js/widgets/widget-filter.min.js
vendored
File diff suppressed because one or more lines are too long
@ -3023,9 +3023,29 @@ $('table').trigger('search', false);</pre></div>
|
||||
<td>Function</td>
|
||||
<td>null</td>
|
||||
<td>
|
||||
Filter widget: Include a function to return an array of values to be added to the column filter select (<span class="version">v2.16.0</span>; <span class="version updated">v2.23.4</span>).
|
||||
Filter widget: Include a function to return an array of values to be added to the column filter select (<span class="version">v2.16.0</span>; <span class="version updated">v2.24.4</span>).
|
||||
<div class="collapsible">
|
||||
<br>
|
||||
In <span class="version updated">v2.24.4</span>, this option will now accept an array of objects which can contain extra information for each option. Here is an example:
|
||||
<pre class="prettyprint lang-js">filter_selectSource : {
|
||||
0 : [
|
||||
{ value : '/\\.js$/', 'data-class' : 'ui-icon-script', text : 'javascript' },
|
||||
{ value : '/\\.(jpg|png|gif)$/', 'data-class' : 'ui-icon-image', text : 'Image' },
|
||||
// plain strings are also acceptable - the string is added to both the text & value attribute
|
||||
'foobar',
|
||||
{ value : '.css', 'data-class' : 'ui-icon-note', text : 'CSS' },
|
||||
{ value : '.html', 'data-class' : 'ui-icon-document', text : 'HTML page' },
|
||||
{ value : '/\\.(json|txt|md)$/', 'data-class' : 'ui-icon-help', text : 'Misc' },
|
||||
]
|
||||
}</pre>
|
||||
<ul>
|
||||
<li>Each object entry <em>must</em> include a <code>text</code> property, or it will get ignored.</li>
|
||||
<li>If no <code>value</code> property is set, the option value will be equal to the <code>text</code> (IE requires a value defined for every option).</li>
|
||||
<li>Plain strings are still allowed within the array. If included, both the option text & value attribute will contain the string.</li>
|
||||
<li><span class="label warning">*NOTE*</span> when returning an array containing objects, the options will not be reduced to obtain unique selections.</li>
|
||||
<li><span class="label warning">*NOTE*</span> because this example is providing a fixed select option source, it can not support "filter-onlyAvail" (only show available options after filtering).</li>
|
||||
</ul>
|
||||
|
||||
In <span class="version updated">v2.21.5</span>, this option will now override the <code>filter_function</code> options (<em>so you need to add them back!</em>), allowing the addition of custom select options and still maintain basic filtering action - see <a href="http://jsfiddle.net/Mottie/856bzzeL/117/">this demo</a> (<a href="http://stackoverflow.com/a/29506523/145346">ref</a>).<br>
|
||||
<br>
|
||||
In <span class="version updated">v2.17.0</span>, the <code>filter_selectSource</code> column can also be referenced by using a jQuery selector (e.g. class name or ID) that points to a table <em>header</em> cell.<br>
|
||||
|
@ -112,6 +112,7 @@
|
||||
or : function( c, data, vars ) {
|
||||
// look for "|", but not if it is inside of a regular expression
|
||||
if ( ( tsf.regex.orTest.test( data.iFilter ) || tsf.regex.orSplit.test( data.filter ) ) &&
|
||||
// this test for regex has potential to slow down the overall search
|
||||
!tsf.regex.regex.test( data.filter ) ) {
|
||||
var indx, filterMatched, query, regex,
|
||||
// duplicate data but split filter
|
||||
@ -997,7 +998,7 @@
|
||||
return filterMatched;
|
||||
},
|
||||
processRow: function( c, data, vars ) {
|
||||
var hasSelect, result, val, filterMatched,
|
||||
var result, filterMatched,
|
||||
fxn, ffxn, txt,
|
||||
regex = tsf.regex,
|
||||
wo = c.widgetOptions,
|
||||
@ -1096,21 +1097,13 @@
|
||||
data.filter = ts.replaceAccents( data.filter );
|
||||
}
|
||||
|
||||
val = true;
|
||||
if ( wo.filter_defaultFilter && regex.iQuery.test( vars.defaultColFilter[ columnIndex ] ) ) {
|
||||
data.filter = tsf.defaultFilter( data.filter, vars.defaultColFilter[ columnIndex ] );
|
||||
// val is used to indicate that a filter select is using a default filter;
|
||||
// so we override the exact & partial matches
|
||||
val = false;
|
||||
}
|
||||
// data.iFilter = case insensitive ( if wo.filter_ignoreCase is true ),
|
||||
// data.filter = case sensitive
|
||||
data.iFilter = wo.filter_ignoreCase ? ( data.filter || '' ).toLowerCase() : data.filter;
|
||||
fxn = vars.functions[ columnIndex ];
|
||||
hasSelect = c.$headerIndexed[ columnIndex ].hasClass( 'filter-select' );
|
||||
filterMatched = null;
|
||||
if ( fxn || ( hasSelect && val ) ) {
|
||||
if ( fxn === true || hasSelect ) {
|
||||
if ( fxn ) {
|
||||
if ( fxn === true ) {
|
||||
// default selector uses exact match unless 'filter-match' class is found
|
||||
filterMatched = data.isMatch ?
|
||||
// data.iExact may be a number
|
||||
@ -1425,7 +1418,6 @@
|
||||
// custom select source function for a SPECIFIC COLUMN
|
||||
arry = fxn( table, column, onlyAvail );
|
||||
}
|
||||
|
||||
if ( arry === false ) {
|
||||
// fall back to original method
|
||||
arry = tsf.getOptions( table, column, onlyAvail );
|
||||
@ -1439,18 +1431,19 @@
|
||||
return false;
|
||||
}
|
||||
table = $( table )[0];
|
||||
var cts, txt, indx, len,
|
||||
var cts, txt, indx, len, parsedTxt, str,
|
||||
c = table.config,
|
||||
validColumn = typeof column !== 'undefined' && column !== null && column >= 0 && column < c.columns,
|
||||
parsed = [];
|
||||
|
||||
// get unique elements and sort the list
|
||||
// if $.tablesorter.sortText exists ( not in the original tablesorter ),
|
||||
// then natural sort the list otherwise use a basic sort
|
||||
arry = $.grep( arry, function( value, indx ) {
|
||||
if ( value.text ) {
|
||||
return true;
|
||||
}
|
||||
return $.inArray( value, arry ) === indx;
|
||||
});
|
||||
|
||||
if ( validColumn && c.$headerIndexed[ column ].hasClass( 'filter-select-nosort' ) ) {
|
||||
// unsorted select options
|
||||
return arry;
|
||||
@ -1459,22 +1452,30 @@
|
||||
// parse select option values
|
||||
for ( indx = 0; indx < len; indx++ ) {
|
||||
txt = arry[ indx ];
|
||||
// check for object
|
||||
str = txt.text ? txt.text : txt;
|
||||
// sortNatural breaks if you don't pass it strings
|
||||
parsedTxt = ( validColumn && c.parsers && c.parsers.length &&
|
||||
c.parsers[ column ].format( str, table, [], column ) || str ).toString();
|
||||
parsedTxt = c.widgetOptions.filter_ignoreCase ? parsedTxt.toLowerCase() : parsedTxt;
|
||||
// parse array data using set column parser; this DOES NOT pass the original
|
||||
// table cell to the parser format function
|
||||
parsed.push({
|
||||
t : txt,
|
||||
// check parser length - fixes #934
|
||||
p : validColumn && c.parsers && c.parsers.length &&
|
||||
c.parsers[ column ].format( txt, table, [], column ) || txt
|
||||
});
|
||||
if ( txt.text ) {
|
||||
txt.parsed = parsedTxt;
|
||||
parsed.push( txt );
|
||||
} else {
|
||||
parsed.push({
|
||||
text : txt,
|
||||
// check parser length - fixes #934
|
||||
parsed : parsedTxt
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// sort parsed select options
|
||||
cts = c.textSorter || '';
|
||||
parsed.sort( function( a, b ) {
|
||||
// sortNatural breaks if you don't pass it strings
|
||||
var x = a.p.toString(),
|
||||
y = b.p.toString();
|
||||
var x = a.parsed,
|
||||
y = b.parsed;
|
||||
if ( validColumn && typeof cts === 'function' ) {
|
||||
// custom OVERALL text sorter
|
||||
return cts( x, y, true, column, table );
|
||||
@ -1492,7 +1493,7 @@
|
||||
arry = [];
|
||||
len = parsed.length;
|
||||
for ( indx = 0; indx < len; indx++ ) {
|
||||
arry.push( parsed[indx].t );
|
||||
arry.push( parsed[indx] );
|
||||
}
|
||||
return arry;
|
||||
}
|
||||
@ -1552,7 +1553,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
var indx, val, txt, t, $filters, $filter,
|
||||
var indx, val, txt, t, $filters, $filter, option,
|
||||
c = table.config,
|
||||
wo = c.widgetOptions,
|
||||
node = c.$headerIndexed[ column ],
|
||||
@ -1577,23 +1578,45 @@
|
||||
if ( $.isArray( arry ) ) {
|
||||
// build option list
|
||||
for ( indx = 0; indx < arry.length; indx++ ) {
|
||||
txt = arry[indx] = ( '' + arry[indx] ).replace( tsf.regex.quote, '"' );
|
||||
val = txt;
|
||||
// allow including a symbol in the selectSource array
|
||||
// 'a-z|A through Z' so that 'a-z' becomes the option value
|
||||
// and 'A through Z' becomes the option text
|
||||
if ( txt.indexOf( wo.filter_selectSourceSeparator ) >= 0 ) {
|
||||
t = txt.split( wo.filter_selectSourceSeparator );
|
||||
val = t[0];
|
||||
txt = t[1];
|
||||
option = arry[ indx ];
|
||||
if ( option.text ) {
|
||||
// OBJECT!! add data-function-name in case the value is set in filter_functions
|
||||
option['data-function-name'] = typeof option.value === 'undefined' ? option.text : option.value;
|
||||
|
||||
// support jQuery < v1.8, otherwise the below code could be shortened to
|
||||
// options += $( '<option>', option )[ 0 ].outerHTML;
|
||||
options += '<option';
|
||||
for ( val in option ) {
|
||||
if ( option.hasOwnProperty( val ) && val !== 'text' ) {
|
||||
options += ' ' + val + '="' + option[ val ] + '"';
|
||||
}
|
||||
}
|
||||
if ( !option.value ) {
|
||||
options += ' value="' + option.text + '"';
|
||||
}
|
||||
options += '>' + option.text + '</option>';
|
||||
// above code is needed in jQuery < v1.8
|
||||
|
||||
// make sure we don't turn an object into a string (objects without a "text" property)
|
||||
} else if ( '' + option !== '[object Object]' ) {
|
||||
txt = option = ( '' + option ).replace( tsf.regex.quote, '"' );
|
||||
val = txt;
|
||||
// allow including a symbol in the selectSource array
|
||||
// 'a-z|A through Z' so that 'a-z' becomes the option value
|
||||
// and 'A through Z' becomes the option text
|
||||
if ( txt.indexOf( wo.filter_selectSourceSeparator ) >= 0 ) {
|
||||
t = txt.split( wo.filter_selectSourceSeparator );
|
||||
val = t[0];
|
||||
txt = t[1];
|
||||
}
|
||||
// replace quotes - fixes #242 & ignore empty strings
|
||||
// see http://stackoverflow.com/q/14990971/145346
|
||||
options += option !== '' ?
|
||||
'<option ' +
|
||||
( val === txt ? '' : 'data-function-name="' + option + '" ' ) +
|
||||
'value="' + val + '">' + txt +
|
||||
'</option>' : '';
|
||||
}
|
||||
// replace quotes - fixes #242 & ignore empty strings
|
||||
// see http://stackoverflow.com/q/14990971/145346
|
||||
options += arry[indx] !== '' ?
|
||||
'<option ' +
|
||||
( val === txt ? '' : 'data-function-name="' + arry[indx] + '" ' ) +
|
||||
'value="' + val + '">' + txt +
|
||||
'</option>' : '';
|
||||
}
|
||||
// clear arry so it doesn't get appended twice
|
||||
arry = [];
|
||||
|
@ -214,8 +214,8 @@ jQuery(function($){
|
||||
function(){ ts.setFilters( table, ['', '', '' , '>20 && <40'], true ); },
|
||||
function(){ assert.cacheCompare( table, 3, [25, 28, 33, 24, 22, 25], 'search ">20 && <40"', true ); }
|
||||
).nextTask(
|
||||
function(){ ts.setFilters( table, ['', '', '' , '<10 or >40'], true ); },
|
||||
function(){ assert.cacheCompare( table, 3, [51, 45, 65], 'search "<10 or >40"', true ); }
|
||||
function(){ ts.setFilters( table, ['', '', '' , '<15 or >40'], true ); },
|
||||
function(){ assert.cacheCompare( table, 3, [12, 51, 45, 13, 65], 'search "<15 or >40"', true ); }
|
||||
).nextTask(
|
||||
function(){ ts.setFilters( table, ['', 'alex|br*'], true ); },
|
||||
function(){ assert.cacheCompare( table, 1, ['Brandon Clark', 'Bruce', 'Alex', 'Bruce Lee', 'Brenda Dexter'], 'search OR match', true ); }
|
||||
|
Loading…
Reference in New Issue
Block a user