3 This file is part of Ext JS 4
5 Copyright (c) 2011 Sencha Inc
7 Contact: http://www.sencha.com/contact
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
16 * @class Ext.grid.plugin.RowEditing
17 * @extends Ext.grid.plugin.Editing
19 * The Ext.grid.plugin.RowEditing plugin injects editing at a row level for a Grid. When editing begins,
20 * a small floating dialog will be shown for the appropriate row. Each editable column will show a field
21 * for editing. There is a button to save or cancel all changes for the edit.
23 * The field that will be used for the editor is defined at the
24 * {@link Ext.grid.column.Column#field field}. The editor can be a field instance or a field configuration.
25 * If an editor is not specified for a particular column then that column won't be editable and the value of
26 * the column will be displayed.
28 * The editor may be shared for each column in the grid, or a different one may be specified for each column.
29 * An appropriate field type should be chosen to match the data structure that it will be editing. For example,
30 * to edit a date, it would be useful to specify {@link Ext.form.field.Date} as the editor.
32 * {@img Ext.grid.plugin.RowEditing/Ext.grid.plugin.RowEditing.png Ext.grid.plugin.RowEditing plugin}
36 * Ext.create('Ext.data.Store', {
37 * storeId:'simpsonsStore',
38 * fields:['name', 'email', 'phone'],
40 * {"name":"Lisa", "email":"lisa@simpsons.com", "phone":"555-111-1224"},
41 * {"name":"Bart", "email":"bart@simpsons.com", "phone":"555--222-1234"},
42 * {"name":"Homer", "email":"home@simpsons.com", "phone":"555-222-1244"},
43 * {"name":"Marge", "email":"marge@simpsons.com", "phone":"555-222-1254"}
54 * Ext.create('Ext.grid.Panel', {
56 * store: Ext.data.StoreManager.lookup('simpsonsStore'),
58 * {header: 'Name', dataIndex: 'name', field: 'textfield'},
59 * {header: 'Email', dataIndex: 'email', flex:1,
65 * {header: 'Phone', dataIndex: 'phone'}
67 * selType: 'rowmodel',
69 * Ext.create('Ext.grid.plugin.RowEditing', {
75 * renderTo: Ext.getBody()
78 Ext.define('Ext.grid.plugin.RowEditing', {
79 extend: 'Ext.grid.plugin.Editing',
80 alias: 'plugin.rowediting',
89 * @cfg {Boolean} autoCancel
90 * `true` to automatically cancel any pending changes when the row editor begins editing a new row.
91 * `false` to force the user to explicitly cancel the pending changes. Defaults to `true`.
97 * @cfg {Number} clicksToMoveEditor
98 * The number of clicks to move the row editor to a new row while it is visible and actively editing another row.
99 * This will default to the same value as {@link Ext.grid.plugin.Editing#clicksToEdit clicksToEdit}.
104 * @cfg {Boolean} errorSummary
105 * `true` to show a {@link Ext.tip.ToolTip tooltip} that summarizes all validation errors present
106 * in the row editor. Set to `false` to prevent the tooltip from showing. Defaults to `true`.
113 * Fires before row editing is triggered. The edit event object has the following properties <br />
114 * <ul style="padding:5px;padding-left:16px;">
115 * <li>grid - The grid this editor is on</li>
116 * <li>view - The grid view</li>
117 * <li>store - The grid store</li>
118 * <li>record - The record being edited</li>
119 * <li>row - The grid table row</li>
120 * <li>column - The grid {@link Ext.grid.column.Column Column} defining the column that initiated the edit</li>
121 * <li>rowIdx - The row index that is being edited</li>
122 * <li>colIdx - The column index that initiated the edit</li>
123 * <li>cancel - Set this to true to cancel the edit or return false from your handler.</li>
125 * @param {Ext.grid.plugin.Editing} editor
126 * @param {Object} e An edit event (see above for description)
130 * Fires after a row is edited. The edit event object has the following properties <br />
131 * <ul style="padding:5px;padding-left:16px;">
132 * <li>grid - The grid this editor is on</li>
133 * <li>view - The grid view</li>
134 * <li>store - The grid store</li>
135 * <li>record - The record being edited</li>
136 * <li>row - The grid table row</li>
137 * <li>column - The grid {@link Ext.grid.column.Column Column} defining the column that initiated the edit</li>
138 * <li>rowIdx - The row index that is being edited</li>
139 * <li>colIdx - The column index that initiated the edit</li>
143 grid.on('edit', onEdit, this);
146 // execute an XHR to send/commit data to the server, in callback do (if successful):
150 * @param {Ext.grid.plugin.Editing} editor
151 * @param {Object} e An edit event (see above for description)
154 * @event validateedit
155 * Fires after a cell is edited, but before the value is set in the record. Return false
156 * to cancel the change. The edit event object has the following properties <br />
157 * <ul style="padding:5px;padding-left:16px;">
158 * <li>grid - The grid this editor is on</li>
159 * <li>view - The grid view</li>
160 * <li>store - The grid store</li>
161 * <li>record - The record being edited</li>
162 * <li>row - The grid table row</li>
163 * <li>column - The grid {@link Ext.grid.column.Column Column} defining the column that initiated the edit</li>
164 * <li>rowIdx - The row index that is being edited</li>
165 * <li>colIdx - The column index that initiated the edit</li>
166 * <li>cancel - Set this to true to cancel the edit or return false from your handler.</li>
168 * Usage example showing how to remove the red triangle (dirty record indicator) from some
169 * records (not all). By observing the grid's validateedit event, it can be cancelled if
170 * the edit occurs on a targeted row (for example) and then setting the field's new value
171 * in the Record directly:
173 grid.on('validateedit', function(e) {
176 if (e.rowIdx == myTargetRow) {
178 e.record.data[e.field] = e.value;
182 * @param {Ext.grid.plugin.Editing} editor
183 * @param {Object} e An edit event (see above for description)
186 constructor: function() {
188 me.callParent(arguments);
190 if (!me.clicksToMoveEditor) {
191 me.clicksToMoveEditor = me.clicksToEdit;
194 me.autoCancel = !!me.autoCancel;
199 * AbstractComponent calls destroy on all its plugins at destroy time.
201 destroy: function() {
203 Ext.destroy(me.editor);
204 me.callParent(arguments);
208 * Start editing the specified record, using the specified Column definition to define which field is being edited.
209 * @param {Model} record The Store data record which backs the row to be edited.
210 * @param {Model} columnHeader The Column object defining the column to be edited.
213 startEdit: function(record, columnHeader) {
215 editor = me.getEditor();
217 if (me.callParent(arguments) === false) {
221 // Fire off our editor
222 if (editor.beforeEdit() !== false) {
223 editor.startEdit(me.context.record, me.context.column);
228 cancelEdit: function() {
232 me.getEditor().cancelEdit();
233 me.callParent(arguments);
238 completeEdit: function() {
241 if (me.editing && me.validateEdit()) {
243 me.fireEvent('edit', me.context);
248 validateEdit: function() {
250 return me.callParent(arguments) && me.getEditor().completeEdit();
254 getEditor: function() {
258 me.editor = me.initEditor();
264 initEditor: function() {
268 headerCt = grid.headerCt;
270 return Ext.create('Ext.grid.RowEditor', {
271 autoCancel: me.autoCancel,
272 errorSummary: me.errorSummary,
273 fields: headerCt.getGridColumns(),
276 // keep a reference..
283 initEditTriggers: function() {
287 headerCt = grid.headerCt,
288 moveEditorEvent = me.clicksToMoveEditor === 1 ? 'click' : 'dblclick';
290 me.callParent(arguments);
292 if (me.clicksToMoveEditor !== me.clicksToEdit) {
293 me.mon(view, 'cell' + moveEditorEvent, me.moveEditorByClick, me);
296 view.on('render', function() {
300 remove: me.onColumnRemove,
301 columnresize: me.onColumnResize,
302 columnhide: me.onColumnHide,
303 columnshow: me.onColumnShow,
304 columnmove: me.onColumnMove,
307 }, me, { single: true });
310 startEditByClick: function() {
312 if (!me.editing || me.clicksToMoveEditor === me.clicksToEdit) {
313 me.callParent(arguments);
317 moveEditorByClick: function() {
320 me.superclass.startEditByClick.apply(me, arguments);
325 onColumnAdd: function(ct, column) {
326 if (column.isHeader) {
330 me.initFieldAccessors(column);
331 editor = me.getEditor();
333 if (editor && editor.onColumnAdd) {
334 editor.onColumnAdd(column);
340 onColumnRemove: function(ct, column) {
341 if (column.isHeader) {
343 editor = me.getEditor();
345 if (editor && editor.onColumnRemove) {
346 editor.onColumnRemove(column);
348 me.removeFieldAccessors(column);
353 onColumnResize: function(ct, column, width) {
354 if (column.isHeader) {
356 editor = me.getEditor();
358 if (editor && editor.onColumnResize) {
359 editor.onColumnResize(column, width);
365 onColumnHide: function(ct, column) {
366 // no isHeader check here since its already a columnhide event.
368 editor = me.getEditor();
370 if (editor && editor.onColumnHide) {
371 editor.onColumnHide(column);
376 onColumnShow: function(ct, column) {
377 // no isHeader check here since its already a columnshow event.
379 editor = me.getEditor();
381 if (editor && editor.onColumnShow) {
382 editor.onColumnShow(column);
387 onColumnMove: function(ct, column, fromIdx, toIdx) {
388 // no isHeader check here since its already a columnmove event.
390 editor = me.getEditor();
392 if (editor && editor.onColumnMove) {
393 editor.onColumnMove(column, fromIdx, toIdx);
398 setColumnField: function(column, field) {
400 me.callParent(arguments);
401 me.getEditor().setField(column.field, column);