EditorGrid_wev8.js
11.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
/*!
* Ext JS Library 3.0.0
* Copyright(c) 2006-2009 Ext JS, LLC
* licensing@extjs.com
* http://www.extjs.com/license
*/
/**
* @class Ext.grid.EditorGridPanel
* @extends Ext.grid.GridPanel
* <p>This class extends the {@link Ext.grid.GridPanel GridPanel Class} to provide cell editing
* on selected {@link Ext.grid.Column columns}. The editable columns are specified by providing
* an {@link Ext.grid.ColumnModel#editor editor} in the {@link Ext.grid.Column column configuration}.</p>
* <p>Editability of columns may be controlled programatically by inserting an implementation
* of {@link Ext.grid.ColumnModel#isCellEditable isCellEditable} into the
* {@link Ext.grid.ColumnModel ColumnModel}.</p>
* <p>Editing is performed on the value of the <i>field</i> specified by the column's
* <tt>{@link Ext.grid.ColumnModel#dataIndex dataIndex}</tt> in the backing {@link Ext.data.Store Store}
* (so if you are using a {@link Ext.grid.ColumnModel#setRenderer renderer} in order to display
* transformed data, this must be accounted for).</p>
* <p>If a value-to-description mapping is used to render a column, then a {@link Ext.form.Field#ComboBox ComboBox}
* which uses the same {@link Ext.form.Field#valueField value}-to-{@link Ext.form.Field#displayFieldField description}
* mapping would be an appropriate editor.</p>
* If there is a more complex mismatch between the visible data in the grid, and the editable data in
* the {@link Edt.data.Store Store}, then code to transform the data both before and after editing can be
* injected using the {@link #beforeedit} and {@link #afteredit} events.
* @constructor
* @param {Object} config The config object
* @xtype editorgrid
*/
Ext.grid.EditorGridPanel = Ext.extend(Ext.grid.GridPanel, {
/**
* @cfg {Number} clicksToEdit
* <p>The number of clicks on a cell required to display the cell's editor (defaults to 2).</p>
* <p>Setting this option to 'auto' means that mousedown <i>on the selected cell</i> starts
* editing that cell.</p>
*/
clicksToEdit: 2,
/**
* @cfg {Boolean} forceValidation
* True to force validation even if the value is unmodified (defaults to false)
*/
forceValidation: false,
// private
isEditor : true,
// private
detectEdit: false,
/**
* @cfg {Boolean} autoEncode
* True to automatically HTML encode and decode values pre and post edit (defaults to false)
*/
autoEncode : false,
/**
* @cfg {Boolean} trackMouseOver @hide
*/
// private
trackMouseOver: false, // causes very odd FF errors
// private
initComponent : function(){
Ext.grid.EditorGridPanel.superclass.initComponent.call(this);
if(!this.selModel){
/**
* @cfg {Object} selModel Any subclass of AbstractSelectionModel that will provide the selection model for
* the grid (defaults to {@link Ext.grid.CellSelectionModel} if not specified).
*/
this.selModel = new Ext.grid.CellSelectionModel();
}
this.activeEditor = null;
this.addEvents(
/**
* @event beforeedit
* Fires before cell editing is triggered. The edit event object has the following properties <br />
* <ul style="padding:5px;padding-left:16px;">
* <li>grid - This grid</li>
* <li>record - The record being edited</li>
* <li>field - The field name being edited</li>
* <li>value - The value for the field being edited.</li>
* <li>row - The grid row index</li>
* <li>column - The grid column index</li>
* <li>cancel - Set this to true to cancel the edit or return false from your handler.</li>
* </ul>
* @param {Object} e An edit event (see above for description)
*/
"beforeedit",
/**
* @event afteredit
* Fires after a cell is edited. The edit event object has the following properties <br />
* <ul style="padding:5px;padding-left:16px;">
* <li>grid - This grid</li>
* <li>record - The record being edited</li>
* <li>field - The field name being edited</li>
* <li>value - The value being set</li>
* <li>originalValue - The original value for the field, before the edit.</li>
* <li>row - The grid row index</li>
* <li>column - The grid column index</li>
* </ul>
*
* <pre><code>
grid.on('afteredit', afterEdit, this );
function afterEdit(e) {
// execute an XHR to send/commit data to the server, in callback do (if successful):
e.record.commit();
};
* </code></pre>
* @param {Object} e An edit event (see above for description)
*/
"afteredit",
/**
* @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 <br />
* <ul style="padding:5px;padding-left:16px;">
* <li>grid - This grid</li>
* <li>record - The record being edited</li>
* <li>field - The field name being edited</li>
* <li>value - The value being set</li>
* <li>originalValue - The original value for the field, before the edit.</li>
* <li>row - The grid row index</li>
* <li>column - The grid column index</li>
* <li>cancel - Set this to true to cancel the edit or return false from your handler.</li>
* </ul>
* 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:
* <pre><code>
grid.on('validateedit', function(e) {
var myTargetRow = 6;
if (e.row == myTargetRow) {
e.cancel = true;
e.record.data[e.field] = e.value;
}
});
* </code></pre>
* @param {Object} e An edit event (see above for description)
*/
"validateedit"
);
},
// private
initEvents : function(){
Ext.grid.EditorGridPanel.superclass.initEvents.call(this);
this.on("bodyscroll", this.stopEditing, this, [true]);
this.on("columnresize", this.stopEditing, this, [true]);
if(this.clicksToEdit == 1){
this.on("cellclick", this.onCellDblClick, this);
}else {
if(this.clicksToEdit == 'auto' && this.view.mainBody){
this.view.mainBody.on("mousedown", this.onAutoEditClick, this);
}
this.on("celldblclick", this.onCellDblClick, this);
}
},
// private
onCellDblClick : function(g, row, col){
this.startEditing(row, col);
},
// private
onAutoEditClick : function(e, t){
if(e.button !== 0){
return;
}
var row = this.view.findRowIndex(t);
var col = this.view.findCellIndex(t);
if(row !== false && col !== false){
this.stopEditing();
if(this.selModel.getSelectedCell){ // cell sm
var sc = this.selModel.getSelectedCell();
if(sc && sc[0] === row && sc[1] === col){
this.startEditing(row, col);
}
}else{
if(this.selModel.isSelected(row)){
this.startEditing(row, col);
}
}
}
},
// private
onEditComplete : function(ed, value, startValue){
this.editing = false;
this.activeEditor = null;
ed.un("specialkey", this.selModel.onEditorKey, this.selModel);
var r = ed.record;
var field = this.colModel.getDataIndex(ed.col);
value = this.postEditValue(value, startValue, r, field);
if(this.forceValidation === true || String(value) !== String(startValue)){
var e = {
grid: this,
record: r,
field: field,
originalValue: startValue,
value: value,
row: ed.row,
column: ed.col,
cancel:false
};
if(this.fireEvent("validateedit", e) !== false && !e.cancel && String(value) !== String(startValue)){
r.set(field, e.value);
delete e.cancel;
this.fireEvent("afteredit", e);
}
}
this.view.focusCell(ed.row, ed.col);
},
/**
* Starts editing the specified for the specified row/column
* @param {Number} rowIndex
* @param {Number} colIndex
*/
startEditing : function(row, col){
this.stopEditing();
if(this.colModel.isCellEditable(col, row)){
this.view.ensureVisible(row, col, true);
var r = this.store.getAt(row);
var field = this.colModel.getDataIndex(col);
var e = {
grid: this,
record: r,
field: field,
value: r.data[field],
row: row,
column: col,
cancel:false
};
if(this.fireEvent("beforeedit", e) !== false && !e.cancel){
this.editing = true;
var ed = this.colModel.getCellEditor(col, row);
if(!ed){
return;
}
if(!ed.rendered){
ed.render(this.view.getEditorParent(ed));
}
(function(){ // complex but required for focus issues in safari, ie and opera
ed.row = row;
ed.col = col;
ed.record = r;
ed.on("complete", this.onEditComplete, this, {single: true});
ed.on("specialkey", this.selModel.onEditorKey, this.selModel);
/**
* The currently active editor or null
* @type Ext.Editor
*/
this.activeEditor = ed;
var v = this.preEditValue(r, field);
ed.startEdit(this.view.getCell(row, col).firstChild, v === undefined ? '' : v);
}).defer(50, this);
}
}
},
// private
preEditValue : function(r, field){
var value = r.data[field];
return this.autoEncode && typeof value == 'string' ? Ext.util.Format.htmlDecode(value) : value;
},
// private
postEditValue : function(value, originalValue, r, field){
return this.autoEncode && typeof value == 'string' ? Ext.util.Format.htmlEncode(value) : value;
},
/**
* Stops any active editing
* @param {Boolean} cancel (optional) True to cancel any changes
*/
stopEditing : function(cancel){
if(this.activeEditor){
this.activeEditor[cancel === true ? 'cancelEdit' : 'completeEdit']();
}
this.activeEditor = null;
}
});
Ext.reg('editorgrid', Ext.grid.EditorGridPanel);