You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
268 lines
7.2 KiB
JavaScript
268 lines
7.2 KiB
JavaScript
3 years ago
|
/**
|
||
|
* @class Ext.ux.grid.menu.RangeMenu
|
||
|
* @extends Ext.menu.Menu
|
||
|
* Custom implementation of {@link Ext.menu.Menu} that has preconfigured items for entering numeric
|
||
|
* range comparison values: less-than, greater-than, and equal-to. This is used internally
|
||
|
* by {@link Ext.ux.grid.filter.NumericFilter} to create its menu.
|
||
|
*/
|
||
|
Ext.define('Ext.ux.grid.menu.RangeMenu', {
|
||
|
extend: 'Ext.menu.Menu',
|
||
|
|
||
|
/**
|
||
|
* @cfg {String} fieldCls
|
||
|
* The Class to use to construct each field item within this menu
|
||
|
* Defaults to:<pre>
|
||
|
* fieldCls : Ext.form.field.Number
|
||
|
* </pre>
|
||
|
*/
|
||
|
fieldCls : 'Ext.form.field.Number',
|
||
|
|
||
|
/**
|
||
|
* @cfg {Object} fieldCfg
|
||
|
* The default configuration options for any field item unless superseded
|
||
|
* by the <code>{@link #fields}</code> configuration.
|
||
|
* Defaults to:<pre>
|
||
|
* fieldCfg : {}
|
||
|
* </pre>
|
||
|
* Example usage:
|
||
|
* <pre><code>
|
||
|
fieldCfg : {
|
||
|
width: 150,
|
||
|
},
|
||
|
* </code></pre>
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @cfg {Object} fields
|
||
|
* The field items may be configured individually
|
||
|
* Defaults to <tt>undefined</tt>.
|
||
|
* Example usage:
|
||
|
* <pre><code>
|
||
|
fields : {
|
||
|
gt: { // override fieldCfg options
|
||
|
width: 200,
|
||
|
fieldCls: Ext.ux.form.CustomNumberField // to override default {@link #fieldCls}
|
||
|
}
|
||
|
},
|
||
|
* </code></pre>
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @cfg {Object} itemIconCls
|
||
|
* The itemIconCls to be applied to each comparator field item.
|
||
|
* Defaults to:<pre>
|
||
|
itemIconCls : {
|
||
|
gt : 'ux-rangemenu-gt',
|
||
|
lt : 'ux-rangemenu-lt',
|
||
|
eq : 'ux-rangemenu-eq'
|
||
|
}
|
||
|
* </pre>
|
||
|
*/
|
||
|
itemIconCls : {
|
||
|
gt : 'ux-rangemenu-gt',
|
||
|
lt : 'ux-rangemenu-lt',
|
||
|
eq : 'ux-rangemenu-eq'
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @cfg {Object} fieldLabels
|
||
|
* Accessible label text for each comparator field item. Can be overridden by localization
|
||
|
* files. Defaults to:<pre>
|
||
|
fieldLabels : {
|
||
|
gt: 'Greater Than',
|
||
|
lt: 'Less Than',
|
||
|
eq: 'Equal To'
|
||
|
}</pre>
|
||
|
*/
|
||
|
fieldLabels: {
|
||
|
gt: 'Greater Than',
|
||
|
lt: 'Less Than',
|
||
|
eq: 'Equal To'
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @cfg {Object} menuItemCfgs
|
||
|
* Default configuration options for each menu item
|
||
|
* Defaults to:<pre>
|
||
|
menuItemCfgs : {
|
||
|
emptyText: 'Enter Filter Text...',
|
||
|
selectOnFocus: true,
|
||
|
width: 125
|
||
|
}
|
||
|
* </pre>
|
||
|
*/
|
||
|
menuItemCfgs : {
|
||
|
emptyText: 'Enter Number...',
|
||
|
selectOnFocus: false,
|
||
|
width: 155
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @cfg {Array} menuItems
|
||
|
* The items to be shown in this menu. Items are added to the menu
|
||
|
* according to their position within this array. Defaults to:<pre>
|
||
|
* menuItems : ['lt','gt','-','eq']
|
||
|
* </pre>
|
||
|
*/
|
||
|
menuItems : ['lt', 'gt', '-', 'eq'],
|
||
|
|
||
|
|
||
|
constructor : function (config) {
|
||
|
var me = this,
|
||
|
fields, fieldCfg, i, len, item, cfg, Cls;
|
||
|
|
||
|
me.callParent(arguments);
|
||
|
|
||
|
fields = me.fields = me.fields || {};
|
||
|
fieldCfg = me.fieldCfg = me.fieldCfg || {};
|
||
|
|
||
|
me.addEvents(
|
||
|
/**
|
||
|
* @event update
|
||
|
* Fires when a filter configuration has changed
|
||
|
* @param {Ext.ux.grid.filter.Filter} this The filter object.
|
||
|
*/
|
||
|
'update'
|
||
|
);
|
||
|
|
||
|
me.updateTask = Ext.create('Ext.util.DelayedTask', me.fireUpdate, me);
|
||
|
|
||
|
for (i = 0, len = me.menuItems.length; i < len; i++) {
|
||
|
item = me.menuItems[i];
|
||
|
if (item !== '-') {
|
||
|
// defaults
|
||
|
cfg = {
|
||
|
itemId: 'range-' + item,
|
||
|
enableKeyEvents: true,
|
||
|
hideLabel: false,
|
||
|
fieldLabel: me.iconTpl.apply({
|
||
|
cls: me.itemIconCls[item] || 'no-icon',
|
||
|
text: me.fieldLabels[item] || '',
|
||
|
src: Ext.BLANK_IMAGE_URL
|
||
|
}),
|
||
|
labelSeparator: '',
|
||
|
labelWidth: 29,
|
||
|
labelStyle: 'position: relative;',
|
||
|
listeners: {
|
||
|
scope: me,
|
||
|
change: me.onInputChange,
|
||
|
keyup: me.onInputKeyUp,
|
||
|
el: {
|
||
|
click: function(e) {
|
||
|
e.stopPropagation();
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
activate: Ext.emptyFn,
|
||
|
deactivate: Ext.emptyFn
|
||
|
};
|
||
|
Ext.apply(
|
||
|
cfg,
|
||
|
// custom configs
|
||
|
Ext.applyIf(fields[item] || {}, fieldCfg[item]),
|
||
|
// configurable defaults
|
||
|
me.menuItemCfgs
|
||
|
);
|
||
|
Cls = cfg.fieldCls || me.fieldCls;
|
||
|
item = fields[item] = Ext.create(Cls, cfg);
|
||
|
}
|
||
|
me.add(item);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
* called by this.updateTask
|
||
|
*/
|
||
|
fireUpdate : function () {
|
||
|
this.fireEvent('update', this);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Get and return the value of the filter.
|
||
|
* @return {String} The value of this filter
|
||
|
*/
|
||
|
getValue : function () {
|
||
|
var result = {}, key, field;
|
||
|
for (key in this.fields) {
|
||
|
field = this.fields[key];
|
||
|
if (field.isValid() && field.getValue() !== null) {
|
||
|
result[key] = field.getValue();
|
||
|
}
|
||
|
}
|
||
|
return result;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Set the value of this menu and fires the 'update' event.
|
||
|
* @param {Object} data The data to assign to this menu
|
||
|
*/
|
||
|
setValue : function (data) {
|
||
|
var me = this,
|
||
|
key,
|
||
|
field;
|
||
|
|
||
|
for (key in me.fields) {
|
||
|
|
||
|
// Prevent field's change event from tiggering a Store filter. The final upate event will do that
|
||
|
field = me.fields[key];
|
||
|
field.suspendEvents();
|
||
|
field.setValue(key in data ? data[key] : '');
|
||
|
field.resumeEvents();
|
||
|
}
|
||
|
|
||
|
// Trigger the filering of the Store
|
||
|
me.fireEvent('update', me);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
* Handler method called when there is a keyup event on an input
|
||
|
* item of this menu.
|
||
|
*/
|
||
|
onInputKeyUp: function(field, e) {
|
||
|
if (e.getKey() === e.RETURN && field.isValid()) {
|
||
|
e.stopEvent();
|
||
|
this.hide();
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
* Handler method called when the user changes the value of one of the input
|
||
|
* items in this menu.
|
||
|
*/
|
||
|
onInputChange: function(field) {
|
||
|
var me = this,
|
||
|
fields = me.fields,
|
||
|
eq = fields.eq,
|
||
|
gt = fields.gt,
|
||
|
lt = fields.lt;
|
||
|
|
||
|
if (field == eq) {
|
||
|
if (gt) {
|
||
|
gt.setValue(null);
|
||
|
}
|
||
|
if (lt) {
|
||
|
lt.setValue(null);
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
eq.setValue(null);
|
||
|
}
|
||
|
|
||
|
// restart the timer
|
||
|
this.updateTask.delay(this.updateBuffer);
|
||
|
}
|
||
|
}, function() {
|
||
|
|
||
|
/**
|
||
|
* @cfg {Ext.XTemplate} iconTpl
|
||
|
* A template for generating the label for each field in the menu
|
||
|
*/
|
||
|
this.prototype.iconTpl = Ext.create('Ext.XTemplate',
|
||
|
'<img src="{src}" alt="{text}" class="' + Ext.baseCSSPrefix + 'menu-item-icon ux-rangemenu-icon {cls}" />'
|
||
|
);
|
||
|
|
||
|
});
|