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; }
11 <script type="text/javascript">
12 function highlight() {
13 document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
17 <body onload="prettyPrint(); highlight();">
18 <pre class="prettyprint lang-js"><span id='Ext-grid-plugin-CellEditing'>/**
19 </span> * @class Ext.grid.plugin.CellEditing
20 * @extends Ext.grid.plugin.Editing
22 * The Ext.grid.plugin.CellEditing plugin injects editing at a cell level for a Grid. Only a single
23 * cell will be editable at a time. 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.
26 * If an editor is not specified for a particular column then that cell will not be editable and it will
27 * be skipped when activated via the mouse or the keyboard.
29 * The editor may be shared for each column in the grid, or a different one may be specified for each column.
30 * An appropriate field type should be chosen to match the data structure that it will be editing. For example,
31 * to edit a date, it would be useful to specify {@link Ext.form.field.Date} as the editor.
33 * {@img Ext.grid.plugin.CellEditing/Ext.grid.plugin.CellEditing.png Ext.grid.plugin.CellEditing plugin}
37 * Ext.create('Ext.data.Store', {
38 * storeId:'simpsonsStore',
39 * fields:['name', 'email', 'phone'],
41 * {"name":"Lisa", "email":"lisa@simpsons.com", "phone":"555-111-1224"},
42 * {"name":"Bart", "email":"bart@simpsons.com", "phone":"555--222-1234"},
43 * {"name":"Homer", "email":"home@simpsons.com", "phone":"555-222-1244"},
44 * {"name":"Marge", "email":"marge@simpsons.com", "phone":"555-222-1254"}
55 * Ext.create('Ext.grid.Panel', {
57 * store: Ext.data.StoreManager.lookup('simpsonsStore'),
59 * {header: 'Name', dataIndex: 'name', field: 'textfield'},
60 * {header: 'Email', dataIndex: 'email', flex:1,
66 * {header: 'Phone', dataIndex: 'phone'}
68 * selType: 'cellmodel',
70 * Ext.create('Ext.grid.plugin.CellEditing', {
76 * renderTo: Ext.getBody()
79 Ext.define('Ext.grid.plugin.CellEditing', {
80 alias: 'plugin.cellediting',
81 extend: 'Ext.grid.plugin.Editing',
82 requires: ['Ext.grid.CellEditor', 'Ext.util.DelayedTask'],
84 constructor: function() {
85 <span id='Ext-grid-plugin-CellEditing-event-beforeedit'> /**
86 </span> * @event beforeedit
87 * Fires before cell editing is triggered. The edit event object has the following properties <br />
88 * <ul style="padding:5px;padding-left:16px;">
89 * <li>grid - The grid</li>
90 * <li>record - The record being edited</li>
91 * <li>field - The field name being edited</li>
92 * <li>value - The value for the field being edited.</li>
93 * <li>row - The grid table row</li>
94 * <li>column - The grid {@link Ext.grid.column.Column Column} defining the column that is being edited.</li>
95 * <li>rowIdx - The row index that is being edited</li>
96 * <li>colIdx - The column index that is being edited</li>
97 * <li>cancel - Set this to true to cancel the edit or return false from your handler.</li>
99 * @param {Ext.grid.plugin.Editing} editor
100 * @param {Object} e An edit event (see above for description)
102 <span id='Ext-grid-plugin-CellEditing-event-edit'> /**
103 </span> * @event edit
104 * Fires after a cell is edited. The edit event object has the following properties <br />
105 * <ul style="padding:5px;padding-left:16px;">
106 * <li>grid - The grid</li>
107 * <li>record - The record that was edited</li>
108 * <li>field - The field name that was edited</li>
109 * <li>value - The value being set</li>
110 * <li>originalValue - The original value for the field, before the edit.</li>
111 * <li>row - The grid table row</li>
112 * <li>column - The grid {@link Ext.grid.column.Column Column} defining the column that was edited.</li>
113 * <li>rowIdx - The row index that was edited</li>
114 * <li>colIdx - The column index that was edited</li>
117 * <pre><code>
118 grid.on('edit', onEdit, this);
121 // execute an XHR to send/commit data to the server, in callback do (if successful):
124 * </code></pre>
125 * @param {Ext.grid.plugin.Editing} editor
126 * @param {Object} e An edit event (see above for description)
128 <span id='Ext-grid-plugin-CellEditing-event-validateedit'> /**
129 </span> * @event validateedit
130 * Fires after a cell is edited, but before the value is set in the record. Return false
131 * to cancel the change. The edit event object has the following properties <br />
132 * <ul style="padding:5px;padding-left:16px;">
133 * <li>grid - The grid</li>
134 * <li>record - The record being edited</li>
135 * <li>field - The field name being edited</li>
136 * <li>value - The value being set</li>
137 * <li>originalValue - The original value for the field, before the edit.</li>
138 * <li>row - The grid table row</li>
139 * <li>column - The grid {@link Ext.grid.column.Column Column} defining the column that is being edited.</li>
140 * <li>rowIdx - The row index that is being edited</li>
141 * <li>colIdx - The column index that is being edited</li>
142 * <li>cancel - Set this to true to cancel the edit or return false from your handler.</li>
144 * Usage example showing how to remove the red triangle (dirty record indicator) from some
145 * records (not all). By observing the grid's validateedit event, it can be cancelled if
146 * the edit occurs on a targeted row (for example) and then setting the field's new value
147 * in the Record directly:
148 * <pre><code>
149 grid.on('validateedit', function(e) {
152 if (e.row == myTargetRow) {
154 e.record.data[e.field] = e.value;
157 * </code></pre>
158 * @param {Ext.grid.plugin.Editing} editor
159 * @param {Object} e An edit event (see above for description)
161 this.callParent(arguments);
162 this.editors = Ext.create('Ext.util.MixedCollection', false, function(editor) {
163 return editor.editorId;
165 this.editTask = Ext.create('Ext.util.DelayedTask');
168 onReconfigure: function(){
169 this.editors.clear();
173 <span id='Ext-grid-plugin-CellEditing-method-destroy'> /**
175 * AbstractComponent calls destroy on all its plugins at destroy time.
177 destroy: function() {
179 me.editTask.cancel();
180 me.editors.each(Ext.destroy, Ext);
182 me.callParent(arguments);
185 onBodyScroll: function() {
186 var ed = this.getActiveEditor();
187 if (ed && ed.field) {
188 if (ed.field.triggerBlur) {
189 ed.field.triggerBlur();
197 // Template method called from base class's initEvents
198 initCancelTriggers: function() {
203 view.addElListener('mousewheel', me.cancelEdit, me);
204 me.mon(view, 'bodyscroll', me.onBodyScroll, me);
206 columnresize: me.cancelEdit,
207 columnmove: me.cancelEdit,
212 <span id='Ext-grid-plugin-CellEditing-method-startEdit'> /**
213 </span> * Start editing the specified record, using the specified Column definition to define which field is being edited.
214 * @param {Model} record The Store data record which backs the row to be edited.
215 * @param {Model} columnHeader The Column object defining the column to be edited.
218 startEdit: function(record, columnHeader) {
220 ed = me.getEditor(record, columnHeader),
221 value = record.get(columnHeader.dataIndex),
222 context = me.getEditingContext(record, columnHeader);
224 record = context.record;
225 columnHeader = context.column;
227 // Complete the edit now, before getting the editor's target
228 // cell DOM element. Completing the edit causes a view refresh.
231 // See if the field is editable for the requested record
232 if (columnHeader && !columnHeader.getEditor(record)) {
237 context.originalValue = context.value = value;
238 if (me.beforeEdit(context) === false || me.fireEvent('beforeedit', context) === false || context.cancel) {
242 me.context = context;
243 me.setActiveEditor(ed);
244 me.setActiveRecord(record);
245 me.setActiveColumn(columnHeader);
247 // Defer, so we have some time between view scroll to sync up the editor
248 me.editTask.delay(15, ed.startEdit, ed, [me.getCell(record, columnHeader), value]);
250 // BrowserBug: WebKit & IE refuse to focus the element, rather
251 // it will focus it and then immediately focus the body. This
252 // temporary hack works for Webkit and IE6. IE7 and 8 are still
254 me.grid.getView().getEl(columnHeader).focus((Ext.isWebKit || Ext.isIE) ? 10 : false);
258 completeEdit: function() {
259 var activeEd = this.getActiveEditor();
261 activeEd.completeEdit();
265 // internal getters/setters
266 setActiveEditor: function(ed) {
267 this.activeEditor = ed;
270 getActiveEditor: function() {
271 return this.activeEditor;
274 setActiveColumn: function(column) {
275 this.activeColumn = column;
278 getActiveColumn: function() {
279 return this.activeColumn;
282 setActiveRecord: function(record) {
283 this.activeRecord = record;
286 getActiveRecord: function() {
287 return this.activeRecord;
290 getEditor: function(record, column) {
292 editors = me.editors,
293 editorId = column.getItemId(),
294 editor = editors.getByKey(editorId);
299 editor = column.getEditor(record);
304 // Allow them to specify a CellEditor in the Column
305 if (!(editor instanceof Ext.grid.CellEditor)) {
306 editor = Ext.create('Ext.grid.CellEditor', {
311 editor.parentEl = me.grid.getEditorParent();
312 // editor.parentEl should be set here.
315 specialkey: me.onSpecialKey,
316 complete: me.onEditComplete,
317 canceledit: me.cancelEdit
324 <span id='Ext-grid-plugin-CellEditing-method-getCell'> /**
325 </span> * Get the cell (td) for a particular record and column.
326 * @param {Ext.data.Model} record
327 * @param {Ext.grid.column.Colunm} column
330 getCell: function(record, column) {
331 return this.grid.getView().getCell(record, column);
334 onSpecialKey: function(ed, field, e) {
335 var grid = this.grid,
337 if (e.getKey() === e.TAB) {
339 sm = grid.getSelectionModel();
340 if (sm.onEditorTab) {
341 sm.onEditorTab(this, e);
346 onEditComplete : function(ed, value, startValue) {
349 sm = grid.getSelectionModel(),
350 activeColumn = me.getActiveColumn(),
354 dataIndex = activeColumn.dataIndex;
356 me.setActiveEditor(null);
357 me.setActiveColumn(null);
358 me.setActiveRecord(null);
359 delete sm.wasEditing;
361 if (!me.validateEdit()) {
364 // Only update the record if the new value is different than the
365 // startValue, when the view refreshes its el will gain focus
366 if (value !== startValue) {
367 me.context.record.set(dataIndex, value);
368 // Restore focus back to the view's element.
370 grid.getView().getEl(activeColumn).focus();
372 me.context.value = value;
373 me.fireEvent('edit', me, me.context);
379 <span id='Ext-grid-plugin-CellEditing-method-cancelEdit'> /**
380 </span> * Cancel any active editing.
382 cancelEdit: function() {
384 activeEd = me.getActiveEditor(),
385 viewEl = me.grid.getView().getEl(me.getActiveColumn());
387 me.setActiveEditor(null);
388 me.setActiveColumn(null);
389 me.setActiveRecord(null);
391 activeEd.cancelEdit();
396 <span id='Ext-grid-plugin-CellEditing-method-startEditByPosition'> /**
397 </span> * Starts editing by position (row/column)
398 * @param {Object} position A position with keys of row and column.
400 startEditByPosition: function(position) {
403 sm = grid.getSelectionModel(),
404 editRecord = grid.store.getAt(position.row),
405 editColumnHeader = grid.headerCt.getHeaderAtIndex(position.column);
407 if (sm.selectByPosition) {
408 sm.selectByPosition(position);
410 me.startEdit(editRecord, editColumnHeader);