ListMenu.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  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.ListMenu
  11. * @extends Ext.menu.Menu
  12. * This is a supporting class for {@link Ext.ux.grid.filter.ListFilter}.
  13. * Although not listed as configuration options for this class, this class
  14. * also accepts all configuration options from {@link Ext.ux.grid.filter.ListFilter}.
  15. */
  16. Ext.define('Ext.ux.grid.menu.ListMenu', {
  17. extend: 'Ext.menu.Menu',
  18. /**
  19. * @cfg {String} labelField
  20. * Defaults to 'text'.
  21. */
  22. labelField : 'text',
  23. /**
  24. * @cfg {String} paramPrefix
  25. * Defaults to 'Loading...'.
  26. */
  27. loadingText : 'Loading...',
  28. /**
  29. * @cfg {Boolean} loadOnShow
  30. * Defaults to true.
  31. */
  32. loadOnShow : true,
  33. /**
  34. * @cfg {Boolean} single
  35. * Specify true to group all items in this list into a single-select
  36. * radio button group. Defaults to false.
  37. */
  38. single : false,
  39. constructor : function (cfg) {
  40. this.selected = [];
  41. this.addEvents(
  42. /**
  43. * @event checkchange
  44. * Fires when there is a change in checked items from this list
  45. * @param {Object} item Ext.menu.CheckItem
  46. * @param {Object} checked The checked value that was set
  47. */
  48. 'checkchange'
  49. );
  50. this.callParent([cfg = cfg || {}]);
  51. if(!cfg.store && cfg.options){
  52. var options = [];
  53. for(var i=0, len=cfg.options.length; i<len; i++){
  54. var value = cfg.options[i];
  55. switch(Ext.type(value)){
  56. case 'array': options.push(value); break;
  57. case 'object': options.push([value.id, value[this.labelField]]); break;
  58. case 'string': options.push([value, value]); break;
  59. }
  60. }
  61. this.store = Ext.create('Ext.data.ArrayStore', {
  62. fields: ['id', this.labelField],
  63. data: options,
  64. listeners: {
  65. 'load': this.onLoad,
  66. scope: this
  67. }
  68. });
  69. this.loaded = true;
  70. } else {
  71. this.add({text: this.loadingText, iconCls: 'loading-indicator'});
  72. this.store.on('load', this.onLoad, this);
  73. }
  74. },
  75. destroy : function () {
  76. if (this.store) {
  77. this.store.destroyStore();
  78. }
  79. this.callParent();
  80. },
  81. /**
  82. * Lists will initially show a 'loading' item while the data is retrieved from the store.
  83. * In some cases the loaded data will result in a list that goes off the screen to the
  84. * right (as placement calculations were done with the loading item). This adapter will
  85. * allow show to be called with no arguments to show with the previous arguments and
  86. * thus recalculate the width and potentially hang the menu from the left.
  87. */
  88. show : function () {
  89. var lastArgs = null;
  90. return function(){
  91. if(arguments.length === 0){
  92. this.callParent(lastArgs);
  93. } else {
  94. lastArgs = arguments;
  95. if (this.loadOnShow && !this.loaded) {
  96. this.store.load();
  97. }
  98. this.callParent(arguments);
  99. }
  100. };
  101. }(),
  102. /** @private */
  103. onLoad : function (store, records) {
  104. var me = this,
  105. visible = me.isVisible(),
  106. gid, item, itemValue, i, len;
  107. me.hide(false);
  108. me.removeAll(true);
  109. gid = me.single ? Ext.id() : null;
  110. for (i = 0, len = records.length; i < len; i++) {
  111. itemValue = records[i].get('id');
  112. item = Ext.create('Ext.menu.CheckItem', {
  113. text: records[i].get(me.labelField),
  114. group: gid,
  115. checked: Ext.Array.contains(me.selected, itemValue),
  116. hideOnClick: false,
  117. value: itemValue
  118. });
  119. item.on('checkchange', me.checkChange, me);
  120. me.add(item);
  121. }
  122. me.loaded = true;
  123. if (visible) {
  124. me.show();
  125. }
  126. me.fireEvent('load', me, records);
  127. },
  128. /**
  129. * Get the selected items.
  130. * @return {Array} selected
  131. */
  132. getSelected : function () {
  133. return this.selected;
  134. },
  135. /** @private */
  136. setSelected : function (value) {
  137. value = this.selected = [].concat(value);
  138. if (this.loaded) {
  139. this.items.each(function(item){
  140. item.setChecked(false, true);
  141. for (var i = 0, len = value.length; i < len; i++) {
  142. if (item.value == value[i]) {
  143. item.setChecked(true, true);
  144. }
  145. }
  146. }, this);
  147. }
  148. },
  149. /**
  150. * Handler for the 'checkchange' event from an check item in this menu
  151. * @param {Object} item Ext.menu.CheckItem
  152. * @param {Object} checked The checked value that was set
  153. */
  154. checkChange : function (item, checked) {
  155. var value = [];
  156. this.items.each(function(item){
  157. if (item.checked) {
  158. value.push(item.value);
  159. }
  160. },this);
  161. this.selected = value;
  162. this.fireEvent('checkchange', item, checked);
  163. }
  164. });