checkcolumn select all;标题操作,选择所有功能

时间:2014-01-23 14:24:01

标签: extjs checkbox grid extjs4.2

在发布问题ExtJS checkcolumn grid - check columns to left, uncheck columns to right并认为存在“全选”选项的现有问题和答案之后,我已经阅读了一些更深入的内容并且它们实际上并没有覆盖我需要的与我的其他相关的内容问题的答案。

我需要知道在每个列标题中生成一个复选框需要什么代码,当选择/取消选择时,会更改给定列中的复选框。

现有参​​考代码:

Ext.Loader.setConfig({
    enabled: true
});
Ext.Loader.setPath('Ext.ux', '../ux');

Ext.require([
    'Ext.ux.CheckColumn'
]);

Ext.onReady(function(){
    Ext.define('ProcessModel', {
        extend: 'Ext.data.Model',
        fields: [
            'Item',
            'Phase1',
            'Phase2',
            'Phase3',
            'Phase4',
            'Phase5',
            'Phase6',
            'Phase7',
            'Phase8',
            'Phase9',
            'Phase10'
        ]
    });

    // create the Data Store
    var processStore = Ext.create('Ext.data.Store', {
        model: 'processModel',
        autoLoad: true,
        proxy: {
            // load using HTTP
            type: 'ajax',
            url: '<?= $site_url ?>/Production/Processes/<?= $itemId ?>',
            reader: {
                type: 'json',
                model: 'ProcessModel',
                root: data
            }
        }
    });

    function onCheckChange (column, rowIndex, checked, eOpts) {
        var record = processStore.getAt(rowIndex);
        var columnIndex = column.getIndex();
        for (var i = 1; i <= 10; i++) {
            if(checked) {
                if (i <= columnIndex) {
                    record.set('Phase'+i, true);
                }
                else
                {
                    record.set('Phase'+i, false);
                }
            }
            else {
                if (i >= columnIndex) {
                    record.set('Phase'+i, false);
                }
            }

        }
    }

    Ext.create('Ext.grid.Panel', {
        width: 800,
        store: processStore,
        title: 'Processes',
        tbar: [
            {
                xtype: 'button',
                text: 'Update',
                handler: function(){
                    //TODO: update by POST function
                }
            }
        ],
        columns: [
            {
                text: 'Item',
                dataIndex: 'Item'
            },{
                xtype: 'checkcolumn',
                text: 'Phase 1',
                dataIndex:'Phase1',
                listeners: {
                    checkChange: onCheckChange
                }
            },{
                xtype: 'checkcolumn',
                text: 'Phase 2',
                dataIndex:'Phase2',
                listeners: {
                    checkChange: onCheckChange
                }
            },{
                xtype: 'checkcolumn',
                text: 'Phase 3',
                dataIndex:'Phase3',
                listeners: {
                    checkChange: onCheckChange
                }
            },{
                xtype: 'checkcolumn',
                text: 'Phase 4',
                dataIndex:'Phase4',
                listeners: {
                    checkChange: onCheckChange
                }
            },{
                xtype: 'checkcolumn',
                text: 'Phase 5',
                dataIndex:'Phase5',
                listeners: {
                    checkChange: onCheckChange
                }
            },{
                xtype: 'checkcolumn',,
                listeners: {
                    checkChange: onCheckChange
                }
                text: 'Phase 6',
                dataIndex:'Phase6',
                listeners: {
                    checkChange: onCheckChange
                }
            },{
                xtype: 'checkcolumn',
                text: 'Phase 7',
                dataIndex:'Phase7',
                listeners: {
                    checkChange: onCheckChange
                }
            },{
                xtype: 'checkcolumn',
                text: 'Phase 8',
                dataIndex:'Phase8',
                listeners: {
                    checkChange: onCheckChange
                }
            },{
                xtype: 'checkcolumn',
                text: 'Phase 9',
                dataIndex:'Phase9',
                listeners: {
                    checkChange: onCheckChange
                }
            },{
                xtype: 'checkcolumn',
                text: 'Phase 10',
                dataIndex:'Phase10',
                listeners: {
                    checkChange: onCheckChange
                }
            }
        ],
        renderTo: Ext.get('sencha_processes')
    });
});

想象一下伪代码来处理选择所有函数,对于我正在寻找的那种效果:

function selectAllInColumn (column, checked, eopts){
    var columnIndex = column.getIndex();
    for( var i = 0; i < processStore.getCount(); i++)
    {
        if(checked)
        {
            var record = processStore.getAt(i);
            for(var j = 1; j <= columnIndex; j++) {
                record.set('Phase'+columnIndex, true);
            }
            for(var j = columnIndex+1; j <= 10; j++) {
                record.set('Phase'+columnIndex, false);
            }
        }
        else
        {
            var record = processStore.getAt(i);
            for(var j = columnIndex; j <= 10; j++) {
                record.set('Phase'+columnIndex, false);
            }
        }
    }
}

3 个答案:

答案 0 :(得分:6)

您可以查看我在每个列标题中生成复选框的变体。请使用描述检查checkcolumn with select all或仅使用示例fiddle

我的支票栏:

Ext.define('Fiddle.CheckColumn', {
    extend: 'Ext.grid.column.CheckColumn',
    alias: 'widget.fiddlecheckcolumn',

    renderTpl: [
        '<div id="{id}-titleEl" data-ref="titleEl" {tipMarkup}class="', Ext.baseCSSPrefix, 'column-header-inner<tpl if="!$comp.isContainer"> ', Ext.baseCSSPrefix, 'leaf-column-header</tpl>',
        '<tpl if="empty"> ', Ext.baseCSSPrefix, 'column-header-inner-empty</tpl>">',

        '<span class="', Ext.baseCSSPrefix, 'column-header-text-container">',
        '<span class="', Ext.baseCSSPrefix, 'column-header-text-wrapper">',
        '<span id="{id}-textEl" data-ref="textEl" class="', Ext.baseCSSPrefix, 'column-header-text',
        '{childElCls}">',
        '<img class="', Ext.baseCSSPrefix, 'grid-checkcolumn" src="' + Ext.BLANK_IMAGE_URL + '"/>',
        '</span>',
        '</span>',
        '</span>',
        '<tpl if="!menuDisabled">',
        '<div id="{id}-triggerEl" data-ref="triggerEl" role="presentation" class="', Ext.baseCSSPrefix, 'column-header-trigger',
        '{childElCls}" style="{triggerStyle}"></div>',
        '</tpl>',
        '</div>',
        '{%this.renderContainer(out,values)%}'
    ],

    constructor : function(config) {
        var me = this;

        Ext.apply(config, {
            stopSelection: true,
            sortable: false,
            draggable: false,
            resizable: false,
            menuDisabled: true,
            hideable: false,
            tdCls: 'no-tip',
            defaultRenderer: me.defaultRenderer,
            checked: false
        });

        me.callParent([ config ]);

        me.on('headerclick', me.onHeaderClick);
        me.on('selectall', me.onSelectAll);

    },

    onHeaderClick: function(headerCt, header, e, el) {
        var me = this,
            grid = headerCt.grid;

        if (!me.checked) {
            me.fireEvent('selectall', grid.getStore(), header, true);
            header.getEl().down('img').addCls(Ext.baseCSSPrefix + 'grid-checkcolumn-checked');
            me.checked = true;
        } else {
            me.fireEvent('selectall', grid.getStore(), header, false);
            header.getEl().down('img').removeCls(Ext.baseCSSPrefix + 'grid-checkcolumn-checked');
            me.checked = false;
        }
    },

    onSelectAll: function(store, column, checked) {
        var dataIndex = column.dataIndex;
        for(var i = 0; i < store.getCount(); i++) {
            var record = store.getAt(i);
            if (checked) {
                record.set(dataIndex, true);
            } else {
                record.set(dataIndex, false);
            }
        }
    }
});

答案 1 :(得分:1)

弄清楚该怎么做;硬编码一个带有id的复选框到每个检查列的标题文本中,移动网格和存储的范围以初始化为全局(但实际上是在Ext.ready上构建),然后具有通过数据存储区记录操作的全局函数for循环:

在Ext.ready之外的

var processGrid = null;
var processStore = null;

function headerClick(col, int){
    if(document.getElementById(col).checked==true)
    {
        selectAllInColumn(int, true);
    }
    else
    {
        selectAllInColumn(int, false);
    }
}

function selectAllInColumn (column, checked, eOpts){
    //foreach record in data store
    for( var i = 0; i < processStore.getCount(); i++)
    {
        if(checked)
        {
            // get record
            var record = processStore.getAt(i);
            // for current column and each preceding column set process step to true and check the header
            for(var j = 1; j <= column; j++) {
                document.getElementById('HeaderPhase'+j).checked = true;
                record.set('Phase'+j, true);
            }
        }
        else
        {
            var record = processStore.getAt(i);
            for(var j = column; j <= 10; j++) {
                document.getElementById('HeaderPhase'+j).checked = false;
                record.set('Phase'+j, false);
            }
        }
    }
}

function startCheckHeaderCheckBox(){
    // foreach checkcolumn
    for(var i = 1; i <= 10; i++)
    {
        // start running tally per column
        var checkedTotal = 0;
        // foreach record in data store
        for (var j = 0; j < processStore.getCount();j++)
        {
            var record = processStore.getAt(j);
            if (record.get('Phase'+i) == "true"){
                checkedTotal++;
            }
        }
        if(checkedTotal==processStore.getCount())
        {
            document.getElementById('HeaderPhase'+i).checked=true;
        }
        else
        {
            document.getElementById('HeaderPhase'+i).checked=false;
        }
    }
}

function inProgressCheckHeaderCheckBox(columnIndex){
    for( var i = 1; i <=columnIndex; i++)
    {
        var checkedTotal = 0;
        for (var j = 0; j < processStore.getCount(); j++)
        {
            var record = processStore.getAt(j);
            if (record.get('Phase'+i)){
                checkedTotal++;
            }
        }
        if(checkedTotal==processStore.getCount())
        {
            document.getElementById('HeaderPhase'+i).checked=true;
        }
    }
}

内部Ext.ready:

// before loading the grid.Panel; onCheckChange called 
function onCheckChange (column, rowIndex, checked, eOpts) {
    var record = processStore.getAt(rowIndex);
    var columnIndex = column.getIndex();
    for (var i = 1; i <= 10; i++) {
        if(checked) {
            if (i <= columnIndex) {
                record.set('Phase'+i, 'true');
                inProgressCheckHeaderCheckBox(columnIndex);
            }
        }
        else {
            if (i >= columnIndex) {
                record.set('Phase'+i, false);
                document.getElementById('HeaderPhase'+i).checked = false;
            }
        }
    }
}

// after loading the grid.Panel to govern setting header check boxes on load
processStore.on('load', startCheckHeaderCheckBox);

// put in each checkColumn, this is the first phase header, change the numbers to match each phase
header: 'Phase 1 <br /> <input type="checkbox" id="HeaderPhase1" style="x-grid-checkcolumn" onclick="headerClick(\'HeaderPhase1\', 1)"/>',

希望这有助于其他人,请记住,我的实现需要针对您正在使用的任何数据集进行定制,并且依赖于名称和ID标准化为Phases / HeaderPhases并附加数字。

答案 2 :(得分:0)

可用于ExtJS 6的插件解决方案。

以下是如何使用它。

{
    xtype: 'checkcolumn',
    text: 'Selected',
    dataIndex: 'selected',
    plugins: {
        ptype: 'selectallcheckcolumnheader',
        checked: false // initial state of the checkbox
    },
    sortable: false // for better UX*
}

以下是如何安装它。

Ext.define('MyApp.ux.plugin.SelectAllCheckColumnHeader', {
    extend: 'Ext.AbstractPlugin',
    alias: 'plugin.selectallcheckcolumnheader',

    init: function (cmp) {
        /*
         * @cfg checked Boolean initial state of checkbox. Defaults to false
         */
        var me = this;
        me.checked = !!me.checked;

        // class that make the div look like a checkbox
        me._checkClass = Ext.baseCSSPrefix + 'grid-checkcolumn'
        cmp.afterText = function(out, values) {
          out.push(
            '<div class="', me._checkClass, '" src="' + Ext.BLANK_IMAGE_URL + '"></div>'
          )
        }

        // Position the checkbox
        // - Make sure that checkbox show right of the header text instead of under it
        // - Also horizontal align the checkbox better
        cmp.cls = 'select-all-checkcolumn-header'
        Ext.util.CSS.createStyleSheet([
          '.', cmp.cls, ' .', Ext.baseCSSPrefix, 'column-header-text {',
          '  display: inline;',
          '}',
          '.', cmp.cls, ' .', me._checkClass, ' {',
          '  display: inline;',
          '  padding-left: 5px;',
          '}',
        ].join(''), 'plugin_selectallcheckcolumnheader');

        // initial display of checkbox or not based on me.checked
        cmp.on('render', me.checkCheckbox, me);
        // listen to header clicks, but only handle the onces exactly on the checkbox
        cmp.on('headerclick', me.onHeaderClick, me);
        // event fired by clicking on the checkbox and (un)checks all checkboxes in the grid
        cmp.on('selectall', me.onSelectAll, me);
    },

    onHeaderClick: function(headerCt, header, e, clickedElement) {
        var me = this;
        var cmp = me.cmp;
        var grid = headerCt.grid;

        if (!Ext.get(clickedElement).hasCls(me._checkClass)) {
          // It was not the particular checkbox that was clicked inside the header.
          // The column header should proceed doing other stuff like sorting
          return
        }
        me.checked = !me.checked;

        cmp.fireEvent('selectall', grid.getStore(), header, me.checked);
        me.checkCheckbox()
    },

    checkCheckbox: function() {
      var me = this;
      var cmp = this.cmp;
      var checkboxEl = cmp.getEl().down('.' + me._checkClass);

      checkboxEl[me.checked ? 'addCls' : 'removeCls'](Ext.baseCSSPrefix + 'grid-checkcolumn-checked');
    },

    onSelectAll: function(store, column, checked) {
        var dataIndex = column.dataIndex;
        var recordCount = store.getCount();
        for (var i = 0; i < recordCount; i++) {
            var record = store.getAt(i);

            record.set(dataIndex, checked);
        }
    }
});

不要忘记在组件中要求插件。

requires: [
    'MyApp.ux.plugin.SelectAllCheckColumnHeader'
    ...
],

*当sortable设置为true时,单击复选框将(un)选中所有复选框并对网格进行排序,这会让人感到困惑。最好将sortable设置为false。