ListMenu.js 5.2 KB

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