ExtJS 6. Pickerfield with treepanel

时间:2016-01-12 16:52:18

标签: extjs extjs6

我不知道创建treepanel pickerfield的正确方法。现在我这样做:

{
    xtype:'pickerfield',
    width:'34%',
    emptyText: 'Choose layer',
    createPicker: function(){
        return Ext.create('Ext.tree.Panel',{
            hidden: true,
            floating: true,
            minHeight: 300,
            pickerField: this,
            root: {
                text: 'Root',
                expanded: true,
                children:[{
                    text: 'Standard',
                    expanded: true,
                    children: [{
                        text: 'Open Street Map',
                        checked: true,
                        leaf: true,
                        itemId: 'OMS'
                    },{
                        text: 'MapQuest',
                        leaf: false,                                    
                        children:[{
                            text: 'Road',
                            leaf:true,
                            checked: false,
                            itemId: 'MapQuest',
                            val: 'osm'
                        },{
                            text: 'Satellite',
                            leaf:true,
                            checked: false,
                            itemId: 'MapQuest',
                            val: 'sat'
                        },{
                            text: 'Hybride',
                            leaf:true,
                            checked: false,
                            itemId: 'MapQuest',
                            val: 'hyb'
                        }]
                    }]
                }]
            }
        });
    }
}

部分工作。当我第一次点击选择器时,它会向我显示一个treepanel,但是当我展开一些节点(leaf = false)时,它会被关闭。当我检查树叶时也是如此 - 我不希望这样,因为允许用户检查多个节点。此外,即使我检查一些叶子,选择器的值保持不变(它一直显示emptyText值)。那么,如何解决这一切呢?

1 个答案:

答案 0 :(得分:3)

您可以使用以下示例:

Ext.define('Ext.ux.TreeCombo',
{
    extend: 'Ext.form.field.Picker',
    alias: 'widget.treecombo',
    tree: false,
    constructor: function(config)
    {
        this.addEvents(
        {
            "itemclick" : true
        });


        this.listeners = config.listeners;
        this.callParent(arguments);
    },
    records: [],
    recursiveRecords: [],
    ids: [],
    selectChildren: true,
    canSelectFolders: true,
    multiselect: false,
    displayField: 'text',
    valueField: 'id',
    treeWidth: 300,
    matchFieldWidth: false,
    treeHeight: 400,
    masN: 0,
    recursivePush: function(node, setIds)
    {
        var me = this;


        me.addRecRecord(node);
        if(setIds) me.addIds(node);

        node.eachChild(function(nodesingle)
        {
            if(nodesingle.hasChildNodes() == true)
            {
                me.recursivePush(nodesingle, setIds);
            }
            else
            {
                me.addRecRecord(nodesingle);
                if(setIds) me.addIds(nodesingle);
            }
        });
    },
    recursiveUnPush: function(node)
    {
        var me = this;
        me.removeIds(node);

        node.eachChild(function(nodesingle)
        {
            if(nodesingle.hasChildNodes() == true)
            {
                me.recursiveUnPush(nodesingle);
            }
            else me.removeIds(nodesingle);
        });
    },
    addRecRecord: function(record)
    {
        var me = this;


        for(var i=0,j=me.recursiveRecords.length;i<j;i++)
        {
            var item = me.recursiveRecords[i];
            if(item)
            {
                if(item.getId() == record.getId()) return;
            }
        }
        me.recursiveRecords.push(record);
    },
    afterLoadSetValue: false,
    setValue: function(valueInit)
    {
        if(typeof valueInit == 'undefined') return;

        var me = this,
            tree = this.tree,
            values = (valueInit == '') ? [] : valueInit.split(','),
            valueFin = [];

        inputEl = me.inputEl;


        if(tree.store.isLoading())
        {
            me.afterLoadSetValue = valueInit;
        }


        if(inputEl && me.emptyText && !Ext.isEmpty(values))
        {
            inputEl.removeCls(me.emptyCls);
        }


        if(tree == false) return false;

        var node = tree.getRootNode();
        if(node == null) return false;

        me.recursiveRecords = [];
        me.recursivePush(node, false);

        me.records = [];
        Ext.each(me.recursiveRecords, function(record)
        {
            var id = record.get(me.valueField),
                index = values.indexOf(''+id);

            if(me.multiselect == true) record.set('checked', false);

            if(index != -1)
            {
                valueFin.push(record.get(me.displayField));
                if(me.multiselect == true) record.set('checked', true);
                me.addRecord(record);
            }
        });


        me.value = valueInit;
        me.setRawValue(valueFin.join(', '));

        me.checkChange();
        me.applyEmptyText();
        return me;
    },
    getValue: function() 
    {
        return this.value;
    },
    getSubmitValue: function()
    {
        return this.value;
    },
    checkParentNodes: function(node)
    {
        if(node == null) return;

        var me = this,
            checkedAll = true;


        node.eachChild(function(nodesingle)
        {
            var id = nodesingle.getId(),
                index = me.ids.indexOf(''+id);

            if(index == -1) checkedAll = false;
        });

        if(checkedAll == true)
        {
            me.addIds(node);
            me.checkParentNodes(node.parentNode);
        }
        else
        {
            me.removeIds(node);
            me.checkParentNodes(node.parentNode);
        }
    },
    initComponent: function() 
    {
        var me = this;

        me.tree = Ext.create('Ext.tree.Panel',
        {
            alias: 'widget.assetstree',
            hidden: true,
            minHeight: 300,
            rootVisible: (typeof me.rootVisible != 'undefined') ? me.rootVisible : true,
            floating: true,
            useArrows: true,
            width: me.treeWidth,
            autoScroll: true,
            height: me.treeHeight,
            store: me.store,
            listeners:
            {
                load: function(store, records)
                {
                    if(me.afterLoadSetValue != false)
                    {
                        me.setValue(me.afterLoadSetValue);
                    }
                },
                itemclick:  function(view, record, item, index, e, eOpts)
                {
                    me.itemTreeClick(view, record, item, index, e, eOpts, me)
                }
            }
        });

        if(me.tree.getRootNode().get('checked') != null) me.multiselect = true;

        this.createPicker = function()
        {
            var me = this;
            return me.tree;
        };

        this.callParent(arguments);
    },
    addIds: function(record)
    {
        var me = this;

        if(me.ids.indexOf(''+record.getId()) == -1) me.ids.push(''+record.get(me.valueField));
    },
    removeIds: function(record)
    {
        var me = this,
            index = me.ids.indexOf(''+record.getId());

        if(index != -1)
        {
            me.ids.splice(index, 1);
        }
    },
    addRecord: function(record)
    {
        var me = this;


        for(var i=0,j=me.records.length;i<j;i++)
        {
            var item = me.records[i];
            if(item)
            {
                if(item.getId() == record.getId()) return;
            }
        }
        me.records.push(record);
    },
    removeRecord: function(record)
    {
        var me = this;


        for(var i=0,j=me.records.length;i<j;i++)
        {
            var item = me.records[i];
            if(item && item.getId() == record.getId()) delete(me.records[i]);
        }
    },
    itemTreeClick: function(view, record, item, index, e, eOpts, treeCombo)
    {
        var me = treeCombo,
            checked = !record.get('checked');//it is still not checked if will be checked in this event

        if(me.multiselect == true) record.set('checked', checked);//check record

        var node = me.tree.getRootNode().findChild(me.valueField, record.get(me.valueField), true);
        if(node == null) 
        {
            if(me.tree.getRootNode().get(me.valueField) == record.get(me.valueField)) node = me.tree.getRootNode();
            else return false;
        }

        if(me.multiselect == false) me.ids = [];

        //if it can't select folders and it is a folder check existing values and return false
        if(me.canSelectFolders == false && record.get('leaf') == false)
        {
            me.setRecordsValue(view, record, item, index, e, eOpts, treeCombo);
            return false;
        }

        //if record is leaf
        if(record.get('leaf') == true) 
        {
            if(checked == true)
            {
                me.addIds(record);
            }
            else
            {
                me.removeIds(record);
            }
        }
        else //it's a directory
        {           
            me.recursiveRecords = [];
            if(checked == true)
            {
                if(me.multiselect == false)
                {
                    if(me.canSelectFolders == true) me.addIds(record); 
                }
                else
                {
                    if(me.canSelectFolders == true)
                    {
                        me.recursivePush(node, true);
                    }
                }
            }
            else
            {
                if(me.multiselect == false)
                {
                    if(me.canSelectFolders == true) me.recursiveUnPush(node);
                    else me.removeIds(record);
                }
                else me.recursiveUnPush(node);
            }
        }

        //this will check every parent node that has his all children selected
        if(me.canSelectFolders == true && me.multiselect == true) me.checkParentNodes(node.parentNode);

        me.setRecordsValue(view, record, item, index, e, eOpts, treeCombo);
    },
    fixIds: function()
    {
        var me = this;

        for(var i=0,j=me.ids.length;i<j;i++)
        {
            if(me.ids[i] == 'NaN') me.ids.splice(i, 1);
        }
    },
    setRecordsValue: function(view, record, item, index, e, eOpts, treeCombo)
    {
        var me = treeCombo;

        me.fixIds();

        me.setValue(me.ids.join(','));


        me.fireEvent('itemclick', me, record, item, index, e, eOpts, me.records, me.ids);


        if(me.multiselect == false) me.onTriggerClick();
    }   
});

 var storeMenu = Ext.create('Ext.data.TreeStore',
    {
        root:
        {
            text: 'Root',
            id: '0',
            expanded: true,
            children:
            [
                {id: '1', text: 'First node', leaf: false, children:
                    [
                        {id: '3', text: 'First child node', leaf: true},
                        {id: '4', text: 'Second child node', leaf: true}
                    ]
                },
                {id: '2', text: 'Second node', leaf: true}
            ]
        },
        folderSort: false
    });

Ext.onReady(function() {
        Ext.create('Ext.ux.TreeCombo', {
            margin:10,
            width:120,
            height: 10,
            treeHeight: 10,
            treeWidth: 240,
            renderTo: 'treecombo3',
            store: storeMenu,
            selectChildren: false,
            canSelectFolders: true
            ,itemTreeClick: function(view, record, item, index, e, eOpts, treeCombo)
            { 
                var id = record.data.id;
            }
        });
});