|
1 /* |
|
2 YUI 3.10.3 (build 2fb5187) |
|
3 Copyright 2013 Yahoo! Inc. All rights reserved. |
|
4 Licensed under the BSD License. |
|
5 http://yuilibrary.com/license/ |
|
6 */ |
|
7 |
|
8 YUI.add('datatable-base', function (Y, NAME) { |
|
9 |
|
10 /** |
|
11 A Widget for displaying tabular data. The base implementation of DataTable |
|
12 provides the ability to dynamically generate an HTML table from a set of column |
|
13 configurations and row data. |
|
14 |
|
15 Two classes are included in the `datatable-base` module: `Y.DataTable` and |
|
16 `Y.DataTable.Base`. |
|
17 |
|
18 @module datatable |
|
19 @submodule datatable-base |
|
20 @main datatable |
|
21 @since 3.5.0 |
|
22 **/ |
|
23 |
|
24 // DataTable API docs included before DataTable.Base to make yuidoc work |
|
25 /** |
|
26 A Widget for displaying tabular data. Before feature modules are `use()`d, |
|
27 this class is functionally equivalent to DataTable.Base. However, feature |
|
28 modules can modify this class in non-destructive ways, expanding the API and |
|
29 functionality. |
|
30 |
|
31 This is the primary DataTable class. Out of the box, it provides the ability |
|
32 to dynamically generate an HTML table from a set of column configurations and |
|
33 row data. But feature module inclusion can add table sorting, pagintaion, |
|
34 highlighting, selection, and more. |
|
35 |
|
36 <pre><code> |
|
37 // The functionality of this table would require additional modules be use()d, |
|
38 // but the feature APIs are aggregated onto Y.DataTable. |
|
39 // (Snippet is for illustration. Not all features are available today.) |
|
40 var table = new Y.DataTable({ |
|
41 columns: [ |
|
42 { type: 'checkbox', defaultChecked: true }, |
|
43 { key: 'firstName', sortable: true, resizable: true }, |
|
44 { key: 'lastName', sortable: true }, |
|
45 { key: 'role', formatter: toRoleName } |
|
46 ], |
|
47 data: { |
|
48 source: 'http://myserver.com/service/json', |
|
49 type: 'json', |
|
50 schema: { |
|
51 resultListLocator: 'results.users', |
|
52 fields: [ |
|
53 'username', |
|
54 'firstName', |
|
55 'lastName', |
|
56 { key: 'role', type: 'number' } |
|
57 ] |
|
58 } |
|
59 }, |
|
60 recordType: UserModel, |
|
61 pagedData: { |
|
62 location: 'footer', |
|
63 pageSizes: [20, 50, 'all'], |
|
64 rowsPerPage: 20, |
|
65 pageLinks: 5 |
|
66 }, |
|
67 editable: true |
|
68 }); |
|
69 </code></pre> |
|
70 |
|
71 ### Column Configuration |
|
72 |
|
73 The column configurations are set in the form of an array of objects, where |
|
74 each object corresponds to a column. For columns populated directly from the |
|
75 row data, a 'key' property is required to bind the column to that property or |
|
76 attribute in the row data. |
|
77 |
|
78 Not all columns need to relate to row data, nor do all properties or attributes |
|
79 of the row data need to have a corresponding column. However, only those |
|
80 columns included in the `columns` configuration attribute will be rendered. |
|
81 |
|
82 Other column configuration properties are supported by the configured |
|
83 `view`, class as well as any features added by plugins or class extensions. |
|
84 See the description of DataTable.TableView and its subviews |
|
85 DataTable.HeaderView, DataTable.BodyView, and DataTable.FooterView (and other |
|
86 DataTable feature classes) to see what column properties they support. |
|
87 |
|
88 Some examples of column configurations would be: |
|
89 |
|
90 <pre><code> |
|
91 // Basic |
|
92 var columns = [{ key: 'firstName' }, { key: 'lastName' }, { key: 'age' }]; |
|
93 |
|
94 // For columns without any additional configuration, strings can be used |
|
95 var columns = ['firstName', 'lastName', 'age']; |
|
96 |
|
97 // Multi-row column headers (see DataTable.HeaderView for details) |
|
98 var columns = [ |
|
99 { |
|
100 label: 'Name', |
|
101 children: [ |
|
102 { key: 'firstName' }, |
|
103 { key: 'lastName' } |
|
104 ] |
|
105 }, |
|
106 'age' // mixing and matching objects and strings is ok |
|
107 ]; |
|
108 |
|
109 // Including columns that are not related 1:1 to row data fields/attributes |
|
110 // (See DataTable.BodyView for details) |
|
111 var columns = [ |
|
112 { |
|
113 label: 'Name', // Needed for the column header |
|
114 formatter: function (o) { |
|
115 // Fill the column cells with data from firstName and lastName |
|
116 if (o.data.age > 55) { |
|
117 o.className += ' senior'; |
|
118 } |
|
119 return o.data.lastName + ', ' + o.data.firstName; |
|
120 } |
|
121 }, |
|
122 'age' |
|
123 ]; |
|
124 |
|
125 // Columns that include feature configurations (for illustration; not all |
|
126 // features are available today). |
|
127 var columns = [ |
|
128 { type: 'checkbox', defaultChecked: true }, |
|
129 { key: 'firstName', sortable: true, resizable: true, min-width: '300px' }, |
|
130 { key: 'lastName', sortable: true, resizable: true, min-width: '300px' }, |
|
131 { key: 'age', emptyCellValue: '<em>unknown</em>' } |
|
132 ]; |
|
133 </code></pre> |
|
134 |
|
135 ### Row Data Configuration |
|
136 |
|
137 The `data` configuration attribute is responsible for housing the data objects |
|
138 that will be rendered as rows. You can provide this information in two ways by default: |
|
139 |
|
140 1. An array of simple objects with key:value pairs |
|
141 2. A ModelList of Base-based class instances (presumably Model subclass |
|
142 instances) |
|
143 |
|
144 If an array of objects is passed, it will be translated into a ModelList filled |
|
145 with instances of the class provided to the `recordType` attribute. This |
|
146 attribute can also create a custom Model subclass from an array of field names |
|
147 or an object of attribute configurations. If no `recordType` is provided, one |
|
148 will be created for you from available information (see `_initRecordType`). |
|
149 Providing either your own ModelList instance for `data`, or at least Model |
|
150 class for `recordType`, is the best way to control client-server |
|
151 synchronization when modifying data on the client side. |
|
152 |
|
153 The ModelList instance that manages the table's data is available in the `data` |
|
154 property on the DataTable instance. |
|
155 |
|
156 |
|
157 ### Rendering |
|
158 |
|
159 Table rendering is a collaborative process between the DataTable and its |
|
160 configured `view`. The DataTable creates an instance of the configured `view` |
|
161 (DataTable.TableView by default), and calls its `render()` method. |
|
162 DataTable.TableView, for instance, then creates the `<table>` and `<caption>`, |
|
163 then delegates the rendering of the specific sections of the table to subviews, |
|
164 which can be configured as `headerView`, `bodyView`, and `footerView`. |
|
165 DataTable.TableView defaults the `headerView` to DataTable.HeaderView and the |
|
166 `bodyView` to DataTable.BodyView, but leaves the `footerView` unassigned. |
|
167 Setting any subview to `null` will result in that table section not being |
|
168 rendered. |
|
169 |
|
170 @class DataTable |
|
171 @extends DataTable.Base |
|
172 @since 3.5.0 |
|
173 **/ |
|
174 |
|
175 // DataTable API docs included before DataTable.Base to make yuidoc work |
|
176 /** |
|
177 The baseline implementation of a DataTable. This class should be used |
|
178 primarily as a superclass for a custom DataTable with a specific set of |
|
179 features. Because features can be composed onto `Y.DataTable`, custom |
|
180 subclasses of DataTable.Base will remain unmodified when new feature modules |
|
181 are loaded. |
|
182 |
|
183 Example usage might look like this: |
|
184 |
|
185 <pre><code> |
|
186 // Custom subclass with only sorting and mutability added. If other datatable |
|
187 // feature modules are loaded, this class will not be affected. |
|
188 var MyTableClass = Y.Base.create('table', Y.DataTable.Base, |
|
189 [ Y.DataTable.Sortable, Y.DataTable.Mutable ]); |
|
190 |
|
191 var table = new MyTableClass({ |
|
192 columns: ['firstName', 'lastName', 'age'], |
|
193 data: [ |
|
194 { firstName: 'Frank', lastName: 'Zappa', age: 71 }, |
|
195 { firstName: 'Frank', lastName: 'Lloyd Wright', age: 144 }, |
|
196 { firstName: 'Albert', lastName: 'Einstein', age: 132 }, |
|
197 ... |
|
198 ] |
|
199 }); |
|
200 |
|
201 table.render('#over-there'); |
|
202 |
|
203 // DataTable.Base can be instantiated if a featureless table is needed. |
|
204 var table = new Y.DataTable.Base({ |
|
205 columns: ['firstName', 'lastName', 'age'], |
|
206 data: [ |
|
207 { firstName: 'Frank', lastName: 'Zappa', age: 71 }, |
|
208 { firstName: 'Frank', lastName: 'Lloyd Wright', age: 144 }, |
|
209 { firstName: 'Albert', lastName: 'Einstein', age: 132 }, |
|
210 ... |
|
211 ] |
|
212 }); |
|
213 |
|
214 table.render('#in-here'); |
|
215 </code></pre> |
|
216 |
|
217 DataTable.Base is built from DataTable.Core, and sets the default `view` |
|
218 to `Y.DataTable.TableView`. |
|
219 |
|
220 @class Base |
|
221 @extends Widget |
|
222 @uses DataTable.Core |
|
223 @namespace DataTable |
|
224 @since 3.5.0 |
|
225 **/ |
|
226 Y.DataTable.Base = Y.Base.create('datatable', Y.Widget, [Y.DataTable.Core], { |
|
227 |
|
228 /** |
|
229 Pass through to `delegate()` called from the `contentBox`. |
|
230 |
|
231 @method delegate |
|
232 @param type {String} the event type to delegate |
|
233 @param fn {Function} the callback function to execute. This function |
|
234 will be provided the event object for the delegated event. |
|
235 @param spec {String|Function} a selector that must match the target of the |
|
236 event or a function to test target and its parents for a match |
|
237 @param context {Object} optional argument that specifies what 'this' refers to |
|
238 @param args* {any} 0..n additional arguments to pass on to the callback |
|
239 function. These arguments will be added after the event object. |
|
240 @return {EventHandle} the detach handle |
|
241 @since 3.5.0 |
|
242 **/ |
|
243 delegate: function () { |
|
244 var contentBox = this.get('contentBox'); |
|
245 |
|
246 return contentBox.delegate.apply(contentBox, arguments); |
|
247 }, |
|
248 |
|
249 /** |
|
250 Destroys the table `View` if it's been created. |
|
251 |
|
252 @method destructor |
|
253 @protected |
|
254 @since 3.6.0 |
|
255 **/ |
|
256 destructor: function () { |
|
257 if (this.view) { |
|
258 this.view.destroy(); |
|
259 } |
|
260 }, |
|
261 |
|
262 /** |
|
263 Returns the `<td>` Node from the given row and column index. Alternately, |
|
264 the `seed` can be a Node. If so, the nearest ancestor cell is returned. |
|
265 If the `seed` is a cell, it is returned. If there is no cell at the given |
|
266 coordinates, `null` is returned. |
|
267 |
|
268 Optionally, include an offset array or string to return a cell near the |
|
269 cell identified by the `seed`. The offset can be an array containing the |
|
270 number of rows to shift followed by the number of columns to shift, or one |
|
271 of "above", "below", "next", or "previous". |
|
272 |
|
273 <pre><code>// Previous cell in the previous row |
|
274 var cell = table.getCell(e.target, [-1, -1]); |
|
275 |
|
276 // Next cell |
|
277 var cell = table.getCell(e.target, 'next'); |
|
278 var cell = table.getCell(e.taregt, [0, 1];</pre></code> |
|
279 |
|
280 This is actually just a pass through to the `view` instance's method |
|
281 by the same name. |
|
282 |
|
283 @method getCell |
|
284 @param {Number[]|Node} seed Array of row and column indexes, or a Node that |
|
285 is either the cell itself or a descendant of one. |
|
286 @param {Number[]|String} [shift] Offset by which to identify the returned |
|
287 cell Node |
|
288 @return {Node} |
|
289 @since 3.5.0 |
|
290 **/ |
|
291 getCell: function (/* seed, shift */) { |
|
292 return this.view && this.view.getCell && |
|
293 this.view.getCell.apply(this.view, arguments); |
|
294 }, |
|
295 |
|
296 /** |
|
297 Returns the `<tr>` Node from the given row index, Model, or Model's |
|
298 `clientId`. If the rows haven't been rendered yet, or if the row can't be |
|
299 found by the input, `null` is returned. |
|
300 |
|
301 This is actually just a pass through to the `view` instance's method |
|
302 by the same name. |
|
303 |
|
304 @method getRow |
|
305 @param {Number|String|Model} id Row index, Model instance, or clientId |
|
306 @return {Node} |
|
307 @since 3.5.0 |
|
308 **/ |
|
309 getRow: function (/* id */) { |
|
310 return this.view && this.view.getRow && |
|
311 this.view.getRow.apply(this.view, arguments); |
|
312 }, |
|
313 |
|
314 /** |
|
315 Updates the `_displayColumns` property. |
|
316 |
|
317 @method _afterDisplayColumnsChange |
|
318 @param {EventFacade} e The `columnsChange` event |
|
319 @protected |
|
320 @since 3.6.0 |
|
321 **/ |
|
322 // FIXME: This is a kludge for back compat with features that reference |
|
323 // _displayColumns. They should be updated to TableView plugins. |
|
324 _afterDisplayColumnsChange: function (e) { |
|
325 this._extractDisplayColumns(e.newVal || []); |
|
326 }, |
|
327 |
|
328 /** |
|
329 Attaches subscriptions to relay core change events to the view. |
|
330 |
|
331 @method bindUI |
|
332 @protected |
|
333 @since 3.6.0 |
|
334 **/ |
|
335 bindUI: function () { |
|
336 this._eventHandles.relayCoreChanges = this.after( |
|
337 ['columnsChange', |
|
338 'dataChange', |
|
339 'summaryChange', |
|
340 'captionChange', |
|
341 'widthChange'], |
|
342 Y.bind('_relayCoreAttrChange', this)); |
|
343 }, |
|
344 |
|
345 /** |
|
346 The default behavior of the `renderView` event. Calls `render()` on the |
|
347 `View` instance on the event. |
|
348 |
|
349 @method _defRenderViewFn |
|
350 @param {EventFacade} e The `renderView` event |
|
351 @protected |
|
352 **/ |
|
353 _defRenderViewFn: function (e) { |
|
354 e.view.render(); |
|
355 }, |
|
356 |
|
357 /** |
|
358 Processes the full column array, distilling the columns down to those that |
|
359 correspond to cell data columns. |
|
360 |
|
361 @method _extractDisplayColumns |
|
362 @param {Object[]} columns The full set of table columns |
|
363 @protected |
|
364 **/ |
|
365 // FIXME: this is a kludge for back compat, duplicating logic in the |
|
366 // tableView |
|
367 _extractDisplayColumns: function (columns) { |
|
368 var displayColumns = []; |
|
369 |
|
370 function process(cols) { |
|
371 var i, len, col; |
|
372 |
|
373 for (i = 0, len = cols.length; i < len; ++i) { |
|
374 col = cols[i]; |
|
375 |
|
376 if (Y.Lang.isArray(col.children)) { |
|
377 process(col.children); |
|
378 } else { |
|
379 displayColumns.push(col); |
|
380 } |
|
381 } |
|
382 } |
|
383 |
|
384 process(columns); |
|
385 |
|
386 /** |
|
387 Array of the columns that correspond to those with value cells in the |
|
388 data rows. Excludes colspan header columns (configured with `children`). |
|
389 |
|
390 @property _displayColumns |
|
391 @type {Object[]} |
|
392 @since 3.5.0 |
|
393 **/ |
|
394 this._displayColumns = displayColumns; |
|
395 }, |
|
396 |
|
397 /** |
|
398 Sets up the instance's events. |
|
399 |
|
400 @method initializer |
|
401 @param {Object} [config] Configuration object passed at construction |
|
402 @protected |
|
403 @since 3.6.0 |
|
404 **/ |
|
405 initializer: function () { |
|
406 this.publish('renderView', { |
|
407 defaultFn: Y.bind('_defRenderViewFn', this) |
|
408 }); |
|
409 |
|
410 // Have to use get('columns'), not config.columns because the setter |
|
411 // needs to transform string columns to objects. |
|
412 this._extractDisplayColumns(this.get('columns') || []); |
|
413 |
|
414 // FIXME: kludge for back compat of features that reference |
|
415 // _displayColumns on the instance. They need to be updated to |
|
416 // TableView plugins, most likely. |
|
417 this.after('columnsChange', Y.bind('_afterDisplayColumnsChange', this)); |
|
418 }, |
|
419 |
|
420 /** |
|
421 Relays attribute changes to the instance's `view`. |
|
422 |
|
423 @method _relayCoreAttrChange |
|
424 @param {EventFacade} e The change event |
|
425 @protected |
|
426 @since 3.6.0 |
|
427 **/ |
|
428 _relayCoreAttrChange: function (e) { |
|
429 var attr = (e.attrName === 'data') ? 'modelList' : e.attrName; |
|
430 |
|
431 this.view.set(attr, e.newVal); |
|
432 }, |
|
433 |
|
434 /** |
|
435 Instantiates the configured `view` class that will be responsible for |
|
436 setting up the View class. |
|
437 |
|
438 @method @renderUI |
|
439 @protected |
|
440 @since 3.6.0 |
|
441 **/ |
|
442 renderUI: function () { |
|
443 var self = this, |
|
444 View = this.get('view'); |
|
445 |
|
446 if (View) { |
|
447 this.view = new View( |
|
448 Y.merge( |
|
449 this.getAttrs(), |
|
450 { |
|
451 host : this, |
|
452 container: this.get('contentBox'), |
|
453 modelList: this.data |
|
454 }, |
|
455 this.get('viewConfig'))); |
|
456 |
|
457 // For back compat, share the view instances and primary nodes |
|
458 // on this instance. |
|
459 // TODO: Remove this? |
|
460 if (!this._eventHandles.legacyFeatureProps) { |
|
461 this._eventHandles.legacyFeatureProps = this.view.after({ |
|
462 renderHeader: function (e) { |
|
463 self.head = e.view; |
|
464 self._theadNode = e.view.theadNode; |
|
465 // TODO: clean up the repetition. |
|
466 // This is here so that subscribers to renderHeader etc |
|
467 // have access to this._tableNode from the DT instance |
|
468 self._tableNode = e.view.get('container'); |
|
469 }, |
|
470 renderFooter: function (e) { |
|
471 self.foot = e.view; |
|
472 self._tfootNode = e.view.tfootNode; |
|
473 self._tableNode = e.view.get('container'); |
|
474 }, |
|
475 renderBody: function (e) { |
|
476 self.body = e.view; |
|
477 self._tbodyNode = e.view.tbodyNode; |
|
478 self._tableNode = e.view.get('container'); |
|
479 }, |
|
480 // FIXME: guarantee that the properties are available, even |
|
481 // if the configured (or omitted) views don't create them |
|
482 renderTable: function () { |
|
483 var contentBox = this.get('container'); |
|
484 |
|
485 self._tableNode = this.tableNode || |
|
486 contentBox.one('.' + this.getClassName('table') + |
|
487 ', table'); |
|
488 |
|
489 // FIXME: _captionNode isn't available until after |
|
490 // renderTable unless in the renderX subs I look for |
|
491 // it under the container's parentNode (to account for |
|
492 // scroll breaking out the caption table). |
|
493 self._captionNode = this.captionNode || |
|
494 contentBox.one('caption'); |
|
495 |
|
496 if (!self._theadNode) { |
|
497 self._theadNode = contentBox.one( |
|
498 '.' + this.getClassName('columns') + ', thead'); |
|
499 } |
|
500 |
|
501 if (!self._tbodyNode) { |
|
502 self._tbodyNode = contentBox.one( |
|
503 '.' + this.getClassName('data') + ', tbody'); |
|
504 } |
|
505 |
|
506 if (!self._tfootNode) { |
|
507 self._tfootNode = contentBox.one( |
|
508 '.' + this.getClassName('footer') + ', tfoot'); |
|
509 } |
|
510 } |
|
511 }); |
|
512 } |
|
513 |
|
514 // To *somewhat* preserve table.on('renderHeader', fn) in the |
|
515 // form of table.on('table:renderHeader', fn), because I couldn't |
|
516 // figure out another option. |
|
517 this.view.addTarget(this); |
|
518 } |
|
519 }, |
|
520 |
|
521 /** |
|
522 Fires the `renderView` event, delegating UI updates to the configured View. |
|
523 |
|
524 @method syncUI |
|
525 @since 3.5.0 |
|
526 **/ |
|
527 syncUI: function () { |
|
528 if (this.view) { |
|
529 this.fire('renderView', { view: this.view }); |
|
530 } |
|
531 }, |
|
532 |
|
533 /** |
|
534 Verifies the input value is a function with a `render` method on its |
|
535 prototype. `null` is also accepted to remove the default View. |
|
536 |
|
537 @method _validateView |
|
538 @protected |
|
539 @since 3.5.0 |
|
540 **/ |
|
541 _validateView: function (val) { |
|
542 // TODO support View instances? |
|
543 return val === null || (Y.Lang.isFunction(val) && val.prototype.render); |
|
544 } |
|
545 }, { |
|
546 ATTRS: { |
|
547 /** |
|
548 The View class used to render the `<table>` into the Widget's |
|
549 `contentBox`. This View can handle the entire table rendering itself |
|
550 or delegate to other Views. |
|
551 |
|
552 It is not strictly necessary that the class function assigned here be |
|
553 a View subclass. It must however have a `render()` method. |
|
554 |
|
555 When the DataTable is rendered, an instance of this View will be |
|
556 created and its `render()` method called. The View instance will be |
|
557 assigned to the DataTable instance's `view` property. |
|
558 |
|
559 @attribute view |
|
560 @type {Function} |
|
561 @default Y.DataTable.TableView |
|
562 @since 3.6.0 |
|
563 **/ |
|
564 view: { |
|
565 value: Y.DataTable.TableView, |
|
566 validator: '_validateView' |
|
567 }, |
|
568 |
|
569 /** |
|
570 Configuration object passed to the class constructor in `view` |
|
571 during render. |
|
572 |
|
573 @attribute viewConfig |
|
574 @type {Object} |
|
575 @default undefined (initially unset) |
|
576 @protected |
|
577 @since 3.6.0 |
|
578 **/ |
|
579 viewConfig: {} |
|
580 |
|
581 /** |
|
582 If the View class assigned to the DataTable's `view` attribute supports |
|
583 it, this class will be used for rendering the contents of the |
|
584 `<thead>`—the column headers for the table. |
|
585 |
|
586 Similar to `view`, the instance of this View will be assigned to the |
|
587 DataTable instance's `head` property. |
|
588 |
|
589 It is not strictly necessary that the class function assigned here be |
|
590 a View subclass. It must however have a `render()` method. |
|
591 |
|
592 @attribute headerView |
|
593 @type {Function|Object} |
|
594 @default Y.DataTable.HeaderView |
|
595 @since 3.5.0 |
|
596 **/ |
|
597 /* |
|
598 headerView: { |
|
599 value: Y.DataTable.HeaderView, |
|
600 validator: '_validateView' |
|
601 }, |
|
602 */ |
|
603 |
|
604 /** |
|
605 Configuration object passed to the class constructor in `headerView` |
|
606 during render. |
|
607 |
|
608 @attribute headerConfig |
|
609 @type {Object} |
|
610 @default undefined (initially unset) |
|
611 @protected |
|
612 @since 3.6.0 |
|
613 **/ |
|
614 //headConfig: {}, |
|
615 |
|
616 /** |
|
617 If the View class assigned to the DataTable's `view` attribute supports |
|
618 it, this class will be used for rendering the contents of the `<tfoot>`. |
|
619 |
|
620 Similar to `view`, the instance of this View will be assigned to the |
|
621 DataTable instance's `foot` property. |
|
622 |
|
623 It is not strictly necessary that the class function assigned here be |
|
624 a View subclass. It must however have a `render()` method. |
|
625 |
|
626 @attribute footerView |
|
627 @type {Function|Object} |
|
628 @since 3.5.0 |
|
629 **/ |
|
630 /* |
|
631 footerView: { |
|
632 validator: '_validateView' |
|
633 }, |
|
634 */ |
|
635 |
|
636 /** |
|
637 Configuration object passed to the class constructor in `footerView` |
|
638 during render. |
|
639 |
|
640 @attribute footerConfig |
|
641 @type {Object} |
|
642 @default undefined (initially unset) |
|
643 @protected |
|
644 @since 3.6.0 |
|
645 **/ |
|
646 //footerConfig: {}, |
|
647 |
|
648 /** |
|
649 If the View class assigned to the DataTable's `view` attribute supports |
|
650 it, this class will be used for rendering the contents of the `<tbody>` |
|
651 including all data rows. |
|
652 |
|
653 Similar to `view`, the instance of this View will be assigned to the |
|
654 DataTable instance's `body` property. |
|
655 |
|
656 It is not strictly necessary that the class function assigned here be |
|
657 a View subclass. It must however have a `render()` method. |
|
658 |
|
659 @attribute bodyView |
|
660 @type {Function} |
|
661 @default Y.DataTable.BodyView |
|
662 @since 3.5.0 |
|
663 **/ |
|
664 /* |
|
665 bodyView: { |
|
666 value: Y.DataTable.BodyView, |
|
667 validator: '_validateView' |
|
668 }, |
|
669 */ |
|
670 |
|
671 /** |
|
672 Configuration object passed to the class constructor in `bodyView` |
|
673 during render. |
|
674 |
|
675 @attribute bodyConfig |
|
676 @type {Object} |
|
677 @default undefined (initially unset) |
|
678 @protected |
|
679 @since 3.6.0 |
|
680 **/ |
|
681 //bodyConfig: {} |
|
682 } |
|
683 }); |
|
684 |
|
685 // The DataTable API docs are above DataTable.Base docs. |
|
686 Y.DataTable = Y.mix( |
|
687 Y.Base.create('datatable', Y.DataTable.Base, []), // Create the class |
|
688 Y.DataTable); // Migrate static and namespaced classes |
|
689 |
|
690 |
|
691 }, '3.10.3', { |
|
692 "requires": [ |
|
693 "datatable-core", |
|
694 "datatable-table", |
|
695 "datatable-head", |
|
696 "datatable-body", |
|
697 "base-build", |
|
698 "widget" |
|
699 ], |
|
700 "skinnable": true |
|
701 }); |