| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 | /** * @class Ext.ux.grid.menu.ListMenu * @extends Ext.menu.Menu * This is a supporting class for {@link Ext.ux.grid.filter.ListFilter}. * Although not listed as configuration options for this class, this class * also accepts all configuration options from {@link Ext.ux.grid.filter.ListFilter}. */Ext.define('Ext.ux.grid.menu.ListMenu', {    extend: 'Ext.menu.Menu',    /**     * @cfg {String} labelField     * Defaults to 'text'.     */    labelField :  'text',    /**     * @cfg {String} paramPrefix     * Defaults to 'Loading...'.     */    loadingText : 'Loading...',    /**     * @cfg {Boolean} loadOnShow     * Defaults to true.     */    loadOnShow : true,    /**     * @cfg {Boolean} single     * Specify true to group all items in this list into a single-select     * radio button group. Defaults to false.     */    single : false,    constructor : function (cfg) {        var me = this,            options,            i,            len,            value;                    me.selected = [];        me.addEvents(            /**             * @event checkchange             * Fires when there is a change in checked items from this list             * @param {Object} item Ext.menu.CheckItem             * @param {Object} checked The checked value that was set             */            'checkchange'        );        me.callParent([cfg = cfg || {}]);        if(!cfg.store && cfg.options) {            options = [];            for(i = 0, len = cfg.options.length; i < len; i++){                value = cfg.options[i];                switch(Ext.type(value)){                    case 'array':  options.push(value); break;                    case 'object': options.push([value.id, value[me.labelField]]); break;                    case 'string': options.push([value, value]); break;                }            }            me.store = Ext.create('Ext.data.ArrayStore', {                fields: ['id', me.labelField],                data:   options,                listeners: {                    load: me.onLoad,                    scope:  me                }            });            me.loaded = true;            me.autoStore = true;        } else {            me.add({                text: me.loadingText,                iconCls: 'loading-indicator'            });            me.store.on('load', me.onLoad, me);        }    },    destroy : function () {        var me = this,            store = me.store;                    if (store) {            if (me.autoStore) {                store.destroyStore();            } else {                store.un('unload', me.onLoad, me);            }        }        me.callParent();    },    /**     * Lists will initially show a 'loading' item while the data is retrieved from the store.     * In some cases the loaded data will result in a list that goes off the screen to the     * right (as placement calculations were done with the loading item). This adapter will     * allow show to be called with no arguments to show with the previous arguments and     * thus recalculate the width and potentially hang the menu from the left.     */    show : function () {        if (this.loadOnShow && !this.loaded && !this.store.loading) {            this.store.load();        }        this.callParent();    },    /** @private */    onLoad : function (store, records) {        var me = this,            gid, itemValue, i, len,            listeners = {                checkchange: me.checkChange,                scope: me            };        Ext.suspendLayouts();        me.removeAll(true);        gid = me.single ? Ext.id() : null;        for (i = 0, len = records.length; i < len; i++) {            itemValue = records[i].get('id');            me.add(Ext.create('Ext.menu.CheckItem', {                text: records[i].get(me.labelField),                group: gid,                checked: Ext.Array.contains(me.selected, itemValue),                hideOnClick: false,                value: itemValue,                listeners: listeners            }));        }        me.loaded = true;        Ext.resumeLayouts(true);        me.fireEvent('load', me, records);    },    /**     * Get the selected items.     * @return {Array} selected     */    getSelected : function () {        return this.selected;    },    /** @private */    setSelected : function (value) {        value = this.selected = [].concat(value);        if (this.loaded) {            this.items.each(function(item){                item.setChecked(false, true);                for (var i = 0, len = value.length; i < len; i++) {                    if (item.value == value[i]) {                        item.setChecked(true, true);                    }                }            }, this);        }    },    /**     * Handler for the 'checkchange' event from an check item in this menu     * @param {Object} item Ext.menu.CheckItem     * @param {Object} checked The checked value that was set     */    checkChange : function (item, checked) {        var value = [];        this.items.each(function(item){            if (item.checked) {                value.push(item.value);            }        },this);        this.selected = value;        this.fireEvent('checkchange', item, checked);    }});
 |