Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / docs / source / CellEditing.html
index ec7a495..0704e7e 100644 (file)
@@ -1,10 +1,24 @@
-<!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.CellEditing'>/**
-</span> * @class Ext.grid.plugin.CellEditing
- * @extends Ext.grid.plugin.Editing
- *
- * The Ext.grid.plugin.CellEditing plugin injects editing at a cell level for a Grid. Only a single
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+  <title>The source code</title>
+  <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
+  <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
+  <style type="text/css">
+    .highlight { display: block; background-color: #ddd; }
+  </style>
+  <script type="text/javascript">
+    function highlight() {
+      document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
+    }
+  </script>
+</head>
+<body onload="prettyPrint(); highlight();">
+  <pre class="prettyprint lang-js"><span id='Ext-grid-plugin-CellEditing'>/**
+</span> * The Ext.grid.plugin.CellEditing plugin injects editing at a cell level for a Grid. Only a single
  * cell will be editable at a time. The field that will be used for the editor is defined at the
- * {@link Ext.grid.column.Column#field field}. The editor can be a field instance or a field configuration.
+ * {@link Ext.grid.column.Column#editor editor}. The editor can be a field instance or a field configuration.
  *
  * If an editor is not specified for a particular column then that cell will not be editable and it will
  * be skipped when activated via the mouse or the keyboard.
  * An appropriate field type should be chosen to match the data structure that it will be editing. For example,
  * to edit a date, it would be useful to specify {@link Ext.form.field.Date} as the editor.
  *
- * {@img Ext.grid.plugin.CellEditing/Ext.grid.plugin.CellEditing.png Ext.grid.plugin.CellEditing plugin}
- *
- * ## Example Usage
- *
+ *     @example
  *     Ext.create('Ext.data.Store', {
  *         storeId:'simpsonsStore',
  *         fields:['name', 'email', 'phone'],
  *             }
  *         }
  *     });
- *     
+ *
  *     Ext.create('Ext.grid.Panel', {
  *         title: 'Simpsons',
  *         store: Ext.data.StoreManager.lookup('simpsonsStore'),
  *         columns: [
- *             {header: 'Name',  dataIndex: 'name', field: 'textfield'},
+ *             {header: 'Name',  dataIndex: 'name', editor: 'textfield'},
  *             {header: 'Email', dataIndex: 'email', flex:1,
  *                 editor: {
- *                     xtype:'textfield',
- *                     allowBlank:false
+ *                     xtype: 'textfield',
+ *                     allowBlank: false
  *                 }
  *             },
  *             {header: 'Phone', dataIndex: 'phone'}
 Ext.define('Ext.grid.plugin.CellEditing', {
     alias: 'plugin.cellediting',
     extend: 'Ext.grid.plugin.Editing',
-    requires: ['Ext.grid.CellEditor'],
+    requires: ['Ext.grid.CellEditor', 'Ext.util.DelayedTask'],
 
     constructor: function() {
-<span id='Ext-grid.plugin.CellEditing-event-beforeedit'>        /**
+<span id='Ext-grid-plugin-CellEditing-event-beforeedit'>        /**
 </span>         * @event beforeedit
-         * Fires before cell editing is triggered. The edit event object has the following properties &lt;br /&gt;
-         * &lt;ul style=&quot;padding:5px;padding-left:16px;&quot;&gt;
-         * &lt;li&gt;grid - The grid&lt;/li&gt;
-         * &lt;li&gt;record - The record being edited&lt;/li&gt;
-         * &lt;li&gt;field - The field name being edited&lt;/li&gt;
-         * &lt;li&gt;value - The value for the field being edited.&lt;/li&gt;
-         * &lt;li&gt;row - The grid table row&lt;/li&gt;
-         * &lt;li&gt;column - The grid {@link Ext.grid.column.Column Column} defining the column that is being edited.&lt;/li&gt;
-         * &lt;li&gt;rowIdx - The row index that is being edited&lt;/li&gt;
-         * &lt;li&gt;colIdx - The column index that is being edited&lt;/li&gt;
-         * &lt;li&gt;cancel - Set this to true to cancel the edit or return false from your handler.&lt;/li&gt;
-         * &lt;/ul&gt;
-         * @param {Ext.grid.plugin.Editing} editor
-         * @param {Object} e An edit event (see above for description)
+         * Fires before cell editing is triggered. Return false from event handler to stop the editing.
+         *
+         * @param {Object} e An edit event with the following properties:
+         *
+         * - grid - The grid
+         * - record - The record being edited
+         * - field - The field name being edited
+         * - value - The value for the field being edited.
+         * - row - The grid table row
+         * - column - The grid {@link Ext.grid.column.Column Column} defining the column that is being edited.
+         * - rowIdx - The row index that is being edited
+         * - colIdx - The column index that is being edited
+         * - cancel - Set this to true to cancel the edit or return false from your handler.
          */
-<span id='Ext-grid.plugin.CellEditing-event-edit'>        /**
+<span id='Ext-grid-plugin-CellEditing-event-edit'>        /**
 </span>         * @event edit
-         * Fires after a cell is edited. The edit event object has the following properties &lt;br /&gt;
-         * &lt;ul style=&quot;padding:5px;padding-left:16px;&quot;&gt;
-         * &lt;li&gt;grid - The grid&lt;/li&gt;
-         * &lt;li&gt;record - The record that was edited&lt;/li&gt;
-         * &lt;li&gt;field - The field name that was edited&lt;/li&gt;
-         * &lt;li&gt;value - The value being set&lt;/li&gt;
-         * &lt;li&gt;originalValue - The original value for the field, before the edit.&lt;/li&gt;
-         * &lt;li&gt;row - The grid table row&lt;/li&gt;
-         * &lt;li&gt;column - The grid {@link Ext.grid.column.Column Column} defining the column that was edited.&lt;/li&gt;
-         * &lt;li&gt;rowIdx - The row index that was edited&lt;/li&gt;
-         * &lt;li&gt;colIdx - The column index that was edited&lt;/li&gt;
-         * &lt;/ul&gt;
+         * Fires after a cell is edited. Usage example:
+         *
+         *     grid.on('edit', function(editor, e) {
+         *         // commit the changes right after editing finished
+         *         e.record.commit();
+         *     };
          *
-         * &lt;pre&gt;&lt;code&gt;
-grid.on('edit', onEdit, this);
-
-function onEdit(e) {
-    // execute an XHR to send/commit data to the server, in callback do (if successful):
-    e.record.commit();
-};
-         * &lt;/code&gt;&lt;/pre&gt;
          * @param {Ext.grid.plugin.Editing} editor
-         * @param {Object} e An edit event (see above for description)
+         * @param {Object} e An edit event with the following properties:
+         *
+         * - grid - The grid
+         * - record - The record that was edited
+         * - field - The field name that was edited
+         * - value - The value being set
+         * - originalValue - The original value for the field, before the edit.
+         * - row - The grid table row
+         * - column - The grid {@link Ext.grid.column.Column Column} defining the column that was edited.
+         * - rowIdx - The row index that was edited
+         * - colIdx - The column index that was edited
          */
-<span id='Ext-grid.plugin.CellEditing-event-validateedit'>        /**
+<span id='Ext-grid-plugin-CellEditing-event-validateedit'>        /**
 </span>         * @event validateedit
-         * Fires after a cell is edited, but before the value is set in the record. Return false
-         * to cancel the change. The edit event object has the following properties &lt;br /&gt;
-         * &lt;ul style=&quot;padding:5px;padding-left:16px;&quot;&gt;
-         * &lt;li&gt;grid - The grid&lt;/li&gt;
-         * &lt;li&gt;record - The record being edited&lt;/li&gt;
-         * &lt;li&gt;field - The field name being edited&lt;/li&gt;
-         * &lt;li&gt;value - The value being set&lt;/li&gt;
-         * &lt;li&gt;originalValue - The original value for the field, before the edit.&lt;/li&gt;
-         * &lt;li&gt;row - The grid table row&lt;/li&gt;
-         * &lt;li&gt;column - The grid {@link Ext.grid.column.Column Column} defining the column that is being edited.&lt;/li&gt;
-         * &lt;li&gt;rowIdx - The row index that is being edited&lt;/li&gt;
-         * &lt;li&gt;colIdx - The column index that is being edited&lt;/li&gt;
-         * &lt;li&gt;cancel - Set this to true to cancel the edit or return false from your handler.&lt;/li&gt;
-         * &lt;/ul&gt;
-         * Usage example showing how to remove the red triangle (dirty record indicator) from some
-         * records (not all).  By observing the grid's validateedit event, it can be cancelled if
-         * the edit occurs on a targeted row (for example) and then setting the field's new value
-         * in the Record directly:
-         * &lt;pre&gt;&lt;code&gt;
-grid.on('validateedit', function(e) {
-  var myTargetRow = 6;
-
-  if (e.row == myTargetRow) {
-    e.cancel = true;
-    e.record.data[e.field] = e.value;
-  }
-});
-         * &lt;/code&gt;&lt;/pre&gt;
+         * Fires after a cell is edited, but before the value is set in the record. Return false from event handler to
+         * cancel the change.
+         *
+         * Usage example showing how to remove the red triangle (dirty record indicator) from some records (not all). By
+         * observing the grid's validateedit event, it can be cancelled if the edit occurs on a targeted row (for
+         * example) and then setting the field's new value in the Record directly:
+         *
+         *     grid.on('validateedit', function(editor, e) {
+         *       var myTargetRow = 6;
+         *
+         *       if (e.row == myTargetRow) {
+         *         e.cancel = true;
+         *         e.record.data[e.field] = e.value;
+         *       }
+         *     });
+         *
          * @param {Ext.grid.plugin.Editing} editor
-         * @param {Object} e An edit event (see above for description)
+         * @param {Object} e An edit event with the following properties:
+         *
+         * - grid - The grid
+         * - record - The record being edited
+         * - field - The field name being edited
+         * - value - The value being set
+         * - originalValue - The original value for the field, before the edit.
+         * - row - The grid table row
+         * - column - The grid {@link Ext.grid.column.Column Column} defining the column that is being edited.
+         * - rowIdx - The row index that is being edited
+         * - colIdx - The column index that is being edited
+         * - cancel - Set this to true to cancel the edit or return false from your handler.
          */
         this.callParent(arguments);
         this.editors = Ext.create('Ext.util.MixedCollection', false, function(editor) {
             return editor.editorId;
         });
+        this.editTask = Ext.create('Ext.util.DelayedTask');
+    },
+    
+    onReconfigure: function(){
+        this.editors.clear();
+        this.callParent();    
     },
 
-<span id='Ext-grid.plugin.CellEditing-method-destroy'>    /**
+<span id='Ext-grid-plugin-CellEditing-method-destroy'>    /**
 </span>     * @private
      * AbstractComponent calls destroy on all its plugins at destroy time.
      */
     destroy: function() {
         var me = this;
+        me.editTask.cancel();
         me.editors.each(Ext.destroy, Ext);
         me.editors.clear();
         me.callParent(arguments);
     },
+    
+    onBodyScroll: function() {
+        var ed = this.getActiveEditor();
+        if (ed &amp;&amp; ed.field) {
+            if (ed.field.triggerBlur) {
+                ed.field.triggerBlur();
+            } else {
+                ed.field.blur();
+            }
+        }
+    },
 
     // private
     // Template method called from base class's initEvents
     initCancelTriggers: function() {
-        var me   = this;
+        var me   = this,
             grid = me.grid,
-            view   = grid.view;
-
-        me.mon(view, {
-            mousewheel: {
-                element: 'el',
-                fn: me.cancelEdit,
-                scope: me
-            }
-        });
+            view = grid.view;
+            
+        view.addElListener('mousewheel', me.cancelEdit, me);
+        me.mon(view, 'bodyscroll', me.onBodyScroll, me);
         me.mon(grid, {
             columnresize: me.cancelEdit,
             columnmove: me.cancelEdit,
@@ -179,17 +197,16 @@ grid.on('validateedit', function(e) {
         });
     },
 
-<span id='Ext-grid.plugin.CellEditing-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.
-     * @override
+<span id='Ext-grid-plugin-CellEditing-method-startEdit'>    /**
+</span>     * Starts editing the specified record, using the specified Column definition to define which field is being edited.
+     * @param {Ext.data.Model} record The Store data record which backs the row to be edited.
+     * @param {Ext.data.Model} columnHeader The Column object defining the column to be edited. @override
      */
     startEdit: function(record, columnHeader) {
         var me = this,
-            ed   = me.getEditor(record, columnHeader),
             value = record.get(columnHeader.dataIndex),
-            context = me.getEditingContext(record, columnHeader);
+            context = me.getEditingContext(record, columnHeader),
+            ed;
 
         record = context.record;
         columnHeader = context.column;
@@ -198,30 +215,31 @@ grid.on('validateedit', function(e) {
         // cell DOM element. Completing the edit causes a view refresh.
         me.completeEdit();
 
+        context.originalValue = context.value = value;
+        if (me.beforeEdit(context) === false || me.fireEvent('beforeedit', context) === false || context.cancel) {
+            return false;
+        }
+        
         // See if the field is editable for the requested record
         if (columnHeader &amp;&amp; !columnHeader.getEditor(record)) {
             return false;
         }
-
+        
+        ed = me.getEditor(record, columnHeader);
         if (ed) {
-            context.originalValue = context.value = value;
-            if (me.beforeEdit(context) === false || me.fireEvent('beforeedit', context) === false || context.cancel) {
-                return false;
-            }
-
             me.context = context;
             me.setActiveEditor(ed);
             me.setActiveRecord(record);
             me.setActiveColumn(columnHeader);
 
             // Defer, so we have some time between view scroll to sync up the editor
-            Ext.defer(ed.startEdit, 15, ed, [me.getCell(record, columnHeader), value]);
+            me.editTask.delay(15, ed.startEdit, ed, [me.getCell(record, columnHeader), value]);
         } else {
             // BrowserBug: WebKit &amp; IE refuse to focus the element, rather
             // it will focus it and then immediately focus the body. This
             // temporary hack works for Webkit and IE6. IE7 and 8 are still
             // broken
-            me.grid.getView().el.focus((Ext.isWebKit || Ext.isIE) ? 10 : false);
+            me.grid.getView().getEl(columnHeader).focus((Ext.isWebKit || Ext.isIE) ? 10 : false);
         }
     },
 
@@ -258,8 +276,9 @@ grid.on('validateedit', function(e) {
     },
 
     getEditor: function(record, column) {
-        var editors = this.editors,
-            editorId = column.itemId || column.id,
+        var me = this,
+            editors = me.editors,
+            editorId = column.getItemId(),
             editor = editors.getByKey(editorId);
 
         if (editor) {
@@ -277,23 +296,31 @@ grid.on('validateedit', function(e) {
                     field: editor
                 });
             }
-            editor.parentEl = this.grid.getEditorParent();
+            editor.parentEl = me.grid.getEditorParent();
             // editor.parentEl should be set here.
             editor.on({
-                scope: this,
-                specialkey: this.onSpecialKey,
-                complete: this.onEditComplete,
-                canceledit: this.cancelEdit
+                scope: me,
+                specialkey: me.onSpecialKey,
+                complete: me.onEditComplete,
+                canceledit: me.cancelEdit
             });
             editors.add(editor);
             return editor;
         }
     },
+    
+    // inherit docs
+    setColumnField: function(column, field) {
+        var ed = this.editors.getByKey(column.getItemId());
+        Ext.destroy(ed, column.field);
+        this.editors.removeAtKey(column.getItemId());
+        this.callParent(arguments);
+    },
 
-<span id='Ext-grid.plugin.CellEditing-method-getCell'>    /**
-</span>     * Get the cell (td) for a particular record and column.
+<span id='Ext-grid-plugin-CellEditing-method-getCell'>    /**
+</span>     * Gets the cell (td) for a particular record and column.
      * @param {Ext.data.Model} record
-     * @param {Ext.grid.column.Colunm} column
+     * @param {Ext.grid.column.Column} column
      * @private
      */
     getCell: function(record, column) {
@@ -316,27 +343,40 @@ grid.on('validateedit', function(e) {
         var me = this,
             grid = me.grid,
             sm = grid.getSelectionModel(),
-            dataIndex = me.getActiveColumn().dataIndex;
-
-        me.setActiveEditor(null);
-        me.setActiveColumn(null);
-        me.setActiveRecord(null);
-        delete sm.wasEditing;
-
-        if (!me.validateEdit()) {
-            return;
+            activeColumn = me.getActiveColumn(),
+            dataIndex;
+
+        if (activeColumn) {
+            dataIndex = activeColumn.dataIndex;
+
+            me.setActiveEditor(null);
+            me.setActiveColumn(null);
+            me.setActiveRecord(null);
+            delete sm.wasEditing;
+    
+            if (!me.validateEdit()) {
+                return;
+            }
+            // Only update the record if the new value is different than the
+            // startValue, when the view refreshes its el will gain focus
+            if (value !== startValue) {
+                me.context.record.set(dataIndex, value);
+            // Restore focus back to the view's element.
+            } else {
+                grid.getView().getEl(activeColumn).focus();
+            }
+            me.context.value = value;
+            me.fireEvent('edit', me, me.context);
         }
-        me.context.record.set(dataIndex, value);
-        me.fireEvent('edit', me, me.context);
     },
 
-<span id='Ext-grid.plugin.CellEditing-method-cancelEdit'>    /**
-</span>     * Cancel any active editing.
+<span id='Ext-grid-plugin-CellEditing-method-cancelEdit'>    /**
+</span>     * Cancels any active editing.
      */
     cancelEdit: function() {
         var me = this,
             activeEd = me.getActiveEditor(),
-            viewEl = me.grid.getView().el;
+            viewEl = me.grid.getView().getEl(me.getActiveColumn());
 
         me.setActiveEditor(null);
         me.setActiveColumn(null);
@@ -347,7 +387,7 @@ grid.on('validateedit', function(e) {
         }
     },
 
-<span id='Ext-grid.plugin.CellEditing-method-startEditByPosition'>    /**
+<span id='Ext-grid-plugin-CellEditing-method-startEditByPosition'>    /**
 </span>     * Starts editing by position (row/column)
      * @param {Object} position A position with keys of row and column.
      */
@@ -363,4 +403,6 @@ grid.on('validateedit', function(e) {
         }
         me.startEdit(editRecord, editColumnHeader);
     }
-});</pre></pre></body></html>
\ No newline at end of file
+});</pre>
+</body>
+</html>