Commit 7a6598b6 authored by Sven Franck's avatar Sven Franck

create backup of filterbar widget

parent ff33d12e
/* ============================= FILTERBAR/FILTERABLE ================================== */
(function( $, undefined ) {
// TODO rename filterCallback/deprecate and default to the item itself as the first argument
var defaultfilterCallback = function( text, searchValue /*, item */) {
return text.toString().toLowerCase().indexOf( searchValue ) === -1;
};
$.widget( "mobile.filterbar", $.mobile.widget, $.extend( {
options: {
theme: "a",
filterPlaceholder: "Filter items...",
filterReveal: false,
filterCallback: defaultfilterCallback,
wrapperClass: "",
inset: false,
enhanced: false,
target: null,
mini: false,
selector: null
},
_onKeyUp: function() {
var search = this._search[ 0 ],
o = this.options,
getAttrFixed = $.mobile.getAttribute,
val = search.value.toLowerCase(),
lastval = getAttrFixed( search, "lastval", true ) + "";
if ( lastval && lastval === val ) {
// Execute the handler only once per value change
return;
}
if (o.timer !== undefined) {
window.clearTimeout(o.timer);
}
o.timer = this._delay(function() {
this._trigger( "beforefilter", "beforefilter", { input: search } );
// Change val as lastval for next execution
search.setAttribute( "data-" + $.mobile.ns + "lastval" , val );
this._filterItems( search, val, lastval );
}, 300 );
},
_getFilterableItems: function() {
var el = this.element,
o = this.options,
items = [];
if (typeof o.selector === "string") {
items = $("." + o.selector).children();
} else {
items = el.find("> li, > option, tbody tr, .ui-controlgroup-controls .ui-btn");
}
return items;
},
_setFilterableItems: function(val, lastval) {
var o = this.options,
filterItems = [],
isCustomfilterCallback = o.filterCallback !== defaultfilterCallback,
_getFilterableItems = this._getFilterableItems();
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
filterItems = _getFilterableItems;
} else {
// Only chars added, not removed, only use visible subset
filterItems = _getFilterableItems.filter( ":not(.ui-screen-hidden)" );
if ( !filterItems.length && o.filterReveal ) {
filterItems = _getFilterableItems.filter( ".ui-screen-hidden" );
}
}
return filterItems;
},
_filterItems: function( search, val, lastval ){
var o = this.options,
getAttrFixed = $.mobile.getAttribute,
filterItems = this._setFilterableItems(val, lastval),
_getFilterableItems = this._getFilterableItems(),
childItems = false,
itemtext = "",
item,
select = this.element.parents( ".ui-select" ),
i;
this._setOption( "timer", undefined );
if ( val ) {
for ( i = filterItems.length - 1; i >= 0; i-- ) {
item = $( filterItems[ i ] );
// NOTE: should itemtext be stored somewhere? Will text() change much
// and does this need to be re-parsed on every iteration? Also, no
// chance to run data-filtertext on anything that JQM wraps, because
// we filter the wrapper and can't access the input/a. Can we?
itemtext = getAttrFixed(filterItems[ i ], "filtertext", true) || item.text();
if ( item.is( ".ui-li-divider" ) ) {
item.toggleClass( "ui-filter-hidequeue" , !childItems );
// New bucket!
childItems = false;
} else if ( o.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;
}
}
this._toggleFilterableItems( filterItems, select, o.filterReveal , true);
} else {
this._toggleFilterableItems( filterItems, select, o.filterReveal );
}
this._addFirstLastClasses( _getFilterableItems, this._getVisibles( _getFilterableItems, false ), false );
},
_toggleFilterableItems: function( filterItems, select, reveal, isVal ) {
if (isVal) {
// Show items, not marked to be hidden
filterItems
.filter( ":not(.ui-filter-hidequeue)" )
.toggleClass( "ui-screen-hidden", false );
// Hide items, marked to be hidden
filterItems
.filter( ".ui-filter-hidequeue" )
.toggleClass( "ui-screen-hidden", true )
.toggleClass( "ui-filter-hidequeue", false );
// select - hide parent when no options match?
if ( select ) {
if ( filterItems.length === filterItems.filter( ".ui-screen-hidden").length ) {
select.addClass( "ui-screen-hidden" );
}
}
} else {
//filtervalue is empty => show all
filterItems.toggleClass( "ui-screen-hidden", !!reveal );
// select
if ( select ) {
select.removeClass( "ui-screen-hidden", !!reveal );
}
}
},
_enhance: function ( items ) {
var el = this.element,
o = this.options,
wrapper = $( "<div>", {
"class": "ui-filter " + o.wrapperClass,
"role": "search",
"id" : "ui-filter-" + this.uuid
}),
search = $( "<input>", {
placeholder: o.filterPlaceholder
})
.attr( "data-" + $.mobile.ns + "type", "search" )
.appendTo( wrapper )
.textinput({
theme: o.filterTheme,
mini: o.mini
});
if ( o.inset ) {
wrapper.addClass( "ui-filter-inset" );
}
if ( o.filterReveal ) {
items.addClass( "ui-screen-hidden" );
}
if ( typeof o.target === "string" ) {
wrapper.prependTo( $( "." + o.target + "" ) );
} else {
wrapper.insertBefore( el );
}
return search;
},
_create: function() {
var search,
o = this.options,
items = this._getFilterableItems();
this._setOption( "timer", undefined );
if ( !o.enhanced ) {
search = this._enhance( items );
} else {
search = $( "#ui-filter-" + this.uuid ).find( "input" );
}
this._on( search, {
keyup: "_onKeyUp",
change: "_onKeyUp",
input: "_onKeyUp"
});
$.extend( this, {
_search: search
});
// NOTE: since the filter was based on the listview, some unit tests seem
// to listen for the initial addFirstLastClasses call when the listview
// is setup (at least I cannot recreate a refreshCornerCount in Qunit
// without setting first and last classes on the filterable elements on
// create). If refresh corners is to be run on the filter, I would prefer
// it being solely called by the filter being triggered and not be the
// "_super()-widget" calling it. So 2x input on the filter should trigger
// 2x addFirstLastClasses vs. currently 3x because of including the call
// when setting up the parent listview.
this._addFirstLastClasses( items, this._getVisibles( items, true ), true );
},
_setOption: function( key, value ) {
var o = this.options,
wrapper = document.getElementById( "ui-filter-" + this.uuid ),
$input = $( wrapper ).find( "input" );
// always update
o[ key ] = value;
if ( key === "disabled" ) {
$input
.toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
.attr( "aria-disabled", value )
.textinput( value ? "disable" : "enable" );
}
return this;
},
widget: function() {
return this.element;
},
_destroy: function() {
var o = this.options,
wrapper = document.getElementById( "ui-filter-" + this.uuid );
if ( !o.enhanced ) {
wrapper.parentNode.removeChild( wrapper );
}
this._toggleFilterableItems( this._getFilterableItems(), false, false );
}
}, $.mobile.behaviors.addFirstLastClasses ) );
$.mobile.filterbar.initSelector = ":jqmData(filter='true')";
//auto self-init widgets
$.mobile._enhancer.add( "mobile.filterbar" );
})( jQuery );
/* ============================= END ================================== */
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment