head.js revision 1080d9c735088a474affe30611ae889315840a17
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith/**
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 Smith
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke SmithTranslates the provided array of column configuration objects into a rendered
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith`<thead>` based on the data in those objects.
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith
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 Smith
e0a1afd287c016be5722249b10ba81684f33886bLuke Smith<pre><code>
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smithnew Y.DataTable.HeaderView({
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith container: tableNode,
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith columns: [
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith { key: 'id' }, // no nesting
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith { key: 'name', children: [
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith { key: 'firstName', label: 'First' },
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith { key: 'lastName', label: 'Last' } ] }
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith ]
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith}).render();
e0a1afd287c016be5722249b10ba81684f33886bLuke Smith</code></pre>
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke SmithThis would translate to the following visualization:
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith
e0a1afd287c016be5722249b10ba81684f33886bLuke Smith<pre>
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith---------------------
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith| | name |
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith| |---------------
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith| id | First | Last |
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith---------------------
e0a1afd287c016be5722249b10ba81684f33886bLuke Smith</pre>
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke SmithSupported properties of the column objects include:
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith
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 row.
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith * `abbr` - The content of the 'abbr' attribute of the `<th>`
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke SmithThrough the life of instantiation and rendering, the column objects will have
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smiththe following properties added to them:
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith
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 Smith
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
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith@module datatable-head
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith@class HeaderView
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith@namespace DataTable
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith@extends View
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith**/
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smithvar fromTemplate = Y.Lang.sub,
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith Lang = Y.Lang,
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith isArray = Lang.isArray,
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith toArray = Y.Array,
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith ClassNameManager = Y.ClassNameManager,
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith _getClassName = ClassNameManager.getClassName;
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke SmithY.namespace('DataTable').HeaderView = Y.Base.create('tableHeader', Y.View, [], {
0e7d399f99fcb097a927af7e6588f393740585a2Luke Smith // -- Instance properties -------------------------------------------------
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith /**
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
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>'
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith **/
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith CELL_TEMPLATE :
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith '<th id="{_yuid}" abbr="{abbr}" ' +
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith 'colspan="{colspan}" rowspan="{rowspan}">' +
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith '<div class="{linerClass}">' +
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith '{content}' +
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith '</div>' +
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith '</th>',
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith /**
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 method.
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @property columns
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @type {Array[]}
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @default (initially unset)
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith **/
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith //TODO: should this be protected?
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith //columns: null,
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith /**
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
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @property source
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @type {Object}
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @default (initially unset)
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith **/
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith //TODO: should this be protected?
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith //source: null,
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith /**
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith Template used to create the table's header row markup. Override this to
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith customize the row markup.
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @property ROW_TEMPLATE
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @type {HTML}
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @default '<tr>{content}</tr>'
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith **/
0e7d399f99fcb097a927af7e6588f393740585a2Luke Smith ROW_TEMPLATE:
0e7d399f99fcb097a927af7e6588f393740585a2Luke Smith '<tr>{content}</tr>',
0e7d399f99fcb097a927af7e6588f393740585a2Luke Smith
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith /**
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith Template used to create the table's thead markup.
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @property THEAD_TEMPLATE
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @type {HTML}
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @default '<thead class="{classes}">{content}</thead>'
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith **/
0e7d399f99fcb097a927af7e6588f393740585a2Luke Smith THEAD_TEMPLATE:
0e7d399f99fcb097a927af7e6588f393740585a2Luke Smith '<thead class="{classes}">{content}</thead>',
0e7d399f99fcb097a927af7e6588f393740585a2Luke Smith
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith
0e7d399f99fcb097a927af7e6588f393740585a2Luke Smith // -- Public methods ------------------------------------------------------
0e7d399f99fcb097a927af7e6588f393740585a2Luke Smith
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith /**
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
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
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith **/
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith getClassName: function () {
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith var args = toArray(arguments);
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith args.unshift(this._cssPrefix);
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith args.push(true);
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith return _getClassName.apply(ClassNameManager, args);
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith },
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith /**
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
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @method render
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @return {HeaderView} The instance
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @chainable
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith **/
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith render: function () {
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith var table = this.get('container'),
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith columns = this.columns,
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith thead = this.source._theadNode,
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith defaults = {
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith abbr: '',
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith colspan: 1,
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith rowspan: 1,
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith // TODO: remove dependence on this.source
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith linerClass: this.getClassName('liner')
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith },
1080d9c735088a474affe30611ae889315840a17Luke Smith existing, i, len, j, jlen, col, html;
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith table = Y.one(table);
1080d9c735088a474affe30611ae889315840a17Luke Smith
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith if (table && table.get('tagName') !== 'TABLE') {
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith table = table.one('table');
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith }
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith if (!table) {
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith Y.log('Could not render thead. Table not provided', 'warn');
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith return this;
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith }
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith existing = table.one('> .' + this.getClassName('columns'));
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith
1080d9c735088a474affe30611ae889315840a17Luke Smith if (existing) {
1080d9c735088a474affe30611ae889315840a17Luke Smith if (!existing.compareTo(thead)) {
1080d9c735088a474affe30611ae889315840a17Luke Smith existing.replace(thead);
1080d9c735088a474affe30611ae889315840a17Luke Smith } else {
1080d9c735088a474affe30611ae889315840a17Luke Smith this._theadNode = existing;
1080d9c735088a474affe30611ae889315840a17Luke Smith }
1080d9c735088a474affe30611ae889315840a17Luke Smith } else {
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith thead = '';
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith
79fac3c43e396f54a5fb368ac33ff7c21df23397Luke Smith if (columns.length) {
79fac3c43e396f54a5fb368ac33ff7c21df23397Luke Smith for (i = 0, len = columns.length; i < len; ++i) {
79fac3c43e396f54a5fb368ac33ff7c21df23397Luke Smith html = '';
79fac3c43e396f54a5fb368ac33ff7c21df23397Luke Smith
79fac3c43e396f54a5fb368ac33ff7c21df23397Luke Smith for (j = 0, jlen = columns[i].length; j < jlen; ++j) {
79fac3c43e396f54a5fb368ac33ff7c21df23397Luke Smith col = columns[i][j];
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith html += fromTemplate(this.CELL_TEMPLATE,
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith Y.merge(
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith defaults,
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith col, {
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith content: col.label ||
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith col.key ||
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith ("Column " + (j + 1))
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith }
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith ));
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith }
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith
79fac3c43e396f54a5fb368ac33ff7c21df23397Luke Smith thead += fromTemplate(this.ROW_TEMPLATE, {
79fac3c43e396f54a5fb368ac33ff7c21df23397Luke Smith content: html
79fac3c43e396f54a5fb368ac33ff7c21df23397Luke Smith });
79fac3c43e396f54a5fb368ac33ff7c21df23397Luke Smith }
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith }
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith
1080d9c735088a474affe30611ae889315840a17Luke Smith this._theadNode = thead = Y.Node.create(
1080d9c735088a474affe30611ae889315840a17Luke Smith fromTemplate(this.THEAD_TEMPLATE, {
1080d9c735088a474affe30611ae889315840a17Luke Smith classes: this.getClassName('columns'),
1080d9c735088a474affe30611ae889315840a17Luke Smith content: thead
1080d9c735088a474affe30611ae889315840a17Luke Smith }));
1080d9c735088a474affe30611ae889315840a17Luke Smith
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith table.insertBefore(thead, table.one('> tfoot, > tbody'));
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith }
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith this.bindUI();
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith return this;
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith },
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith // -- Protected and private properties and methods ------------------------
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith /**
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith The base token for classes created with the `getClassName` method.
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @property _cssPrefix
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @type {String}
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @default 'yui3-table'
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @protected
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith **/
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith _cssPrefix: ClassNameManager.getClassName('table'),
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith /**
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith Handles changes in the source's columns attribute. Redraws the headers.
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith
1080d9c735088a474affe30611ae889315840a17Luke Smith @method _afterColumnsChange
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @param {EventFacade} e The `columnsChange` event object
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @protected
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith **/
1080d9c735088a474affe30611ae889315840a17Luke Smith _afterColumnsChange: function (e) {
1080d9c735088a474affe30611ae889315840a17Luke Smith this.columns = this._parseColumns(e.newVal);
1080d9c735088a474affe30611ae889315840a17Luke Smith
1080d9c735088a474affe30611ae889315840a17Luke Smith if (this._theadNode) {
1080d9c735088a474affe30611ae889315840a17Luke Smith this._theadNode.remove().destroy(true);
1080d9c735088a474affe30611ae889315840a17Luke Smith delete this._theadNode;
1080d9c735088a474affe30611ae889315840a17Luke Smith }
1080d9c735088a474affe30611ae889315840a17Luke Smith
1080d9c735088a474affe30611ae889315840a17Luke Smith this.render();
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith },
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith /**
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith Binds event subscriptions from the UI and the source (if assigned).
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @method bindUI
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @protected
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith **/
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith bindUI: function () {
1080d9c735088a474affe30611ae889315840a17Luke Smith if (this.source && !this._eventHandles.columnsChange) {
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith // TODO: How best to decouple this?
1080d9c735088a474affe30611ae889315840a17Luke Smith this._eventHandles.columnsChange =
1080d9c735088a474affe30611ae889315840a17Luke Smith this.source.after('columnsChange',
1080d9c735088a474affe30611ae889315840a17Luke Smith Y.bind('_afterColumnsChange', this));
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith }
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith },
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith
1080d9c735088a474affe30611ae889315840a17Luke Smith /**
1080d9c735088a474affe30611ae889315840a17Luke Smith Destroys the instance.
1080d9c735088a474affe30611ae889315840a17Luke Smith
1080d9c735088a474affe30611ae889315840a17Luke Smith @method destructor
1080d9c735088a474affe30611ae889315840a17Luke Smith @protected
1080d9c735088a474affe30611ae889315840a17Luke Smith **/
1080d9c735088a474affe30611ae889315840a17Luke Smith destructor: function () {
1080d9c735088a474affe30611ae889315840a17Luke Smith (new Y.EventHandle(Y.Object.values(this._eventHandles))).detach();
1080d9c735088a474affe30611ae889315840a17Luke Smith },
1080d9c735088a474affe30611ae889315840a17Luke Smith
1080d9c735088a474affe30611ae889315840a17Luke Smith /**
1080d9c735088a474affe30611ae889315840a17Luke Smith Holds the event subscriptions needing to be detached when the instance is
1080d9c735088a474affe30611ae889315840a17Luke Smith `destroy()`ed.
1080d9c735088a474affe30611ae889315840a17Luke Smith
1080d9c735088a474affe30611ae889315840a17Luke Smith @property _eventHandles
1080d9c735088a474affe30611ae889315840a17Luke Smith @type {Object}
1080d9c735088a474affe30611ae889315840a17Luke Smith @default undefined (initially unset)
1080d9c735088a474affe30611ae889315840a17Luke Smith @protected
1080d9c735088a474affe30611ae889315840a17Luke Smith **/
1080d9c735088a474affe30611ae889315840a17Luke Smith //_eventHandles: null,
1080d9c735088a474affe30611ae889315840a17Luke Smith
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith /**
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith Initializes the instance. Reads the following configuration properties:
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith
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
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @method initializer
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith @param {Object} config Configuration data
e0a1afd287c016be5722249b10ba81684f33886bLuke Smith @protected
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith **/
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith initializer: function (config) {
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith config || (config = {});
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith var cssPrefix = config.cssPrefix || (config.source || {}).cssPrefix;
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith this.source = config.source;
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith this.columns = this._parseColumns(config.columns);
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith this._eventHandles = [];
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith if (cssPrefix) {
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith this._cssPrefix = cssPrefix;
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith }
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith },
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith /**
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
e0a1afd287c016be5722249b10ba81684f33886bLuke Smith <pre><code>
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith [
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith { key: 'id' }, // no nesting
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith { key: 'name', children: [
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith { key: 'firstName', label: 'First' },
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith { key: 'lastName', label: 'Last' } ] }
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith ]
e0a1afd287c016be5722249b10ba81684f33886bLuke Smith </code></pre>
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith
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
e0a1afd287c016be5722249b10ba81684f33886bLuke Smith <pre>
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith ---------------------
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith | | name |
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith | |---------------
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith | id | First | Last |
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith ---------------------
e0a1afd287c016be5722249b10ba81684f33886bLuke Smith </pre>
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith Supported properties of the column objects include:
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith
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 row.
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith * `abbr` - The content of the 'abbr' attribute of the `<th>`
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith
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
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
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
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
e0a1afd287c016be5722249b10ba81684f33886bLuke Smith @protected
cfb2dc43f7aba18c4c6b0db07ca060089bd2e670Luke Smith **/
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith _parseColumns: function (data) {
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith var columns = [],
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith stack = [],
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith rowSpan = 1,
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith entry, row, col, children, parent, i, len, j;
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith if (isArray(data) && data.length) {
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith // First pass, assign colspans and calculate row count for
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith // non-nested headers' rowspan
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith stack.push([data, -1]);
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith while (stack.length) {
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith entry = stack[stack.length - 1];
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith row = entry[0];
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith i = entry[1] + 1;
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith for (len = row.length; i < len; ++i) {
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith col = row[i];
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith children = col.children;
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith Y.stamp(col);
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith if (isArray(children) && children.length) {
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith stack.push([children, -1]);
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith entry[1] = i;
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith rowSpan = Math.max(rowSpan, stack.length);
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith // break to let the while loop process the children
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith break;
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith } else {
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith col.colspan = 1;
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith }
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith }
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith if (i >= len) {
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith // All columns in this row are processed
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith if (stack.length > 1) {
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith entry = stack[stack.length - 2];
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith parent = entry[0][entry[1]];
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith parent.colspan = 0;
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith for (i = 0, len = row.length; i < len; ++i) {
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith // Can't use .length because in 3+ rows, colspan
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith // needs to aggregate the colspans of children
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith parent.colspan += row[i].colspan;
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith // Assign the parent column for ease of navigation
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith row[i].parent = parent;
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith }
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith }
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith stack.pop();
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith }
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith }
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith // Second pass, build row arrays and assign rowspan
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith for (i = 0; i < rowSpan; ++i) {
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith columns.push([]);
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith }
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith stack.push([data, -1]);
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith while (stack.length) {
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith entry = stack[stack.length - 1];
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith row = entry[0];
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith i = entry[1] + 1;
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith for (len = row.length; i < len; ++i) {
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith col = row[i];
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith children = col.children;
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith columns[stack.length - 1].push(col);
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith entry[1] = i;
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith if (children && children.length) {
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith // parent cells must assume rowspan 1 (long story)
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith // break to let the while loop process the children
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith stack.push([children, -1]);
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith break;
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith } else {
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith // collect the IDs of parent cols
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith col.headers = [col._yuid];
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith for (j = stack.length - 2; j >= 0; --j) {
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith parent = stack[j][0][stack[j][1]];
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith col.headers.unshift(parent._yuid);
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith }
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith col.rowspan = rowSpan - stack.length + 1;
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith }
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith }
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith if (i >= len) {
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith // All columns in this row are processed
deb753fedac28c24a82440a4f7ca53df8a72a124Luke Smith stack.pop();
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith }
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith }
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith }
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith return columns;
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith }
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith});