Permalink
Browse files

Listview: Filter: Convert to extension.

  • Loading branch information...
1 parent a45edfa commit 3f7a78871db19cf3d2c7a61b088cfd52b7487e44 @gabrielschulhof gabrielschulhof committed Mar 26, 2013
Showing with 109 additions and 93 deletions.
  1. +109 −93 js/widgets/listview.filter.js
@@ -8,130 +8,146 @@ define( [ "jquery", "./listview", "./forms/textinput" ], function( jQuery ) {
//>>excludeEnd("jqmBuildExclude");
(function( $, undefined ) {
-$.mobile.listview.prototype.options.filter = false;
-$.mobile.listview.prototype.options.filterPlaceholder = "Filter items...";
-$.mobile.listview.prototype.options.filterTheme = "c";
-$.mobile.listview.prototype.options.filterReveal = false;
// 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;
- };
+ return text.toString().toLowerCase().indexOf( searchValue ) === -1;
+};
+
+$.widget( "mobile.listview", $.mobile.listview, {
+ options: {
+ filter: false,
+ filterPlaceholder: "Filter items...",
+ filterTheme: "c",
+ filterReveal: false,
+ filterCallback: defaultFilterCallback
+ },
+
+ _onKeyUp: function( e ) {
+ var search = this._search,
+ o = this.options,
+ list = this.element,
+ val = search[ 0 ].value.toLowerCase(),
+ listItems = null,
+ li = list.children(),
+ lastval = search.jqmData( "lastval" ) + "",
+ childItems = false,
+ itemtext = "",
+ item,
+ // Check if a custom filter callback applies
+ isCustomFilterCallback = o.filterCallback !== defaultFilterCallback;
+
+ if ( lastval && lastval === val ) {
+ // Execute the handler only once per value change
+ return;
+ }
+
+ this._trigger( "beforefilter", "beforefilter", { input: search[ 0 ] } );
+
+ // Change val as lastval for next execution
+ search.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 ( !listItems.length && o.filterReveal ) {
+ listItems = list.children( ".ui-screen-hidden" );
+ }
+ }
-$.mobile.listview.prototype.options.filterCallback = defaultFilterCallback;
+ if ( val ) {
-$.mobile.document.delegate( "ul, ol", "listviewcreate", function() {
- var list = $( this ),
- listview = list.data( "mobile-listview" );
+ // This handles hiding regular rows without the text we search for
+ // and any list dividers without regular rows shown under it
- if ( !listview || !listview.options.filter ) {
- return;
- }
+ for ( var i = listItems.length - 1; i >= 0; i-- ) {
+ item = $( listItems[ i ] );
+ itemtext = item.jqmData( "filtertext" ) || item.text();
- if ( listview.options.filterReveal ) {
- list.children().addClass( "ui-screen-hidden" );
- }
+ if ( item.is( "li:jqmData(role=list-divider)" ) ) {
- var wrapper = $( "<form>", {
- "class": "ui-listview-filter ui-bar-" + listview.options.filterTheme,
- "role": "search"
- }).submit( function( e ) {
- search.blur();
- return false;
- }),
- onKeyUp = function( e ) {
- var $this = $( this ),
- val = this.value.toLowerCase(),
- listItems = null,
- li = list.children(),
- lastval = $this.jqmData( "lastval" ) + "",
- childItems = false,
- itemtext = "",
- item,
- // Check if a custom filter callback applies
- isCustomFilterCallback = listview.options.filterCallback !== defaultFilterCallback;
-
- if ( lastval && lastval === val ) {
- // Execute the handler only once per value change
- return;
- }
-
- listview._trigger( "beforefilter", "beforefilter", { input: this } );
+ item.toggleClass( "ui-filter-hidequeue" , !childItems );
- // Change val as lastval for next execution
- $this.jqmData( "lastval" , val );
- if ( isCustomFilterCallback || val.length < lastval.length || val.indexOf( lastval ) !== 0 ) {
+ // New bucket!
+ childItems = false;
- // Custom filter callback applies or removed chars or pasted something totally different, check all items
- listItems = list.children();
- } else {
+ } else if ( o.filterCallback( itemtext, val, item ) ) {
- // Only chars added, not removed, only use visible subset
- listItems = list.children( ":not(.ui-screen-hidden)" );
+ //mark to be hidden
+ item.toggleClass( "ui-filter-hidequeue" , true );
+ } else {
- if ( !listItems.length && listview.options.filterReveal ) {
- listItems = list.children( ".ui-screen-hidden" );
+ // There's a shown item in the bucket
+ childItems = true;
}
}
- 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 = item.jqmData( "filtertext" ) || item.text();
+ // Show items, not marked to be hidden
+ listItems
+ .filter( ":not(.ui-filter-hidequeue)" )
+ .toggleClass( "ui-screen-hidden", false );
- if ( item.is( "li:jqmData(role=list-divider)" ) ) {
+ // Hide items, marked to be hidden
+ listItems
+ .filter( ".ui-filter-hidequeue" )
+ .toggleClass( "ui-screen-hidden", true )
+ .toggleClass( "ui-filter-hidequeue", false );
- item.toggleClass( "ui-filter-hidequeue" , !childItems );
+ } else {
- // New bucket!
- childItems = false;
+ //filtervalue is empty => show all
+ listItems.toggleClass( "ui-screen-hidden", !!o.filterReveal );
+ }
+ this._addFirstLastClasses( li, this._getVisibles( li, false ), false );
+ },
- } else if ( listview.options.filterCallback( itemtext, val, item ) ) {
+ _create: function() {
+ var list, wrapper, onKeyUp, search,
+ o = this.options;
- //mark to be hidden
- item.toggleClass( "ui-filter-hidequeue" , true );
- } else {
+ this._super();
- // 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 );
+ if ( !o.filter ) {
+ return;
+ }
- // Hide items, marked to be hidden
- listItems
- .filter( ".ui-filter-hidequeue" )
- .toggleClass( "ui-screen-hidden", true )
- .toggleClass( "ui-filter-hidequeue", false );
+ list = this.element;
- } else {
+ if ( o.filterReveal ) {
+ list.children().addClass( "ui-screen-hidden" );
+ }
- //filtervalue is empty => show all
- listItems.toggleClass( "ui-screen-hidden", !!listview.options.filterReveal );
- }
- listview._addFirstLastClasses( li, listview._getVisibles( li, false ), false );
- },
+ wrapper = $( "<form>", {
+ "class": "ui-listview-filter ui-bar-" + o.filterTheme,
+ "role": "search"
+ }).submit( function( e ) {
+ search.blur();
+ return false;
+ });
search = $( "<input>", {
- placeholder: listview.options.filterPlaceholder
+ placeholder: o.filterPlaceholder
})
.attr( "data-" + $.mobile.ns + "type", "search" )
.jqmData( "lastval", "" )
- .bind( "keyup change input", onKeyUp )
.appendTo( wrapper )
.textinput();
- if ( listview.options.inset ) {
- wrapper.addClass( "ui-listview-filter-inset" );
- }
+ this._on( search, { keyup: "_onKeyUp", change: "_onKeyUp", input: "_onKeyUp" } );
+
+ $.extend( this, {
+ _search: search
+ });
- wrapper.insertBefore( list );
+ if ( o.inset ) {
+ wrapper.addClass( "ui-listview-filter-inset" );
+ }
+
+ wrapper.insertBefore( list );
+ }
});
})( jQuery );

0 comments on commit 3f7a788

Please sign in to comment.