Filterable Widgetversion added: 1.4
Description: Makes the children of an element filterable.
Filterable Widget
The filterable widget allows you to filter the children of an element. The filtering is accomplished by applying the class ui-screen-hidden
to those children for which a filter callback function provided via the widget's filterCallback
option returns true
.
Backwards compatibility
The filterable widget features provided for backwards compatibility are deprecated as of 1.4.0 and will be removed in 1.5.0.The filterable widget is a generalization of the listview
widget's filter extension that was available in jQuery Mobile 1.3. It retains API compatibility with the listview
filter. Its behavior is also made backwards compatible by the following deprecated features:
- If no source is provided for the filterable via a
data-input
attribute, it will generate a text input and place it before the element. - It provides the
filterPlaceholder
option which sets theplaceholder
attribute on the generated text input. - It provides the
filterTheme
option which sets thetheme
option on the generated text input. - If a collapsibleset, selectmenu, controlgroup, or listview widget is instantiated on the element whose children are to be filtered, it synchronizes those widget options with the generated text input that the text input widget also provides (options such as "corners" or "mini").
- It provides special handling for listviews:
- When filtering listview items, the default filter callback will not hide list items marked as dividers, however,
- When filtering listview items, the widget enables the listview widget's
hidedividers
option, which causes the new listview hidedividers extension to automatically hide dividers for categories wherein all items are hidden.
Setup
To render the children of an element filterable, perform the following steps:
- Create an element that will serve as the source for the filterable. It can be any element that emits a
change
signal and has a value that can be accessed via the jQuery .val() plugin. This is usually a text input. The filterable widget reacts to thechange
signal by reading the value of the input after a short delay and iterating over all the children to determine whether they should be shown or hidden according to the filter callback provided. - Add the attribute
data-filter="true"
to the element whose children will be filtered. - Add the attribute
data-input
to the element whose children will be filtered. The value of the attribute is a string containing a jQuery selector that will return the element to be used as the source for the filterable. - Add the child elements that will be filtered. You may add or remove child elements at any time, however, when you add or remove child elements you should call the
refresh
method on the filterable widget, to ensure that the new children are shown or hidden in accordance with the latest input provided by the user.Child elements may have the
data-filtertext
attribute set. In that case, the default filter callback will hide a given child element only if the value of thedata-filtertext
attribute does not contain the string provided by the user. If thedata-filtertext
attribute is absent, the child will be hidden if its text content does not contain the string provided by the user.
<form> <input type="text" data-type="search" id="filterable-input"> </form> <form data-role="controlgroup" data-filter="true" data-input="#filterable-input"> <label for="pizza"> Pizza <input type="checkbox" id="pizza"> </label> <label for="goulash"> Goulash <input type="checkbox" id="goulash"> </label> <label for="falafel"> Falafel <input type="checkbox" id="falafel"> </label> <label for="spring-rolls"> Spring Rolls <input type="checkbox" id="spring-rolls"> </label> </form>
"Reveal" mode
The normal initial state of a filterable widget is that all the children are shown. In contrast, a filterable in "reveal" mode initially hides all its children. Once the user starts filtering, however, the filterable widget will display only those children that contain the text entered by the user, whether the filterable widget is in "reveal" mode or not.
You can turn on "reveal" mode by adding the attribute data-filter-reveal="true"
to the element whose children will be filtered.
The example below illustrates the behavior of a filterable widget in "reveal" mode:
<form> <input type="text" data-type="search" id="filterable-input"> </form> <form data-role="controlgroup" data-filter-reveal="true" data-filter="true" data-input="#filterable-input"> <label for="pizza"> Pizza <input type="checkbox" id="pizza"> </label> <label for="goulash"> Goulash <input type="checkbox" id="goulash"> </label> <label for="falafel"> Falafel <input type="checkbox" id="falafel"> </label> <label for="spring-rolls"> Spring Rolls <input type="checkbox" id="spring-rolls"> </label> </form>
Custom filters
The filterable widget's filterCallback
option allows you to set a custom callback. In the example below items are filtered by their ordinal, which can be specified using page printing conventions such as "1,2" or "4-9", or both ("1,2,4-9,12").
$.mobile.filterable.prototype.options.filterCallback = function( index, searchValue ) { var idx; if ( searchValue ) { searchValue = searchValue.split( "," ); searchValue = $.map( searchValue, function( element ) { var ar = element.split( "-" ); return ar.length === 1 ? parseInt( element ) : [ [ parseInt( ar[ 0 ] ), parseInt( ar[ 1 ] ) ] ]; }); for ( idx = 0 ; idx < searchValue.length ; idx++ ) { if ( ( $.type( searchValue[ idx ] ) === "number" && index === searchValue[ idx ] ) || ( $.type( searchValue[ idx ] ) === "array" && index >= searchValue[ idx ][ 0 ] && index <= searchValue[ idx ][ 1 ] ) ) { return false; } } } return !!searchValue; };
Providing pre-rendered markup
You can improve the load time of your page by providing the markup that the filterable widget would normally create during its initialization.
By providing this markup yourself, and by indicating that you have done so by setting the attribute data-enhanced="true"
, you instruct the filterable widget to skip these DOM manipulations during instantiation and to assume that the required DOM structure is already present.
When you provide such pre-rendered markup you must also set all the classes that the framework would normally set, and you must also set all data attributes whose values differ from the default to indicate that the pre-rendered markup reflects the non-default value of the corresponding widget option.
The filterable widget runs the filter on its children upon instantiation to ensure that the initial list of displayed children satisfies the initial value of the input source. By setting the attribute data-enhanced="true"
, you instruct the filterable widget that no initial filtering is to be performed. This means that you must apply the class ui-screen-hidden
to any children which must initially be hidden due to the initial value of the search input.
Note: If the element whose children are to be filtered is enhanced by another widget as well, such as for example a listview or a controlgroup then you are required to provide pre-rendered markup for the other widget as well, because the attribute data-enhanced="true"
will influence the initialization behavior of the other widget as well.
In the example below, pre-rendered markup for a filterable is provided. The attribute data-filter-reveal="true"
is explicitly specified, since the presence of the ui-screen-hidden
class on all the children indicates that they are initially hidden. The controlgroup widget containing the children is also pre-rendered, because the data-enhanced="true"
attribute applies to the controlgroup widget as much as it does to the filterable widget.
<form> <input id="pre-rendered-filterable" data-type="search"> </form> <div class="ui-controlgroup ui-controlgroup-vertical ui-corner-all" data-role="controlgroup" data-filter="true" data-input="#pre-rendered-filterable" data-filter-reveal="true" data-enhanced="true"> <div class="ui-controlgroup-controls"> <a href="index.html" class="ui-screen-hidden" data-role="button">General</a> <a href="settings.html" class="ui-screen-hidden" data-role="button">Settings</a> <a href="advanced.html" class="ui-screen-hidden" data-role="button">Advanced</a> <a href="notifications.html" class="ui-screen-hidden" data-role="button">Notifications</a> </div> </div>
Options
children
"> li, > option, > optgroup option, > tbody tr, > .ui-controlgroup-controls > .ui-btn, > .ui-controlgroup-controls > .ui-checkbox, > .ui-controlgroup-controls > .ui-radio"
This option is also exposed as a data attribute: data-children=".my-children"
.
- String: A jQuery selector that will be used to select from the children of the element.
- jQuery: A jQuery object containing the list of elements to filter.
- Function: A function that returns a jQuery object containing the list of elements to filter. It will be called with no arguments whenever filtering needs to be performed.
- Element: A DOM element. This is a trivial application of the filter.
Initialize the filterable with the children
option specified:
$( ".selector" ).filterable({ children: ".my-children" });
Get or set the children
option, after initialization:
// Getter var children = $( ".selector" ).filterable( "option", "children" ); // Setter $( ".selector" ).filterable( "option", "children", ".my-children" );
defaults
false
true
indicates that other widgets options have default values and causes jQuery Mobile's widget autoenhancement code to omit the step where it retrieves option values from data attributes. This can improve startup time. This option is also exposed as a data attribute: data-defaults="true"
.
Initialize the filterable with the defaults
option specified:
$( ".selector" ).filterable({ defaults: true });
Get or set the defaults
option, after initialization:
// Getter var defaults = $( ".selector" ).filterable( "option", "defaults" ); // Setter $( ".selector" ).filterable( "option", "defaults", true );
disabled
false
true
. This option is also exposed as a data attribute: data-disabled="true"
.
Initialize the filterable with the disabled
option specified:
$( ".selector" ).filterable({ disabled: true });
Get or set the disabled
option, after initialization:
// Getter var disabled = $( ".selector" ).filterable( "option", "disabled" ); // Setter $( ".selector" ).filterable( "option", "disabled", true );
enhanced
false
This option is also exposed as a data attribute: data-enhanced="true"
.
Initialize the filterable with the enhanced
option specified:
$( ".selector" ).filterable({ enhanced: true });
Get or set the enhanced
option, after initialization:
// Getter var enhanced = $( ".selector" ).filterable( "option", "enhanced" ); // Setter $( ".selector" ).filterable( "option", "enhanced", true );
filterCallback
default callback
true
if the element is to be filtered, and it must return false
if the element is to be shown. The function is called once for each of the DOM elements and its context is set to the DOM element for which a decision is needed. Thus, the keyword this
refers to the DOM element for which it must be decided whether it should be shown. The default value of this attribute is a function that will examine each child for the presence of the data-filtertext
attribute. If such an attribute is found, the function returns true
if the string contained in the function's searchValue
parameter cannot be found inside the value of the data-filtertext
attribute. If no such attribute is found, the text content of the child is searched for the presence of the value of the function's searchValue
parameter, and the function returns true
if the search fails.
For backwards compatibility with the jQuery Mobile 1.3 listview filter extension, the function provided as the default value of this attribute will never hide listview dividers, however, this behavior is deprecated as of jQuery Mobile 1.4.0 and will be removed in jQuery Mobile 1.5.0.
You can provide a custom callback if you need to process the children in special ways.
filterPlaceholder
"Filter items..."
A string that will be used as the value of the placeholder
attribute for the generated text input.
This option is also exposed as a data attribute: data-filter-placeholder="Refine options..."
.
Initialize the filterable with the filterPlaceholder
option specified:
$( ".selector" ).filterable({ filterPlaceholder: "Refine options..." });
Get or set the filterPlaceholder
option, after initialization:
// Getter var filterPlaceholder = $( ".selector" ).filterable( "option", "filterPlaceholder" ); // Setter $( ".selector" ).filterable( "option", "filterPlaceholder", "Refine options..." );
filterReveal
false
true
all children are hidden whenever the search string is empty. This option is also exposed as a data attribute: data-filter-reveal="true"
.
Initialize the filterable with the filterReveal
option specified:
$( ".selector" ).filterable({ filterReveal: true });
Get or set the filterReveal
option, after initialization:
// Getter var filterReveal = $( ".selector" ).filterable( "option", "filterReveal" ); // Setter $( ".selector" ).filterable( "option", "filterReveal", true );
filterTheme
null, inherited from parent
Sets the color scheme (swatch) for the generated text input. It accepts a single letter from a-z that maps to the swatches included in your theme.
Possible values: swatch letter (a-z).
If a collapsibleset, selectmenu, controlgroup, or listview widget is instantiated on the element and its options are being synchronized with the options of the generated text input, then the value of this option, if set, takes precedence overe the value of the theme
option retrieved from the the widget.
This option is also exposed as a data attribute: data-filter-theme="b"
.
Initialize the filterable with the filterTheme
option specified:
$( ".selector" ).filterable({ filterTheme: b });
Get or set the filterTheme
option, after initialization:
// Getter var filterTheme = $( ".selector" ).filterable( "option", "filterTheme" ); // Setter $( ".selector" ).filterable( "option", "filterTheme", b );
input
null
This option is also exposed as a data attribute: data-input="#input-for-filterable"
.
- String: A jQuery selector that will be used to retrieve the element that will serve as the input source.
- jQuery: A jQuery object containing the element that will serve as the input source.
- Element: The element that will serve as the input source.
Initialize the filterable with the input
option specified:
$( ".selector" ).filterable({ input: "#input-for-filterable" });
Get or set the input
option, after initialization:
// Getter var input = $( ".selector" ).filterable( "option", "input" ); // Setter $( ".selector" ).filterable( "option", "input", "#input-for-filterable" );
Methods
destroy()Returns: jQuery (plugin only)
- This method does not accept any arguments.
Invoke the destroy method:
$( ".selector" ).filterable( "destroy" );
disable()Returns: jQuery (plugin only)
- This method does not accept any arguments.
Invoke the disable method:
$( ".selector" ).filterable( "disable" );
enable()Returns: jQuery (plugin only)
- This method does not accept any arguments.
Invoke the enable method:
$( ".selector" ).filterable( "enable" );
option( optionName )Returns: Object
optionName
.- optionNameType: StringThe name of the option to get.
Invoke the method:
var isDisabled = $( ".selector" ).filterable( "option", "disabled" );
option()Returns: PlainObject
- This signature does not accept any arguments.
Invoke the method:
var options = $( ".selector" ).filterable( "option" );
option( optionName, value )Returns: jQuery (plugin only)
optionName
.- optionNameType: StringThe name of the option to set.
- valueType: ObjectA value to set for the option.
Invoke the method:
$( ".selector" ).filterable( "option", "disabled", true );
option( options )Returns: jQuery (plugin only)
- optionsType: ObjectA map of option-value pairs to set.
Invoke the method:
$( ".selector" ).filterable( "option", { disabled: true } );
refresh()Returns: jQuery (plugin only)
If you manipulate a filterable widget via JavaScript (e.g. by adding new children or removing old ones), you must call the refresh()
method on it to update the visual styling.
- This method does not accept any arguments.
Invoke the refresh method:
$( ".selector" ).filterable( "refresh" );
Events
beforefilter( event )Type: filterablebeforefilter
- eventType: Event
Note: The ui
object is empty but included for consistency with other events.
Initialize the filterable with the beforefilter callback specified:
$( ".selector" ).filterable({ beforefilter: function( event, ui ) {} });
Bind an event listener to the filterablebeforefilter event:
$( ".selector" ).on( "filterablebeforefilter", function( event, ui ) {} );
create( event, ui )Type: filterablecreate
Note: The ui
object is empty but included for consistency with other events.
Initialize the filterable with the create callback specified:
$( ".selector" ).filterable({ create: function( event, ui ) {} });
Bind an event listener to the filterablecreate event:
$( ".selector" ).on( "filterablecreate", function( event, ui ) {} );
filter( event, ui )Type: filterablefilter
ui
parameter contains the list of children that was processed.- eventType: Event
- uiType: Object
- itemsType: jQueryA jQuery collection object containing the items over which the filter has iterated.
-
Initialize the filterable with the filter callback specified:
$( ".selector" ).filterable({ filter: function( event, ui ) {} });
Bind an event listener to the filterablefilter event:
$( ".selector" ).on( "filterablefilter", function( event, ui ) {} );