【问题标题】:multiple cell selection in extjs 4.2 gridextjs 4.2网格中的多个单元格选择
【发布时间】:2015-05-18 07:45:09
【问题描述】:

我需要在具有多个单元格选择功能的 extjs 4.2 中实现类似网格的电子表格,但我在与 4.2 兼容的 sencha 论坛中找不到任何有用的资源!网格中没有多个单元格的选择模型,我该如何实现?

extjs 5 example

【问题讨论】:

    标签: extjs extjs4.2


    【解决方案1】:

    这不是一个完美的解决方案,如果可能,我建议升级到 ExtJS 5。

    但是,不久前有一个 sencha forum post 通过创建用于单元格选择的自定义选择模型具有类似的能力。

    请注意,我不是这段代码的原作者。我能够让它在小提琴中工作。

    这是自定义选择模型

    Ext.define('MyApp.MultiCellSelectionModel', {
    
                extend: 'Ext.selection.Model',
    
                alias: 'selection.cellmodel',
    
                requires: ['Ext.util.KeyNav'],
    
                enableKeyNav: true,
    
                preventWrap: false,
    
                selected: null,
    
                constructor: function() {
    
                    this.addEvents('deselect', 'select');
    
                    this.callParent(arguments);
    
                },
    
                bindComponent: function(view) {
    
                    var me = this;
                    me.primaryView = view;
                    me.views = me.views || [];
                    me.views.push(view);
                    //me.bind(view.getStore(), true);
    
                    view.on({
                        cellmousedown: me.onMouseDown,
                        refresh: me.onViewRefresh,
                        scope: me
                    });
    
                    if (me.enableKeyNav) {
    
                        me.initKeyNav(view);
    
                    }
    
                },
    
                initKeyNav: function(view) {
    
                    var me = this;
    
                    if (!view.rendered) {
    
                        view.on('render', Ext.Function.bind(me.initKeyNav, me, [view], 0), me, {
                            single: true
                        });
                        return;
    
                    }
    
                    view.el.set({
                        tabIndex: -1
                    });
    
                    me.keyNav = Ext.create('Ext.util.KeyNav', view.el, {
                        up: me.onKeyUp,
                        down: me.onKeyDown,
                        right: me.onKeyRight,
                        left: me.onKeyLeft,
                        tab: me.onKeyTab,
                        scope: me
                    });
                },
    
                getHeaderCt: function() {
    
                    return this.primaryView.headerCt;
    
                },
    
                allCellDeselect: function() {
    
                    var me = this,
                        i = 0,
                        len = me.selected.items.length;
    
                    for (; i < len; i++) {
    
                        me.primaryView.onCellDeselect(me.selected.items[i].position);
    
                    }
    
                    me.fireEvent('deselect', me, this.selected);
                    me.selected.items = [];
    
                },
    
                onKeyUp: function(e, t) {
    
                    this.move('up', e);
    
                },
    
                onKeyDown: function(e, t) {
    
                    this.move('down', e);
    
                },
    
                onKeyLeft: function(e, t) {
    
                    this.move('left', e);
    
                },
    
                onKeyRight: function(e, t) {
    
                    this.move('right', e);
    
                },
    
                move: function(dir, e) {
    
                    var me = this,
                        pos = me.primaryView.walkCells(me.getCurrentPosition(), dir, e, me.preventWrap),
                        cell = me.view.getCellByPosition(pos);
    
                    if (pos) {
    
                        me.setCurrentPosition(pos);
    
                    }
    
                    cell.position = pos;
    
                    if (e.ctrlKey && me.isSelected(cell)) {
    
                        if (me.allowDeselect) {
    
                            var index = this.selected.items.indexOf(cell);
                            this.selected.items.splice(index, 1);
                            me.primaryView.onCellDeselect(me.getCurrentPosition());
    
                        }
    
                    } else if (e.shiftKey && me.lastSelected) {
    
                        if (me.getCurrentPosition()) {
    
                            me.allCellDeselect();
    
                        }
    
                        me.selectRange(cell, false);
    
                    } else if (e.ctrlKey) {
    
                        me.doMultiSelect(cell, true, true);
    
                    } else {
    
                        if (me.getCurrentPosition()) {
    
                            me.allCellDeselect();
    
                        }
    
                        me.doSingleSelect(cell, true);
    
                    }
    
                    return pos;
    
                },
    
                getCurrentPosition: function() {
    
                    return this.position;
    
                },
    
                setCurrentPosition: function(pos) {
    
                    var me = this;
                    this.position = pos;
    
                },
    
                onMouseDown: function(view, cell, cellIndex, record, row, rowIndex, e) {
    
                    var me = this;
    
                    me.setCurrentPosition({
                        row: rowIndex,
                        column: cellIndex
                    });
    
                    me.selectWithEvent(record, e);
    
                },
    
                isSelected: function(record) {
    
                    record = Ext.isNumber(record) ? this.store.getAt(record) : record;
    
                    if (this.selected.items == null || this.selected.items == '') {
    
                        return false;
    
                    }
    
                    return this.selected.items.indexOf(record) !== -1;
    
                },
    
                selectWithEvent: function(record, e) {
    
                    var me = this;
    
                    var cell = me.view.getCellByPosition(me.getCurrentPosition());
                    cell.position = me.getCurrentPosition();
    
                    switch (me.selectionMode) {
    
                    case 'MULTI':
    
                        if (e.ctrlKey && me.isSelected(cell)) {
    
                            if (me.allowDeselect) {
    
                                var index = this.selected.items.indexOf(cell);
                                this.selected.items.splice(index, 1);
                                me.primaryView.onCellDeselect(me.getCurrentPosition());
    
                            }
    
                        } else if (e.shiftKey && me.lastSelected) {
    
                            if (me.getCurrentPosition()) {
    
                                me.allCellDeselect();
    
                            }
    
                            me.selectRange(cell, false);
    
                        } else if (e.ctrlKey) {
    
                            me.doMultiSelect(cell, true, true);
    
                        } else {
    
                            if (me.getCurrentPosition()) {
    
                                me.allCellDeselect();
    
                            }
    
                            me.doSingleSelect(cell, true);
    
                        }
    
                        break;
    
                    case 'SIMPLE':
    
                        if (me.isSelected(record)) {
    
                            me.doDeselect(record);
    
                        } else {
    
                            me.doSelect(record, true);
    
                        }
    
                        break;
    
                    case 'SINGLE':
    
                        if (me.allowDeselect && me.isSelected(record)) {
    
                            me.doDeselect(record);
    
                        } else {
    
                            me.doSelect(record, false);
    
                        }
    
                        break;
    
                    }
    
                },
    
                doSingleSelect: function(record, suppressEvent) {
    
                    var me = this,
                        changed = false,
                        selected = me.selected;
    
                    if (me.locked) {
    
                        return;
    
                    }
    
                    if (me.isSelected(record)) {
    
                        return;
    
                    }
    
                    function commit() {
                        me.bulkChange = true;
                        if (selected.getCount() > 0 && me.doDeselect(me.lastSelected, suppressEvent) === false) {
                            delete me.bulkChange;
                            return false;
                        }
                        delete me.bulkChange;
    
                        me.selected.items.push(record);
                        me.lastSelected = record;
                        changed = true;
    
                    }
    
                    me.onSelectChange(record, true, suppressEvent, commit);
                    me.primaryView.onCellSelect(record.position);
    
                    if (changed) {
                        if (!suppressEvent) {
                            me.setLastFocused(record);
                        }
                        me.maybeFireSelectionChange(!suppressEvent);
                    }
    
    
                },
    
                doMultiSelect: function(records, keepExisting, suppressEvent) {
    
                    var me = this,
                        selected = me.selected,
                        change = false,
                        i = 0,
                        len, record;
    
                    if (me.locked) {
                        return;
                    }
    
    
                    records = !Ext.isArray(records) ? [records] : records;
                    len = records.length;
                    if (!keepExisting && selected.getCount() > 0) {
                        if (me.doDeselect(me.getSelection(), suppressEvent) === false) {
                            return;
                        }
                    }
    
                    function commit() {
                        selected.items.push(record);
                        change = true;
                    }
    
                    for (; i < len; i++) {
    
                        record = records[i];
                        if (keepExisting && me.isSelected(record)) {
                            continue;
                        }
    
                        me.onSelectChange(record, true, suppressEvent, commit);
                        me.primaryView.onCellSelect(record.position);
                    }
                    me.setLastFocused(record, suppressEvent);
                    me.maybeFireSelectionChange(change && !suppressEvent);
    
                },
    
                selectRange: function(record, keepExisting) {
    
                    var me = this,
                        start, end,
                        x, y, xmin, ymin, xmax, ymax,
                        records = [];
    
                    if (me.isLocked()) {
                        return;
                    }
    
                    start = record.position;
                    end = me.lastSelected.position
    
                    if (start.column < end.column) {
    
                        xmin = start.column;
                        xmax = end.column;
    
                    } else {
    
                        xmin = end.column;
                        xmax = start.column;
    
                    }
    
                    if (start.row < end.row) {
    
                        ymin = start.row;
                        ymax = end.row;
    
                    } else {
    
                        ymin = end.row;
                        ymax = start.row;
    
                    }
    
                    for (x = xmin; x <= xmax; x++) {
    
                        for (y = ymin; y <= ymax; y++) {
    
                            var cell = me.view.getCellByPosition({
                                row: y,
                                column: x
                            });
                            cell.position = {
                                row: y,
                                column: x
                            };
                            me.doMultiSelect(cell, keepExisting, true);
    
                        }
    
                    }
    
    
                },
    
                onSelectChange: function(record, isSelected, suppressEvent, commitFn) {
    
                    var me = this,
                        view = me.view,
                        eventName = isSelected ? 'select' : 'deselect';
    
                    if ((suppressEvent || me.fireEvent('before' + eventName, me, record)) !== false && commitFn() !== false) {
    
                        if (isSelected) {
                            view.onItemSelect(record);
                        } else {
                            view.onItemDeselect(record);
                        }
    
                        if (!suppressEvent) {
                            me.fireEvent(eventName, me, record);
                        }
                    }
                },
    
                onKeyTab: function(e, t) {
                    var me = this,
                        direction = e.shiftKey ? 'left' : 'right',
                        editingPlugin = me.view.editingPlugin,
                        position = me.move(direction, e);
    
                    if (editingPlugin && position && me.wasEditing) {
                        editingPlugin.startEditByPosition(position);
                    }
                    delete me.wasEditing;
                },
    
                onEditorTab: function(editingPlugin, e) {
                    var me = this,
                        direction = e.shiftKey ? 'left' : 'right',
                        position = me.move(direction, e);
    
                    if (position) {
                        editingPlugin.startEditByPosition(position);
                        me.wasEditing = true;
                    }
                },
    
                refresh: Ext.emptyFn,
    
                onViewRefresh: Ext.emptyFn,
    
                selectByPosition: function(position) {
                    this.setCurrentPosition(position);
                }
            });
    

    使用我构建一个 store and grid 具有以下内容:

    var store = Ext.create('Ext.data.Store', {
                fields:['first_name','last_name','phone','isOld'],
                data:[{
                    first_name: 'Andrew',
                    last_name: 'Meeks',
                    phone: '9993332332',
                    isOld: false
                },{
                    first_name: 'Ben',
                    last_name: 'Blah',
                    phone: '9993332332',
                    isOld: false
                },{
                    first_name: 'Anna',
                    last_name: 'Hohen',
                    phone: '9993332332',
                    isOld: false
                },{
                    first_name: 'Jeff',
                    last_name: 'Melborne',
                    phone: '9993332332',
                    isOld: false
                }]
            });
            console.log(store);
            Ext.create('Ext.grid.Panel', {
                renderTo: Ext.getBody(),
                height: 300,
                width: 500,
                store: store,
                title: 'My Peeps',
                selModel: Ext.create('MyApp.MultiCellSelectionModel', {
                    mode: 'MULTI',
                    allowDeselect: true
                }),
                multiSelect: true,
                selType: 'cellmodel',
                columns: [{
                    header: 'First Name',
                    dataIndex: 'first_name'
                }, {
                    header: 'Last Name',
                    dataIndex: 'last_name'
                }, {
                    header: 'Phone',
                    dataIndex: 'phone'
                }, {
                    header: 'Old?',
                    dataIndex: 'isOld',
                    renderer: function(value) {
                        if (value) return 'yes';
                        else return 'no';
                    }
                }],
                bbar:[{
                    text:'Get Selection',
                    handler: function(btn){
                        console.log(btn.up('grid').getSelectionModel().getSelection());
                    }
                }]
            });
    

    还有一个working fiddle。我添加了一个带有按钮的bbar 来获取当前选择,该选择返回选定的单元格。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多