diff --git a/docs/example-widget-filter-custom.html b/docs/example-widget-filter-custom.html index 3dc8670c..bdfd638f 100644 --- a/docs/example-widget-filter-custom.html +++ b/docs/example-widget-filter-custom.html @@ -165,24 +165,25 @@ -
filter_functions
option for the column to true
,filter_functions : { // Add select menu to this column - // set the column value to true, and/or add "filter-select" class name to header + // set the column value to true, and/or add "filter-select" class name to header 0 : true -}or add a "filter-select" class to the column header cell (see code below).
data-placeholder
attribute of the column header cell. And when active, it will show all table rows.<th class="filter-select" data-placeholder="Select a name">First Name</th>
<th class="filter-select filter-match" data-placeholder="Select a name">First Name</th>
data-placeholder
attribute of the column header cell. And when active, it will show all table rows.<th class="filter-select" data-placeholder="Select a name">First Name</th>
<th class="filter-select filter-match" data-placeholder="Select a name">First Name</th>
filter_functions
option following this example:filter_functions : { @@ -194,27 +195,27 @@ }
filter_searchDelay
option to be a bit longer.===
) meaning the filter_ignoreCase
option is ignored, but other comparisons can be made using regex and the insensitive "i" flag.===
) meaning the filter_ignoreCase
option is ignored, but other comparisons can be made using regex and the insensitive "i" flag.filter_functions
option.filter_functions : { // Add these options to the select dropdown (regex example) 2 : { - "A - D" : function(e, n, f, i) { return /^[A-D]/.test(e); }, - "E - H" : function(e, n, f, i) { return /^[E-H]/.test(e); }, - "I - L" : function(e, n, f, i) { return /^[I-L]/.test(e); }, - "M - P" : function(e, n, f, i) { return /^[M-P]/.test(e); }, - "Q - T" : function(e, n, f, i) { return /^[Q-T]/.test(e); }, - "U - X" : function(e, n, f, i) { return /^[U-X]/.test(e); }, - "Y - Z" : function(e, n, f, i) { return /^[Y-Z]/.test(e); } + "A - D" : function(e, n, f, i) { return /^[A-D]/.test(e); }, + "E - H" : function(e, n, f, i) { return /^[E-H]/.test(e); }, + "I - L" : function(e, n, f, i) { return /^[I-L]/.test(e); }, + "M - P" : function(e, n, f, i) { return /^[M-P]/.test(e); }, + "Q - T" : function(e, n, f, i) { return /^[Q-T]/.test(e); }, + "U - X" : function(e, n, f, i) { return /^[U-X]/.test(e); }, + "Y - Z" : function(e, n, f, i) { return /^[Y-Z]/.test(e); } } }
<th class="filter-select filter-onlyAvail">Discount</th>
City | Age | Total | -Discount | +Discount | Date | diff --git a/docs/example-widget-filter.html b/docs/example-widget-filter.html index d86b6f6d..83635edf 100644 --- a/docs/example-widget-filter.html +++ b/docs/example-widget-filter.html @@ -182,16 +182,16 @@ $(function(){
---|
Type (1) | Description | Example |
---|---|---|
text | Any text entered in the filter will match text found within the column | abc (finds "abc", "abcd", "abcde", etc) |
" | To exactly match the search query, add a quote, apostrophe or equal sign to the beginning and/or end of the query | abc" or abc= (exactly match "abc") |
? | Wildcard for a single, non-space character. | J?n (finds "Jan" and "Jun", but not "Joan") |
* | Wildcard for zero or more non-space characters. | B*k (matches "Black" and "Book") |
/\d/ | Add any regex to the query to use in the query | /b[aeiou]g/i (finds "bag", "beg", "BIG", "Bug", etc) |
text | Any text entered in the filter will match text found within the column | abc (finds "abc", "abcd", "abcde", etc) |
" | To exactly match the search query, add a quote, apostrophe or equal sign to the beginning and/or end of the query | abc" or abc= (exactly match "abc") |
? | Wildcard for a single, non-space character. | J?n (finds "Jan" and "Jun", but not "Joan") |
* | Wildcard for zero or more non-space characters. | B*k (matches "Black" and "Book") |
/\d/ | Add any regex to the query to use in the query | /b[aeiou]g/i (finds "bag", "beg", "BIG", "Bug", etc) |
< <= >= > | Find alphabetical or numerical values less than or greater than or equal to the filtered query (2) | >= 10 (find values greater than or equal to 10) |
! | Not operator. Filter the column with content that do not match the query. | !fe (hide rows with "female" in that column, but shows rows with "male") |
&& or AND | Logical "and". Filter the column for content that matches text from either side of the operator. | box && bat (matches a column cell that contains both "box" and "bat") |
| or OR | Logical "or" (Vertical bar). Filter the column for content that matches text from either side of the bar. | box|bat (matches a column cell with either "box" or "bat") |
- or to | Find a range of values. Make sure there is a space before and after the dash (or the word "to") (2). | 10 - 30 or 10 to 30 (match values between 10 and 30) |
! | Not operator. Filter the column with content that do not match the query. | !fe (hide rows with "female" in that column, but shows rows with "male") |
&& or AND | Logical "and". Filter the column for content that matches text from either side of the operator. | box && bat (matches a column cell that contains both "box" and "bat") |
| or OR | Logical "or" (Vertical bar). Filter the column for content that matches text from either side of the bar. | box|bat (matches a column cell with either "box" or "bat") |
- or to | Find a range of values. Make sure there is a space before and after the dash (or the word "to") (2). | 10 - 30 or 10 to 30 (match values between 10 and 30) |
filter_hideFilters : false
- if true, filters are hidden initially, but can be revealed by clicking on the filter icon.filter_ignoreCase : true
- if true, make all searches case-insensitive.filter_liveSearch : true
- if true, search column content while the user types (with a delay). If false, the user must press enter to start the search. If set to a number, when the length of the input text reaches this minimum length, a search will initiate.filter_onlyAvail : 'filter-onlyAvail'
- a header with a select dropdown & this class name will only show available (visible) options within that drop down.filter_reset : null
- jQuery selector string of an element used to reset the filters.filter_searchDelay : 300
- typing delay in milliseconds before starting a search.filter_serversideFiltering : false
- if true, filter will be done server-side. The client-side filtering will be disabled, but the ui and events will still be used..filter_serversideFiltering : false
- if true, filter will be done server-side. The client-side filtering will be disabled, but the ui and events will still be used.filter_startsWith : false
- if true, filter start from the beginning of the cell contents.filter_useParsedData : false
- filter all data using parsed content.filter-false
- disable the filter for a specific header column.filter-select
- build a default select box for a column (shows unique column content). See the custom filter widget demo for an example.filter-match
- only applies to "filter-select" columns. Makes the select match the column contents instead of exactly matching.filter-match
- only applies to "filter-select" columns. Makes the select match the column contents instead of exactly matching.filter-parsed
- set a column to filter through parsed data instead of the actual table cell content.filter-onlyAvail
- show only available (visible) options within a default select box. See the custom filter widget demo "Discount" column for an example.With this method, you can pass an array of filter values: -// apply "2?%" filter to the fifth column (zero-based index) +// apply "2?%" filter to the fifth column (zero-based index) var columns = []; columns[5] = '2?%'; // or define the array this way var columns = [ '', '', '', '', '', '2?%' ] @@ -293,7 +295,7 @@ $.tablesorter.setFilters( $('table'), [ '', '', '', '', '', '2?%' ], true );- (search the Discount column for "2?%")
+ (search the Discount column for "2?%")
diff --git a/docs/index.html b/docs/index.html index 6683102c..26d97e10 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1307,6 +1307,8 @@ $(function(){ filter_ignoreCase : true, // if true, search column content while the user types (with a delay) filter_liveSearch : true, + // a selector in a header with this class name will only show selected options in the drop down + filter_onlyAvail : 'filter-onlyAvail', // jQuery selector string of an element used to reset the filters. filter_reset : null, // typing delay in milliseconds before starting a search. @@ -1837,6 +1839,20 @@ $(function(){
+ + +filter_onlyAvail +String +'filter-onlyAvail' ++ Filter widget: If a header contains a select dropdown and this class name, only the available (visible) options in the column will show (v2.10.1). + +++
+ This option is useful after one or more columns have been filtered, then the column select filter with this class applied will only show the contents of the column within the dropdown that are currently visible. See the custom filter widget demo "Discount" column for an example (sort the "First Name" column first). +Example +filter_reset String diff --git a/js/jquery.tablesorter.widgets.js b/js/jquery.tablesorter.widgets.js index 48217e9a..774c7f93 100644 --- a/js/jquery.tablesorter.widgets.js +++ b/js/jquery.tablesorter.widgets.js @@ -332,6 +332,7 @@ ts.addWidget({ filter_hideFilters : false, // collapse filter row when mouse leaves the area filter_ignoreCase : true, // if true, make all searches case-insensitive filter_liveSearch : true, // if true, search column content while the user types (with a delay) + filter_onlyAvail : 'filter-onlyAvail', // a header with a select dropdown & this class name will only show available (visible) options within the drop down filter_reset : null, // jQuery selector string of an element used to reset the filters filter_searchDelay : 300, // typing delay in milliseconds before starting a search filter_startsWith : false, // if true, filter start from the beginning of the cell contents @@ -522,14 +523,16 @@ ts.addWidget({ $t.trigger('applyWidgets'); // make sure zebra widget is applied $t.trigger('filterEnd'); }, - buildSelect = function(i, updating){ - var o, arry = []; + buildSelect = function(i, updating, onlyavail){ + var o, t, arry = [], currentVal; i = parseInt(i, 10); o = ''; for (k = 0; k < b.length; k++ ){ l = c.cache[k].row.length; // loop through the rows for (j = 0; j < l; j++){ + // check if has class filtered + if (onlyavail && c.cache[k].row[j][0].className.match(wo.filter_filteredRow)) { continue; } // get non-normalized cell content if (wo.filter_useParsedData){ arry.push( '' + c.cache[k].normalized[j][i] ); @@ -550,10 +553,14 @@ ts.addWidget({ }); arry = (ts.sortText) ? arry.sort(function(a, b){ return ts.sortText(table, a, b, i); }) : arry.sort(true); + // Get curent filter value + currentVal = $t.find('thead').find('select.' + css + '[data-column="' + i + '"]').val(); + // build option list for (k = 0; k < arry.length; k++){ + t = arry[k].replace(/\"/g, """); // replace quotes - fixes #242 & ignore empty strings - see http://stackoverflow.com/q/14990971/145346 - o += arry[k] !== '' ? '' : ''; + o += arry[k] !== '' ? '' : ''; } $t.find('thead').find('select.' + css + '[data-column="' + i + '"]')[ updating ? 'html' : 'append' ](o); }, @@ -565,7 +572,7 @@ ts.addWidget({ if ((t.hasClass('filter-select') || wo.filter_functions && wo.filter_functions[i] === true) && !t.hasClass('filter-false')){ if (!wo.filter_functions) { wo.filter_functions = {}; } wo.filter_functions[i] = true; // make sure this select gets processed by filter_functions - buildSelect(i, updating); + buildSelect(i, updating, t.hasClass(wo.filter_onlyAvail)); } } }; @@ -622,8 +629,8 @@ ts.addWidget({ } } $t - .bind('addRows updateCell update updateRows updateComplete appendCache filterReset search '.split(' ').join('.tsfilter '), function(e, filter){ - if (!/(search|filterReset)/.test(e.type)){ + .bind('addRows updateCell update updateRows updateComplete appendCache filterReset filterEnd search '.split(' ').join('.tsfilter '), function(e, filter){ + if (!/(search|filterReset|filterEnd)/.test(e.type)){ e.stopPropagation(); buildDefault(true); } @@ -633,6 +640,9 @@ ts.addWidget({ // send false argument to force a new search; otherwise if the filter hasn't changed, it will return filter = e.type === 'search' ? filter : e.type === 'updateComplete' ? $t.data('lastSearch') : ''; checkFilters(filter); + if (e.type === 'filterEnd') { + buildDefault(true); + } return false; }) .find('input.' + css).bind('keyup search', function(e, filter){