/** * This class specializes `Ext.Editor` for the purpose of editing grid cells inline. This * class is not instantiated by user code but rather by `Ext.grid.plugin.CellEditing`. * @private * @since 6.5.0 */Ext.define('Ext.grid.CellEditor', { extend: 'Ext.Editor', xtype: 'celleditor', isCellEditor: true, floated: false, classCls: Ext.baseCSSPrefix + 'celleditor', config: { /** * @cfg {Boolean} autoPin * Determines if the row that the cell editor is attached to will pin to the top * and bottom when scrolling. * If `false` editing will be canceled when cell editor is scrolled off the list. */ autoPin: true }, swallowKeys: false, layout: 'fit', shadow: false, allowBlur: true, alignment: 'tl-tl', zIndex: 10, // Do not use the cell's rendered value useBoundValue: false, inheritUi: true, field: { inheritUi: true }, /** * Starts editing at the passed {@link Ext.grid.Location location} using the passed value. * @param {Ext.grid.Location} location Where to start editing * @param {*} [value] The value to place in the editor. * @param {Boolean} [doFocus] `true` to focus the editor. * @return {Ext.grid.Location} The location where actionable mode was successfully started. */ startEdit: function(location, value, doFocus) { var me = this, cell, el, row, grid, result; if (location) { cell = location.cell; el = cell.el; value = value != null ? value : location.record.get(cell.dataIndex); // VERY important for focus management. // We must have an upward ownership link so that onFocusLeave // bubbles correctly. // This link must never be severed - it just is updated on each edit. me.ownerCmp = cell; // CellEditors are positioned and fitted within the cell using their CSS rules. me.render(el); me.callParent([el, value, doFocus]); // Superclass events may veto edit start. // If we are editing, set up our context. if (me.editing) { me.$activeRow = row = location.row; me.$activeGrid = grid = row.getGrid(); me.editingPlugin.editing = true; me.editingPlugin.location = me.$activeLocation = result = new Ext.grid.Location( grid, me.getField().getFocusEl() ); me.editingPlugin.activeEditor = me; grid.stickItem(row, { autoPin: me.getAutoPin() }); } } return result; }, onFocusLeave: function(e) { // FocusLeave result of destruction. Must not do anything. if (!this.editingPlugin.getGrid().destroying) { if (this.isCancelling) { this.cancelEdit(); } else { this.completeEdit(false); } } this.isCancelling = false; }, onFocusEnter: function(e) { // Force automatic focus reversion to go to our currently active cell. if (this.$activeLocation) { e.relatedTarget = e.fromElement = this.$activeLocation.getFocusEl('dom'); } this.callParent([e]); }, /** * @returns {Ext.grid.Location} The location where editing is active *if* editing is * active, else `null`. */ getLocation: function() { return this.$activeLocation; }, onSpecialKey: function(field, event) { var me = this; // Allow the NavigationModel handles the actual navigation. // When the CellEditing#activateCell finds this still active // it will complete the edit if the cancelling flag is not set if (event.getKey() === event.ESC) { me.isCancelling = true; } else { me.callParent([field, event]); } }, onEditComplete: function(remainVisible, cancelling) { var me = this, location = me.$activeLocation, value = me.getValue(), record, dataIndex, row, grid, sticky; me.callParent([remainVisible, cancelling]); if (location) { grid = location.row.getGrid(); // If we are not coming from a cancelEdit, and the field's changed // then update the record. if (!cancelling && value !== me.startValue) { record = location.record; dataIndex = location.cell.dataIndex; if (record) { record.set(dataIndex, value); // The row may change due to auto sorting, so bring it into view // and refresh the location grid.ensureVisible(location.record); location.refresh(); } } if (!remainVisible) { row = location.row; sticky = !!row.$sticky; if (sticky) { grid.stickItem(row, null); grid.ensureVisible(location.record, { column: location.columnIndex, focus: true }); } me.$stickyVisibility = me.$activeLocation = me.$activeRow = me.$activeGrid = null; me.editingPlugin.editing = false; me.editingPlugin.location = me.editingPlugin.activeEditor = null; } } }, // CellEditors are positioned and fitted within the cell using their CSS rules. realign: Ext.emptyFn, toggleBoundEl: function(visible) { var location = this.$activeLocation, cell, bodyEl; if (location && this.hideEl) { cell = location.cell; // If the location is still rendered... if (cell) { bodyEl = cell.bodyElement; bodyEl.setVisibility(visible); } } }});