/ext-4.1.0_b3/docs/extjs/examples/ux/grid/menu/RangeMenu.js
JavaScript | 257 lines | 118 code | 23 blank | 116 comment | 19 complexity | 7f5057c0977aa409dfc631cd3ed9082c MD5 | raw file
1/**
2 * @class Ext.ux.grid.menu.RangeMenu
3 * @extends Ext.menu.Menu
4 * Custom implementation of {@link Ext.menu.Menu} that has preconfigured items for entering numeric
5 * range comparison values: less-than, greater-than, and equal-to. This is used internally
6 * by {@link Ext.ux.grid.filter.NumericFilter} to create its menu.
7 */
8Ext.define('Ext.ux.grid.menu.RangeMenu', {
9 extend: 'Ext.menu.Menu',
10
11 /**
12 * @cfg {String} fieldCls
13 * The Class to use to construct each field item within this menu
14 * Defaults to:<pre>
15 * fieldCls : Ext.form.field.Number
16 * </pre>
17 */
18 fieldCls : 'Ext.form.field.Number',
19
20 /**
21 * @cfg {Object} fieldCfg
22 * The default configuration options for any field item unless superseded
23 * by the <code>{@link #fields}</code> configuration.
24 * Defaults to:<pre>
25 * fieldCfg : {}
26 * </pre>
27 * Example usage:
28 * <pre><code>
29fieldCfg : {
30 width: 150,
31},
32 * </code></pre>
33 */
34
35 /**
36 * @cfg {Object} fields
37 * The field items may be configured individually
38 * Defaults to <tt>undefined</tt>.
39 * Example usage:
40 * <pre><code>
41fields : {
42 gt: { // override fieldCfg options
43 width: 200,
44 fieldCls: Ext.ux.form.CustomNumberField // to override default {@link #fieldCls}
45 }
46},
47 * </code></pre>
48 */
49
50 /**
51 * @cfg {Object} iconCls
52 * The iconCls to be applied to each comparator field item.
53 * Defaults to:<pre>
54iconCls : {
55 gt : 'ux-rangemenu-gt',
56 lt : 'ux-rangemenu-lt',
57 eq : 'ux-rangemenu-eq'
58}
59 * </pre>
60 */
61 iconCls : {
62 gt : 'ux-rangemenu-gt',
63 lt : 'ux-rangemenu-lt',
64 eq : 'ux-rangemenu-eq'
65 },
66
67 /**
68 * @cfg {Object} fieldLabels
69 * Accessible label text for each comparator field item. Can be overridden by localization
70 * files. Defaults to:<pre>
71fieldLabels : {
72 gt: 'Greater Than',
73 lt: 'Less Than',
74 eq: 'Equal To'
75}</pre>
76 */
77 fieldLabels: {
78 gt: 'Greater Than',
79 lt: 'Less Than',
80 eq: 'Equal To'
81 },
82
83 /**
84 * @cfg {Object} menuItemCfgs
85 * Default configuration options for each menu item
86 * Defaults to:<pre>
87menuItemCfgs : {
88 emptyText: 'Enter Filter Text...',
89 selectOnFocus: true,
90 width: 125
91}
92 * </pre>
93 */
94 menuItemCfgs : {
95 emptyText: 'Enter Number...',
96 selectOnFocus: false,
97 width: 155
98 },
99
100 /**
101 * @cfg {Array} menuItems
102 * The items to be shown in this menu. Items are added to the menu
103 * according to their position within this array. Defaults to:<pre>
104 * menuItems : ['lt','gt','-','eq']
105 * </pre>
106 */
107 menuItems : ['lt', 'gt', '-', 'eq'],
108
109
110 constructor : function (config) {
111 var me = this,
112 fields, fieldCfg, i, len, item, cfg, Cls;
113
114 me.callParent(arguments);
115
116 fields = me.fields = me.fields || {};
117 fieldCfg = me.fieldCfg = me.fieldCfg || {};
118
119 me.addEvents(
120 /**
121 * @event update
122 * Fires when a filter configuration has changed
123 * @param {Ext.ux.grid.filter.Filter} this The filter object.
124 */
125 'update'
126 );
127
128 me.updateTask = Ext.create('Ext.util.DelayedTask', me.fireUpdate, me);
129
130 for (i = 0, len = me.menuItems.length; i < len; i++) {
131 item = me.menuItems[i];
132 if (item !== '-') {
133 // defaults
134 cfg = {
135 itemId: 'range-' + item,
136 enableKeyEvents: true,
137 hideLabel: false,
138 fieldLabel: me.iconTpl.apply({
139 cls: me.iconCls[item] || 'no-icon',
140 text: me.fieldLabels[item] || '',
141 src: Ext.BLANK_IMAGE_URL
142 }),
143 labelSeparator: '',
144 labelWidth: 29,
145 labelStyle: 'position: relative;',
146 listeners: {
147 scope: me,
148 change: me.onInputChange,
149 keyup: me.onInputKeyUp,
150 el: {
151 click: function(e) {
152 e.stopPropagation();
153 }
154 }
155 },
156 activate: Ext.emptyFn,
157 deactivate: Ext.emptyFn
158 };
159 Ext.apply(
160 cfg,
161 // custom configs
162 Ext.applyIf(fields[item] || {}, fieldCfg[item]),
163 // configurable defaults
164 me.menuItemCfgs
165 );
166 Cls = cfg.fieldCls || me.fieldCls;
167 item = fields[item] = Ext.create(Cls, cfg);
168 }
169 me.add(item);
170 }
171 },
172
173 /**
174 * @private
175 * called by this.updateTask
176 */
177 fireUpdate : function () {
178 this.fireEvent('update', this);
179 },
180
181 /**
182 * Get and return the value of the filter.
183 * @return {String} The value of this filter
184 */
185 getValue : function () {
186 var result = {}, key, field;
187 for (key in this.fields) {
188 field = this.fields[key];
189 if (field.isValid() && field.getValue() !== null) {
190 result[key] = field.getValue();
191 }
192 }
193 return result;
194 },
195
196 /**
197 * Set the value of this menu and fires the 'update' event.
198 * @param {Object} data The data to assign to this menu
199 */
200 setValue : function (data) {
201 var key;
202 for (key in this.fields) {
203 this.fields[key].setValue(key in data ? data[key] : '');
204 }
205 this.fireEvent('update', this);
206 },
207
208 /**
209 * @private
210 * Handler method called when there is a keyup event on an input
211 * item of this menu.
212 */
213 onInputKeyUp: function(field, e) {
214 if (e.getKey() === e.RETURN && field.isValid()) {
215 e.stopEvent();
216 this.hide();
217 }
218 },
219
220 /**
221 * @private
222 * Handler method called when the user changes the value of one of the input
223 * items in this menu.
224 */
225 onInputChange: function(field) {
226 var me = this,
227 fields = me.fields,
228 eq = fields.eq,
229 gt = fields.gt,
230 lt = fields.lt;
231
232 if (field == eq) {
233 if (gt) {
234 gt.setValue(null);
235 }
236 if (lt) {
237 lt.setValue(null);
238 }
239 }
240 else {
241 eq.setValue(null);
242 }
243
244 // restart the timer
245 this.updateTask.delay(this.updateBuffer);
246 }
247}, function() {
248
249 /**
250 * @cfg {Ext.XTemplate} iconTpl
251 * A template for generating the label for each field in the menu
252 */
253 this.prototype.iconTpl = Ext.create('Ext.XTemplate',
254 '<img src="{src}" alt="{text}" class="' + Ext.baseCSSPrefix + 'menu-item-icon ux-rangemenu-icon {cls}" />'
255 );
256
257});