| //>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude); |
| //>>description: Extends the listview to add a search box to filter lists |
| //>>label: Listview: Filter |
| //>>group: Widgets |
| |
| |
| define( [ "jquery", "./listview", "./forms/textinput" ], function( jQuery ) { |
| //>>excludeEnd("jqmBuildExclude"); |
| (function( $, undefined ) { |
| |
| $.mobile.listview.prototype.options.filter = false; |
| $.mobile.listview.prototype.options.filterPlaceholder = ""; |
| $.mobile.listview.prototype.options.filterTheme = "c"; |
| // TODO rename callback/deprecate and default to the item itself as the first argument |
| var defaultFilterCallback = function( text, searchValue, item ) { |
| return text.toString().toLowerCase().indexOf( searchValue ) === -1; |
| }; |
| |
| $.mobile.listview.prototype.options.filterCallback = defaultFilterCallback; |
| |
| $.mobile.$document.delegate( ":jqmData(role='listview')", "listviewcreate", function() { |
| |
| var list = $( this ), |
| listview = list.data( "listview" ); |
| |
| if ( !listview.options.filter ) { |
| return; |
| } |
| |
| var wrapper = $( "<form>", { |
| "class": "ui-listview-filter ui-bar-" + listview.options.filterTheme, |
| "role": "search" |
| }), |
| search = $( "<input>", { |
| placeholder: listview.options.filterPlaceholder |
| }) |
| .attr( "data-" + $.mobile.ns + "type", "search" ) |
| .jqmData( "lastval", "" ) |
| .bind( "keyup change", function() { |
| |
| var $this = $( this ), |
| val = this.value.toLowerCase(), |
| listItems = null, |
| lastval = $this.jqmData( "lastval" ) + "", |
| childItems = false, |
| itemtext = "", |
| item, |
| // Check if a custom filter callback applies |
| isCustomFilterCallback = listview.options.filterCallback !== defaultFilterCallback; |
| |
| listview._trigger( "beforefilter", "beforefilter", { input: this } ); |
| |
| // Change val as lastval for next execution |
| $this.jqmData( "lastval" , val ); |
| if ( isCustomFilterCallback || val.length < lastval.length || val.indexOf( lastval ) !== 0 ) { |
| |
| // Custom filter callback applies or removed chars or pasted something totally different, check all items |
| listItems = list.children(); |
| } else { |
| |
| // Only chars added, not removed, only use visible subset |
| listItems = list.children( ":not(.ui-screen-hidden)" ); |
| } |
| |
| if ( val ) { |
| |
| // This handles hiding regular rows without the text we search for |
| // and any list dividers without regular rows shown under it |
| |
| for ( var i = listItems.length - 1; i >= 0; i-- ) { |
| item = $( listItems[ i ] ); |
| itemtext = $.mobile.getAttrFixed( item[0], "data-" + $.mobile.ns + "filtertext" ) || item.text(); |
| |
| if ( item.is( "li:jqmData(role=list-divider)" ) ) { |
| |
| item.toggleClass( "ui-filter-hidequeue" , !childItems ); |
| |
| // New bucket! |
| childItems = false; |
| |
| } else if ( listview.options.filterCallback( itemtext, val, item ) ) { |
| |
| //mark to be hidden |
| item.toggleClass( "ui-filter-hidequeue" , true ); |
| } else { |
| |
| // There's a shown item in the bucket |
| childItems = true; |
| } |
| } |
| |
| // Show items, not marked to be hidden |
| listItems |
| .filter( ":not(.ui-filter-hidequeue)" ) |
| .toggleClass( "ui-screen-hidden", false ); |
| |
| // Hide items, marked to be hidden |
| listItems |
| .filter( ".ui-filter-hidequeue" ) |
| .toggleClass( "ui-screen-hidden", true ) |
| .toggleClass( "ui-filter-hidequeue", false ); |
| |
| } else { |
| |
| //filtervalue is empty => show all |
| listItems.toggleClass( "ui-screen-hidden", false ); |
| } |
| listview._refreshCorners(); |
| }) |
| .appendTo( wrapper ) |
| .textinput(); |
| |
| if ( listview.options.inset ) { |
| wrapper.addClass( "ui-listview-filter-inset" ); |
| } |
| |
| wrapper.bind( "submit", function() { |
| return false; |
| }) |
| .insertBefore( list ); |
| }); |
| |
| })( jQuery ); |
| //>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude); |
| }); |
| //>>excludeEnd("jqmBuildExclude"); |