【问题标题】:ExtJS 4 select multiple CheckColumn checkboxes with checkbox headerExtJS 4 选择带有复选框标题的多个 CheckColumn 复选框
【发布时间】:2012-07-09 10:55:27
【问题描述】:

我有一列checkcolumn 类型来启用切换布尔值。我希望能够一次切换该值的所有行。理想情况下,我可以在checkcolumn 标头中添加一个复选框并监听更改。这可能吗?

我想指出,我不是在寻找复选框模型来选择行。

【问题讨论】:

    标签: extjs extjs4 extjs4.1


    【解决方案1】:

    我为此创建了 Ext.ux.CheckColumn 的更新版本,只需在包含 extjs 代码后包含此代码:

    Ext.define('Ext.ux.CheckColumn', {
        extend: 'Ext.grid.column.Column',
        alias: 'widget.checkcolumn',
    
        disableColumn: false,
        disableFunction: null,
        disabledColumnDataIndex: null,
        columnHeaderCheckbox: false,
    
        constructor: function(config) {
    
            var me = this;
            if(config.columnHeaderCheckbox)
            {
                var store = config.store;
                store.on("datachanged", function(){
                    me.updateColumnHeaderCheckbox(me);
                });
                store.on("update", function(){
                    me.updateColumnHeaderCheckbox(me);
                });
                config.text = me.getHeaderCheckboxImage(store, config.dataIndex);
            }
    
            me.addEvents(
                /**
                 * @event checkchange
                 * Fires when the checked state of a row changes
                 * @param {Ext.ux.CheckColumn} this
                 * @param {Number} rowIndex The row index
                 * @param {Boolean} checked True if the box is checked
                 */
                'beforecheckchange',
                /**
                 * @event checkchange
                 * Fires when the checked state of a row changes
                 * @param {Ext.ux.CheckColumn} this
                 * @param {Number} rowIndex The row index
                 * @param {Boolean} checked True if the box is checked
                 */
                'checkchange'
            );
    
            me.callParent(arguments);
        },
    
        updateColumnHeaderCheckbox: function(column){
            var image = column.getHeaderCheckboxImage(column.store, column.dataIndex);
            column.setText(image);
        },
    
        toggleSortState: function(){
            var me = this;
            if(me.columnHeaderCheckbox)
            {
                var store = me.up('tablepanel').store;
                var isAllChecked = me.getStoreIsAllChecked(store, me.dataIndex);
                store.each(function(record){
                    record.set(me.dataIndex, !isAllChecked);
                    record.commit();
                });
            }
            else
                me.callParent(arguments);
        },
    
        getStoreIsAllChecked: function(store, dataIndex){
            var allTrue = true;
            store.each(function(record){
                if(!record.get(dataIndex))
                    allTrue = false;
            });
            return allTrue;
        },
    
        getHeaderCheckboxImage: function(store, dataIndex){
    
            var allTrue = this.getStoreIsAllChecked(store, dataIndex);
    
            var cssPrefix = Ext.baseCSSPrefix,
                cls = [cssPrefix + 'grid-checkheader'];
    
            if (allTrue) {
                cls.push(cssPrefix + 'grid-checkheader-checked');
            }
            return '<div class="' + cls.join(' ') + '">&#160;</div>'
        },
    
        /**
         * @private
         * Process and refire events routed from the GridView's processEvent method.
         */
        processEvent: function(type, view, cell, recordIndex, cellIndex, e) {
            if (type == 'mousedown' || (type == 'keydown' && (e.getKey() == e.ENTER || e.getKey() == e.SPACE))) {
                var record = view.panel.store.getAt(recordIndex),
                    dataIndex = this.dataIndex,
                    checked = !record.get(dataIndex),
                    column = view.panel.columns[cellIndex];
                if(!(column.disableColumn || record.get(column.disabledColumnDataIndex) || (column.disableFunction && column.disableFunction(checked, record))))
                {
                    if(this.fireEvent('beforecheckchange', this, recordIndex, checked, record))
                    {
                        record.set(dataIndex, checked);
                        this.fireEvent('checkchange', this, recordIndex, checked, record);
                    }
                }
                // cancel selection.
                return false;
            } else {
                return this.callParent(arguments);
            }
        },
    
        // Note: class names are not placed on the prototype bc renderer scope
        // is not in the header.
        renderer : function(value, metaData, record, rowIndex, colIndex, store, view){
            var disabled = "",
                column = view.panel.columns[colIndex];
            if(column.disableColumn || column.disabledColumnDataIndex || (column.disableFunction && column.disableFunction(value, record)))
                disabled = "-disabled";
            var cssPrefix = Ext.baseCSSPrefix,
                cls = [cssPrefix + 'grid-checkheader' + disabled];
    
            if (value) {
                cls.push(cssPrefix + 'grid-checkheader-checked' + disabled);
            }
            return '<div class="' + cls.join(' ') + '">&#160;</div>';
        }
    });
    

    那么复选框列的示例设置将如下所示:

    {
        xtype: "checkcolumn",
        columnHeaderCheckbox: true,//this setting is necessary for what you want
        store: (you need to put the grids store here),
        sortable: false,
        hideable: false,
        menuDisabled: true,
        dataIndex: "value_flag",
        listeners: {
            checkchange: function(column, rowIndex, checked){
                 //code for whatever on checkchange here
            }
        }
    }
    

    看起来像这样:

    【讨论】:

    • 哦,请确保从页面上的包含中转储旧的检查列 :)
    • 唯一的问题是当您单击标题中的复选框时不会触发“checkchange”。有解决方案吗?否则这正是我所需要的,谢谢!!
    • 我假设您希望它触发所有在标题状态更改时更改的复选框?我可能会对此版本进行更新,如果我这样做了,我会通知您这些更改。这可能会对我的代码产生负面影响。
    • 这对 Extjs 4.2.x 有效吗?除非有人已经知道答案,否则我会尝试自己并在这里更新...
    • 我相信由于网格组件的重组,它不适用于 Extjs 4.2 以后的版本。
    【解决方案2】:

    我根据@Reimius 提供的代码创建了一个补丁。 它只在必要时调用 getStoreIsAllChecked 方法以稍微提高性能。 它还支持 Extjs 4.2 希望对您有所帮助。

    https://github.com/twinssbc/extjs-CheckColumnPatch

    【讨论】:

    • 干得好,我的朋友!它真的,真的救了我,非常感谢!
    • 我必须使用checkcolumn 事件。我该怎么办?
    【解决方案3】:

    如果您使用 ExtJS 6.5.2 或更高版本,则应使用此设置。

    { 
      xtype: 'checkcolumn',
      headerCheckbox: true, // THIS OPETION SHOW YOU CHECKBOX ON HEADER.
      sortable: false, // THIS OPTION DISABLE SORTING.
      hideable: false, // THIS OPTION EXCLUDE COLUMN FORM MENU.
      menuDisabled: true, //THIS OPTION HIDE MENU ON THE HEADER.
      dataIndex: 'isChecked',
      width: 25
    }
    

    输出将是这样的。

    如果你喜欢这个建议,请点赞。

    【讨论】:

      【解决方案4】:

      使用上面 bocong 的方法对我来说并没有开箱即用:标题复选框显示为未选中,并且在单击时没有切换其状态(它看起来也有点时髦,只是被切断了一点点左侧)。

      我修改(并大大简化)了上面 bocong 的代码,以使其适用于 ExtJS 4.2.1(从常规行的复选框中复制必要的标记):

      getHeaderCheckboxImage: function (allChecked) {
          return '<img class="x4-grid-checkcolumn ' + ( allChecked ? 'x4-grid-checkcolumn-checked' : '' ) + '">';    
      }
      

      看起来效果不错!

      【讨论】:

        【解决方案5】:

        **

         selModel: {
           selType: 'checkboxmodel',
           showHeaderCheckbox: true
         }
        

        **

        更多详情请参考:

        http://docs.sencha.com/extjs/5.1.0/api/Ext.selection.CheckboxModel.html#cfg-showHeaderCheckbox

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-06-20
          • 2011-03-12
          • 2020-10-17
          • 2014-01-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多