body.js revision 53c97f474022b2633bdeccab063f518c4015f27a
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith/**
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke SmithView class responsible for rendering the `<tbody>` section of a table. Used as
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smiththe default `bodyView` for `Y.DataTable.Base` and `Y.DataTable` classes.
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith@module datatable
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith@submodule datatable-body
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith@since 3.5.0
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith**/
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smithvar Lang = Y.Lang,
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith isArray = Lang.isArray,
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith fromTemplate = Lang.sub,
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith htmlEscape = Y.Escape.html,
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith toArray = Y.Array,
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith bind = Y.bind,
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith YObject = Y.Object,
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith ClassNameManager = Y.ClassNameManager,
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith _getClassName = ClassNameManager.getClassName;
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith/**
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke SmithView class responsible for rendering the `<tbody>` section of a table. Used as
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smiththe default `bodyView` for `Y.DataTable.Base` and `Y.DataTable` classes.
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke SmithTranslates the provided `modelList` into a rendered `<tbody>` based on the data
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smithin the constituent Models, altered or ammended by any special column
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smithconfigurations.
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke SmithThe `columns` configuration, passed to the constructor, determines which
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smithcolumns will be rendered.
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke SmithThe rendering process involves constructing an HTML template for a complete row
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smithof data, built by concatenating a customized copy of the instance's
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith`CELL_TEMPLATE` into the `ROW_TEMPLATE` once for each column. This template is
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smiththen populated with values from each Model in the `modelList`, aggregating a
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smithcomplete HTML string of all row and column data. A `<tbody>` Node is then created from the markup and any column `nodeFormatter`s are applied.
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke SmithSupported properties of the column objects include:
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith * `key` - Used to link a column to an attribute in a Model.
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith * `name` - Used for columns that don't relate to an attribute in the Model
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith (`formatter` or `nodeFormatter` only) if the implementer wants a
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith predictable name to refer to in their CSS.
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith * `cellTemplate` - Overrides the instance's `CELL_TEMPLATE` for cells in this
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith column only.
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith * `formatter` - Used to customize or override the content value from the
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith Model. These do not have access to the cell or row Nodes and should
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith return string (HTML) content.
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith * `nodeFormatter` - Used to provide content for a cell as well as perform any
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith custom modifications on the cell or row Node that could not be performed by
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith `formatter`s. Should be used sparingly for better performance.
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith * `emptyCellValue` - String (HTML) value to use if the Model data for a
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith column, or the content generated by a `formatter`, is the empty string,
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith `null`, or `undefined`.
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith * `allowHTML` - Set to `true` if a column value, `formatter`, or
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith `emptyCellValue` can contain HTML. This defaults to `false` to protect
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith against XSS.
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith * `className` - Space delimited CSS classes to add to all `<td>`s in a column.
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke SmithColumn `formatter`s are passed an object (`o`) with the following properties:
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith * `value` - The current value of the column's associated attribute, if any.
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith * `data` - An object map of Model keys to their current values.
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith * `record` - The Model instance.
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith * `column` - The column configuration object for the current column.
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith * `className` - Initially empty string to allow `formatter`s to add CSS
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith classes to the cell's `<td>`.
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith * `rowIndex` - The zero-based row number.
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith * `rowClass` - Initially empty string to allow `formatter`s to add CSS
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith classes to the cell's containing row `<tr>`.
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke SmithThey may return a value or update `o.value` to assign specific HTML content. A
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smithreturned value has higher precedence.
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke SmithColumn `nodeFormatter`s are passed an object (`o`) with the following
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smithproperties:
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith * `value` - The current value of the column's associated attribute, if any.
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith * `td` - The `<td>` Node instance.
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith * `cell` - The `<div>` liner Node instance if present, otherwise, the `<td>`.
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith When adding content to the cell, prefer appending into this property.
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith * `data` - An object map of Model keys to their current values.
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith * `record` - The Model instance.
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith * `column` - The column configuration object for the current column.
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith * `rowIndex` - The zero-based row number.
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke SmithThey are expected to inject content into the cell's Node directly, including
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smithany "empty" cell content. Each `nodeFormatter` will have access through the
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke SmithNode API to all cells and rows in the `<tbody>`, but not to the `<table>`, as
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smithit will not be attached yet.
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke SmithIf a `nodeFormatter` returns `false`, the `o.td` and `o.cell` Nodes will be
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith`destroy()`ed to remove them from the Node cache and free up memory. The DOM
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smithelements will remain as will any content added to them. _It is highly
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smithadvisable to always return `false` from your `nodeFormatter`s_.
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith@class BodyView
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith@namespace DataTable
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith@extends View
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith@since 3.5.0
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith**/
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke SmithY.namespace('DataTable').BodyView = Y.Base.create('tableBody', Y.View, [], {
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith // -- Instance properties -------------------------------------------------
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith /**
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith HTML template used to create table cells.
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith @property CELL_TEMPLATE
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith @type {HTML}
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith @default '<td {headers} class="{className}">{content}</td>'
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith @since 3.5.0
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith **/
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith CELL_TEMPLATE: '<td {headers} class="{className}">{content}</td>',
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith /**
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith CSS class applied to even rows. This is assigned at instantiation after
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith setting up the `_cssPrefix` for the instance.
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith For DataTable, this will be `yui3-datatable-even`.
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith @property CLASS_EVEN
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith @type {String}
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith @default 'yui3-table-even'
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith @since 3.5.0
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith **/
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith //CLASS_EVEN: null
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith /**
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith CSS class applied to odd rows. This is assigned at instantiation after
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith setting up the `_cssPrefix` for the instance.
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith When used by DataTable instances, this will be `yui3-datatable-odd`.
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith @property CLASS_ODD
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith @type {String}
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith @default 'yui3-table-odd'
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith @since 3.5.0
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith **/
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith //CLASS_ODD: null
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith /**
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith HTML template used to create table rows.
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith @property ROW_TEMPLATE
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith @type {HTML}
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith @default '<tr id="{rowId}" class="{rowClass}">{content}</tr>'
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith @since 3.5.0
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith **/
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith ROW_TEMPLATE : '<tr id="{rowId}" class="{rowClass}">{content}</tr>',
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith /**
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith The object that serves as the source of truth for column and row data.
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith This property is assigned at instantiation from the `source` property of
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith the configuration object passed to the constructor.
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith @property source
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith @type {Object}
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith @default (initially unset)
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith @since 3.5.0
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith **/
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith //TODO: should this be protected?
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith //source: null,
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith // -- Public methods ------------------------------------------------------
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith /**
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith Returns the `<td>` Node from the given row and column index. If there is
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith no cell at the given coordinates, `null` is returned.
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith @method getCell
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith @param {Number} row Zero based index of the row with the target cell
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith @param {Number} col Zero based index of the column with the target cell
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith @return {Node}
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith @since 3.5.0
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith **/
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith getCell: function (row, col) {
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith var tbody = this.get('container'),
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith el;
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith if (tbody) {
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith el = tbody.getDOMNode().rows[+row];
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith el && (el = el.cells[+col]);
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith }
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith return Y.one(el);
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith },
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith /**
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith Builds a CSS class name from the provided tokens. If the instance is
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith created with `cssPrefix` or `source` in the configuration, it will use this
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith prefix (the `_cssPrefix` of the `source` object) as the base token. This
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith allows class instances to generate markup with class names that correspond
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith to the parent class that is consuming them.
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith @method getClassName
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith @param {String} token* Any number of tokens to include in the class name
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith @return {String} The generated class name
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith @since 3.5.0
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith **/
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith getClassName: function () {
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith var args = toArray(arguments);
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith args.unshift(this._cssPrefix);
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith args.push(true);
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith return _getClassName.apply(ClassNameManager, args);
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith },
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith /**
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith Returns the `<tr>` Node from the given row index. If there is
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith no row at the given index, `null` is returned.
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith @method getRow
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith @param {Number} row Zero based index of the row
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith @return {Node}
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith @since 3.5.0
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith **/
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith // TODO: Support index as clientId => container.one('> #' + index)?
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith getRow: function (index) {
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith var tbody = this.get('container');
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith return Y.one(tbody && tbody.getDOMNode().rows[+index]);
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith },
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith /**
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith Creates the table's `<tbody>` content by assembling markup generated by
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith populating the `ROW\_TEMPLATE`, and `CELL\_TEMPLATE` templates with content
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith from the `columns` property and `modelList` attribute.
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith The rendering process happens in three stages:
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith 1. A row template is assembled from the `columns` property (see
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith `_createRowTemplate`)
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith 2. An HTML string is built up by concatening the application of the data in
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith each Model in the `modelList` to the row template. For cells with
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith `formatter`s, the function is called to generate cell content. Cells
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith with `nodeFormatter`s are ignored. For all other cells, the data value
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith from the Model attribute for the given column key is used. The
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith accumulated row markup is then inserted into the container.
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith 3. If any column is configured with a `nodeFormatter`, the `modelList` is
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith iterated again to apply the `nodeFormatter`s.
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith Supported properties of the column objects include:
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith * `key` - Used to link a column to an attribute in a Model.
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith * `name` - Used for columns that don't relate to an attribute in the Model
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith (`formatter` or `nodeFormatter` only) if the implementer wants a
59c94cbcd6e39e484a57bf3665a8ab98beafc57eLuke Smith predictable name to refer to in their CSS.
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith * `cellTemplate` - Overrides the instance's `CELL_TEMPLATE` for cells in
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith this column only.
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith * `formatter` - Used to customize or override the content value from the
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith Model. These do not have access to the cell or row Nodes and should
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith return string (HTML) content.
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith * `nodeFormatter` - Used to provide content for a cell as well as perform
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith any custom modifications on the cell or row Node that could not be
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith performed by `formatter`s. Should be used sparingly for better
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith performance.
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith * `emptyCellValue` - String (HTML) value to use if the Model data for a
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith column, or the content generated by a `formatter`, is the empty string,
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith `null`, or `undefined`.
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith * `allowHTML` - Set to `true` if a column value, `formatter`, or
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith `emptyCellValue` can contain HTML. This defaults to `false` to protect
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith against XSS.
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith * `className` - Space delimited CSS classes to add to all `<td>`s in a
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith column.
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith Column `formatter`s are passed an object (`o`) with the following
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith properties:
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith * `value` - The current value of the column's associated attribute, if
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith any.
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith * `data` - An object map of Model keys to their current values.
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith * `record` - The Model instance.
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith * `column` - The column configuration object for the current column.
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith * `className` - Initially empty string to allow `formatter`s to add CSS
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith classes to the cell's `<td>`.
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith * `rowIndex` - The zero-based row number.
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith * `rowClass` - Initially empty string to allow `formatter`s to add CSS
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith classes to the cell's containing row `<tr>`.
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith They may return a value or update `o.value` to assign specific HTML
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith content. A returned value has higher precedence.
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith Column `nodeFormatter`s are passed an object (`o`) with the following
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith properties:
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith * `value` - The current value of the column's associated attribute, if
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith any.
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith * `td` - The `<td>` Node instance.
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith * `cell` - The `<div>` liner Node instance if present, otherwise, the
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith `<td>`. When adding content to the cell, prefer appending into this
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith property.
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith * `data` - An object map of Model keys to their current values.
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith * `record` - The Model instance.
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith * `column` - The column configuration object for the current column.
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith * `rowIndex` - The zero-based row number.
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith They are expected to inject content into the cell's Node directly, including
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith any "empty" cell content. Each `nodeFormatter` will have access through the
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith Node API to all cells and rows in the `<tbody>`, but not to the `<table>`,
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith as it will not be attached yet.
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith If a `nodeFormatter` returns `false`, the `o.td` and `o.cell` Nodes will be
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith `destroy()`ed to remove them from the Node cache and free up memory. The
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith DOM elements will remain as will any content added to them. _It is highly
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith advisable to always return `false` from your `nodeFormatter`s_.
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith @method render
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith @return {BodyView} The instance
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith @chainable
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith @since 3.5.0
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith **/
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith render: function () {
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith var tbody = this.get('container'),
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith data = this.get('modelList'),
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith columns = this.columns;
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith // Needed for mutation
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith this._createRowTemplate(columns);
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith if (tbody && data) {
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith tbody.setContent(this._createDataHTML(columns));
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith this._applyNodeFormatters(tbody, columns);
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith }
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith this.bindUI();
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith return this;
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith },
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith // -- Protected and private methods ---------------------------------------
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith /**
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith Handles changes in the source's columns attribute. Redraws the table data.
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith @method _afterColumnsChange
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith @param {EventFacade} e The `columnsChange` event object
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith @protected
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith @since 3.5.0
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith **/
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith // TODO: Preserve existing DOM
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith // This will involve parsing and comparing the old and new column configs
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith // and reacting to four types of changes:
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith // 1. formatter, nodeFormatter, emptyCellValue changes
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith // 2. column deletions
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith // 3. column additions
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith // 4. column moves (preserve cells)
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith _afterColumnsChange: function (e) {
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith this.columns = this._parseColumns(e.newVal);
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith this.render();
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith },
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith /**
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith Handles modelList changes, including additions, deletions, and updates.
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith Modifies the existing table DOM accordingly.
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith @method _afterDataChange
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith @param {EventFacade} e The `change` event from the ModelList
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith @protected
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith @since 3.5.0
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith **/
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith _afterDataChange: function (e) {
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith // Baseline view will just rerender the tbody entirely
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith this.render();
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith },
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith /**
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith Reacts to a change in the instance's `modelList` attribute by breaking
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith down the bubbling relationship with the previous `modelList` and setting up
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith that relationship with the new one.
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith @method _afterModelListChange
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith @param {EventFacade} e The `modelListChange` event
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith @protected
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith @since 3.5.0
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith **/
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith _afterModelListChange: function (e) {
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith var old = e.prevVal,
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith now = e.newVal;
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith if (old && old.removeTarget) {
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith old.removeTarget(this);
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith }
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith if (now && now.addTarget(this)) {
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith now.addTarget(this);
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith }
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith },
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith /**
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith Iterates the `modelList`, and calls any `nodeFormatter`s found in the
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith `columns` param on the appropriate cell Nodes in the `tbody`.
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith @method _applyNodeFormatters
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith @param {Node} tbody The `<tbody>` Node whose columns to update
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith @param {Object[]} columns The column configurations
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith @protected
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith @since 3.5.0
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith **/
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith _applyNodeFormatters: function (tbody, columns) {
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith var source = this.source,
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith data = this.get('modelList'),
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith formatters = [],
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith linerQuery = '.' + this.getClassName('liner'),
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith rows, i, len;
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith // Only iterate the ModelList again if there are nodeFormatters
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith for (i = 0, len = columns.length; i < len; ++i) {
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith if (columns[i].nodeFormatter) {
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith formatters.push(i);
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith }
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith }
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith if (data && formatters.length) {
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith rows = tbody.get('childNodes');
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith data.each(function (record, index) {
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith var formatterData = {
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith data : record.toJSON(),
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith record : record,
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith rowIndex : index
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith },
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith row = rows.item(index),
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith i, len, col, key, cells, cell, keep;
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith if (row) {
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith cells = row.get('childNodes');
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith for (i = 0, len = formatters.length; i < len; ++i) {
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith cell = cells.item(formatters[i]);
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith if (cell) {
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith col = formatterData.column = columns[formatters[i]];
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith key = col.key || col.id;
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith formatterData.value = record.get(key);
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith formatterData.td = cell;
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith formatterData.cell = cell.one(linerQuery) || cell;
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith keep = col.nodeFormatter.call(source,formatterData);
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith if (keep === false) {
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith // Remove from the Node cache to reduce
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith // memory footprint. This also purges events,
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith // which you shouldn't be scoping to a cell
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith // anyway. You've been warned. Incidentally,
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith // you should always return false. Just sayin.
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith cell.destroy(true);
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith }
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith }
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith }
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith }
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith });
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith }
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith },
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith /**
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith Binds event subscriptions from the UI and the source (if assigned).
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith @method bindUI
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith @protected
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith @since 3.5.0
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith **/
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith bindUI: function () {
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith var handles = this._eventHandles,
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith data = this.get('modelList');
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith if (this.source && !handles.columnsChange) {
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith handles.columnsChange = this.source.after('columnsChange',
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith bind('_afterColumnsChange', this));
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith }
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith if (!handles.dataChange) {
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith handles.dataChange = this.after(
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith ['modelListChange', '*:change', '*:add', '*:remove', '*:reset'],
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith bind('_afterDataChange', this));
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith }
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith },
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith /**
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith The base token for classes created with the `getClassName` method.
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith @property _cssPrefix
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith @type {String}
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith @default 'yui3-table'
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith @protected
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith @since 3.5.0
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith **/
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith _cssPrefix: ClassNameManager.getClassName('table'),
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith /**
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith Iterates the `modelList` and applies each Model to the `_rowTemplate`,
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith allowing any column `formatter` or `emptyCellValue` to override cell
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith content for the appropriate column. The aggregated HTML string is
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith returned.
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith @method _createDataHTML
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith @param {Object[]} columns The column configurations to customize the
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith generated cell content or class names
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith @return {HTML} The markup for all Models in the `modelList`, each applied
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith to the `_rowTemplate`
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith @protected
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith @since 3.5.0
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith **/
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith _createDataHTML: function (columns) {
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith var data = this.get('modelList'),
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith html = '';
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith if (data) {
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith data.each(function (model, index) {
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith html += this._createRowHTML(model, index);
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith }, this);
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith }
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith return html;
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith },
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith /**
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith Applies the data of a given Model, modified by any column formatters and
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith supplemented by other template values to the instance's `_rowTemplate` (see
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith `_createRowTemplate`). The generated string is then returned.
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith The data from Model's attributes is fetched by `toJSON` and this data
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith object is appended with other properties to supply values to {placeholders}
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith in the template. For a template generated from a Model with 'foo' and 'bar'
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith attributes, the data object would end up with the following properties
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith before being used to populate the `_rowTemplate`:
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith * `clientID` - From Model, used the assign the `<tr>`'s 'id' attribute.
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith * `foo` - The value to populate the 'foo' column cell content. This
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith value will be the value stored in the Model's `foo` attribute, or the
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith result of the column's `formatter` if assigned. If the value is '',
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith `null`, or `undefined`, and the column's `emptyCellValue` is assigned,
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith that value will be used.
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith * `bar` - Same for the 'bar' column cell content.
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith * `foo-className` - String of CSS classes to apply to the `<td>`.
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith * `bar-className` - Same.
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith * `rowClass` - String of CSS classes to apply to the `<tr>`. This
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith will be the odd/even class per the specified index plus any additional
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith classes assigned by column formatters (via `o.rowClass`).
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith Because this object is available to formatters, any additional properties
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith can be added to fill in custom {placeholders} in the `_rowTemplate`.
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith @method _createRowHTML
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith @param {Model} model The Model instance to apply to the row template
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith @param {Number} index The index the row will be appearing
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith @return {HTML} The markup for the provided Model, less any `nodeFormatter`s
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith @protected
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith @since 3.5.0
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith **/
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith _createRowHTML: function (model, index) {
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith var data = model.toJSON(),
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith values = {
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith rowId : model.get('clientId'),
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith rowClass: (index % 2) ? this.CLASS_ODD : this.CLASS_EVEN
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith },
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith source = this.source || this,
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith columns = this.columns,
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith i, len, col, token, value, formatterData;
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith for (i = 0, len = columns.length; i < len; ++i) {
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith col = columns[i];
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith value = data[col.key];
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith token = col._id;
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith values[token + '-className'] = '';
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith if (col.formatter) {
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith formatterData = {
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith value : value,
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith data : data,
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith column : col,
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith record : model,
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith className: '',
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith rowClass : '',
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith rowIndex : index
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith };
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith if (typeof col.formatter === 'string') {
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith if (value !== undefined) {
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith // TODO: look for known formatters by string name
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith value = fromTemplate(col.formatter, formatterData);
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith }
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith } else {
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith // Formatters can either return a value
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith value = col.formatter.call(source, formatterData);
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith // or update the value property of the data obj passed
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith if (value === undefined) {
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith value = formatterData.value;
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith }
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith values[token + '-className'] = formatterData.className;
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith values.rowClass += ' ' + formatterData.rowClass;
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith }
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith }
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith if (value === undefined || value === null || value === '') {
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith value = col.emptyCellValue || '';
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith }
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith values[token] = col.allowHTML ? value : htmlEscape(value);
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith values.rowClass = values.rowClass.replace(/\s+/g, ' ');
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith }
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith return fromTemplate(this._rowTemplate, values);
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith },
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith /**
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith Creates a custom HTML template string for use in generating the markup for
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith individual table rows with {placeholder}s to capture data from the Models
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith in the `modelList` attribute or from column `formatter`s.
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith Assigns the `_rowTemplate` property.
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith @method _createRowTemplate
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith @param {Object[]} columns Array of column configuration objects
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith @protected
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith @since 3.5.0
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith **/
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith _createRowTemplate: function (columns) {
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith var html = '',
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith cellTemplate = this.CELL_TEMPLATE,
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith i, len, col, key, token, headers, tokenValues;
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith for (i = 0, len = columns.length; i < len; ++i) {
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith col = columns[i];
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith key = col.key;
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith token = col._id;
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith // Only include headers if there are more than one
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith headers = (col._headers || []).length > 1 ?
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith 'headers="' + col._headers.join(' ') + '"' : '';
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith tokenValues = {
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith content : '{' + token + '}',
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith headers : headers,
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith className: this.getClassName('col', token) + ' ' +
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith (col.className || '') + ' ' +
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith this.getClassName('cell') +
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith ' {' + token + '-className}'
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith };
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith if (col.nodeFormatter) {
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith // Defer all node decoration to the formatter
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith tokenValues.content = '';
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith }
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith html += fromTemplate(col.cellTemplate || cellTemplate, tokenValues);
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith }
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith this._rowTemplate = fromTemplate(this.ROW_TEMPLATE, {
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith content: html
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith });
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith },
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith /**
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith Destroys the instance.
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith @method destructor
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith @protected
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith @since 3.5.0
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith **/
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith destructor: function () {
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith // will unbind the bubble relationship and clear the table if necessary
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith this.set('modelList', null);
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith (new Y.EventHandle(YObject.values(this._eventHandles))).detach();
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith },
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith /**
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith Holds the event subscriptions needing to be detached when the instance is
f5df3320c255ef9e7c007469613dc31b4f91a3d8Luke Smith `destroy()`ed.
f5df3320c255ef9e7c007469613dc31b4f91a3d8Luke Smith
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith @property _eventHandles
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith @type {Object}
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith @default undefined (initially unset)
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith @protected
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith @since 3.5.0
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith **/
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith //_eventHandles: null,
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith /**
f5df3320c255ef9e7c007469613dc31b4f91a3d8Luke Smith Initializes the instance. Reads the following configuration properties in
f5df3320c255ef9e7c007469613dc31b4f91a3d8Luke Smith addition to the instance attributes:
f5df3320c255ef9e7c007469613dc31b4f91a3d8Luke Smith
f5df3320c255ef9e7c007469613dc31b4f91a3d8Luke Smith * `columns` - (REQUIRED) The initial column information
f5df3320c255ef9e7c007469613dc31b4f91a3d8Luke Smith * `cssPrefix` - The base string for classes generated by `getClassName`
f5df3320c255ef9e7c007469613dc31b4f91a3d8Luke Smith * `source` - The object to serve as source of truth for column info
f5df3320c255ef9e7c007469613dc31b4f91a3d8Luke Smith
f5df3320c255ef9e7c007469613dc31b4f91a3d8Luke Smith @method initializer
8fff801a4a38e13d6ff8181ff097fb01d058d617Luke Smith @param {Object} config Configuration data
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith @protected
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith @since 3.5.0
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith **/
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith initializer: function (config) {
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith var cssPrefix = config.cssPrefix || (config.source || {}).cssPrefix,
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith modelList = this.get('modelList');
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith this.source = config.source;
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith this.columns = this._parseColumns(config.columns);
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith this._eventHandles = {};
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith if (cssPrefix) {
f5df3320c255ef9e7c007469613dc31b4f91a3d8Luke Smith this._cssPrefix = cssPrefix;
f5df3320c255ef9e7c007469613dc31b4f91a3d8Luke Smith }
f5df3320c255ef9e7c007469613dc31b4f91a3d8Luke Smith
f5df3320c255ef9e7c007469613dc31b4f91a3d8Luke Smith this.CLASS_ODD = this.getClassName('odd');
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith this.CLASS_EVEN = this.getClassName('even');
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith this.after('modelListChange', bind('_afterModelListChange', this));
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith if (modelList && modelList.addTarget) {
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith modelList.addTarget(this);
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith }
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith },
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith /**
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith Flattens an array of potentially nested column configurations into a single
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith depth array of data columns. Columns that have children are disregarded in
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith favor of searching their child columns. The resulting array corresponds 1:1
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith with columns that will contain data in the `<tbody>`.
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith @method _parseColumns
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith @param {Object[]} data Array of unfiltered column configuration objects
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith @param {Object[]} columns Working array of data columns. Used for recursion.
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith @return {Object[]} Only those columns that will be rendered.
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith @protected
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith @since 3.5.0
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith **/
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith _parseColumns: function (data, columns) {
f5443cec5378e1eba162c289f05b690b699c9c7bLuke Smith var col, i, len;
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith columns || (columns = []);
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith if (isArray(data) && data.length) {
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith for (i = 0, len = data.length; i < len; ++i) {
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith col = data[i];
32624ce45f113c04dfa5469b3cc77df42c4c46f4Luke Smith
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith if (typeof col === 'string') {
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith col = { key: col };
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith }
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith
4eafc0c9b36f7e8efc8808ab27dbed7ff8dc87abLuke Smith if (col.key || col.formatter || col.nodeFormatter) {
col.index = columns.length;
columns.push(col);
} else if (col.children) {
this._parseColumns(col.children, columns);
}
}
}
return columns;
}
/**
The HTML template used to create a full row of markup for a single Model in
the `modelList` plus any customizations defined in the column
configurations.
@property _rowTemplate
@type {HTML}
@default (initially unset)
@protected
@since 3.5.0
**/
//_rowTemplate: null
}, {
ATTRS: {
modelList: {
setter: '_setModelList'
}
}
});