RangeMenu.js 7.5 KB

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