forked from SitePen/dgrid
-
Notifications
You must be signed in to change notification settings - Fork 0
/
GridFromHtml.js
140 lines (124 loc) · 4.23 KB
/
GridFromHtml.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
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;
});