1. #1
    Sencha User
    Join Date
    Jan 2012
    Posts
    7
    Vote Rating
    0
    lucarossi is on a distinguished road

      0  

    Default Unanswered: ItemSelector problem configuration

    Unanswered: ItemSelector problem configuration


    Hi all,
    (sorry for my English)
    I need to porting an old app write with extj2 in the ultimate version of the sencha framework. In a dialog (implemented by a Ext.window.Window) i have a Ext.tab.Panel who contain a 5 Panel: some of their need to contain an itemselector. All the itemselector have associate 2 dataStore (ajax) and when i submit the window i need to save on DB the rigth choose of the itemselector;
    For now i have 2 big problem:
    1) I don't know how i can associate the left-multiselect-datastore, because the old toStore doesn't work,
    2) when i hide the window and then i re-show the window this is what i see: itemSelector.png
    And only one is selectable.
    This is the code i'm using now for view this itemselector:
    Code:
                         {xtype: 'itemselector',
                                        id:'userdialog.rolesTab.itemselector',
                                        name:'userRoles',
                                        anchor:'100%',
                                        store: dsRoles,
                                        toStore: dsUserRoles,
                                        valueField    :'id',
                                        displayField:'name',
                                        value: dsUserRoles ,
                                        msgTarget: 'side',
                                        fromTitle : 'Available',
                                        toTitle : 'Selected'}
    Any help is helpfull.

  2. #2
    Sencha User
    Join Date
    Jan 2012
    Posts
    7
    Vote Rating
    0
    lucarossi is on a distinguished road

      0  

    Default ItemSelector2.js

    ItemSelector2.js


    I don't know if is helpfull for anyone but i rewrite the Ext.ux.ItemSelector for eliminate the second problem and for give more power to the rigth multiselect like submit value. This is my new version:

    Code:
    /*
     * Note that this control will most likely remain as an example, and not as a core Ext form
     * control.  However, the API will be changing in a future release and so should not yet be
     * treated as a final, stable API at this time.
     */
    
    /**
     * A control that allows selection of between two Ext.ux.form.MultiSelect controls.
     */
    Ext.define('Ext.ux.form.ItemSelector', {
        extend: 'Ext.ux.form.MultiSelect',
        alias: ['widget.itemselectorfield', 'widget.itemselector'],
        alternateClassName: ['Ext.ux.ItemSelector'],
        requires: [
            'Ext.button.Button',
            'Ext.ux.form.MultiSelect'
        ],
    
        /**
         * @cfg {Boolean} [hideNavIcons=false] True to hide the navigation icons
         */
        hideNavIcons:false,
    
        /**
         * @cfg {Array} buttons Defines the set of buttons that should be displayed in between the ItemSelector
         * fields. Defaults to <tt>['top', 'up', 'add', 'remove', 'down', 'bottom']</tt>. These names are used
         * to build the button CSS class names, and to look up the button text labels in {@link #buttonsText}.
         * This can be overridden with a custom Array to change which buttons are displayed or their order.
         */
        buttons: ['top', 'up', 'add', 'remove', 'down', 'bottom'],
    
        /**
         * @cfg {Object} buttonsText The tooltips for the {@link #buttons}.
         * Labels for buttons.
         */
        buttonsText: {
            top: "Move to Top",
            up: "Move Up",
            add: "Add to Selected",
            remove: "Remove from Selected",
            down: "Move Down",
            bottom: "Move to Bottom"
        },
    
        layout: {
            type: 'hbox',
            align: 'stretch'
        },
    
        initComponent: function() {
            var me = this;
    
            me.ddGroup = me.id + '-dd';
            me.callParent();
    
            // bindStore must be called after the fromField has been created because
            // it copies records from our configured Store into the fromField's Store
            //me.bindStore(me.store);
        },
    
        createList: function(title, store){
            var me = this;
    
            return Ext.create('Ext.ux.form.MultiSelect', {
                // We don't want the multiselects themselves to act like fields,
                // so override these methods to prevent them from including
                // any of their values
                submitValue: false,
                getSubmitData: function(){
                    return null;
                },
                getModelData: function(){
                    return null;    
                },
                flex: 1,
                dragGroup: me.ddGroup,
                dropGroup: me.ddGroup,
                title: title,
                store: store, 
                displayField: me.displayField,
                valueField: me.valueField,
                disabled: me.disabled,
                listeners: {
                    boundList: {
                        scope: me,
                        itemdblclick: me.onItemDblClick,
                        drop: me.syncValue
                    }
                }
            });
        },
        createListRight: function(title, store){
            var me = this;
    
            return Ext.create('Ext.ux.form.MultiSelect', {
                // We don't want the multiselects themselves to act like fields,
                // so override these methods to prevent them from including
                // any of their values
                submitValue: true,
                flex: 1,
                dragGroup: me.ddGroup,
                dropGroup: me.ddGroup,
                title: title,
                store: store, 
                displayField: me.displayField,
                valueField: me.valueField,
                disabled: me.disabled,
                listeners: {
                    boundList: {
                        scope: me,
                        itemdblclick: me.onItemDblClick,
                        drop: me.syncValue
                    }
                }
            });
        },
    
        setupItems: function() {
            var me = this;
    
            me.fromField = me.createList(me.fromTitle, me.store);
            me.toField = me.createListRight(me.toTitle, me.toStore);
    
            return [
                me.fromField,
                {
                    xtype: 'container',
                    margins: '0 4',
                    layout: {
                        type: 'vbox',
                        pack: 'center'
                    },
                    items: me.createButtons()
                },
                me.toField
            ];
        },
    
        createButtons: function() {
            var me = this,
                buttons = [];
    
            if (!me.hideNavIcons) {
                Ext.Array.forEach(me.buttons, function(name) {
                    buttons.push({
                        xtype: 'button',
                        tooltip: me.buttonsText[name],
                        handler: me['on' + Ext.String.capitalize(name) + 'BtnClick'],
                        cls: Ext.baseCSSPrefix + 'form-itemselector-btn',
                        iconCls: Ext.baseCSSPrefix + 'form-itemselector-' + name,
                        navBtn: true,
                        scope: me,
                        margin: '4 0 0 0'
                    });
                });
            }
            return buttons;
        },
    
        /**
         * Get the selected records from the specified list.
         * 
         * Records will be returned *in store order*, not in order of selection.
         * @param {Ext.view.BoundList} list The list to read selections from.
         * @return {Ext.data.Model[]} The selected records in store order.
         * 
         */
        getSelections: function(list) {
            var store = list.getStore();
    
            return Ext.Array.sort(list.getSelectionModel().getSelection(), function(a, b) {
                a = store.indexOf(a);
                b = store.indexOf(b);
    
                if (a < b) {
                    return -1;
                } else if (a > b) {
                    return 1;
                }
                return 0;
            });
        },
    
        onTopBtnClick : function() {
            var list = this.toField.boundList,
                store = list.getStore(),
                selected = this.getSelections(list);
    
            store.suspendEvents();
            store.remove(selected, true);
            store.insert(0, selected);
            store.resumeEvents();
            list.refresh();
            this.syncValue(); 
            list.getSelectionModel().select(selected);
        },
    
        onBottomBtnClick : function() {
            var list = this.toField.boundList,
                store = list.getStore(),
                selected = this.getSelections(list);
    
            store.suspendEvents();
            store.remove(selected, true);
            store.add(selected);
            store.resumeEvents();
            list.refresh();
            this.syncValue();
            list.getSelectionModel().select(selected);
        },
    
        onUpBtnClick : function() {
            var list = this.toField.boundList,
                store = list.getStore(),
                selected = this.getSelections(list),
                rec,
                i = 0,
                len = selected.length,
                index = 0;
    
            // Move each selection up by one place if possible
            store.suspendEvents();
            for (; i < len; ++i, index++) {
                rec = selected[i];
                index = Math.max(index, store.indexOf(rec) - 1);
                store.remove(rec, true);
                store.insert(index, rec);
            }
            store.resumeEvents();
            list.refresh();
            this.syncValue();
            list.getSelectionModel().select(selected);
        },
    
        onDownBtnClick : function() {
            var list = this.toField.boundList,
                store = list.getStore(),
                selected = this.getSelections(list),
                rec,
                i = selected.length - 1,
                index = store.getCount() - 1;
    
            // Move each selection down by one place if possible
            store.suspendEvents();
            for (; i > -1; --i, index--) {
                rec = selected[i];
                index = Math.min(index, store.indexOf(rec) + 1);
                store.remove(rec, true);
                store.insert(index, rec);
            }
            store.resumeEvents();
            list.refresh();
            this.syncValue();
            list.getSelectionModel().select(selected);
        },
    
        onAddBtnClick : function() {
            var me = this,
                selected = me.getSelections(me.fromField.boundList);
    
            me.moveRec(true, selected);
            me.toField.boundList.getSelectionModel().select(selected);
        },
    
        onRemoveBtnClick : function() {
            var me = this,
                selected = me.getSelections(me.toField.boundList);
    
            me.moveRec(false, selected);
            me.fromField.boundList.getSelectionModel().select(selected);
        },
    
        moveRec: function(add, recs) {
            var me = this,
                fromField = me.fromField,
                toField   = me.toField,
                fromStore = add ? fromField.store : toField.store,
                toStore   = add ? toField.store   : fromField.store;
    
            fromStore.suspendEvents();
            toStore.suspendEvents();
            fromStore.remove(recs);
            toStore.add(recs);
            fromStore.resumeEvents();
            toStore.resumeEvents();
    
            fromField.boundList.refresh();
            toField.boundList.refresh();
    
            me.syncValue();
        },
    
        // Synchronizes the submit value with the current state of the toStore
        syncValue: function() {
            var me = this; 
            me.mixins.field.setValue.call(me, me.setupValue(me.toField.store.getRange()));
        },
    
        onItemDblClick: function(view, rec) {
            this.moveRec(view === this.fromField.boundList, rec);
        },
    
        setValue: function(value) {
            var me = this,
                fromField = me.fromField,
                toField = me.toField,
                fromStore = fromField.store,
                toStore = toField.store,
                selected;
    
            // Wait for from store to be loaded
            if (!me.fromStorePopulated) {
                me.fromField.store.on({
                    load: Ext.Function.bind(me.setValue, me, [value]),
                    single: true
                });
                return;
            }
    
            value = me.setupValue(value);
            me.mixins.field.setValue.call(me, value);
    
            selected = me.getRecordsForValue(value);
    
            // Clear both left and right Stores.
            // Both stores must not fire events during this process.
            fromStore.suspendEvents();
            toStore.suspendEvents();
            fromStore.removeAll();
            toStore.removeAll();
    
            // Reset fromStore
            me.populateFromStore(me.store);
    
            // Copy selection across to toStore
            Ext.Array.forEach(selected, function(rec){
                // In the from store, move it over
                if (fromStore.indexOf(rec) > -1) {
                    fromStore.remove(rec);
                }
                toStore.add(rec);
            });
    
            // Stores may now fire events
            fromStore.resumeEvents();
            toStore.resumeEvents();
    
            // Refresh both sides and then update the app layout
            Ext.suspendLayouts();
            fromField.boundList.refresh();
            toField.boundList.refresh();
            Ext.resumeLayouts(true);        
        },
    
        onBindStore: function(store, initial) {
            var me = this;
    
            if (me.fromField) {
                me.fromField.store.removeAll()
                me.toField.store.removeAll();
    
                // Add everything to the from field as soon as the Store is loaded
                if (store.getCount()) {
                    me.populateFromStore(store);
                } else {
                    me.store.on('load', me.populateFromStore, me);
                }
            }
        },
    
        populateFromStore: function(store) {
            var fromStore = this.fromField.store;
    
            // Flag set when the fromStore has been loaded
            this.fromStorePopulated = true;
    
            fromStore.add(store.getRange());
    
            // setValue waits for the from Store to be loaded
            fromStore.fireEvent('load', fromStore);
        },
    
        onEnable: function(){
            var me = this;
    
            me.callParent();
            me.fromField.enable();
            me.toField.enable();
    
            Ext.Array.forEach(me.query('[navBtn]'), function(btn){
                btn.enable();
            });
        },
    
        onDisable: function(){
            var me = this;
    
            me.callParent();
            me.fromField.disable();
            me.toField.disable();
    
            Ext.Array.forEach(me.query('[navBtn]'), function(btn){
                btn.disable();
            });
        },
    
        onDestroy: function(){
            this.bindStore(null);
            this.callParent();
        }
    });