head.js revision b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3
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 -------------------------------------------------
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
0e7d399f99fcb097a927af7e6588f393740585a2Luke Smith ROW_TEMPLATE:
0e7d399f99fcb097a927af7e6588f393740585a2Luke Smith '<tr>{content}</tr>',
0e7d399f99fcb097a927af7e6588f393740585a2Luke Smith
0e7d399f99fcb097a927af7e6588f393740585a2Luke Smith THEAD_TEMPLATE:
0e7d399f99fcb097a927af7e6588f393740585a2Luke Smith '<thead class="{classes}">{content}</thead>',
0e7d399f99fcb097a927af7e6588f393740585a2Luke Smith
0e7d399f99fcb097a927af7e6588f393740585a2Luke Smith // -- Public methods ------------------------------------------------------
0e7d399f99fcb097a927af7e6588f393740585a2Luke Smith bindUI: function () {
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith // TODO: How best to decouple this?
0e7d399f99fcb097a927af7e6588f393740585a2Luke Smith this._eventHandles.push(
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith this.host.after('columnsChange', this._afterColumnChange));
0e7d399f99fcb097a927af7e6588f393740585a2Luke Smith },
0e7d399f99fcb097a927af7e6588f393740585a2Luke Smith
0e7d399f99fcb097a927af7e6588f393740585a2Luke Smith destructor: function () {
0e7d399f99fcb097a927af7e6588f393740585a2Luke Smith (new Y.EventHandle(this._eventHandles)).detach();
0e7d399f99fcb097a927af7e6588f393740585a2Luke Smith },
0e7d399f99fcb097a927af7e6588f393740585a2Luke 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
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith initializer: function (config) {
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith var cssPrefix = config.cssPrefix || (config.host || {}).cssPrefix;
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith this.host = config.source;
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith this.columns = this._parseColumns(config.columns);
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith this._eventHandles = [];
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith if (cssPrefix) {
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith this._cssPrefix = cssPrefix;
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith }
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith },
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith render: function () {
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith var table = this.get('container'),
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith columns = this.columns,
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith thead = this.host._theadNode,
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith defaults = {
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith abbr: '',
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith colspan: 1,
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith rowspan: 1,
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith // TODO: remove dependence on this.host
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith linerClass: this.getClassName('liner')
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith },
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith existing, replace, i, len, j, jlen, col, html;
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith table = Y.one(table);
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'));
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith replace = existing && (!thead || !thead.compareTo(existing));
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith if (!thead) {
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 ||
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith ("Column " + j)
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
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith thead = fromTemplate(this.THEAD_TEMPLATE, {
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith classes: this.getClassName('columns'),
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith content: thead
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith });
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith }
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith if (existing) {
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith if (replace) {
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith existing.replace(thead);
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith }
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith } else {
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
0e7d399f99fcb097a927af7e6588f393740585a2Luke Smith // -- Protected and private methods ---------------------------------------
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith _afterColumnChange: function (e) {
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith // TODO
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith },
a3e011a6940a2707d43148e12f3d3cd6fd388794Luke Smith
b30dbdf0ef8772c980fc59f2d2015a295c0b4dc3Luke Smith _cssPrefix: 'table',
d15134141197c4fc93eb6094020e03eb72aa8d73Luke 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 if (typeof col === 'string') {
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith row[i] = col = { key: col };
d15134141197c4fc93eb6094020e03eb72aa8d73Luke Smith }
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});