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