/** * RowModel Selection Model implements row based navigation for * {@link Ext.grid.Panel grid panels} via user input. RowModel is the default grid selection * model and, generally, will not need to be specified. * * By utilizing the selModel config as an object, you may also set configurations for: * * + {@link #mode} - Specifies whether user may select multiple rows or single rows * + {@link #allowDeselect} - Specifies whether user may deselect records when in SINGLE mode * + {@link #ignoreRightMouseSelection} - Specifies whether user may ignore right clicks * for selection purposes * * In the example below, we've enabled MULTI mode. This means that multiple rows can be selected. * * @example * var store = Ext.create('Ext.data.Store', { * fields: ['name', 'email', 'phone'], * data: [ * { name: 'Lisa', email: 'lisa@simpsons.com', phone: '555-111-1224' }, * { name: 'Bart', email: 'bart@simpsons.com', phone: '555-222-1234' }, * { name: 'Homer', email: 'homer@simpsons.com', phone: '555-222-1244' }, * { name: 'Marge', email: 'marge@simpsons.com', phone: '555-222-1254' } * ] * }); * * Ext.create('Ext.grid.Panel', { * title: 'Simpsons', * store: store, * width: 400, * renderTo: Ext.getBody(), * selModel: { * selType: 'rowmodel', // rowmodel is the default selection model * mode: 'MULTI' // Allows selection of multiple rows * }, * columns: [ * { text: 'Name', dataIndex: 'name' }, * { text: 'Email', dataIndex: 'email', flex: 1 }, * { text: 'Phone', dataIndex: 'phone' } * ] * }); */Ext.define('Ext.selection.RowModel', { extend: 'Ext.selection.DataViewModel', alias: 'selection.rowmodel', requires: [ 'Ext.grid.CellContext' ], /** * @cfg {Boolean} enableKeyNav * * Turns on/off keyboard navigation within the grid. */ enableKeyNav: true, /** * @event beforedeselect * Fired before a record is deselected. If any listener returns false, the * deselection is cancelled. * @param {Ext.selection.RowModel} this * @param {Ext.data.Model} record The deselected record * @param {Number} index The row index deselected */ /** * @event beforeselect * Fired before a record is selected. If any listener returns false, the * selection is cancelled. * @param {Ext.selection.RowModel} this * @param {Ext.data.Model} record The selected record * @param {Number} index The row index selected */ /** * @event deselect * Fired after a record is deselected * @param {Ext.selection.RowModel} this * @param {Ext.data.Model} record The deselected record * @param {Number} index The row index deselected */ /** * @event select * Fired after a record is selected * @param {Ext.selection.RowModel} this * @param {Ext.data.Model} record The selected record * @param {Number} index The row index selected */ isRowModel: true, /** * @inheritdoc */ deselectOnContainerClick: false, onUpdate: function(record) { var me = this, view = me.view, index; if (view && me.isSelected(record)) { index = view.indexOf(record); view.onRowSelect(index); if (record === me.lastFocused) { view.onRowFocus(index, true); } } }, // Allow the GridView to update the UI by // adding/removing a CSS class from the row. onSelectChange: function(record, isSelected, suppressEvent, commitFn) { var me = this, views = me.views || [me.view], viewsLn = views.length, recordIndex = me.store.indexOf(record), eventName = isSelected ? 'select' : 'deselect', i, view; if ((suppressEvent || me.fireEvent('before' + eventName, me, record, recordIndex)) !== false && commitFn() !== false) { // Selection models can handle more than one view for (i = 0; i < viewsLn; i++) { view = views[i]; recordIndex = view.indexOf(record); // The record might not be rendered due to either buffered rendering, // or removal/hiding of all columns (eg empty locked side). if (view.indexOf(record) !== -1) { if (isSelected) { view.onRowSelect(recordIndex, suppressEvent); } else { view.onRowDeselect(recordIndex, suppressEvent); } } } if (!suppressEvent) { me.fireEvent(eventName, me, record, recordIndex); } } }, /** * Returns position of the first selected cell in the selection in the format {row: row, column: column} * @deprecated 5.0.1 Use the {@link Ext.view.Table#getNavigationModel NavigationModel} instead. */ getCurrentPosition: function() { var firstSelection = this.selected.getAt(0); if (firstSelection) { return new Ext.grid.CellContext(this.view).setPosition(this.store.indexOf(firstSelection), 0); } }, selectByPosition: function (position, keepExisting) { if (!position.isCellContext) { position = new Ext.grid.CellContext(this.view).setPosition(position.row, position.column); } this.select(position.record, keepExisting); }, /** * Selects the record immediately following the currently selected record. * @param {Boolean} [keepExisting] True to retain existing selections * @param {Boolean} [suppressEvent] Set to false to not fire a select event * @return {Boolean} `true` if there is a next record, else `false` */ selectNext: function(keepExisting, suppressEvent) { var me = this, store = me.store, selection = me.getSelection(), record = selection[selection.length - 1], index = me.view.indexOf(record) + 1, success; if (index === store.getCount() || index === 0) { success = false; } else { me.doSelect(index, keepExisting, suppressEvent); success = true; } return success; }, /** * Selects the record that precedes the currently selected record. * @param {Boolean} [keepExisting] True to retain existing selections * @param {Boolean} [suppressEvent] Set to false to not fire a select event * @return {Boolean} `true` if there is a previous record, else `false` */ selectPrevious: function(keepExisting, suppressEvent) { var me = this, selection = me.getSelection(), record = selection[0], index = me.view.indexOf(record) - 1, success; if (index < 0) { success = false; } else { me.doSelect(index, keepExisting, suppressEvent); success = true; } return success; }, isRowSelected: function(record) { return this.isSelected(record); }, isCellSelected: function(view, record, columnHeader) { return this.isSelected(record); }, vetoSelection: function(e) { var navModel = this.view.getNavigationModel(), key = e.getKey(), isLeftRight = key === e.RIGHT || key === e.LEFT; // Veto row selection upon key-based, in-row left/right navigation. // Else pass to superclass to veto. return (isLeftRight && navModel.previousRecord === navModel.record) || this.callParent([e]); }});