head.js revision e0a1afd287c016be5722249b10ba81684f33886b
6cd85fc002ad88c48179730400dc0bc36a7a9f5bDav Glass/**
4d589fe0c1bf5d088a90cdf29f3bc777942006cbDav GlassView class responsible for rendering the `<thead>` section of a table. Used as
ad598bab533c3f4f0bdb0f536bcf5e0ac0769d15Dav Glassthe default `headerView` for `Y.DataTable.Base` and `Y.DataTable` classes.
4d589fe0c1bf5d088a90cdf29f3bc777942006cbDav Glass
4d589fe0c1bf5d088a90cdf29f3bc777942006cbDav GlassTranslates the provided array of column configuration objects into a rendered
4d589fe0c1bf5d088a90cdf29f3bc777942006cbDav Glass`<thead>` based on the data in those objects.
4d589fe0c1bf5d088a90cdf29f3bc777942006cbDav Glass
ad598bab533c3f4f0bdb0f536bcf5e0ac0769d15Dav Glass
4d589fe0c1bf5d088a90cdf29f3bc777942006cbDav GlassThe structure of the column data is expected to be a single array of objects,
4d589fe0c1bf5d088a90cdf29f3bc777942006cbDav Glasswhere each object corresponds to a `<th>`. Those objects may contain a
4d589fe0c1bf5d088a90cdf29f3bc777942006cbDav Glass`children` property containing a similarly structured array to indicate the
4d589fe0c1bf5d088a90cdf29f3bc777942006cbDav Glassnested cells should be grouped under the parent column's colspan in a separate
4d589fe0c1bf5d088a90cdf29f3bc777942006cbDav Glassrow of header cells. E.g.
4d589fe0c1bf5d088a90cdf29f3bc777942006cbDav Glass
4d589fe0c1bf5d088a90cdf29f3bc777942006cbDav Glass<pre><code>
482da2d388e0f999f372383039af944e21bc717bDav Glassnew Y.DataTable.HeaderView({
482da2d388e0f999f372383039af944e21bc717bDav Glass container: tableNode,
6cd85fc002ad88c48179730400dc0bc36a7a9f5bDav Glass columns: [
482da2d388e0f999f372383039af944e21bc717bDav Glass { key: 'id' }, // no nesting
713a27b6ab5ab057e9b4ab551617b54730e8906eDav Glass { key: 'name', children: [
4d589fe0c1bf5d088a90cdf29f3bc777942006cbDav Glass { key: 'firstName', label: 'First' },
6cd85fc002ad88c48179730400dc0bc36a7a9f5bDav Glass { key: 'lastName', label: 'Last' } ] }
6cd85fc002ad88c48179730400dc0bc36a7a9f5bDav Glass ]
482da2d388e0f999f372383039af944e21bc717bDav Glass}).render();
f05c0eb9de3e3021b733c24fb7d17ba9ae093272Dav Glass</code></pre>
f05c0eb9de3e3021b733c24fb7d17ba9ae093272Dav Glass
f05c0eb9de3e3021b733c24fb7d17ba9ae093272Dav GlassThis would translate to the following visualization:
f05c0eb9de3e3021b733c24fb7d17ba9ae093272Dav Glass
f05c0eb9de3e3021b733c24fb7d17ba9ae093272Dav Glass<pre>
f05c0eb9de3e3021b733c24fb7d17ba9ae093272Dav Glass---------------------
4d589fe0c1bf5d088a90cdf29f3bc777942006cbDav Glass| | name |
3b3bd34996b581ab171be1465201869cb009dbadDav Glass| |---------------
4d589fe0c1bf5d088a90cdf29f3bc777942006cbDav Glass| id | First | Last |
4d589fe0c1bf5d088a90cdf29f3bc777942006cbDav Glass---------------------
3b3bd34996b581ab171be1465201869cb009dbadDav Glass</pre>
4d589fe0c1bf5d088a90cdf29f3bc777942006cbDav Glass
4d589fe0c1bf5d088a90cdf29f3bc777942006cbDav GlassSupported properties of the column objects include:
3b3bd34996b581ab171be1465201869cb009dbadDav Glass
4d589fe0c1bf5d088a90cdf29f3bc777942006cbDav Glass * `label` - The HTML content of the header cell.
4d589fe0c1bf5d088a90cdf29f3bc777942006cbDav Glass * `key` - If `label` is not specified, the `key` is used for content.
6cd85fc002ad88c48179730400dc0bc36a7a9f5bDav Glass * `children` - Array of columns to appear below this column in the next
3b3bd34996b581ab171be1465201869cb009dbadDav Glass row.
3b3bd34996b581ab171be1465201869cb009dbadDav Glass * `abbr` - The content of the 'abbr' attribute of the `<th>`
482da2d388e0f999f372383039af944e21bc717bDav Glass
3b3bd34996b581ab171be1465201869cb009dbadDav GlassThrough the life of instantiation and rendering, the column objects will have
3b3bd34996b581ab171be1465201869cb009dbadDav Glassthe following properties added to them:
3b3bd34996b581ab171be1465201869cb009dbadDav Glass
482da2d388e0f999f372383039af944e21bc717bDav Glass * `colspan` - To supply the `<th>` attribute
3b3bd34996b581ab171be1465201869cb009dbadDav Glass * `rowspan` - To supply the `<th>` attribute
3b3bd34996b581ab171be1465201869cb009dbadDav Glass * `parent` - If the column is a child of another column, this points to
3b3bd34996b581ab171be1465201869cb009dbadDav Glass its parent column
3b3bd34996b581ab171be1465201869cb009dbadDav Glass * `_yuid` - A unique YUI generated id used as the `<th>`'s 'id' for
482da2d388e0f999f372383039af944e21bc717bDav Glass reference in the data `<td>`'s 'headers' attribute.
3b3bd34996b581ab171be1465201869cb009dbadDav Glass
3b3bd34996b581ab171be1465201869cb009dbadDav GlassThe column object is also used to provide values for {placeholder} tokens in the
3b3bd34996b581ab171be1465201869cb009dbadDav Glassinstance's `CELL_TEMPLATE`, so you can modify the template and include other
482da2d388e0f999f372383039af944e21bc717bDav Glasscolumn object properties to populate them.
eba99cf5219728ad7993f0b1ed3b75f7fdb78193Dav Glass
eba99cf5219728ad7993f0b1ed3b75f7fdb78193Dav Glass@module datatable-head
eba99cf5219728ad7993f0b1ed3b75f7fdb78193Dav Glass@class HeaderView
eba99cf5219728ad7993f0b1ed3b75f7fdb78193Dav Glass@namespace DataTable
eba99cf5219728ad7993f0b1ed3b75f7fdb78193Dav Glass@extends View
3b3bd34996b581ab171be1465201869cb009dbadDav Glass**/
3b3bd34996b581ab171be1465201869cb009dbadDav Glassvar fromTemplate = Y.Lang.sub,
3b3bd34996b581ab171be1465201869cb009dbadDav Glass Lang = Y.Lang,
eba99cf5219728ad7993f0b1ed3b75f7fdb78193Dav Glass isArray = Lang.isArray,
3b3bd34996b581ab171be1465201869cb009dbadDav Glass toArray = Y.Array,
3b3bd34996b581ab171be1465201869cb009dbadDav Glass
3b3bd34996b581ab171be1465201869cb009dbadDav Glass ClassNameManager = Y.ClassNameManager,
eba99cf5219728ad7993f0b1ed3b75f7fdb78193Dav Glass _getClassName = ClassNameManager.getClassName;
713a27b6ab5ab057e9b4ab551617b54730e8906eDav Glass
eba99cf5219728ad7993f0b1ed3b75f7fdb78193Dav GlassY.namespace('DataTable').HeaderView = Y.Base.create('tableHeader', Y.View, [], {
eba99cf5219728ad7993f0b1ed3b75f7fdb78193Dav Glass // -- Instance properties -------------------------------------------------
eba99cf5219728ad7993f0b1ed3b75f7fdb78193Dav Glass
a201dfca71f32a095917fac03611f2f999cb3b97Dav Glass /**
eba99cf5219728ad7993f0b1ed3b75f7fdb78193Dav Glass Template used to create the table's header cell markup. Override this to
713a27b6ab5ab057e9b4ab551617b54730e8906eDav Glass customize how these cells' markup is created.
713a27b6ab5ab057e9b4ab551617b54730e8906eDav Glass
713a27b6ab5ab057e9b4ab551617b54730e8906eDav Glass @property CELL_TEMPLATE
a201dfca71f32a095917fac03611f2f999cb3b97Dav Glass @type {HTML}
713a27b6ab5ab057e9b4ab551617b54730e8906eDav Glass @default '<th id="{_yuid}" abbr="{abbr} colspan="{colspan}" rowspan="{rowspan}"><div class="{linerClass}">{content}</div></th>'
a201dfca71f32a095917fac03611f2f999cb3b97Dav Glass **/
713a27b6ab5ab057e9b4ab551617b54730e8906eDav Glass CELL_TEMPLATE :
482da2d388e0f999f372383039af944e21bc717bDav Glass '<th id="{_yuid}" abbr="{abbr}" ' +
3b3bd34996b581ab171be1465201869cb009dbadDav Glass 'colspan="{colspan}" rowspan="{rowspan}">' +
3b3bd34996b581ab171be1465201869cb009dbadDav Glass '<div class="{linerClass}">' +
3b3bd34996b581ab171be1465201869cb009dbadDav Glass '{content}' +
3b3bd34996b581ab171be1465201869cb009dbadDav Glass '</div>' +
482da2d388e0f999f372383039af944e21bc717bDav Glass '</th>',
3b3bd34996b581ab171be1465201869cb009dbadDav Glass
3b3bd34996b581ab171be1465201869cb009dbadDav Glass /**
3b3bd34996b581ab171be1465201869cb009dbadDav Glass The data representation of the header rows to render. This is assigned by
482da2d388e0f999f372383039af944e21bc717bDav Glass parsing the `columns` configuration array, and is used by the render()
3b3bd34996b581ab171be1465201869cb009dbadDav Glass method.
3b3bd34996b581ab171be1465201869cb009dbadDav Glass
3b3bd34996b581ab171be1465201869cb009dbadDav Glass @property columns
3b3bd34996b581ab171be1465201869cb009dbadDav Glass @type {Array[]}
3b3bd34996b581ab171be1465201869cb009dbadDav Glass @default (initially unset)
482da2d388e0f999f372383039af944e21bc717bDav Glass **/
3b3bd34996b581ab171be1465201869cb009dbadDav Glass //TODO: should this be protected?
3b3bd34996b581ab171be1465201869cb009dbadDav Glass //columns: null,
3b3bd34996b581ab171be1465201869cb009dbadDav Glass
482da2d388e0f999f372383039af944e21bc717bDav Glass /**
3b3bd34996b581ab171be1465201869cb009dbadDav Glass The object that serves as the source of truth for column and row data.
3b3bd34996b581ab171be1465201869cb009dbadDav Glass This property is assigned at instantiation from the `source` property of
eba99cf5219728ad7993f0b1ed3b75f7fdb78193Dav Glass the configuration object passed to the constructor.
482da2d388e0f999f372383039af944e21bc717bDav Glass
eba99cf5219728ad7993f0b1ed3b75f7fdb78193Dav Glass @property source
6cd85fc002ad88c48179730400dc0bc36a7a9f5bDav Glass @type {Object}
713a27b6ab5ab057e9b4ab551617b54730e8906eDav Glass @default (initially unset)
482da2d388e0f999f372383039af944e21bc717bDav Glass **/
713a27b6ab5ab057e9b4ab551617b54730e8906eDav Glass //TODO: should this be protected?
3b3bd34996b581ab171be1465201869cb009dbadDav Glass //source: null,
482da2d388e0f999f372383039af944e21bc717bDav Glass
3b3bd34996b581ab171be1465201869cb009dbadDav Glass /**
482da2d388e0f999f372383039af944e21bc717bDav Glass Template used to create the table's header row markup. Override this to
482da2d388e0f999f372383039af944e21bc717bDav Glass customize the row markup.
482da2d388e0f999f372383039af944e21bc717bDav Glass
4d589fe0c1bf5d088a90cdf29f3bc777942006cbDav Glass @property ROW_TEMPLATE
482da2d388e0f999f372383039af944e21bc717bDav Glass @type {HTML}
4d589fe0c1bf5d088a90cdf29f3bc777942006cbDav Glass @default '<tr>{content}</tr>'
6cd85fc002ad88c48179730400dc0bc36a7a9f5bDav Glass **/
482da2d388e0f999f372383039af944e21bc717bDav Glass ROW_TEMPLATE:
482da2d388e0f999f372383039af944e21bc717bDav Glass '<tr>{content}</tr>',
6cd85fc002ad88c48179730400dc0bc36a7a9f5bDav Glass
6cd85fc002ad88c48179730400dc0bc36a7a9f5bDav Glass /**
eba99cf5219728ad7993f0b1ed3b75f7fdb78193Dav Glass Template used to create the table's thead markup.
6cd85fc002ad88c48179730400dc0bc36a7a9f5bDav Glass
eba99cf5219728ad7993f0b1ed3b75f7fdb78193Dav Glass @property THEAD_TEMPLATE
6cd85fc002ad88c48179730400dc0bc36a7a9f5bDav Glass @type {HTML}
eba99cf5219728ad7993f0b1ed3b75f7fdb78193Dav Glass @default '<thead class="{classes}">{content}</thead>'
6cd85fc002ad88c48179730400dc0bc36a7a9f5bDav Glass **/
eba99cf5219728ad7993f0b1ed3b75f7fdb78193Dav Glass THEAD_TEMPLATE:
482da2d388e0f999f372383039af944e21bc717bDav Glass '<thead class="{classes}">{content}</thead>',
6cd85fc002ad88c48179730400dc0bc36a7a9f5bDav Glass
4d589fe0c1bf5d088a90cdf29f3bc777942006cbDav Glass
4d589fe0c1bf5d088a90cdf29f3bc777942006cbDav Glass // -- Public methods ------------------------------------------------------
4d589fe0c1bf5d088a90cdf29f3bc777942006cbDav Glass
4d589fe0c1bf5d088a90cdf29f3bc777942006cbDav Glass /**
4d589fe0c1bf5d088a90cdf29f3bc777942006cbDav Glass Destroys the instance.
4d589fe0c1bf5d088a90cdf29f3bc777942006cbDav Glass
eba99cf5219728ad7993f0b1ed3b75f7fdb78193Dav Glass @method destructor
eba99cf5219728ad7993f0b1ed3b75f7fdb78193Dav Glass **/
6cd85fc002ad88c48179730400dc0bc36a7a9f5bDav Glass destructor: function () {
6cd85fc002ad88c48179730400dc0bc36a7a9f5bDav Glass (new Y.EventHandle(this._eventHandles)).detach();
eba99cf5219728ad7993f0b1ed3b75f7fdb78193Dav Glass },
eba99cf5219728ad7993f0b1ed3b75f7fdb78193Dav Glass
eba99cf5219728ad7993f0b1ed3b75f7fdb78193Dav Glass /**
eba99cf5219728ad7993f0b1ed3b75f7fdb78193Dav Glass Builds a CSS class name from the provided tokens. If the instance is
eba99cf5219728ad7993f0b1ed3b75f7fdb78193Dav Glass created with `cssPrefix` or `source` in the configuration, it will use this
eba99cf5219728ad7993f0b1ed3b75f7fdb78193Dav Glass prefix (the `\_cssPrefix` of the `source` object) as the base token. This
eba99cf5219728ad7993f0b1ed3b75f7fdb78193Dav Glass allows class instances to generate markup with class names that correspond
f05c0eb9de3e3021b733c24fb7d17ba9ae093272Dav Glass to the parent class that is consuming them.
eba99cf5219728ad7993f0b1ed3b75f7fdb78193Dav Glass
3b3bd34996b581ab171be1465201869cb009dbadDav Glass @method getClassName
3b3bd34996b581ab171be1465201869cb009dbadDav Glass @param {String} token* Any number of tokens to include in the class name
6cd85fc002ad88c48179730400dc0bc36a7a9f5bDav Glass @return {String} The generated class name
eba99cf5219728ad7993f0b1ed3b75f7fdb78193Dav Glass **/
eba99cf5219728ad7993f0b1ed3b75f7fdb78193Dav Glass getClassName: function () {
6cd85fc002ad88c48179730400dc0bc36a7a9f5bDav Glass var args = toArray(arguments);
eba99cf5219728ad7993f0b1ed3b75f7fdb78193Dav Glass args.unshift(this._cssPrefix);
6cd85fc002ad88c48179730400dc0bc36a7a9f5bDav Glass args.push(true);
3b3bd34996b581ab171be1465201869cb009dbadDav Glass
3b3bd34996b581ab171be1465201869cb009dbadDav Glass return _getClassName.apply(ClassNameManager, args);
3b3bd34996b581ab171be1465201869cb009dbadDav Glass },
3b3bd34996b581ab171be1465201869cb009dbadDav Glass
3b3bd34996b581ab171be1465201869cb009dbadDav Glass /**
3b3bd34996b581ab171be1465201869cb009dbadDav Glass Creates the `<thead>` Node by assembling markup generated by populating the
3b3bd34996b581ab171be1465201869cb009dbadDav Glass `THEAD\_TEMPLATE`, `ROW\_TEMPLATE`, and `CELL\_TEMPLATE` templates with
3b3bd34996b581ab171be1465201869cb009dbadDav Glass content from the `columns` property.
3b3bd34996b581ab171be1465201869cb009dbadDav Glass
3b3bd34996b581ab171be1465201869cb009dbadDav Glass @method render
482da2d388e0f999f372383039af944e21bc717bDav Glass @return {HeaderView} The instance
3b3bd34996b581ab171be1465201869cb009dbadDav Glass @chainable
3b3bd34996b581ab171be1465201869cb009dbadDav Glass **/
3b3bd34996b581ab171be1465201869cb009dbadDav Glass render: function () {
3b3bd34996b581ab171be1465201869cb009dbadDav Glass var table = this.get('container'),
3b3bd34996b581ab171be1465201869cb009dbadDav Glass columns = this.columns,
3b3bd34996b581ab171be1465201869cb009dbadDav Glass thead = this.source._theadNode,
3b3bd34996b581ab171be1465201869cb009dbadDav Glass defaults = {
3b3bd34996b581ab171be1465201869cb009dbadDav Glass abbr: '',
6cd85fc002ad88c48179730400dc0bc36a7a9f5bDav Glass colspan: 1,
3b3bd34996b581ab171be1465201869cb009dbadDav Glass rowspan: 1,
3b3bd34996b581ab171be1465201869cb009dbadDav Glass // TODO: remove dependence on this.source
6cd85fc002ad88c48179730400dc0bc36a7a9f5bDav Glass linerClass: this.getClassName('liner')
a201dfca71f32a095917fac03611f2f999cb3b97Dav Glass },
713a27b6ab5ab057e9b4ab551617b54730e8906eDav Glass existing, replace, i, len, j, jlen, col, html;
482da2d388e0f999f372383039af944e21bc717bDav Glass
482da2d388e0f999f372383039af944e21bc717bDav Glass table = Y.one(table);
eba99cf5219728ad7993f0b1ed3b75f7fdb78193Dav Glass if (table && table.get('tagName') !== 'TABLE') {
eba99cf5219728ad7993f0b1ed3b75f7fdb78193Dav Glass table = table.one('table');
eba99cf5219728ad7993f0b1ed3b75f7fdb78193Dav Glass }
482da2d388e0f999f372383039af944e21bc717bDav Glass
482da2d388e0f999f372383039af944e21bc717bDav Glass if (!table) {
482da2d388e0f999f372383039af944e21bc717bDav Glass Y.log('Could not render thead. Table not provided', 'warn');
482da2d388e0f999f372383039af944e21bc717bDav Glass return this;
482da2d388e0f999f372383039af944e21bc717bDav Glass }
482da2d388e0f999f372383039af944e21bc717bDav Glass
482da2d388e0f999f372383039af944e21bc717bDav Glass existing = table.one('> .' + this.getClassName('columns'));
482da2d388e0f999f372383039af944e21bc717bDav Glass replace = existing && (!thead || !thead.compareTo(existing));
482da2d388e0f999f372383039af944e21bc717bDav Glass
482da2d388e0f999f372383039af944e21bc717bDav Glass if (!thead) {
482da2d388e0f999f372383039af944e21bc717bDav Glass thead = '';
482da2d388e0f999f372383039af944e21bc717bDav Glass
482da2d388e0f999f372383039af944e21bc717bDav Glass if (columns.length) {
482da2d388e0f999f372383039af944e21bc717bDav Glass for (i = 0, len = columns.length; i < len; ++i) {
482da2d388e0f999f372383039af944e21bc717bDav Glass html = '';
482da2d388e0f999f372383039af944e21bc717bDav Glass
482da2d388e0f999f372383039af944e21bc717bDav Glass for (j = 0, jlen = columns[i].length; j < jlen; ++j) {
482da2d388e0f999f372383039af944e21bc717bDav Glass col = columns[i][j];
482da2d388e0f999f372383039af944e21bc717bDav Glass html += fromTemplate(this.CELL_TEMPLATE,
482da2d388e0f999f372383039af944e21bc717bDav Glass Y.merge(
482da2d388e0f999f372383039af944e21bc717bDav Glass defaults,
482da2d388e0f999f372383039af944e21bc717bDav Glass col, {
482da2d388e0f999f372383039af944e21bc717bDav Glass content: col.label ||
482da2d388e0f999f372383039af944e21bc717bDav Glass col.key ||
482da2d388e0f999f372383039af944e21bc717bDav Glass ("Column " + (j + 1))
482da2d388e0f999f372383039af944e21bc717bDav Glass }
482da2d388e0f999f372383039af944e21bc717bDav Glass ));
482da2d388e0f999f372383039af944e21bc717bDav Glass }
482da2d388e0f999f372383039af944e21bc717bDav Glass
482da2d388e0f999f372383039af944e21bc717bDav Glass thead += fromTemplate(this.ROW_TEMPLATE, {
482da2d388e0f999f372383039af944e21bc717bDav Glass content: html
482da2d388e0f999f372383039af944e21bc717bDav Glass });
482da2d388e0f999f372383039af944e21bc717bDav Glass }
482da2d388e0f999f372383039af944e21bc717bDav Glass }
482da2d388e0f999f372383039af944e21bc717bDav Glass
482da2d388e0f999f372383039af944e21bc717bDav Glass thead = fromTemplate(this.THEAD_TEMPLATE, {
482da2d388e0f999f372383039af944e21bc717bDav Glass classes: this.getClassName('columns'),
482da2d388e0f999f372383039af944e21bc717bDav Glass content: thead
482da2d388e0f999f372383039af944e21bc717bDav Glass });
482da2d388e0f999f372383039af944e21bc717bDav Glass }
482da2d388e0f999f372383039af944e21bc717bDav Glass
482da2d388e0f999f372383039af944e21bc717bDav Glass if (existing) {
482da2d388e0f999f372383039af944e21bc717bDav Glass if (replace) {
482da2d388e0f999f372383039af944e21bc717bDav Glass existing.replace(thead);
482da2d388e0f999f372383039af944e21bc717bDav Glass }
482da2d388e0f999f372383039af944e21bc717bDav Glass } else {
482da2d388e0f999f372383039af944e21bc717bDav Glass table.insertBefore(thead, table.one('> tfoot, > tbody'));
482da2d388e0f999f372383039af944e21bc717bDav Glass }
482da2d388e0f999f372383039af944e21bc717bDav Glass
482da2d388e0f999f372383039af944e21bc717bDav Glass this.bindUI();
482da2d388e0f999f372383039af944e21bc717bDav Glass
482da2d388e0f999f372383039af944e21bc717bDav Glass return this;
482da2d388e0f999f372383039af944e21bc717bDav Glass },
482da2d388e0f999f372383039af944e21bc717bDav Glass
482da2d388e0f999f372383039af944e21bc717bDav Glass // -- Protected and private properties and methods ------------------------
482da2d388e0f999f372383039af944e21bc717bDav Glass /**
482da2d388e0f999f372383039af944e21bc717bDav Glass The base token for classes created with the `getClassName` method.
482da2d388e0f999f372383039af944e21bc717bDav Glass
482da2d388e0f999f372383039af944e21bc717bDav Glass @property _cssPrefix
482da2d388e0f999f372383039af944e21bc717bDav Glass @type {String}
482da2d388e0f999f372383039af944e21bc717bDav Glass @default 'yui3-table'
482da2d388e0f999f372383039af944e21bc717bDav Glass @protected
482da2d388e0f999f372383039af944e21bc717bDav Glass **/
482da2d388e0f999f372383039af944e21bc717bDav Glass _cssPrefix: ClassNameManager.getClassName('table'),
482da2d388e0f999f372383039af944e21bc717bDav Glass
482da2d388e0f999f372383039af944e21bc717bDav Glass /**
482da2d388e0f999f372383039af944e21bc717bDav Glass Handles changes in the source's columns attribute. Redraws the headers.
482da2d388e0f999f372383039af944e21bc717bDav Glass
482da2d388e0f999f372383039af944e21bc717bDav Glass @method _afterColumnChange
482da2d388e0f999f372383039af944e21bc717bDav Glass @param {EventFacade} e The `columnsChange` event object
482da2d388e0f999f372383039af944e21bc717bDav Glass @protected
482da2d388e0f999f372383039af944e21bc717bDav Glass **/
482da2d388e0f999f372383039af944e21bc717bDav Glass _afterColumnChange: function (e) {
482da2d388e0f999f372383039af944e21bc717bDav Glass // TODO
482da2d388e0f999f372383039af944e21bc717bDav Glass },
482da2d388e0f999f372383039af944e21bc717bDav Glass
482da2d388e0f999f372383039af944e21bc717bDav Glass /**
482da2d388e0f999f372383039af944e21bc717bDav Glass Binds event subscriptions from the UI and the source (if assigned).
482da2d388e0f999f372383039af944e21bc717bDav Glass
482da2d388e0f999f372383039af944e21bc717bDav Glass @method bindUI
482da2d388e0f999f372383039af944e21bc717bDav Glass @protected
482da2d388e0f999f372383039af944e21bc717bDav Glass **/
482da2d388e0f999f372383039af944e21bc717bDav Glass bindUI: function () {
a201dfca71f32a095917fac03611f2f999cb3b97Dav Glass if (this.source) {
6cd85fc002ad88c48179730400dc0bc36a7a9f5bDav Glass // TODO: How best to decouple this?
6cd85fc002ad88c48179730400dc0bc36a7a9f5bDav Glass this._eventHandles.push(
6cd85fc002ad88c48179730400dc0bc36a7a9f5bDav Glass this.source.after('columnsChange', this._afterColumnsChange));
3b3bd34996b581ab171be1465201869cb009dbadDav Glass }
3b3bd34996b581ab171be1465201869cb009dbadDav Glass },
3b3bd34996b581ab171be1465201869cb009dbadDav Glass
3b3bd34996b581ab171be1465201869cb009dbadDav Glass /**
3b3bd34996b581ab171be1465201869cb009dbadDav Glass Initializes the instance. Reads the following configuration properties:
3b3bd34996b581ab171be1465201869cb009dbadDav Glass
3b3bd34996b581ab171be1465201869cb009dbadDav Glass * `columns` - (REQUIRED) The initial column information
3b3bd34996b581ab171be1465201869cb009dbadDav Glass * `cssPrefix` - The base string for classes generated by `getClassName`
3b3bd34996b581ab171be1465201869cb009dbadDav Glass * `source` - The object to serve as source of truth for column info
3b3bd34996b581ab171be1465201869cb009dbadDav Glass
3b3bd34996b581ab171be1465201869cb009dbadDav Glass @method initializer
3b3bd34996b581ab171be1465201869cb009dbadDav Glass @param {Object} config Configuration data
3b3bd34996b581ab171be1465201869cb009dbadDav Glass @protected
3b3bd34996b581ab171be1465201869cb009dbadDav Glass **/
3b3bd34996b581ab171be1465201869cb009dbadDav Glass initializer: function (config) {
3b3bd34996b581ab171be1465201869cb009dbadDav Glass config || (config = {});
3b3bd34996b581ab171be1465201869cb009dbadDav Glass
3b3bd34996b581ab171be1465201869cb009dbadDav Glass var cssPrefix = config.cssPrefix || (config.source || {}).cssPrefix;
3b3bd34996b581ab171be1465201869cb009dbadDav Glass
3b3bd34996b581ab171be1465201869cb009dbadDav Glass this.source = config.source;
3b3bd34996b581ab171be1465201869cb009dbadDav Glass this.columns = this._parseColumns(config.columns);
3b3bd34996b581ab171be1465201869cb009dbadDav Glass
3b3bd34996b581ab171be1465201869cb009dbadDav Glass this._eventHandles = [];
3b3bd34996b581ab171be1465201869cb009dbadDav Glass
3b3bd34996b581ab171be1465201869cb009dbadDav Glass if (cssPrefix) {
3b3bd34996b581ab171be1465201869cb009dbadDav Glass this._cssPrefix = cssPrefix;
3b3bd34996b581ab171be1465201869cb009dbadDav Glass }
713a27b6ab5ab057e9b4ab551617b54730e8906eDav Glass },
3b3bd34996b581ab171be1465201869cb009dbadDav Glass
3b3bd34996b581ab171be1465201869cb009dbadDav Glass /**
3b3bd34996b581ab171be1465201869cb009dbadDav Glass Translate the input column format into a structure useful for rendering a
3b3bd34996b581ab171be1465201869cb009dbadDav Glass `<thead>`, rows, and cells. The structure of the input is expected to be a
3b3bd34996b581ab171be1465201869cb009dbadDav Glass single array of objects, where each object corresponds to a `<th>`. Those
3b3bd34996b581ab171be1465201869cb009dbadDav Glass objects may contain a `children` property containing a similarly structured
3b3bd34996b581ab171be1465201869cb009dbadDav Glass array to indicate the nested cells should be grouped under the parent
6cd85fc002ad88c48179730400dc0bc36a7a9f5bDav Glass column's colspan in a separate row of header cells. E.g.
482da2d388e0f999f372383039af944e21bc717bDav Glass
6cd85fc002ad88c48179730400dc0bc36a7a9f5bDav Glass <pre><code>
[
{ key: 'id' }, // no nesting
{ key: 'name', children: [
{ key: 'firstName', label: 'First' },
{ key: 'lastName', label: 'Last' } ] }
]
</code></pre>
would indicate two header rows with the first column 'id' being assigned a
`rowspan` of `2`, the 'name' column appearing in the first row with a
`colspan` of `2`, and the 'firstName' and 'lastName' columns appearing in
the second row, below the 'name' column.
<pre>
---------------------
| | name |
| |---------------
| id | First | Last |
---------------------
</pre>
Supported properties of the column objects include:
* `label` - The HTML content of the header cell.
* `key` - If `label` is not specified, the `key` is used for content.
* `children` - Array of columns to appear below this column in the next
row.
* `abbr` - The content of the 'abbr' attribute of the `<th>`
The output structure is basically a simulation of the `<thead>` structure
with arrays for rows and objects for cells. Column objects have the
following properties added to them:
* `colspan` - Per the `<th>` attribute
* `rowspan` - Per the `<th>` attribute
* `parent` - If the column is a child of another column, this points to
its parent column
* `_yuid` - A unique YUI generated id used as the `<th>`'s 'id' for
reference in the data `<td>`'s 'headers' attribute.
The column object is also used to provide values for {placeholder}
replacement in the `CELL_TEMPLATE`, so you can modify the template and
include other column object properties to populate them.
@method _parseColumns
@param {Object[]} data Array of column object data
@return {Array[]} An array of arrays corresponding to the header row
structure to render
@protected
**/
_parseColumns: function (data) {
var columns = [],
stack = [],
rowSpan = 1,
entry, row, col, children, parent, i, len, j;
if (isArray(data) && data.length) {
// First pass, assign colspans and calculate row count for
// non-nested headers' rowspan
stack.push([data, -1]);
while (stack.length) {
entry = stack[stack.length - 1];
row = entry[0];
i = entry[1] + 1;
for (len = row.length; i < len; ++i) {
col = row[i];
children = col.children;
Y.stamp(col);
if (isArray(children) && children.length) {
stack.push([children, -1]);
entry[1] = i;
rowSpan = Math.max(rowSpan, stack.length);
// break to let the while loop process the children
break;
} else {
col.colspan = 1;
}
}
if (i >= len) {
// All columns in this row are processed
if (stack.length > 1) {
entry = stack[stack.length - 2];
parent = entry[0][entry[1]];
parent.colspan = 0;
for (i = 0, len = row.length; i < len; ++i) {
// Can't use .length because in 3+ rows, colspan
// needs to aggregate the colspans of children
parent.colspan += row[i].colspan;
// Assign the parent column for ease of navigation
row[i].parent = parent;
}
}
stack.pop();
}
}
// Second pass, build row arrays and assign rowspan
for (i = 0; i < rowSpan; ++i) {
columns.push([]);
}
stack.push([data, -1]);
while (stack.length) {
entry = stack[stack.length - 1];
row = entry[0];
i = entry[1] + 1;
for (len = row.length; i < len; ++i) {
col = row[i];
children = col.children;
columns[stack.length - 1].push(col);
entry[1] = i;
if (children && children.length) {
// parent cells must assume rowspan 1 (long story)
// break to let the while loop process the children
stack.push([children, -1]);
break;
} else {
// collect the IDs of parent cols
col.headers = [col._yuid];
for (j = stack.length - 2; j >= 0; --j) {
parent = stack[j][0][stack[j][1]];
col.headers.unshift(parent._yuid);
}
col.rowspan = rowSpan - stack.length + 1;
}
}
if (i >= len) {
// All columns in this row are processed
stack.pop();
}
}
}
return columns;
}
});