X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/0494b8d9b9bb03ab6c22b34dae81261e3cd7e3e6..7a654f8d43fdb43d78b63d90528bed6e86b608cc:/src/selection/CheckboxModel.js diff --git a/src/selection/CheckboxModel.js b/src/selection/CheckboxModel.js new file mode 100644 index 00000000..a905d083 --- /dev/null +++ b/src/selection/CheckboxModel.js @@ -0,0 +1,159 @@ +/** + * @class Ext.selection.CheckboxModel + * @extends Ext.selection.RowModel + * + * A selection model that renders a column of checkboxes that can be toggled to + * select or deselect rows. The default mode for this selection model is MULTI. + * + * The selection model will inject a header for the checkboxes in the first view + * and according to the 'injectCheckbox' configuration. + */ +Ext.define('Ext.selection.CheckboxModel', { + extend: 'Ext.selection.RowModel', + + /** + * @cfg {String} mode + * Modes of selection. + * Valid values are SINGLE, SIMPLE, and MULTI. Defaults to 'MULTI' + */ + mode: 'MULTI', + + /** + * @cfg {Mixed} injectCheckbox + * Instructs the SelectionModel whether or not to inject the checkbox header + * automatically or not. (Note: By not placing the checkbox in manually, the + * grid view will need to be rendered 2x on initial render.) + * Supported values are a Number index, false and the strings 'first' and 'last'. + * Default is 0. + */ + injectCheckbox: 0, + + /** + * @cfg {Boolean} checkOnly true if rows can only be selected by clicking on the + * checkbox column (defaults to false). + */ + checkOnly: false, + + // private + checkerOnCls: Ext.baseCSSPrefix + 'grid-hd-checker-on', + + bindComponent: function() { + this.sortable = false; + this.callParent(arguments); + + var view = this.views[0], + headerCt = view.headerCt; + + if (this.injectCheckbox !== false) { + if (this.injectCheckbox == 'first') { + this.injectCheckbox = 0; + } else if (this.injectCheckbox == 'last') { + this.injectCheckbox = headerCt.getColumnCount(); + } + headerCt.add(this.injectCheckbox, this.getHeaderConfig()); + } + headerCt.on('headerclick', this.onHeaderClick, this); + }, + + /** + * Toggle the ui header between checked and unchecked state. + * @param {Boolean} isChecked + * @private + */ + toggleUiHeader: function(isChecked) { + var view = this.views[0], + headerCt = view.headerCt, + checkHd = headerCt.child('gridcolumn[isCheckerHd]'); + + if (checkHd) { + if (isChecked) { + checkHd.el.addCls(this.checkerOnCls); + } else { + checkHd.el.removeCls(this.checkerOnCls); + } + } + }, + + /** + * Toggle between selecting all and deselecting all when clicking on + * a checkbox header. + */ + onHeaderClick: function(headerCt, header, e) { + if (header.isCheckerHd) { + e.stopEvent(); + var isChecked = header.el.hasCls(Ext.baseCSSPrefix + 'grid-hd-checker-on'); + if (isChecked) { + // We have to supress the event or it will scrollTo the change + this.deselectAll(true); + } else { + // We have to supress the event or it will scrollTo the change + this.selectAll(true); + } + } + }, + + /** + * Retrieve a configuration to be used in a HeaderContainer. + * This should be used when injectCheckbox is set to false. + */ + getHeaderConfig: function() { + return { + isCheckerHd: true, + text : ' ', + width: 24, + sortable: false, + fixed: true, + hideable: false, + menuDisabled: true, + dataIndex: '', + cls: Ext.baseCSSPrefix + 'column-header-checkbox ', + renderer: Ext.Function.bind(this.renderer, this) + }; + }, + + /** + * Generates the HTML to be rendered in the injected checkbox column for each row. + * Creates the standard checkbox markup by default; can be overridden to provide custom rendering. + * See {@link Ext.grid.column.Column#renderer} for description of allowed parameters. + */ + renderer: function(value, metaData, record, rowIndex, colIndex, store, view) { + metaData.tdCls = Ext.baseCSSPrefix + 'grid-cell-special'; + return '
 
'; + }, + + // override + onRowMouseDown: function(view, record, item, index, e) { + view.el.focus(); + var me = this, + checker = e.getTarget('.' + Ext.baseCSSPrefix + 'grid-row-checker'); + + // checkOnly set, but we didn't click on a checker. + if (me.checkOnly && !checker) { + return; + } + + if (checker) { + var mode = me.getSelectionMode(); + // dont change the mode if its single otherwise + // we would get multiple selection + if (mode !== 'SINGLE') { + me.setSelectionMode('SIMPLE'); + } + me.selectWithEvent(record, e); + me.setSelectionMode(mode); + } else { + me.selectWithEvent(record, e); + } + }, + + /** + * Synchronize header checker value as selection changes. + * @private + */ + onSelectChange: function(record, isSelected) { + this.callParent([record, isSelected]); + // check to see if all records are selected + var hdSelectStatus = this.selected.getCount() === this.store.getCount(); + this.toggleUiHeader(hdSelectStatus); + } +});