jQuery tablesorter 2.0 - Filter Widget

# tablesorter

## Filter Widget

### Flexible client-side table sorting

Back to documentation

### Notes

- In v2.29.4, `filter_filterLabel` option was added to include an ARIA-label to the filter inputs and selects.
- In v2.27.3, `filter_liveSearch` will now accept an object containing zero-based column indexes or header class names.
- In v2.26.6, the `hideFilters` setting will now accept a function to determine when to hide the filter row.
- In v2.25.6, added `filterResetSaved` method to clear stored filter values.
- In v2.25.2, added `filter_resetOnEsc` option.
- In v2.22.2,
  - The `getFilters` function will now target the last used filter properly.
  - The `filter_selectSource` option now ignores parsers if none are set.
  - Added the ability to nest filter types with a logical "OR" or a logical "AND". Try these filters:
    (*NOTE* try this with and without the filter-match class applied),
    or

### Older Notes

- In v2.22.0
  - Regex filter searches now cache the created regex object for each query to optimize speed & a regex search now properly uses case-sensitive content.
  - Add `data` parameter to `filter_functions` (get more details).
  - Any match searches which target specific columns will no longer save each filter to its respective column; see "AnyMatch Searches" documentation.
  - Operator filter searchs now ignore empty strings (because `"" < 10` is `true`).
  - Added `filter_childByColumn` option which allows the filtering columns in both the parent & child rows. Demo added to the filtered child rows demo
- In v2.18.0, added `filter_cellFilter` & the ability to set multiple "any" match columns for an external search (see the external inputs demo for more details).
- In v2.17.8, filter selects will default to exact matches unless the header cell has a `"filter-match"` class added.
- In v2.17.1, added a not exact match (`!=`) filter type.
- In v2.16+,
  - When a default filter select is added to a column, it is now parsed from the assigned parser, then sorted using the `textSorter` setting, and falls back to an alphanumeric sort (v2.16.3).
  - Adding a class of `"filter-select-nosort"` will now leave the select options unsorted (v2.16.3).
  - Added `filter_placeholder` option (v2.16.0).
  - Added `filter_selectSource` option (v2.16.3).
  - updated `filter_reset` option (v2.16.3).
- In v2.15,
  - The `filter_anyMatch` widget option was completely removed. Sorry for not deprecating this option, but the filter any match code was completely rewritten.
  - Added a `filter_external` widget option to only accept a jQuery selector string/object; please see the updated filter any match demo for more details.
- Added & set `filter_saveFilters` to `true` (default is `false`) in this demo (v2.14).

- *NOTE* The filter widget is set to use extracted (parsed) content as parsed values and the raw cell content as unparsed values; and most of the time the filter is searching unparsed content (see `filter-parsed` class and `filter_useParsedData` option. But, when a data-attribute is used (see `textAttribute` option), both the parsed and raw cached data will contain the exact same content (ref)!
- *NOTE* If using a custom theme, make sure to add the class set in the `filter_filteredRow` option (set to `filtered` by default) in the css, and set it to `display:none`. When filtering rows, the filter widget adds the `"filtered"` class to hide the row; all available themes include this definition.
- Hover over the grey bar below the table header to open the filter row. Disable this by setting `filter_hideFilters` option to `false`.
- This widget uses jQuery's `.nextUntil()` function which is only available is jQuery version 1.4+.
- This widget does NOT work with tablesorter v2.0.5.
- Using the built-in filters (learn how to customize them here - demo created v2.17.5):

  Priority | Type (1) | Description | Examples
  --- | --- | --- | ---
  1 | `|` or `OR` | Logical "or" (Vertical bar). Filter the column for content that matches text from either side of the bar (2). | `box|bat` (matches a column cell with either "box" or "bat"); (Find text that contains either "Alex" or "Peter");
  2 | `&&` 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"), (Find text that contains both "br" and "c"), or (When "filter-match" is set, find content with the letter "a", but not the letter "o")
  3 | `/\d/` | Add any regex to the query to use in the query ("mig" flags can be included `/\w/mig`) | `/b[aeiou]g/i` (finds "bag", "beg", "BIG", "Bug", etc); (matches text that ends with an "r")
  4 | `< <= >= >` | Find alphabetical or numerical values less than or greater than or equal to the filtered query (1). | (find values greater than or equal to 10)
  5 | `!` or `!=` | Not operator, or not exactly match. Filter the column with content that do not match the query. Include an equal (`=`), single (`'`) or double quote (`"`) to exactly not match a filter (v2.17.1). | `!fe` (hide rows with "female" in that column, but shows rows with "male"); (find text that doesn't contain an "a"); (find content that does not exactly match "Bruce")
  6 | `"` or `=` | 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"); or (exactly match "John")
  7 | `-` or `to` | Find a range of values. Make sure there is a space before and after the dash (or the word "to") (3). | or (match values between 10 and 30)
  8 | `?` | Wildcard for a single, non-space character. | `J?n` (finds "Jan" and "Jun", but not "Joan"); (finds "Dumass" and "Evans", but not "McMasters")
  8 | `*` | Wildcard for zero or more non-space characters. | `B*k` (matches "Black" and "Book"); (matches "Dumass", "Evans" and "McMasters")
  9 | `~` | Perform a fuzzy search (matches sequential characters) by adding a tilde to the beginning of the query (v2.13.3) | (matches "Bruce Lee" and "Brenda Dexter"), or (matches "Philip Aaron Wong")
  10 | text | Any text entered in the filter will match text found within the column | `abc` (finds "abc", "abcd", "abcde", etc); (finds "Aaron" and "Philip Aaron Wong")

  (1) The filter order (or precendence) of how searches are checked in "priority" (first column) order; so an exact match will override "range" searches (*NOTE* order changed in v2.15, operators prioritized before exact; see issue #465; order changed again in v2.17.1 to move "not match" before "exact" and allow for exact not matches; see issue #628). In v2.22.2, the "or" and "and" types can combine any of the other filter types together.
  (2) Logical "or" comparisons can now show exact matches (by default; v2.10.1) or just match cell contents.
  (3) In tablesorter v2.10, comparisons can be made in date columns (if properly parsed).

### Options

#### Filter widget defaults (added inside of tablesorter `widgetOptions`)

#### NOTE This table includes very basic information about the filter options. For more extensive information & links to demos, see the main page Widget & Pager Options section.

TIP! Click on the link in the function column to reveal full details (or toggle|show|hide all) or double click to update the browser location.

Option | Default | Description
--- | --- | ---
filter_childRows | false | if `true`, filter includes child row content in the search.
filter_childByColumn | false | if `true`, queries will search child row content by column (v2.22.0). The `filter_childRows` option must be `true` for this option to work. If `false`, and the `filter_childRows` option is `true`, then queries in any column will search all child content, as before this option was added.
filter_childWithSibs | true | if `true`, all sibling rows of the matching child row will also be visible (v2.23.4). Both `filter_childRows` & `filter_childByColumn` options must be set to `true` for this option to work. If `false`, this option will only show the child row that matches the filter; and its parent row.
filter_columnFilters | true | if `true`, a filter will be added to the top of each table column.
filter_columnAnyMatch | true | if `true`, allows using "#:{query}" in anyMatch searches (v2.20.0). Users can use the anymatch input to target a specific column, using a one-based index. For example: In the table below, searching for `2:aa` in an anymatch filter will result in "Phillip Aaron Wong" and "Aaron" showing in the First Name column. See live examples in the Filter Widget External Search demo.
filter_cellFilter | '' | Extra css class name (string or array) added to the filter element (input or select) (v2.18.0) The filter cell (`<td>`) is not to be confused with the `filter_cssFilter` option which adds an extra class name to the filter inputs (`<input>`).
filter_cssFilter | '' | Extra css class name(s) applied to the table row containing the filters & the inputs within that row (v2.15). This option can either be a string (class applied to all filters) or an array (class applied to indexed filter).
filter_defaultAttrib | 'data-value' | this option contains the name of the data-attribute which contains the default (starting) filter value.
filter_defaultFilter | { } | Set a default filter for a set column (v2.17.8).
filter_excludeFilter | { } | Set a column to exclude the chosen filter types (range, exact, notMatch, etc) (v2.17.8).
filter_external | '' | Set to a jQuery selector (or object) pointing to an input to be used to match the contents of any column (v2.15). Please refer to the updated filter-any-match demo for the limitations of this setting.
filter_filteredRow | 'filtered' | CSS class name added to filtered rows (rows that are not showing); needed by pager plugin. If modifying this definition, make sure that the new class is set to `display: none;` to hide the filtered rows.
filter_filterLabel | 'Filter "{{label}}" column by...' | This option contains the ARIA-label value to be added to the filter input or select (v2.29.4). By default, a `{{label}}` is included in the setting to insert a column label. The content is obtained from the header cell's `data-label` attribute (do not include the `data-` prefix), if it exists, or the column header text. See the "First Name" column below for an example. Note See the main page documentation for more important details!
filter_formatter | null | Add custom filter element(s) to the filter row Custom filter elements include: jQuery UI widgets: slider, spinner & datepicker HTML5 elements: range, number input, color selector. Select2 plugin.
filter_functions | null | Add custom filter functions using this option. See the custom filter widget functions demo for more details and numerous examples.
filter_hideEmpty | true | Hide filter row when the table is empty (v2.15).
filter_hideFilters | false | If `true`, filters are hidden initially, but can be revealed by hovering over the filter row, or giving a filter input focus (tabbing down the page). In v2.26.6, a function can now be used to return a boolean value to set the visibility of the filter row. See the main documentation for an example.
filter_ignoreCase | true | If `true`, all searches are case-insensitive.
filter_liveSearch | true | If `true`, search column content while the user types (with a short 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. In v2.27.3, this option can be set as an object containing column zero-based indexes or header class names. If a column isn't defined in the object, the "fallback" key is checked and if undefined, the value defaults to `false`.
filter_matchType | { 'input': 'exact', 'select': 'exact' } | This option sets the global setting that applied to either input or select filters (v2.25.5) There are only two options: "exact" and "match"; and it defaults to "exact" if anything else is entered.
filter_onlyAvail | 'filter-onlyAvail' | A header with a select dropdown & this class name set, will only show available (visible) options within that drop down.
filter_placeholder | { search : '', select : '' } | Default placeholder text (overridden by any header "data-placeholder" setting; v2.16).
filter_reset | null | jQuery selector string of an element used to reset the filters (v2.4; v2.16.0).
filter_resetOnEsc | true | Press escape to clear filter input - normalized across browsers (v2.25.2).
filter_saveFilters | false | Uses the `$.tablesorter.storage` utility to save the most recent filters.
filter_searchDelay | 300 | Typing delay in milliseconds before starting a search.
filter_searchFiltered | true | Allow searching through already filtered rows in special circumstances; will speed up searching in large tables if `true`.
filter_selectSource | null | Include a function to return an array of values to be added to the column filter select (v2.16.0).
filter_selectSourceSeparator | null | `filter_selectSource` array text left of the separator is added to the option value, right into the option text.
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.
Removed options
filter_anyMatch | null | jQuery selector string (or jQuery object) of external anyMatch filter (removed in v2.15; please see the demo for more details)

### Classes

Class names that can be added to the `th` header cells:

- `filter-exact` - applies to the column where the user can use the logical "or" or "and" search. This does the opposite of the "filter-match" class, and overrides it if applied.
- `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-select-nosort` - when a default select box is built, this option prevents the sorting of select options leaving them in their original table order (v2.16.3).
- `filter-select-sort-desc` - when a default select box is built, it is automatically set to an ascending sort. Adding this class name will perform a descending sort on the values (v2.27.7).
- `filter-match` - applies to "filter-select" columns and columns where the user can use the logical "or" search. Makes the filter/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.
  - This class name is set by the `filter_onlyAvail` option.
  - See the custom filter widget demo "Discount" column for an example.

### Methods

### Set Filter Placeholder Text

> Set a `data-placeholder` attribute on the associated table header with your desired placeholder text

>     <th data-placeholder="Enter Something">Name</th>

> or, set the header cell's jQuery data

>     $('.tablesorter th:eq(0)').data('placeholder', 'Search for...')

### Set Filter Initial Searches

> Set a `data-value` attribute (data-attribute name set by the `filter_defaultAttrib` option) on the associated table header with the desired initial search value.

>     <th data-value="<=100">Price</th>

> or, set the header cell's jQuery data

>     $('.tablesorter th:eq(0)').data('value', '<=100')

### filterReset

> Use the `filterReset` method to reset (clear) all of the current filters as follows:

>     $('table').trigger('filterReset');

> or, just add an element to your page and point to it by setting the `filter_reset` option, to allow user interaction.

> *NOTE* delegated event bindings are used so these "reset" elements can be dynamically added and removed from the document.

### filterResetSaved

> Use the `filterResetSaved` method to reset (clear) the saved filters (in storage) as follows (v2.25.6):

>     // equivalent to:
>     // $.tablesorter.storage( $('#table'), 'tablesorter-filters', '' );
>     $('#table').trigger('filterResetSaved');

### Search

> With this method, you can pass an array of filter values:

>     // apply "2?%" filter to the fifth column (zero-based index)
>     var columns = [];
>     columns[5] = '2?%';
>     // or define the array this way var columns = [ '', '', '', '', '', '2?%' ]
>     $('table').trigger('search', [ columns ]);

> or, just pass `false` to refresh the current search:

>     $('table').trigger('search', false);

> * Note: using this search method will update the contents of the filters within the filter row.
> In v2.15, one additional parameter can be added to the array to perform an "any-match" of the table; Warning! please note that if no external input (with a `data-column="all"` is attached using `bindSearch` function) is visible, the user will not know that a filter has been applied.

>     // in a table with 4 columns; set the 5th parameter to any-match
>     $('table').trigger( 'search', [['', '', '', '', 'orange']] ); // find orange in any column

### Get current filters

> Get an array of the currently applied filters (v2.9).

>     $.tablesorter.getFilters( $('table') ); // or $('table.hasFilters')

> This method returns an array of filter values or `false` if the selected table does not contain a filter row.
> Internally, the get filters functions returns the filters stored within this table data `$('table').data('lastSearch')`, unless an additional parameter of `true` is passed to the function:

>     $.tablesorter.getFilters( $('table'), true ); // get current input values instead of data stored filters

> As of v2.15, if an external "any-match" filter (see `filter_external` widget option) is included, one additional array parameter will be returned in the filter - the value of the any match search.

>     // in a table with six columns, this function will return an array with seven
>     // parameters; something like this: [ '', '', '', '', '', '', '11' ],
>     // where the "11" will be obtained from the "any-match" input
>     var filters = $.tablesorter.getFilters( $('table') );

### Set current filters

> Set the values of the actual filters using this method; include a `false` boolean to not apply the search (v2.9).

> In v2.24.3, if the last boolean parameter is `undefined` or set to `true`, the search will be applied. Only when the boolean is set to `false` will the search not be applied!

>     // update filters, AND apply the search
>     $.tablesorter.setFilters( $('table'), [ '', '', '', '', '', '2?%' ] ); // , true is optional

>     // update filters, but DOES NOT apply the search
>     $.tablesorter.setFilters( $('table'), [ '', '', '', '', '', '2?%' ], false );

> This method returns `true` if the filters were sucessfully applied, or `false` if the table does have a filter row.
> As of v2.15, if an external "any-match" filter (see `filter_external` widget option) is included, add an additional array parameter to set that filter; so if a table has six columns, add the any-match search as the seventh value.

>     // in a table with 6 columns, the 7th filter will apply
>     // to the any-match filter & match any table column with "11"
>     $.tablesorter.setFilters( $('table'), [ '', '', '', '', '', '', '11' ], true );

### Bind external filter

> Use this method to bind external search filters
> - Include a data-attribute `data-column` with the column index to target
> - Or, use `data-column="all"` to preform an "any-match" search on all of the table columns (v2.15).
> - Or, add multiple columns `data-column="0-2,4,6-8"` to perform an "any-match" search on selected columns (v2.18.0).
> If no `data-column` is added to the input, the input will be ignored.

>     <!-- will perform an "any-match" type of search (matches any column) -->
>     <input type="search" class="search" data-column="all">
>     <!-- will only search the first column (zero-based index) -->
>     <input type="search" class="search" data-column="0">

>     // Target the $('.search') input using built in functioning
>     // this binds to the search using "search" and "keyup" and allows using filter_liveSearch
>     // or delayed search & pressing escape to cancel the search
>     // pass an optional third parameter (false boolean) to force the inputs to update
>     // this allows changing the data-column for an input dynamically
>     $.tablesorter.filter.bindSearch( $table, $('.search'), false );

> If you don't care about the enhanced search filter, then bind to both the "keyup" and "search" events

>     // Basic search binding, alternate to the above
>     // bind to search - pressing enter and clicking on "x" to clear (Webkit)
>     // keyup allows dynamic searching
>     $(".search").bind('search keyup', function (e) {
>       $('table').trigger('search', [ [this.value] ]);
>     });

### Events

- `filterEnd` - Event triggered when the filter widget has finished processing the search.
- `filterInit` - Event triggered when the filter widget has finished initializing.
- `filterStart` - Event triggered when the filter widget has started processing the search.

### Changes

Moved to the wiki pages - change log.

### Localization

You can now change the language of the searches used within the filter widget. For example, to change the localization to French, do the following:

    // add French support
    $.extend($.tablesorter.language, {
    	to  : 'à',
    	or  : 'ou',
    	and : 'et'
    });

If you want to support multiple languages, separate the language variables with a vertical bar (`|`, `Shift` + `\`):

    // add French & Spanish support
    $.extend($.tablesorter.language, {
    	to  : 'à|a',
    	or  : 'ou|o',
    	and : 'et|y'
    });

### Notes

- Info These changes still require the user to enter spaces in the filter to perform the search, e.g. `1 à 10` (shows rows with numbers between 1 and 10).
- Info Extra spaces around the value will be trimmed and it is valid to set a value to an empty string; but this won't disable the filter type (use `-` for "to", `|` for "or" and `&&` for "and").
- Warning These language values are added to a regular expression using `new RegExp()`:
  - So you will need to escape any special characters contained in these values (e.g. `. \ + * ? [ ^ ] $ ( ) { } = ! < > | : -`).
  - This function might help (ref):

        function escapeRegExp( string ) {
          return string.replace( /[.*+?^${}()|[\]\\]/g, '\\$&' );
        }

# Demo

filter_startsWith : false (if true, search from beginning of cell content only)
filter_ignoreCase : true (if false, the search will be case sensitive)
filter-match (if class name added to the "First Name" column, all "or" searches will only match the content; Search
in the First Name column (2.10.1).

Search
in the Discount column

Rank | First Name ( filter-match ) | Last Name | Age | Total | Discount | Date
--- | --- | --- | --- | --- | --- | ---
1 | Philip Aaron Wong | Johnson Sr Esq | 25 | $5.95 | 22% | Jun 26, 2004 7:22 AM
11 | Aaron | Hibert | 12 | $2.99 | 5% | Aug 21, 2009 12:21 PM
12 | Brandon Clark | Henry Jr | 51 | $42.29 | 18% | Oct 13, 2000 1:15 PM
111 | Peter | Parker | 28 | $9.99 | 20% | Jul 6, 2006 8:14 AM
21 | John | Hood | 33 | $19.99 | 25% | Dec 10, 2002 5:14 AM
013 | Clark | Kent Sr. | 18 | $15.89 | 44% | Jan 12, 2003 11:14 AM
005 | Bruce | Almighty Esq | 45 | $153.19 | 44% | Jan 18, 2021 9:12 AM
10 | Alex | Dumass | 13 | $5.29 | 4% | Jan 8, 2012 5:11 PM
16 | Jim | Franco | 24 | $14.19 | 14% | Jan 14, 2004 11:23 AM
166 | Bruce Lee | Evans | 22 | $13.19 | 11% | Jan 18, 2007 9:12 AM
100 | Brenda Dexter | McMasters | 18 | $55.20 | 15% | Feb 12, 2010 7:23 PM
55 | Dennis | Bronson | 65 | $123.00 | 32% | Jan 20, 2001 1:12 PM
9 | Martha | delFuego | 25 | $22.09 | 17% | Jun 11, 2011 10:55 AM

# Page Header

    <!-- blue theme stylesheet -->
    <link rel="stylesheet" href="css/theme.blue.css">
    <!-- tablesorter plugin -->
    <script src="js/jquery-latest.min.js"></script>
    <script src="js/jquery.tablesorter.js"></script>

    <!-- tablesorter widget file - loaded after the plugin -->
    <script src="js/jquery.tablesorter.widgets.js"></script>

# Javascript

# CSS

    /* REQUIRED in CUSTOM THEMES!
     This is the only definition that MUST BE added to any custom themes.
     This is how rows are hidden by filtering (included in provided themes) */
    .tablesorter .filtered {
    	display: none;
    }

    /* All of the following css is already contained within each theme file; modify it as desired */
    /* filter row */
    .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-filter-row .disabled {
      opacity: 0.5;
      filter: alpha(opacity=50);
      cursor: not-allowed;
    }

    /* hidden filter row */
    .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-filter-row.hideme * {
      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-filter {
      width: 95%;
      height: inherit;
      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;
    }

# HTML

Next up: jQuery Any Match filter widget ››