3 This file is part of Ext JS 4
5 Copyright (c) 2011 Sencha Inc
7 Contact: http://www.sencha.com/contact
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
16 * @class Ext.util.Filter
18 * <p>Represents a filter that can be applied to a {@link Ext.util.MixedCollection MixedCollection}. Can either simply
19 * filter on a property/value pair or pass in a filter function with custom logic. Filters are always used in the context
20 * of MixedCollections, though {@link Ext.data.Store Store}s frequently create them when filtering and searching on their
21 * records. Example usage:</p>
23 //set up a fictional MixedCollection containing a few people to filter on
24 var allNames = new Ext.util.MixedCollection();
26 {id: 1, name: 'Ed', age: 25},
27 {id: 2, name: 'Jamie', age: 37},
28 {id: 3, name: 'Abe', age: 32},
29 {id: 4, name: 'Aaron', age: 26},
30 {id: 5, name: 'David', age: 32}
33 var ageFilter = new Ext.util.Filter({
38 var longNameFilter = new Ext.util.Filter({
39 filterFn: function(item) {
40 return item.name.length > 4;
44 //a new MixedCollection with the 3 names longer than 4 characters
45 var longNames = allNames.filter(longNameFilter);
47 //a new MixedCollection with the 2 people of age 24:
48 var youngFolk = allNames.filter(ageFilter);
51 Ext.define('Ext.util.Filter', {
53 /* Begin Definitions */
57 * @cfg {String} property The property to filter on. Required unless a {@link #filterFn} is passed
61 * @cfg {Function} filterFn A custom filter function which is passed each item in the {@link Ext.util.MixedCollection}
62 * in turn. Should return true to accept each item or false to reject it
66 * @cfg {Boolean} anyMatch True to allow any match - no regex start/end line anchors will be added. Defaults to false
71 * @cfg {Boolean} exactMatch True to force exact match (^ and $ characters added to the regex). Defaults to false.
72 * Ignored if anyMatch is true.
77 * @cfg {Boolean} caseSensitive True to make the regex case sensitive (adds 'i' switch to regex). Defaults to false.
82 * @cfg {String} root Optional root property. This is mostly useful when filtering a Store, in which case we set the
83 * root to 'data' to make the filter pull the {@link #property} out of the data object of each item
88 * @param {Object} config (optional) Config object
90 constructor: function(config) {
91 Ext.apply(this, config);
93 //we're aliasing filter to filterFn mostly for API cleanliness reasons, despite the fact it dirties the code here.
94 //Ext.util.Sorter takes a sorterFn property but allows .sort to be called - we do the same here
95 this.filter = this.filter || this.filterFn;
97 if (this.filter == undefined) {
98 if (this.property == undefined || this.value == undefined) {
99 // Commented this out temporarily because it stops us using string ids in models. TODO: Remove this once
100 // Model has been updated to allow string ids
102 // Ext.Error.raise("A Filter requires either a property or a filterFn to be set");
104 this.filter = this.createFilterFn();
107 this.filterFn = this.filter;
113 * Creates a filter function for the configured property/value/anyMatch/caseSensitive options for this Filter
115 createFilterFn: function() {
117 matcher = me.createValueMatcher(),
118 property = me.property;
120 return function(item) {
121 return matcher.test(me.getRoot.call(me, item)[property]);
127 * Returns the root property of the given item, based on the configured {@link #root} property
128 * @param {Object} item The item
129 * @return {Object} The root property of the object
131 getRoot: function(item) {
132 return this.root == undefined ? item : item[this.root];
137 * Returns a regular expression based on the given value and matching options
139 createValueMatcher : function() {
142 anyMatch = me.anyMatch,
143 exactMatch = me.exactMatch,
144 caseSensitive = me.caseSensitive,
145 escapeRe = Ext.String.escapeRegex;
147 if (!value.exec) { // not a regex
148 value = String(value);
150 if (anyMatch === true) {
151 value = escapeRe(value);
153 value = '^' + escapeRe(value);
154 if (exactMatch === true) {
158 value = new RegExp(value, caseSensitive ? '' : 'i');