Upgrade to ExtJS 4.0.1 - Released 05/18/2011
[extjs.git] / docs / source / RowEditing.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5   <title>The source code</title>
6   <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
7   <script type="text/javascript" src="../prettify/prettify.js"></script>
8   <style type="text/css">
9     .highlight { display: block; background-color: #ddd; }
10   </style>
11   <script type="text/javascript">
12     function highlight() {
13       document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
14     }
15   </script>
16 </head>
17 <body onload="prettyPrint(); highlight();">
18   <pre class="prettyprint lang-js"><span id='Ext-grid-plugin-RowEditing'>/**
19 </span> * @class Ext.grid.plugin.RowEditing
20  * @extends Ext.grid.plugin.Editing
21  * 
22  * The Ext.grid.plugin.RowEditing plugin injects editing at a row level for a Grid. When editing begins,
23  * a small floating dialog will be shown for the appropriate row. Each editable column will show a field
24  * for editing. There is a button to save or cancel all changes for the edit.
25  * 
26  * The field that will be used for the editor is defined at the
27  * {@link Ext.grid.column.Column#field field}. The editor can be a field instance or a field configuration.
28  * If an editor is not specified for a particular column then that column won't be editable and the value of
29  * the column will be displayed.
30  *
31  * The editor may be shared for each column in the grid, or a different one may be specified for each column.
32  * An appropriate field type should be chosen to match the data structure that it will be editing. For example,
33  * to edit a date, it would be useful to specify {@link Ext.form.field.Date} as the editor.
34  * 
35  * {@img Ext.grid.plugin.RowEditing/Ext.grid.plugin.RowEditing.png Ext.grid.plugin.RowEditing plugin}
36  *
37  * ## Example Usage
38  *
39  *     Ext.create('Ext.data.Store', {
40  *         storeId:'simpsonsStore',
41  *         fields:['name', 'email', 'phone'],
42  *         data:{'items':[
43  *             {&quot;name&quot;:&quot;Lisa&quot;, &quot;email&quot;:&quot;lisa@simpsons.com&quot;, &quot;phone&quot;:&quot;555-111-1224&quot;},
44  *             {&quot;name&quot;:&quot;Bart&quot;, &quot;email&quot;:&quot;bart@simpsons.com&quot;, &quot;phone&quot;:&quot;555--222-1234&quot;},
45  *             {&quot;name&quot;:&quot;Homer&quot;, &quot;email&quot;:&quot;home@simpsons.com&quot;, &quot;phone&quot;:&quot;555-222-1244&quot;},                        
46  *             {&quot;name&quot;:&quot;Marge&quot;, &quot;email&quot;:&quot;marge@simpsons.com&quot;, &quot;phone&quot;:&quot;555-222-1254&quot;}            
47  *         ]},
48  *         proxy: {
49  *             type: 'memory',
50  *             reader: {
51  *                 type: 'json',
52  *                 root: 'items'
53  *             }
54  *         }
55  *     });
56  *     
57  *     Ext.create('Ext.grid.Panel', {
58  *         title: 'Simpsons',
59  *         store: Ext.data.StoreManager.lookup('simpsonsStore'),
60  *         columns: [
61  *             {header: 'Name',  dataIndex: 'name', field: 'textfield'},
62  *             {header: 'Email', dataIndex: 'email', flex:1, 
63  *                 editor: {
64  *                     xtype:'textfield',
65  *                     allowBlank:false
66  *                 }
67  *             },
68  *             {header: 'Phone', dataIndex: 'phone'}
69  *         ],
70  *         selType: 'rowmodel',
71  *         plugins: [
72  *             Ext.create('Ext.grid.plugin.RowEditing', {
73  *                 clicksToEdit: 1
74  *             })
75  *         ],
76  *         height: 200,
77  *         width: 400,
78  *         renderTo: Ext.getBody()
79  *     });
80  */
81 Ext.define('Ext.grid.plugin.RowEditing', {
82     extend: 'Ext.grid.plugin.Editing',
83     alias: 'plugin.rowediting',
84
85     requires: [
86         'Ext.grid.RowEditor'
87     ],
88
89     editStyle: 'row',
90
91 <span id='Ext-grid-plugin-RowEditing-cfg-autoCancel'>    /**
92 </span>     * @cfg {Boolean} autoCancel
93      * `true` to automatically cancel any pending changes when the row editor begins editing a new row.
94      * `false` to force the user to explicitly cancel the pending changes. Defaults to `true`.
95      * @markdown
96      */
97     autoCancel: true,
98
99 <span id='Ext-grid-plugin-RowEditing-cfg-clicksToMoveEditor'>    /**
100 </span>     * @cfg {Number} clicksToMoveEditor
101      * The number of clicks to move the row editor to a new row while it is visible and actively editing another row.
102      * This will default to the same value as {@link Ext.grid.plugin.Editing#clicksToEdit clicksToEdit}.
103      * @markdown
104      */
105
106 <span id='Ext-grid-plugin-RowEditing-cfg-errorSummary'>    /**
107 </span>     * @cfg {Boolean} errorSummary
108      * `true` to show a {@link Ext.tip.ToolTip tooltip} that summarizes all validation errors present
109      * in the row editor. Set to `false` to prevent the tooltip from showing. Defaults to `true`.
110      * @markdown
111      */
112     errorSummary: true,
113
114 <span id='Ext-grid-plugin-RowEditing-event-beforeedit'>    /**
115 </span>     * @event beforeedit
116      * Fires before row editing is triggered. The edit event object has the following properties &lt;br /&gt;
117      * &lt;ul style=&quot;padding:5px;padding-left:16px;&quot;&gt;
118      * &lt;li&gt;grid - The grid this editor is on&lt;/li&gt;
119      * &lt;li&gt;view - The grid view&lt;/li&gt;
120      * &lt;li&gt;store - The grid store&lt;/li&gt;
121      * &lt;li&gt;record - The record being edited&lt;/li&gt;
122      * &lt;li&gt;row - The grid table row&lt;/li&gt;
123      * &lt;li&gt;column - The grid {@link Ext.grid.column.Column Column} defining the column that initiated the edit&lt;/li&gt;
124      * &lt;li&gt;rowIdx - The row index that is being edited&lt;/li&gt;
125      * &lt;li&gt;colIdx - The column index that initiated the edit&lt;/li&gt;
126      * &lt;li&gt;cancel - Set this to true to cancel the edit or return false from your handler.&lt;/li&gt;
127      * &lt;/ul&gt;
128      * @param {Ext.grid.plugin.Editing} editor
129      * @param {Object} e An edit event (see above for description)
130      */
131 <span id='Ext-grid-plugin-RowEditing-event-edit'>    /**
132 </span>     * @event edit
133      * Fires after a row is edited. The edit event object has the following properties &lt;br /&gt;
134      * &lt;ul style=&quot;padding:5px;padding-left:16px;&quot;&gt;
135      * &lt;li&gt;grid - The grid this editor is on&lt;/li&gt;
136      * &lt;li&gt;view - The grid view&lt;/li&gt;
137      * &lt;li&gt;store - The grid store&lt;/li&gt;
138      * &lt;li&gt;record - The record being edited&lt;/li&gt;
139      * &lt;li&gt;row - The grid table row&lt;/li&gt;
140      * &lt;li&gt;column - The grid {@link Ext.grid.column.Column Column} defining the column that initiated the edit&lt;/li&gt;
141      * &lt;li&gt;rowIdx - The row index that is being edited&lt;/li&gt;
142      * &lt;li&gt;colIdx - The column index that initiated the edit&lt;/li&gt;
143      * &lt;/ul&gt;
144      *
145      * &lt;pre&gt;&lt;code&gt;
146 grid.on('edit', onEdit, this);
147
148 function onEdit(e) {
149     // execute an XHR to send/commit data to the server, in callback do (if successful):
150     e.record.commit();
151 };
152      * &lt;/code&gt;&lt;/pre&gt;
153      * @param {Ext.grid.plugin.Editing} editor
154      * @param {Object} e An edit event (see above for description)
155      */
156 <span id='Ext-grid-plugin-RowEditing-event-validateedit'>    /**
157 </span>     * @event validateedit
158      * Fires after a cell is edited, but before the value is set in the record. Return false
159      * to cancel the change. The edit event object has the following properties &lt;br /&gt;
160      * &lt;ul style=&quot;padding:5px;padding-left:16px;&quot;&gt;
161      * &lt;li&gt;grid - The grid this editor is on&lt;/li&gt;
162      * &lt;li&gt;view - The grid view&lt;/li&gt;
163      * &lt;li&gt;store - The grid store&lt;/li&gt;
164      * &lt;li&gt;record - The record being edited&lt;/li&gt;
165      * &lt;li&gt;row - The grid table row&lt;/li&gt;
166      * &lt;li&gt;column - The grid {@link Ext.grid.column.Column Column} defining the column that initiated the edit&lt;/li&gt;
167      * &lt;li&gt;rowIdx - The row index that is being edited&lt;/li&gt;
168      * &lt;li&gt;colIdx - The column index that initiated the edit&lt;/li&gt;
169      * &lt;li&gt;cancel - Set this to true to cancel the edit or return false from your handler.&lt;/li&gt;
170      * &lt;/ul&gt;
171      * Usage example showing how to remove the red triangle (dirty record indicator) from some
172      * records (not all).  By observing the grid's validateedit event, it can be cancelled if
173      * the edit occurs on a targeted row (for example) and then setting the field's new value
174      * in the Record directly:
175      * &lt;pre&gt;&lt;code&gt;
176 grid.on('validateedit', function(e) {
177   var myTargetRow = 6;
178
179   if (e.rowIdx == myTargetRow) {
180     e.cancel = true;
181     e.record.data[e.field] = e.value;
182   }
183 });
184      * &lt;/code&gt;&lt;/pre&gt;
185      * @param {Ext.grid.plugin.Editing} editor
186      * @param {Object} e An edit event (see above for description)
187      */
188
189     constructor: function() {
190         var me = this;
191         me.callParent(arguments);
192
193         if (!me.clicksToMoveEditor) {
194             me.clicksToMoveEditor = me.clicksToEdit;
195         }
196
197         me.autoCancel = !!me.autoCancel;
198     },
199
200 <span id='Ext-grid-plugin-RowEditing-method-destroy'>    /**
201 </span>     * @private
202      * AbstractComponent calls destroy on all its plugins at destroy time.
203      */
204     destroy: function() {
205         var me = this;
206         Ext.destroy(me.editor);
207         me.callParent(arguments);
208     },
209
210 <span id='Ext-grid-plugin-RowEditing-method-startEdit'>    /**
211 </span>     * Start editing the specified record, using the specified Column definition to define which field is being edited.
212      * @param {Model} record The Store data record which backs the row to be edited.
213      * @param {Model} columnHeader The Column object defining the column to be edited.
214      * @override
215      */
216     startEdit: function(record, columnHeader) {
217         var me = this,
218             editor = me.getEditor();
219
220         if (me.callParent(arguments) === false) {
221             return false;
222         }
223
224         // Fire off our editor
225         if (editor.beforeEdit() !== false) {
226             editor.startEdit(me.context.record, me.context.column);
227         }
228     },
229
230     // private
231     cancelEdit: function() {
232         var me = this;
233
234         if (me.editing) {
235             me.getEditor().cancelEdit();
236             me.callParent(arguments);
237         }
238     },
239
240     // private
241     completeEdit: function() {
242         var me = this;
243
244         if (me.editing &amp;&amp; me.validateEdit()) {
245             me.editing = false;
246             me.fireEvent('edit', me.context);
247         }
248     },
249
250     // private
251     validateEdit: function() {
252         var me = this;
253         return me.callParent(arguments) &amp;&amp; me.getEditor().completeEdit();
254     },
255
256     // private
257     getEditor: function() {
258         var me = this;
259
260         if (!me.editor) {
261             me.editor = me.initEditor();
262         }
263         return me.editor;
264     },
265
266     // private
267     initEditor: function() {
268         var me = this,
269             grid = me.grid,
270             view = me.view,
271             headerCt = grid.headerCt;
272
273         return Ext.create('Ext.grid.RowEditor', {
274             autoCancel: me.autoCancel,
275             errorSummary: me.errorSummary,
276             fields: headerCt.getGridColumns(),
277             hidden: true,
278
279             // keep a reference..
280             editingPlugin: me,
281             renderTo: view.el
282         });
283     },
284
285     // private
286     initEditTriggers: function() {
287         var me = this,
288             grid = me.grid,
289             view = me.view,
290             headerCt = grid.headerCt,
291             moveEditorEvent = me.clicksToMoveEditor === 1 ? 'click' : 'dblclick';
292
293         me.callParent(arguments);
294
295         if (me.clicksToMoveEditor !== me.clicksToEdit) {
296             me.mon(view, 'cell' + moveEditorEvent, me.moveEditorByClick, me);
297         }
298
299         view.on('render', function() {
300             // Column events
301             me.mon(headerCt, {
302                 add: me.onColumnAdd,
303                 remove: me.onColumnRemove,
304                 columnresize: me.onColumnResize,
305                 columnhide: me.onColumnHide,
306                 columnshow: me.onColumnShow,
307                 columnmove: me.onColumnMove,
308                 scope: me
309             });
310         }, me, { single: true });
311     },
312
313     startEditByClick: function() {
314         var me = this;
315         if (!me.editing || me.clicksToMoveEditor === me.clicksToEdit) {
316             me.callParent(arguments);
317         }
318     },
319
320     moveEditorByClick: function() {
321         var me = this;
322         if (me.editing) {
323             me.superclass.startEditByClick.apply(me, arguments);
324         }
325     },
326
327     // private
328     onColumnAdd: function(ct, column) {
329         if (column.isHeader) {
330             var me = this,
331                 editor;
332             
333             me.initFieldAccessors(column);
334             editor = me.getEditor();
335             
336             if (editor &amp;&amp; editor.onColumnAdd) {
337                 editor.onColumnAdd(column);
338             }
339         }
340     },
341
342     // private
343     onColumnRemove: function(ct, column) {
344         if (column.isHeader) {
345             var me = this,
346                 editor = me.getEditor();
347     
348             if (editor &amp;&amp; editor.onColumnRemove) {
349                 editor.onColumnRemove(column);
350             }
351             me.removeFieldAccessors(column);  
352         }
353     },
354
355     // private
356     onColumnResize: function(ct, column, width) {
357         if (column.isHeader) {
358             var me = this,
359                 editor = me.getEditor();
360     
361             if (editor &amp;&amp; editor.onColumnResize) {
362                 editor.onColumnResize(column, width);
363             }
364         }
365     },
366
367     // private
368     onColumnHide: function(ct, column) {
369         // no isHeader check here since its already a columnhide event.
370         var me = this,
371             editor = me.getEditor();
372
373         if (editor &amp;&amp; editor.onColumnHide) {
374             editor.onColumnHide(column);
375         }
376     },
377
378     // private
379     onColumnShow: function(ct, column) {
380         // no isHeader check here since its already a columnshow event.
381         var me = this,
382             editor = me.getEditor();
383
384         if (editor &amp;&amp; editor.onColumnShow) {
385             editor.onColumnShow(column);
386         }
387     },
388
389     // private
390     onColumnMove: function(ct, column, fromIdx, toIdx) {
391         // no isHeader check here since its already a columnmove event.
392         var me = this,
393             editor = me.getEditor();
394
395         if (editor &amp;&amp; editor.onColumnMove) {
396             editor.onColumnMove(column, fromIdx, toIdx);
397         }
398     },
399
400     // private
401     setColumnField: function(column, field) {
402         var me = this;
403         me.callParent(arguments);
404         me.getEditor().setField(column.field, column);
405     }
406 });</pre>
407 </body>
408 </html>