/* This file is part of Ext JS 4 Copyright (c) 2011 Sencha Inc Contact: http://www.sencha.com/contact GNU General Public License Usage 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. If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact. */ /** * @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:
     * fieldCls : Ext.form.field.Number
     * 
*/ fieldCls : 'Ext.form.field.Number', /** * @cfg {Object} fieldCfg * The default configuration options for any field item unless superseded * by the {@link #fields} configuration. * Defaults to:
     * fieldCfg : {}
     * 
* Example usage: *

fieldCfg : {
    width: 150,
},
     * 
*/ /** * @cfg {Object} fields * The field items may be configured individually * Defaults to undefined. * Example usage: *

fields : {
    gt: { // override fieldCfg options
        width: 200,
        fieldCls: Ext.ux.form.CustomNumberField // to override default {@link #fieldCls}
    }
},
     * 
*/ /** * @cfg {Object} iconCls * The iconCls to be applied to each comparator field item. * Defaults to:
iconCls : {
    gt : 'ux-rangemenu-gt',
    lt : 'ux-rangemenu-lt',
    eq : 'ux-rangemenu-eq'
}
     * 
*/ iconCls : { 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:
fieldLabels : {
     gt: 'Greater Than',
     lt: 'Less Than',
     eq: 'Equal To'
}
*/ fieldLabels: { gt: 'Greater Than', lt: 'Less Than', eq: 'Equal To' }, /** * @cfg {Object} menuItemCfgs * Default configuration options for each menu item * Defaults to:
menuItemCfgs : {
    emptyText: 'Enter Filter Text...',
    selectOnFocus: true,
    width: 125
}
     * 
*/ 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:
     * menuItems : ['lt','gt','-','eq']
     * 
*/ 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.iconCls[item] || 'no-icon', text: me.fieldLabels[item] || '', src: Ext.BLANK_IMAGE_URL }), labelSeparator: '', labelWidth: 29, 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 key; for (key in this.fields) { this.fields[key].setValue(key in data ? data[key] : ''); } this.fireEvent('update', this); }, /** * @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', '{text}' ); });