SearchField.js (6495B)
1 /** 2 * Defines a search field, which automatically hooks into the passed store. 3 * 4 * The "clear" trigger is shown only when text is entered. 5 */ 6 Ext.define('PartKeepr.form.field.SearchField', { 7 extend: 'Ext.form.field.Text', 8 alias: 'widget.partkeepr-searchfield', 9 10 triggers: { 11 clear: { 12 cls: Ext.baseCSSPrefix + 'form-clear-trigger', 13 hidden: true, 14 handler: 'resetSearch', 15 scope: 'this', 16 }, 17 search: { 18 cls: Ext.baseCSSPrefix + 'form-search-trigger', 19 handler: 'startSearch', 20 scope: 'this' 21 } 22 }, 23 24 /** 25 * @var {Boolean} Specifies if the search field has an active search 26 */ 27 hasSearch: false, 28 29 /** 30 * @cfg {String} Specifies the target property to search 31 */ 32 targetField: 'query', 33 34 35 /** 36 * @cfg {String} Specifies the system property which defines all fields to be searched 37 */ 38 searchFieldSystemPreference: null, 39 40 /** 41 * @cfg {Array} Specifies the default fields to be searched 42 */ 43 searchFieldSystemPreferenceDefaults: [], 44 45 /** 46 * @cfg {String} Specifies the system property which defines if the search terms should be splitted 47 */ 48 splitSearchTermSystemPreference: null, 49 50 /** 51 * @cfg {String} Specifies the default for search term splitting 52 */ 53 splitSearchTermSystemPreferenceDefaults: true, 54 55 /** 56 * @var {Ext.util.Filter} The filter set by the search field 57 */ 58 filter: null, 59 60 listeners: { 61 'specialkey': { 62 fn: 'keyHandler', 63 scope: 'this' 64 } 65 }, 66 67 initComponent: function () 68 { 69 this.store.on("filterchange", this.onFilterChange, this); 70 this.filter = Ext.create("PartKeepr.util.Filter"); 71 this.callParent(arguments); 72 }, 73 onFilterChange: function () 74 { 75 if (!this.store.getFilters().contains(this.filter)) { 76 this.setValue(""); 77 78 this.getTrigger("clear").hide(); 79 this.hasSearch = false; 80 } 81 82 }, 83 /** 84 * Handles special keys used in this field. 85 * 86 * Enter: Starts the search 87 * Escape: Removes the search and clears the field contents 88 */ 89 keyHandler: function (field, e) 90 { 91 switch (e.getKey()) { 92 case e.ENTER: 93 this.startSearch(); 94 break; 95 case e.ESC: 96 this.resetSearch(); 97 break; 98 } 99 }, 100 /** 101 * Resets the search field to empty and re-triggers the store to load the matching records. 102 */ 103 resetSearch: function () 104 { 105 var me = this, 106 store = me.store; 107 108 if (store.isLoading()) { 109 Ext.defer(this.resetSearch, 200, this); 110 return; 111 } 112 113 me.setValue(''); 114 this.filter.setValue(''); 115 116 if (me.hasSearch) { 117 118 if (store.getFilters().contains(this.filter)) { 119 store.getFilters().remove(this.filter); 120 } 121 122 store.currentPage = 1; 123 store.load({start: 0}); 124 me.hasSearch = false; 125 126 this.getTrigger("clear").hide(); 127 } 128 }, 129 /** 130 * Starts the search with the entered value. 131 */ 132 startSearch: function () 133 { 134 var me = this, 135 store = me.store, 136 searchValue = me.getValue(), 137 searchTerms = searchValue.split(" "), 138 splitTerms = true, 139 orSubFilters = [], 140 i, 141 j, 142 subFilters = []; 143 144 if (this.splitSearchTermSystemPreference !== null) { 145 splitTerms = Boolean(PartKeepr.getApplication().getSystemPreference(this.splitSearchTermSystemPreference, 146 this.splitSearchTermSystemPreferenceDefaults)); 147 } 148 149 if (this.searchFieldSystemPreference !== null) { 150 var fields = PartKeepr.getApplication().getSystemPreference(this.searchFieldSystemPreference, 151 this.searchFieldSystemPreferenceDefaults); 152 153 if (splitTerms === true) { 154 for (j = 0; j < searchTerms.length; j++) { 155 orSubFilters = []; 156 for (i = 0; i < fields.length; i++) { 157 orSubFilters.push(this.createFilter(fields[i], searchTerms[j])); 158 } 159 160 subFilters.push(Ext.create("PartKeepr.util.Filter", { 161 type: "OR", 162 subfilters: orSubFilters 163 })); 164 } 165 166 this.filter.setConfig({ 167 type: "AND", 168 subfilters: subFilters 169 }); 170 171 } else { 172 for (i = 0; i < fields.length; i++) { 173 subFilters.push(this.createFilter(fields[i], searchValue)); 174 } 175 176 this.filter.setConfig({ 177 type: "OR", 178 subfilters: subFilters 179 }); 180 } 181 182 183 } else { 184 if (splitTerms === true) { 185 for (j = 0; j < searchTerms.length; j++) { 186 subFilters.push(this.createFilter(this.targetField, searchTerms[j])); 187 } 188 189 this.filter.setConfig({ 190 type: "OR", 191 subfilters: subFilters 192 }); 193 } else { 194 this.filter.setConfig({ 195 property: this.targetField, 196 value: "%" + searchValue+ "%", 197 operator: 'like' 198 }); 199 } 200 } 201 202 if (searchValue.length < 1) { 203 me.resetSearch(); 204 return; 205 } 206 207 if (store.isLoading()) { 208 Ext.defer(this.startSearch, 200, this); 209 return; 210 } 211 212 this.filter.setValue(searchValue); 213 214 if (!store.getFilters().contains(this.filter)) { 215 store.getFilters().add(this.filter); 216 } 217 218 store.getFilters().itemChanged(this.filter); 219 220 me.hasSearch = true; 221 this.getTrigger("clear").show(); 222 }, 223 createFilter: function (property, term) 224 { 225 return Ext.create("PartKeepr.util.Filter", { 226 property: property, 227 value: "%" + term + "%", 228 operator: 'like' 229 }); 230 }, 231 /** 232 * Sets the store to use 233 * 234 * @param {Ext.data.Store} store The store to set 235 */ 236 setStore: function (store) 237 { 238 this.store = store; 239 } 240 });