2012-07-09 241 views
6

我有一列checkcolumn类型来启用切换布尔值。我希望能够一次切换所有行的值。理想情况下,我可以添加一个复选框到checkcolumn标题并监听更改。那可能吗?ExtJS 4用复选框标题选择多个CheckColumn复选框

我想指出,我不是在寻找一个checkboxmodel来选择行。

回答

9

我创建了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 
     } 
    } 
} 

是这样的: enter image description here

+0

哦,请务必从倾倒旧checkcolumn您包括在页面:) – Reimius 2012-07-11 20:24:55

+0

唯一的问题是,当点击标题中的复选框时,'checkchange'不会被触发。有没有解决方案?否则,这正是我需要的,谢谢! – Jason 2013-01-08 22:04:51

+1

我假设你想让它触发所有更改标题状态时改变的复选框吗?我可以更新我的版本,如果我这样做,我会通知您这些更改。这可能会对我的代码产生负面影响。 – Reimius 2013-01-14 15:11:06

3

我创建了一个基于由@Reimius提供的代码补丁。 它只在必要时调用getStoreIsAllChecked方法来提高性能。 它也支持Extjs 4.2 希望它有帮助。

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

+0

好的工作,我的朋友!真的,真的救了我,非常感谢! – Almas 2015-07-23 09:42:45

+0

我必须使用'checkcolumn'事件。我在这里怎么办? – Arun 2015-08-12 14:47:05

0

使用从上面bocong对我来说并没有开箱的做法:头复选框被显示出来选中,并没有切换上点击其状态(也显得有点古怪,被切断关闭只是在左侧一点)。

我修改(并大大简化)从上面bocong得到它的ExtJS的4.2.1很好地工作(复制从常规行的复选框必要的标记)代码:

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

看来工作大!

0

如果您使用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 
} 

输出会是这样的。 Output will be like this

竖起大拇指,如果你喜欢这个建议。