/** * A Column subclass which renders a checkbox in each column cell which toggles the truthiness of the associated data field on click. * * Example usage: * * @example * var store = Ext.create('Ext.data.Store', { * fields : ['name', 'email', 'phone', 'active'], * data : { * items : [ * { name : 'Lisa', email : '[email protected]', phone : '555-111-1224', active : true }, * { name : 'Bart', email : '[email protected]', phone : '555-222-1234', active : true }, * { name : 'Homer', email : '[email protected]', phone : '555-222-1244', active : false }, * { name : 'Marge', email : '[email protected]', phone : '555-222-1254', active : true } * ] * }, * proxy : { * type : 'memory', * reader : { * type : 'json', * root : 'items' * } * } * }); * * Ext.create('Ext.grid.Panel', { * title : 'Simpsons', * height : 200, * width : 400, * renderTo : Ext.getBody(), * store : store, * columns : [ * { text : 'Name', dataIndex : 'name' }, * { text : 'Email', dataIndex : 'email', flex : 1 }, * { text : 'Phone', dataIndex : 'phone' }, * { xtype : 'checkcolumn', text : 'Active', dataIndex : 'active' } * ] * }); * * The check column can be at any index in the columns array. */ Ext.define('Ext.grid.column.CheckColumn', { extend: 'Ext.grid.column.Column', alternateClassName: 'Ext.ux.CheckColumn', alias: 'widget.checkcolumn', /** * @cfg * @hide * Overridden from base class. Must center to line up with editor. */ align: 'center', /** * @cfg {Boolean} [stopSelection=true] * Prevent grid selection upon mousedown. */ stopSelection: true, tdCls: Ext.baseCSSPrefix + 'grid-cell-checkcolumn', constructor: function() { this.addEvents( /** * @event beforecheckchange * Fires when before checked state of a row changes. * The change may be vetoed by returning `false` from a listener. * @param {Ext.ux.CheckColumn} this CheckColumn * @param {Number} rowIndex The row index * @param {Boolean} checked True if the box is to be checked */ 'beforecheckchange', /** * @event checkchange * Fires when the checked state of a row changes * @param {Ext.ux.CheckColumn} this CheckColumn * @param {Number} rowIndex The row index * @param {Boolean} checked True if the box is now checked */ 'checkchange' ); this.scope = this; this.callParent(arguments); }, /** * @private * Process and refire events routed from the GridView's processEvent method. */ processEvent: function(type, view, cell, recordIndex, cellIndex, e, record, row) { var me = this, key = type === 'keydown' && e.getKey(), mousedown = type == 'mousedown'; if (!me.disabled && (mousedown || (key == e.ENTER || key == e.SPACE))) { var dataIndex = me.dataIndex, checked = !record.get(dataIndex); // Allow apps to hook beforecheckchange if (me.fireEvent('beforecheckchange', me, recordIndex, checked) !== false) { record.set(dataIndex, checked); me.fireEvent('checkchange', me, recordIndex, checked); // Mousedown on the now nonexistent cell causes the view to blur, so stop it continuing. if (mousedown) { e.stopEvent(); } // Selection will not proceed after this because of the DOM update caused by the record modification // Invoke the SelectionModel unless configured not to do so if (!me.stopSelection) { view.selModel.selectByPosition({ row: recordIndex, column: cellIndex }); } // Prevent the view from propagating the event to the selection model - we have done that job. return false; } else { // Prevent the view from propagating the event to the selection model if configured to do so. return !me.stopSelection; } } else { return me.callParent(arguments); } }, /** * Enables this CheckColumn. * @param {Boolean} [silent=false] */ onEnable: function(silent) { var me = this; me.callParent(arguments); me.up('tablepanel').el.select('.' + Ext.baseCSSPrefix + 'grid-cell-' + me.id).removeCls(me.disabledCls); if (!silent) { me.fireEvent('enable', me); } }, /** * Disables this CheckColumn. * @param {Boolean} [silent=false] */ onDisable: function(silent) { var me = this; me.callParent(arguments); me.up('tablepanel').el.select('.' + Ext.baseCSSPrefix + 'grid-cell-' + me.id).addCls(me.disabledCls); if (!silent) { me.fireEvent('disable', me); } }, // Note: class names are not placed on the prototype bc renderer scope // is not in the header. renderer : function(value, meta) { var cssPrefix = Ext.baseCSSPrefix, cls = [cssPrefix + 'grid-checkcolumn']; if (this.disabled) { meta.tdCls += ' ' + this.disabledCls; } if (value) { cls.push(cssPrefix + 'grid-checkcolumn-checked'); } return '<img class="' + cls.join(' ') + '" src="' + Ext.BLANK_IMAGE_URL + '"/>'; } });