ListMenu.js 5.3 KB

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