【问题标题】:checkcolumn select all; header manipulation, select all function检查列全选;标题操作,选择所有功能
【发布时间】:2014-01-23 14:24:01
【问题描述】:

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

I need to know what code is required to generate a checkbox in each column header that, when selected/deselected, changes the checkboxes in the given column.

现有代码供参考:

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);
            }
        }
    }
}

【问题讨论】:

    标签: extjs checkbox grid extjs4.2


    【解决方案1】:

    您可以查看我在每个列标题中生成复选框的变体。检查 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);
                }
            }
        }
    });
    

    【讨论】:

    • 这是好东西!比第一个答案更好,很好地放入一个继承类:)
    • 仅供参考,这很好用,我不需要 header.getEl().down('img')... 行,因为调用 onSelectAll 时会自动显示复选标记
    【解决方案2】:

    想出了如何去做;将带有 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。

    【讨论】:

      【解决方案3】:

      可用于 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,单击复选框将(取消)选中所有复选框并对令人困惑的网格进行排序。最好将 sortable 设置为 false。

      【讨论】:

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