]>
Commit | Line | Data |
---|---|---|
6527f429 DM |
1 | /**\r |
2 | * The rowbody feature enhances the grid's markup to have an additional\r | |
3 | * tr -> td -> div which spans the entire width of the original row.\r | |
4 | *\r | |
5 | * This is useful to to associate additional information with a particular\r | |
6 | * record in an Ext.grid.Grid.\r | |
7 | *\r | |
8 | * Rowbodies are initially hidden unless you override {@link #getAdditionalData}.\r | |
9 | *\r | |
10 | * The events fired by RowBody are relayed to the owning \r | |
11 | * {@link Ext.view.Table grid view} (and subsequently the owning grid).\r | |
12 | *\r | |
13 | * # Example\r | |
14 | *\r | |
15 | * @example\r | |
16 | * Ext.define('Animal', {\r | |
17 | * extend: 'Ext.data.Model',\r | |
18 | * fields: ['name', 'latin', 'desc', 'lifespan']\r | |
19 | * });\r | |
20 | * \r | |
21 | * Ext.create('Ext.grid.Panel', {\r | |
22 | * width: 400,\r | |
23 | * height: 300,\r | |
24 | * renderTo: Ext.getBody(),\r | |
25 | * store: {\r | |
26 | * model: 'Animal',\r | |
27 | * data: [{\r | |
28 | * name: 'Tiger',\r | |
29 | * latin: 'Panthera tigris',\r | |
30 | * desc: 'The largest cat species, weighing up to 306 kg (670 lb).',\r | |
31 | * lifespan: '20 - 26 years (in captivity)'\r | |
32 | * }, {\r | |
33 | * name: 'Roman snail',\r | |
34 | * latin: 'Helix pomatia',\r | |
35 | * desc: 'A species of large, edible, air-breathing land snail.',\r | |
36 | * lifespan: '20 - 35 years'\r | |
37 | * }, {\r | |
38 | * name: 'Yellow-winged darter',\r | |
39 | * latin: 'Sympetrum flaveolum',\r | |
40 | * desc: 'A dragonfly found in Europe and mid and Northern China.',\r | |
41 | * lifespan: '4 - 6 weeks'\r | |
42 | * }, {\r | |
43 | * name: 'Superb Fairy-wren',\r | |
44 | * latin: 'Malurus cyaneus',\r | |
45 | * desc: 'Common and familiar across south-eastern Australia.',\r | |
46 | * lifespan: '5 - 6 years'\r | |
47 | * }]\r | |
48 | * },\r | |
49 | * columns: [{\r | |
50 | * dataIndex: 'name',\r | |
51 | * text: 'Common name',\r | |
52 | * width: 125\r | |
53 | * }, {\r | |
54 | * dataIndex: 'latin',\r | |
55 | * text: 'Scientific name',\r | |
56 | * flex: 1\r | |
57 | * }],\r | |
58 | * features: [{\r | |
59 | * ftype: 'rowbody',\r | |
60 | * getAdditionalData: function (data, idx, record, orig) {\r | |
61 | * // Usually you would style the my-body-class in a CSS file\r | |
62 | * return {\r | |
63 | * rowBody: '<div style="padding: 1em">' + record.get("desc") + '</div>',\r | |
64 | * rowBodyCls: "my-body-class"\r | |
65 | * };\r | |
66 | * }\r | |
67 | * }],\r | |
68 | * listeners: {\r | |
69 | * rowbodyclick: function(view, rowEl, e, eOpts) {\r | |
70 | * var itemEl = Ext.get(rowEl).up(view.itemSelector),\r | |
71 | * rec = view.getRecord(itemEl);\r | |
72 | * \r | |
73 | * Ext.Msg.alert(rec.get('name') + ' life span', rec.get('lifespan'));\r | |
74 | * }\r | |
75 | * }\r | |
76 | * });\r | |
77 | *\r | |
78 | * # Cell Editing and Cell Selection Model\r | |
79 | *\r | |
80 | * Note that if {@link Ext.grid.plugin.CellEditing cell editing} or the {@link Ext.selection.CellModel cell selection model} are going\r | |
81 | * to be used, then the {@link Ext.grid.feature.RowBody RowBody} feature, or {@link Ext.grid.plugin.RowExpander RowExpander} plugin MUST\r | |
82 | * be used for intra-cell navigation to be correct.\r | |
83 | */\r | |
84 | Ext.define('Ext.grid.feature.RowBody', {\r | |
85 | extend: 'Ext.grid.feature.Feature',\r | |
86 | alias: 'feature.rowbody',\r | |
87 | \r | |
88 | rowBodyCls: Ext.baseCSSPrefix + 'grid-row-body',\r | |
89 | rowBodyHiddenCls: Ext.baseCSSPrefix + 'grid-row-body-hidden',\r | |
90 | rowBodyTdSelector: 'td.' + Ext.baseCSSPrefix + 'grid-cell-rowbody',\r | |
91 | eventPrefix: 'rowbody',\r | |
92 | eventSelector: 'tr.' + Ext.baseCSSPrefix + 'grid-rowbody-tr',\r | |
93 | \r | |
94 | colSpanDecrement: 0,\r | |
95 | \r | |
96 | /**\r | |
97 | * @cfg {Boolean} [bodyBefore=false]\r | |
98 | * Configure as `true` to put the row expander body *before* the data row.\r | |
99 | */\r | |
100 | bodyBefore: false,\r | |
101 | \r | |
102 | outerTpl: {\r | |
103 | fn: function(out, values, parent) {\r | |
104 | var view = values.view,\r | |
105 | rowValues = view.rowValues;\r | |
106 | \r | |
107 | this.rowBody.setup(values.rows, rowValues);\r | |
108 | this.nextTpl.applyOut(values, out, parent);\r | |
109 | this.rowBody.cleanup(values.rows, rowValues);\r | |
110 | },\r | |
111 | priority: 100\r | |
112 | },\r | |
113 | \r | |
114 | extraRowTpl: [\r | |
115 | '{%',\r | |
116 | 'if(this.rowBody.bodyBefore) {',\r | |
117 | // MUST output column sizing elements because the first row in this table\r | |
118 | // contains one colspanning TD, and that overrides subsequent column width settings.\r | |
119 | 'values.view.renderColumnSizer(values, out);',\r | |
120 | '} else {',\r | |
121 | 'this.nextTpl.applyOut(values, out, parent);',\r | |
122 | '}',\r | |
123 | 'values.view.rowBodyFeature.setupRowData(values.record, values.recordIndex, values);',\r | |
124 | '%}',\r | |
125 | '<tr class="' + Ext.baseCSSPrefix + 'grid-rowbody-tr {rowBodyCls}" {ariaRowAttr}>',\r | |
126 | '<td class="' + Ext.baseCSSPrefix + 'grid-td ' + Ext.baseCSSPrefix + 'grid-cell-rowbody" colspan="{rowBodyColspan}" {ariaCellAttr}>',\r | |
127 | '<div class="' + Ext.baseCSSPrefix + 'grid-rowbody {rowBodyDivCls}" {ariaCellInnerAttr}>{rowBody}</div>',\r | |
128 | '</td>',\r | |
129 | '</tr>',\r | |
130 | '{%',\r | |
131 | 'if(this.rowBody.bodyBefore) {',\r | |
132 | 'this.nextTpl.applyOut(values, out, parent);',\r | |
133 | '}',\r | |
134 | '%}', {\r | |
135 | priority: 100,\r | |
136 | \r | |
137 | beginRowSync: function (rowSync) {\r | |
138 | rowSync.add('rowBody', this.owner.eventSelector);\r | |
139 | },\r | |
140 | \r | |
141 | syncContent: function(destRow, sourceRow, columnsToUpdate) {\r | |
142 | var owner = this.owner,\r | |
143 | destRowBody = Ext.fly(destRow).down(owner.eventSelector, true),\r | |
144 | sourceRowBody;\r | |
145 | \r | |
146 | // Sync the heights of row body elements in each row if they need it.\r | |
147 | if (destRowBody && (sourceRowBody = Ext.fly(sourceRow).down(owner.eventSelector, true))) {\r | |
148 | Ext.fly(destRowBody).syncContent(sourceRowBody);\r | |
149 | }\r | |
150 | }\r | |
151 | }\r | |
152 | ],\r | |
153 | \r | |
154 | init: function(grid) {\r | |
155 | var me = this,\r | |
156 | view = me.view = grid.getView();\r | |
157 | \r | |
158 | // The extra data means variableRowHeight\r | |
159 | grid.variableRowHeight = view.variableRowHeight = true;\r | |
160 | view.rowBodyFeature = me;\r | |
161 | \r | |
162 | grid.mon(view, {\r | |
163 | element: 'el',\r | |
164 | click: me.onClick,\r | |
165 | scope: me\r | |
166 | });\r | |
167 | \r | |
168 | view.headerCt.on({\r | |
169 | columnschanged: me.onColumnsChanged,\r | |
170 | scope: me\r | |
171 | });\r | |
172 | view.addTpl(me.outerTpl).rowBody = me;\r | |
173 | view.addRowTpl(Ext.XTemplate.getTpl(this, 'extraRowTpl')).rowBody = me;\r | |
174 | me.callParent(arguments);\r | |
175 | },\r | |
176 | \r | |
177 | // Needed to select the data row when clicked on the body row.\r | |
178 | onClick: function(e) {\r | |
179 | var me = this,\r | |
180 | tableRow = e.getTarget(me.eventSelector);\r | |
181 | \r | |
182 | // If we have clicked on a row body TR and its previous (or next - we can put the body first) sibling is a grid row,\r | |
183 | // pass that onto the view for processing\r | |
184 | if (tableRow && Ext.fly(tableRow = (tableRow.previousSibling || tableRow.nextSibling)).is(me.view.rowSelector)) {\r | |
185 | e.target = tableRow;\r | |
186 | me.view.handleEvent(e);\r | |
187 | }\r | |
188 | },\r | |
189 | \r | |
190 | getSelectedRow: function(view, rowIndex) {\r | |
191 | var selectedRow = view.getNode(rowIndex);\r | |
192 | if (selectedRow) {\r | |
193 | return Ext.fly(selectedRow).down(this.eventSelector);\r | |
194 | }\r | |
195 | return null;\r | |
196 | },\r | |
197 | \r | |
198 | // When columns added/removed, keep row body colspan in sync with number of columns.\r | |
199 | onColumnsChanged: function(headerCt) {\r | |
200 | var items = this.view.el.query(this.rowBodyTdSelector),\r | |
201 | colspan = headerCt.getVisibleGridColumns().length,\r | |
202 | len = items.length,\r | |
203 | i;\r | |
204 | \r | |
205 | for (i = 0; i < len; ++i) {\r | |
206 | items[i].setAttribute('colSpan', colspan);\r | |
207 | }\r | |
208 | },\r | |
209 | \r | |
210 | /**\r | |
211 | * @method getAdditionalData\r | |
212 | * @protected\r | |
213 | * @template\r | |
214 | * Provides additional data to the prepareData call within the grid view.\r | |
215 | * The rowbody feature adds 3 additional variables into the grid view's template.\r | |
216 | * These are `rowBody`, `rowBodyCls`, and `rowBodyColspan`.\r | |
217 | * \r | |
218 | * - **rowBody:** *{String}* The HTML to display in the row body element. Defaults \r | |
219 | * to *undefined*.\r | |
220 | * - **rowBodyCls:** *{String}* An optional CSS class (or multiple classes \r | |
221 | * separated by spaces) to apply to the row body element. Defaults to \r | |
222 | * {@link #rowBodyCls}.\r | |
223 | * - **rowBodyColspan:** *{Number}* The number of columns that the row body element \r | |
224 | * should span. Defaults to the number of visible columns.\r | |
225 | * \r | |
226 | * @param {Object} data The data for this particular record.\r | |
227 | * @param {Number} idx The row index for this record.\r | |
228 | * @param {Ext.data.Model} record The record instance\r | |
229 | * @param {Object} orig The original result from the prepareData call to massage.\r | |
230 | * @return {Object} An object containing additional variables for use in the grid \r | |
231 | * view's template\r | |
232 | */\r | |
233 | \r | |
234 | /*\r | |
235 | * @private\r | |
236 | */\r | |
237 | setupRowData: function(record, rowIndex, rowValues) {\r | |
238 | if (this.getAdditionalData) {\r | |
239 | Ext.apply(rowValues, this.getAdditionalData(record.data, rowIndex, record, rowValues));\r | |
240 | }\r | |
241 | },\r | |
242 | \r | |
243 | setup: function(rows, rowValues) {\r | |
244 | rowValues.rowBodyCls = this.rowBodyCls;\r | |
245 | rowValues.rowBodyColspan = this.view.headerCt.visibleColumnManager.getColumns().length - this.colSpanDecrement;\r | |
246 | },\r | |
247 | \r | |
248 | cleanup: function(rows, rowValues) {\r | |
249 | rowValues.rowBodyCls = rowValues.rowBodyColspan = rowValues.rowBody = null;\r | |
250 | }\r | |
251 | \r | |
252 | /**\r | |
253 | * @event beforerowbodymousedown\r | |
254 | * @preventable\r | |
255 | * @member Ext.view.Table\r | |
256 | * Fires before the mousedown event on a row body element is processed. Return false \r | |
257 | * to cancel the default action.\r | |
258 | * \r | |
259 | * **Note:** This event is fired only when the Ext.grid.feature.RowBody feature is \r | |
260 | * used.\r | |
261 | * \r | |
262 | * @param {Ext.view.View} view The rowbody's owning View\r | |
263 | * @param {HTMLElement} rowBodyEl The row body's element\r | |
264 | * @param {Ext.event.Event} e The raw event object\r | |
265 | */\r | |
266 | \r | |
267 | /**\r | |
268 | * @event beforerowbodymouseup\r | |
269 | * @preventable\r | |
270 | * @member Ext.view.Table\r | |
271 | * Fires before the mouseup event on a row body element is processed. Return false \r | |
272 | * to cancel the default action.\r | |
273 | * \r | |
274 | * **Note:** This event is fired only when the Ext.grid.feature.RowBody feature is \r | |
275 | * used.\r | |
276 | * \r | |
277 | * @inheritdoc #beforerowbodymousedown\r | |
278 | */\r | |
279 | \r | |
280 | /**\r | |
281 | * @event beforerowbodyclick\r | |
282 | * @preventable\r | |
283 | * @member Ext.view.Table\r | |
284 | * Fires before the click event on a row body element is processed. Return false to \r | |
285 | * cancel the default action.\r | |
286 | * \r | |
287 | * **Note:** This event is fired only when the Ext.grid.feature.RowBody feature is \r | |
288 | * used.\r | |
289 | * \r | |
290 | * @inheritdoc #beforerowbodymousedown\r | |
291 | */\r | |
292 | \r | |
293 | /**\r | |
294 | * @event beforerowbodydblclick\r | |
295 | * @preventable\r | |
296 | * @member Ext.view.Table\r | |
297 | * Fires before the dblclick event on a row body element is processed. Return false \r | |
298 | * to cancel the default action.\r | |
299 | * \r | |
300 | * **Note:** This event is fired only when the Ext.grid.feature.RowBody feature is \r | |
301 | * used.\r | |
302 | * \r | |
303 | * @inheritdoc #beforerowbodymousedown\r | |
304 | */\r | |
305 | \r | |
306 | /**\r | |
307 | * @event beforerowbodycontextmenu\r | |
308 | * @preventable\r | |
309 | * @member Ext.view.Table\r | |
310 | * Fires before the contextmenu event on a row body element is processed. Return \r | |
311 | * false to cancel the default action.\r | |
312 | * \r | |
313 | * **Note:** This event is fired only when the Ext.grid.feature.RowBody feature is \r | |
314 | * used.\r | |
315 | * \r | |
316 | * @inheritdoc #beforerowbodymousedown\r | |
317 | */\r | |
318 | \r | |
319 | /**\r | |
320 | * @event beforerowbodylongpress\r | |
321 | * @preventable\r | |
322 | * @member Ext.view.Table\r | |
323 | * Fires before the longpress event on a row body element is processed. Return \r | |
324 | * false to cancel the default action.\r | |
325 | * \r | |
326 | * **Note:** This event is fired only when the Ext.grid.feature.RowBody feature is \r | |
327 | * used.\r | |
328 | * \r | |
329 | * @inheritdoc #beforerowbodymousedown\r | |
330 | */\r | |
331 | \r | |
332 | /**\r | |
333 | * @event beforerowbodykeydown\r | |
334 | * @preventable\r | |
335 | * @member Ext.view.Table\r | |
336 | * Fires before the keydown event on a row body element is processed. Return false \r | |
337 | * to cancel the default action.\r | |
338 | * \r | |
339 | * **Note:** This event is fired only when the Ext.grid.feature.RowBody feature is \r | |
340 | * used.\r | |
341 | * \r | |
342 | * @inheritdoc #beforerowbodymousedown\r | |
343 | */\r | |
344 | \r | |
345 | /**\r | |
346 | * @event beforerowbodykeyup\r | |
347 | * @preventable\r | |
348 | * @member Ext.view.Table\r | |
349 | * Fires before the keyup event on a row body element is processed. Return false to \r | |
350 | * cancel the default action.\r | |
351 | * \r | |
352 | * **Note:** This event is fired only when the Ext.grid.feature.RowBody feature is \r | |
353 | * used.\r | |
354 | * \r | |
355 | * @inheritdoc #beforerowbodymousedown\r | |
356 | */\r | |
357 | \r | |
358 | /**\r | |
359 | * @event beforerowbodykeypress\r | |
360 | * @preventable\r | |
361 | * @member Ext.view.Table\r | |
362 | * Fires before the keypress event on a row body element is processed. Return false \r | |
363 | * to cancel the default action.\r | |
364 | * \r | |
365 | * **Note:** This event is fired only when the Ext.grid.feature.RowBody feature is \r | |
366 | * used.\r | |
367 | * \r | |
368 | * @inheritdoc #beforerowbodymousedown\r | |
369 | */\r | |
370 | \r | |
371 | /**\r | |
372 | * @event rowbodymousedown\r | |
373 | * @member Ext.view.Table\r | |
374 | * Fires when there is a mouse down on a row body element\r | |
375 | * \r | |
376 | * **Note:** This event is fired only when the Ext.grid.feature.RowBody feature is \r | |
377 | * used.\r | |
378 | * \r | |
379 | * @inheritdoc #beforerowbodymousedown\r | |
380 | */\r | |
381 | \r | |
382 | /**\r | |
383 | * @event rowbodymouseup\r | |
384 | * @member Ext.view.Table\r | |
385 | * Fires when there is a mouse up on a row body element\r | |
386 | * \r | |
387 | * **Note:** This event is fired only when the Ext.grid.feature.RowBody feature is \r | |
388 | * used.\r | |
389 | * \r | |
390 | * @inheritdoc #beforerowbodymousedown\r | |
391 | */\r | |
392 | \r | |
393 | /**\r | |
394 | * @event rowbodyclick\r | |
395 | * @member Ext.view.Table\r | |
396 | * Fires when a row body element is clicked\r | |
397 | * \r | |
398 | * **Note:** This event is fired only when the Ext.grid.feature.RowBody feature is \r | |
399 | * used.\r | |
400 | * \r | |
401 | * @inheritdoc #beforerowbodymousedown\r | |
402 | */\r | |
403 | \r | |
404 | /**\r | |
405 | * @event rowbodydblclick\r | |
406 | * @member Ext.view.Table\r | |
407 | * Fires when a row body element is double clicked\r | |
408 | * \r | |
409 | * **Note:** This event is fired only when the Ext.grid.feature.RowBody feature is \r | |
410 | * used.\r | |
411 | * \r | |
412 | * @inheritdoc #beforerowbodymousedown\r | |
413 | */\r | |
414 | \r | |
415 | /**\r | |
416 | * @event rowbodycontextmenu\r | |
417 | * @member Ext.view.Table\r | |
418 | * Fires when a row body element is right clicked\r | |
419 | * \r | |
420 | * **Note:** This event is fired only when the Ext.grid.feature.RowBody feature is \r | |
421 | * used.\r | |
422 | * \r | |
423 | * @inheritdoc #beforerowbodymousedown\r | |
424 | */\r | |
425 | \r | |
426 | /**\r | |
427 | * @event rowbodylongpress\r | |
428 | * @member Ext.view.Table\r | |
429 | * Fires on a row body element longpress event\r | |
430 | * \r | |
431 | * **Note:** This event is fired only when the Ext.grid.feature.RowBody feature is \r | |
432 | * used.\r | |
433 | * \r | |
434 | * @inheritdoc #beforerowbodymousedown\r | |
435 | */\r | |
436 | \r | |
437 | /**\r | |
438 | * @event rowbodykeydown\r | |
439 | * @member Ext.view.Table\r | |
440 | * Fires when a key is pressed down while a row body element is currently selected\r | |
441 | * \r | |
442 | * **Note:** This event is fired only when the Ext.grid.feature.RowBody feature is \r | |
443 | * used.\r | |
444 | * \r | |
445 | * @inheritdoc #beforerowbodymousedown\r | |
446 | */\r | |
447 | \r | |
448 | /**\r | |
449 | * @event rowbodykeyup\r | |
450 | * @member Ext.view.Table\r | |
451 | * Fires when a key is released while a row body element is currently selected\r | |
452 | * \r | |
453 | * **Note:** This event is fired only when the Ext.grid.feature.RowBody feature is \r | |
454 | * used.\r | |
455 | * \r | |
456 | * @inheritdoc #beforerowbodymousedown\r | |
457 | */\r | |
458 | \r | |
459 | /**\r | |
460 | * @event rowbodykeypress\r | |
461 | * @member Ext.view.Table\r | |
462 | * Fires when a key is pressed while a row body element is currently selected.\r | |
463 | * \r | |
464 | * **Note:** This event is fired only when the Ext.grid.feature.RowBody feature is \r | |
465 | * used.\r | |
466 | * \r | |
467 | * @inheritdoc #beforerowbodymousedown\r | |
468 | */\r | |
469 | });\r |