head.js revision 1080d9c735088a474affe30611ae889315840a17
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke SmithView class responsible for rendering the `<thead>` section of a table. Used as
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smiththe default `headerView` for `Y.DataTable.Base` and `Y.DataTable` classes.
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke SmithTranslates the provided array of column configuration objects into a rendered
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith`<thead>` based on the data in those objects.
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke SmithThe structure of the column data is expected to be a single array of objects,
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smithwhere each object corresponds to a `<th>`. Those objects may contain a
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith`children` property containing a similarly structured array to indicate the
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smithnested cells should be grouped under the parent column's colspan in a separate
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smithrow of header cells. E.g.
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smithnew Y.DataTable.HeaderView({
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith container: tableNode,
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith { key: 'id' }, // no nesting
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith { key: 'name', children: [
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith { key: 'firstName', label: 'First' },
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith { key: 'lastName', label: 'Last' } ] }
e0a1afd287c016be5722249b10ba81684f33886bLuke Smith</code></pre>
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke SmithThis would translate to the following visualization:
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith---------------------
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith| |---------------
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith| id | First | Last |
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith---------------------
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke SmithSupported properties of the column objects include:
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith * `label` - The HTML content of the header cell.
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith * `key` - If `label` is not specified, the `key` is used for content.
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith * `children` - Array of columns to appear below this column in the next
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith * `abbr` - The content of the 'abbr' attribute of the `<th>`
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke SmithThrough the life of instantiation and rendering, the column objects will have
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smiththe following properties added to them:
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith * `colspan` - To supply the `<th>` attribute
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith * `rowspan` - To supply the `<th>` attribute
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith * `parent` - If the column is a child of another column, this points to
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith its parent column
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith * `_yuid` - A unique YUI generated id used as the `<th>`'s 'id' for
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith reference in the data `<td>`'s 'headers' attribute.
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke SmithThe column object is also used to provide values for {placeholder} tokens in the
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smithinstance's `CELL_TEMPLATE`, so you can modify the template and include other
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smithcolumn object properties to populate them.
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith@module datatable-head
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith@class HeaderView
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith@namespace DataTable
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith@extends View
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke SmithY.namespace('DataTable').HeaderView = Y.Base.create('tableHeader', Y.View, [], {
0e7d399f99fcb097a927af7e6588f393740585a2Luke Smith // -- Instance properties -------------------------------------------------
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith Template used to create the table's header cell markup. Override this to
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith customize how these cells' markup is created.
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @property CELL_TEMPLATE
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @type {HTML}
e0a1afd287c016be5722249b10ba81684f33886bLuke Smith @default '<th id="{_yuid}" abbr="{abbr} colspan="{colspan}" rowspan="{rowspan}"><div class="{linerClass}">{content}</div></th>'
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith '<th id="{_yuid}" abbr="{abbr}" ' +
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith 'colspan="{colspan}" rowspan="{rowspan}">' +
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith '<div class="{linerClass}">' +
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith '{content}' +
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith The data representation of the header rows to render. This is assigned by
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith parsing the `columns` configuration array, and is used by the render()
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @property columns
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @type {Array[]}
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @default (initially unset)
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith //TODO: should this be protected?
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith //columns: null,
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith The object that serves as the source of truth for column and row data.
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith This property is assigned at instantiation from the `source` property of
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith the configuration object passed to the constructor.
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @property source
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @type {Object}
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @default (initially unset)
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith //TODO: should this be protected?
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith //source: null,
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith Template used to create the table's header row markup. Override this to
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith customize the row markup.
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @property ROW_TEMPLATE
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @type {HTML}
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @default '<tr>{content}</tr>'
0e7d399f99fcb097a927af7e6588f393740585a2Luke Smith '<tr>{content}</tr>',
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith Template used to create the table's thead markup.
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @property THEAD_TEMPLATE
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @type {HTML}
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @default '<thead class="{classes}">{content}</thead>'
0e7d399f99fcb097a927af7e6588f393740585a2Luke Smith '<thead class="{classes}">{content}</thead>',
0e7d399f99fcb097a927af7e6588f393740585a2Luke Smith // -- Public methods ------------------------------------------------------
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith Builds a CSS class name from the provided tokens. If the instance is
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith created with `cssPrefix` or `source` in the configuration, it will use this
e0a1afd287c016be5722249b10ba81684f33886bLuke Smith prefix (the `\_cssPrefix` of the `source` object) as the base token. This
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith allows class instances to generate markup with class names that correspond
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith to the parent class that is consuming them.
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @method getClassName
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @param {String} token* Any number of tokens to include in the class name
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @return {String} The generated class name
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith getClassName: function () {
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith return _getClassName.apply(ClassNameManager, args);
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith Creates the `<thead>` Node by assembling markup generated by populating the
e0a1afd287c016be5722249b10ba81684f33886bLuke Smith `THEAD\_TEMPLATE`, `ROW\_TEMPLATE`, and `CELL\_TEMPLATE` templates with
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith content from the `columns` property.
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @method render
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @return {HeaderView} The instance
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith render: function () {
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith // TODO: remove dependence on this.source
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith Y.log('Could not render thead. Table not provided', 'warn');
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith return this;
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith existing = table.one('> .' + this.getClassName('columns'));
79fac3c43e396f54a5fb368ac33ff7c21df23397Luke Smith for (i = 0, len = columns.length; i < len; ++i) {
79fac3c43e396f54a5fb368ac33ff7c21df23397Luke Smith for (j = 0, jlen = columns[i].length; j < jlen; ++j) {
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith table.insertBefore(thead, table.one('> tfoot, > tbody'));
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith return this;
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith // -- Protected and private properties and methods ------------------------
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith The base token for classes created with the `getClassName` method.
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @property _cssPrefix
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @type {String}
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @default 'yui3-table'
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith _cssPrefix: ClassNameManager.getClassName('table'),
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith Handles changes in the source's columns attribute. Redraws the headers.
1080d9c735088a474affe30611ae889315840a17Luke Smith @method _afterColumnsChange
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @param {EventFacade} e The `columnsChange` event object
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith Binds event subscriptions from the UI and the source (if assigned).
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @method bindUI
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith bindUI: function () {
1080d9c735088a474affe30611ae889315840a17Luke Smith if (this.source && !this._eventHandles.columnsChange) {
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith // TODO: How best to decouple this?
1080d9c735088a474affe30611ae889315840a17Luke Smith Destroys the instance.
1080d9c735088a474affe30611ae889315840a17Luke Smith @method destructor
1080d9c735088a474affe30611ae889315840a17Luke Smith destructor: function () {
1080d9c735088a474affe30611ae889315840a17Luke Smith (new Y.EventHandle(Y.Object.values(this._eventHandles))).detach();
1080d9c735088a474affe30611ae889315840a17Luke Smith Holds the event subscriptions needing to be detached when the instance is
1080d9c735088a474affe30611ae889315840a17Luke Smith `destroy()`ed.
1080d9c735088a474affe30611ae889315840a17Luke Smith @property _eventHandles
1080d9c735088a474affe30611ae889315840a17Luke Smith @type {Object}
1080d9c735088a474affe30611ae889315840a17Luke Smith @default undefined (initially unset)
1080d9c735088a474affe30611ae889315840a17Luke Smith //_eventHandles: null,
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith Initializes the instance. Reads the following configuration properties:
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith * `columns` - (REQUIRED) The initial column information
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith * `cssPrefix` - The base string for classes generated by `getClassName`
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith * `source` - The object to serve as source of truth for column info
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @method initializer
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @param {Object} config Configuration data
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith var cssPrefix = config.cssPrefix || (config.source || {}).cssPrefix;
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith this.columns = this._parseColumns(config.columns);
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith Translate the input column format into a structure useful for rendering a
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith `<thead>`, rows, and cells. The structure of the input is expected to be a
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith single array of objects, where each object corresponds to a `<th>`. Those
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith objects may contain a `children` property containing a similarly structured
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith array to indicate the nested cells should be grouped under the parent
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith column's colspan in a separate row of header cells. E.g.
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith { key: 'id' }, // no nesting
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith { key: 'name', children: [
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith { key: 'firstName', label: 'First' },
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith { key: 'lastName', label: 'Last' } ] }
e0a1afd287c016be5722249b10ba81684f33886bLuke Smith </code></pre>
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith would indicate two header rows with the first column 'id' being assigned a
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith `rowspan` of `2`, the 'name' column appearing in the first row with a
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith `colspan` of `2`, and the 'firstName' and 'lastName' columns appearing in
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith the second row, below the 'name' column.
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith ---------------------
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith | |---------------
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith | id | First | Last |
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith ---------------------
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith Supported properties of the column objects include:
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith * `label` - The HTML content of the header cell.
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith * `key` - If `label` is not specified, the `key` is used for content.
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith * `children` - Array of columns to appear below this column in the next
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith * `abbr` - The content of the 'abbr' attribute of the `<th>`
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith The output structure is basically a simulation of the `<thead>` structure
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith with arrays for rows and objects for cells. Column objects have the
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith following properties added to them:
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith * `colspan` - Per the `<th>` attribute
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith * `rowspan` - Per the `<th>` attribute
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith * `parent` - If the column is a child of another column, this points to
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith its parent column
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith * `_yuid` - A unique YUI generated id used as the `<th>`'s 'id' for
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith reference in the data `<td>`'s 'headers' attribute.
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith The column object is also used to provide values for {placeholder}
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith replacement in the `CELL_TEMPLATE`, so you can modify the template and
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith include other column object properties to populate them.
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @method _parseColumns
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @param {Object[]} data Array of column object data
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @return {Array[]} An array of arrays corresponding to the header row
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith structure to render
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith // First pass, assign colspans and calculate row count for
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith // non-nested headers' rowspan
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith // break to let the while loop process the children
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith // All columns in this row are processed
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith // Can't use .length because in 3+ rows, colspan
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith // needs to aggregate the colspans of children
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith // Assign the parent column for ease of navigation
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith // Second pass, build row arrays and assign rowspan
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith // parent cells must assume rowspan 1 (long story)
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith // break to let the while loop process the children
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith // collect the IDs of parent cols
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith // All columns in this row are processed