define([
|
'./Grid',
|
'dojo/_base/declare',
|
'dojo/dom-construct'
|
], function (Grid, declare, domConstruct) {
|
// summary:
|
// This module supports parsing grid structure information from an HTML table.
|
// This module does NOT support ColumnSets; see GridWithColumnSetsFromHtml
|
|
// name of data attribute to check for column properties
|
var bagName = 'data-dgrid-column';
|
|
function getSubRowsFromDom(domNode) {
|
// summary:
|
// generate columns from DOM. Should this be in here, or a separate module?
|
var columns = [], // to be pushed upon / returned
|
trs = domNode.getElementsByTagName('tr'),
|
trslen = trs.length,
|
getCol = GridFromHtml.utils.getColumnFromCell,
|
rowColumns, tr, ths, thslen;
|
|
for (var i = 0; i < trslen; i++) {
|
rowColumns = [];
|
columns.push(rowColumns);
|
tr = trs[i];
|
ths = tr.getElementsByTagName('th'), thslen = ths.length;
|
for (var j = 0; j < thslen; j++) {
|
rowColumns.push(getCol(ths[j]));
|
}
|
}
|
if (tr) {
|
// NOTE: this assumes that applicable TRs were ONLY found under one
|
// grouping element (e.g. thead)
|
domNode.removeChild(tr.parentNode);
|
}
|
|
return columns;
|
}
|
|
var GridFromHtml = declare(Grid, {
|
configStructure: function () {
|
// summary:
|
// Configure subRows based on HTML originally in srcNodeRef
|
if (!this._checkedTrs) {
|
this._checkedTrs = true;
|
this.subRows = getSubRowsFromDom(this.srcNodeRef, this.subRows);
|
}
|
return this.inherited(arguments);
|
},
|
|
create: function (params, srcNodeRef) {
|
// We need to replace srcNodeRef, presumably a table, with a div.
|
// (Otherwise we'll generate highly invalid markup, which IE doesn't like)
|
var div = document.createElement('div'),
|
id = srcNodeRef.id,
|
style = srcNodeRef.getAttribute('style');
|
|
// Copy some commonly-used attributes...
|
if (id) {
|
this.id = id; // Will be propagated in List's create
|
}
|
div.className = srcNodeRef.className;
|
style && div.setAttribute('style', style);
|
|
// replace srcNodeRef in DOM with the div
|
srcNodeRef.parentNode.replaceChild(div, srcNodeRef);
|
|
(params = params || {}).srcNodeRef = srcNodeRef;
|
// call inherited with the new node
|
// (but configStructure will look at srcNodeRef)
|
this.inherited(arguments, [params, div]);
|
|
// destroy srcNodeRef for good now that we're done with it
|
domConstruct.destroy(srcNodeRef);
|
}
|
});
|
|
// hang some utility functions, potentially useful for extensions
|
GridFromHtml.utils = {
|
// Functions for getting various types of values from HTML attributes
|
getBoolFromAttr: function (node, attr) {
|
// used for e.g. sortable
|
var val = node.getAttribute(attr);
|
return val && val !== 'false';
|
},
|
getNumFromAttr: function (node, attr) {
|
// used for e.g. rowSpan, colSpan
|
var val = node.getAttribute(attr);
|
val = val && Number(val);
|
return isNaN(val) ? undefined : val;
|
},
|
getPropsFromNode: function (node) {
|
// used to pull properties out of bag e.g. "data-dgrid-column".
|
var obj,
|
str = node.getAttribute(bagName);
|
if (!str) {
|
return {};
|
}
|
|
try {
|
/* jshint evil: true */
|
// Yes, eval is evil, but this is ultimately the same thing that
|
// dojo/parser does for objects.
|
obj = eval('(' + str + ')');
|
} catch (error) {
|
throw new Error('Error in ' + bagName + ' {' + str + '}: ' + error.toString());
|
}
|
return obj;
|
},
|
|
// Function for aggregating th attributes into column properties
|
getColumnFromCell: function (th) {
|
var getNum = GridFromHtml.utils.getNumFromAttr,
|
obj,
|
tmp;
|
|
// Look for properties in data attribute.
|
// It's imperative that we hold on to this object as returned, as the
|
// object may be augmented further by other sources,
|
// e.g. Grid adding the grid property to reference the instance.
|
obj = GridFromHtml.utils.getPropsFromNode(th);
|
|
// inspect standard attributes, but data attribute takes precedence
|
obj.label = 'label' in obj ? obj.label : th.innerHTML;
|
obj.field = obj.field || th.className || th.innerHTML;
|
if (!obj.className && th.className) {
|
obj.className = th.className;
|
}
|
if (!obj.rowSpan && (tmp = getNum(th, 'rowspan'))) {
|
obj.rowSpan = tmp;
|
}
|
if (!obj.colSpan && (tmp = getNum(th, 'colspan'))) {
|
obj.colSpan = tmp;
|
}
|
|
return obj;
|
}
|
};
|
return GridFromHtml;
|
});
|