--- /dev/null
+<!DOCTYPE html><html><head><title>Sencha Documentation Project</title><link rel="stylesheet" href="../reset.css" type="text/css"><link rel="stylesheet" href="../prettify.css" type="text/css"><link rel="stylesheet" href="../prettify_sa.css" type="text/css"><script type="text/javascript" src="../prettify.js"></script></head><body onload="prettyPrint()"><pre class="prettyprint"><pre>
+<span id='Ext-grid.plugin.Editing'>/**
+</span> * @class Ext.grid.plugin.Editing
+
+This class provides an abstract grid editing plugin on selected {@link Ext.grid.column.Column columns}.
+The editable columns are specified by providing an {@link Ext.grid.column.Column#editor editor}
+in the {@link Ext.grid.column.Column column configuration}.
+
+*Note:* This class should not be used directly. See {@link Ext.grid.plugin.CellEditing} and
+{@link Ext.grid.plugin.RowEditing}.
+
+ * @markdown
+ */
+Ext.define('Ext.grid.plugin.Editing', {
+ alias: 'editing.editing',
+
+ requires: [
+ 'Ext.grid.column.Column',
+ 'Ext.util.KeyNav'
+ ],
+
+ mixins: {
+ observable: 'Ext.util.Observable'
+ },
+
+<span id='Ext-grid.plugin.Editing-cfg-clicksToEdit'> /**
+</span> * @cfg {Number} clicksToEdit
+ * The number of clicks on a grid required to display the editor (defaults to 2).
+ */
+ clicksToEdit: 2,
+
+ // private
+ defaultFieldXType: 'textfield',
+
+ // cell, row, form
+ editStyle: '',
+
+ constructor: function(config) {
+ var me = this;
+ Ext.apply(me, config);
+
+ me.addEvents(
+ // Doc'ed in separate editing plugins
+ 'beforeedit',
+
+ // Doc'ed in separate editing plugins
+ 'edit',
+
+ // Doc'ed in separate editing plugins
+ 'validateedit'
+ );
+ me.mixins.observable.constructor.call(me);
+ // TODO: Deprecated, remove in 5.0
+ me.relayEvents(me, ['afteredit'], 'after');
+ },
+
+ // private
+ init: function(grid) {
+ var me = this;
+
+ me.grid = grid;
+ me.view = grid.view;
+ me.initEvents();
+ me.initFieldAccessors(me.view.getGridColumns());
+
+ grid.relayEvents(me, ['beforeedit', 'edit', 'validateedit']);
+ // Marks the grid as editable, so that the SelectionModel
+ // can make appropriate decisions during navigation
+ grid.isEditable = true;
+ grid.editingPlugin = grid.view.editingPlugin = me;
+ },
+
+<span id='Ext-grid.plugin.Editing-method-destroy'> /**
+</span> * @private
+ * AbstractComponent calls destroy on all its plugins at destroy time.
+ */
+ destroy: function() {
+ var me = this,
+ grid = me.grid,
+ headerCt = grid.headerCt,
+ events = grid.events;
+
+ Ext.destroy(me.keyNav);
+ me.removeFieldAccessors(grid.getView().getGridColumns());
+
+ // Clear all listeners from all our events, clear all managed listeners we added to other Observables
+ me.clearListeners();
+
+ delete me.grid.editingPlugin;
+ delete me.grid.view.editingPlugin;
+ delete me.grid;
+ delete me.view;
+ delete me.editor;
+ delete me.keyNav;
+ },
+
+ // private
+ getEditStyle: function() {
+ return this.editStyle;
+ },
+
+ // private
+ initFieldAccessors: function(column) {
+ var me = this;
+
+ if (Ext.isArray(column)) {
+ Ext.Array.forEach(column, me.initFieldAccessors, me);
+ return;
+ }
+
+ // Augment the Header class to have a getEditor and setEditor method
+ // Important: Only if the header does not have its own implementation.
+ Ext.applyIf(column, {
+ getEditor: function(record, defaultField) {
+ return me.getColumnField(this, defaultField);
+ },
+
+ setEditor: function(field) {
+ me.setColumnField(this, field);
+ }
+ });
+ },
+
+ // private
+ removeFieldAccessors: function(column) {
+ var me = this;
+
+ if (Ext.isArray(column)) {
+ Ext.Array.forEach(column, me.removeFieldAccessors, me);
+ return;
+ }
+
+ delete column.getEditor;
+ delete column.setEditor;
+ },
+
+ // private
+ // remaps to the public API of Ext.grid.column.Column.getEditor
+ getColumnField: function(columnHeader, defaultField) {
+ var field = columnHeader.field;
+
+ if (!field && columnHeader.editor) {
+ field = columnHeader.editor;
+ delete columnHeader.editor;
+ }
+
+ if (!field && defaultField) {
+ field = defaultField;
+ }
+
+ if (field) {
+ if (Ext.isString(field)) {
+ field = { xtype: field };
+ }
+ if (Ext.isObject(field) && !field.isFormField) {
+ field = Ext.ComponentManager.create(field, this.defaultFieldXType);
+ columnHeader.field = field;
+ }
+
+ Ext.apply(field, {
+ name: columnHeader.dataIndex
+ });
+
+ return field;
+ }
+ },
+
+ // private
+ // remaps to the public API of Ext.grid.column.Column.setEditor
+ setColumnField: function(column, field) {
+ if (Ext.isObject(field) && !field.isFormField) {
+ field = Ext.ComponentManager.create(field, this.defaultFieldXType);
+ }
+ column.field = field;
+ },
+
+ // private
+ initEvents: function() {
+ var me = this;
+ me.initEditTriggers();
+ me.initCancelTriggers();
+ },
+
+ // @abstract
+ initCancelTriggers: Ext.emptyFn,
+
+ // private
+ initEditTriggers: function() {
+ var me = this,
+ view = me.view,
+ clickEvent = me.clicksToEdit === 1 ? 'click' : 'dblclick';
+
+ // Start editing
+ me.mon(view, 'cell' + clickEvent, me.startEditByClick, me);
+ view.on('render', function() {
+ me.keyNav = Ext.create('Ext.util.KeyNav', view.el, {
+ enter: me.onEnterKey,
+ esc: me.onEscKey,
+ scope: me
+ });
+ }, me, { single: true });
+ },
+
+ // private
+ onEnterKey: function(e) {
+ var me = this,
+ grid = me.grid,
+ selModel = grid.getSelectionModel(),
+ record,
+ columnHeader = grid.headerCt.getHeaderAtIndex(0);
+
+ // Calculate editing start position from SelectionModel
+ // CellSelectionModel
+ if (selModel.getCurrentPosition) {
+ pos = selModel.getCurrentPosition();
+ record = grid.store.getAt(pos.row);
+ columnHeader = grid.headerCt.getHeaderAtIndex(pos.column);
+ }
+ // RowSelectionModel
+ else {
+ record = selModel.getLastSelected();
+ }
+ me.startEdit(record, columnHeader);
+ },
+
+ // private
+ onEscKey: function(e) {
+ this.cancelEdit();
+ },
+
+ // private
+ startEditByClick: function(view, cell, colIdx, record, row, rowIdx, e) {
+ this.startEdit(record, view.getHeaderAtIndex(colIdx));
+ },
+
+<span id='Ext-grid.plugin.Editing-property-beforeEdit'> /**
+</span> * @private
+ * @abstract. Template method called before editing begins.
+ * @param {Object} context The current editing context
+ * @return {Boolean} Return false to cancel the editing process
+ */
+ beforeEdit: Ext.emptyFn,
+
+<span id='Ext-grid.plugin.Editing-method-startEdit'> /**
+</span> * Start editing the specified record, using the specified Column definition to define which field is being edited.
+ * @param {Model} record The Store data record which backs the row to be edited.
+ * @param {Model} columnHeader The Column object defining the column to be edited.
+ */
+ startEdit: function(record, columnHeader) {
+ var me = this,
+ context = me.getEditingContext(record, columnHeader);
+
+ if (me.beforeEdit(context) === false || me.fireEvent('beforeedit', context) === false || context.cancel) {
+ return false;
+ }
+
+ me.context = context;
+ me.editing = true;
+ },
+
+<span id='Ext-grid.plugin.Editing-method-getEditingContext'> /**
+</span> * @private Collects all information necessary for any subclasses to perform their editing functions.
+ * @param record
+ * @param columnHeader
+ * @returns {Object} The editing context based upon the passed record and column
+ */
+ getEditingContext: function(record, columnHeader) {
+ var me = this,
+ grid = me.grid,
+ store = grid.store,
+ rowIdx,
+ colIdx,
+ view = grid.getView(),
+ value;
+
+ // If they'd passed numeric row, column indices, look them up.
+ if (Ext.isNumber(record)) {
+ rowIdx = record;
+ record = store.getAt(rowIdx);
+ } else {
+ rowIdx = store.indexOf(record);
+ }
+ if (Ext.isNumber(columnHeader)) {
+ colIdx = columnHeader;
+ columnHeader = grid.headerCt.getHeaderAtIndex(colIdx);
+ } else {
+ colIdx = columnHeader.getIndex();
+ }
+
+ value = record.get(columnHeader.dataIndex);
+ return {
+ grid: grid,
+ record: record,
+ field: columnHeader.dataIndex,
+ value: value,
+ row: view.getNode(rowIdx),
+ column: columnHeader,
+ rowIdx: rowIdx,
+ colIdx: colIdx
+ };
+ },
+
+<span id='Ext-grid.plugin.Editing-method-cancelEdit'> /**
+</span> * Cancel any active edit that is in progress.
+ */
+ cancelEdit: function() {
+ this.editing = false;
+ },
+
+<span id='Ext-grid.plugin.Editing-method-completeEdit'> /**
+</span> * Complete the edit if there is an active edit in progress.
+ */
+ completeEdit: function() {
+ var me = this;
+
+ if (me.editing && me.validateEdit()) {
+ me.fireEvent('edit', me.context);
+ }
+
+ delete me.context;
+ me.editing = false;
+ },
+
+ // @abstract
+ validateEdit: function() {
+ var me = this,
+ context = me.context;
+
+ return me.fireEvent('validateedit', me, context) !== false && !context.cancel;
+ }
+});</pre></pre></body></html>
\ No newline at end of file