-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjsontotable.js
131 lines (117 loc) · 4.7 KB
/
jsontotable.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
<script>
const defaultTableStyle = 'border-spacing: 0 0; border-color: #808080; border-collapse: collapse;';
const defaultTdStyle = 'border: 1px solid #2d2d2d; padding: 3px;';
const defaultTdKeyStyle = 'background: #F6F4F0; ' + defaultTdStyle;
const defaultThStyle = 'background: #F6F4F0;' + defaultTdStyle;
const defaultTrStyle = '';
function jsonToTableHtmlString (json, options) {
let arr = isObject(json) ? objectToArray(json) : json;
if (!Array.isArray(arr)) {
arr = []
}
return arrayToTable(arr, options)
}
function isObject (obj) {
return Object.prototype.toString.call(obj) === '[object Object]';
}
function objectToArray (json) {
if (isObject(json)) {
let arr = [];
for (let key in json) {
arr.push({ $_key: key, $_value: objectToArray(json[key]) })
}
return arr
} else if (Array.isArray(json)) {
let arr = [];
for (let item of json) {
if (isObject(json)) {
arr.push(objectToArray(json))
} else {
arr.push(item)
}
}
return arr
}
return json
}
function arrayToTable (array, options) {
function _recur(arr, tableDepth = 1) {
let fieldSet = new Set();
for (let i = 0; i < arr.length; i++) {
const item = arr[i];
if (isObject(item)) {
Object.keys(item).forEach(i => fieldSet.add(i))
} else if (Array.isArray(item)) {
return _recur(item, tableDepth + 1)
}
}
let fields = Array.from(fieldSet);
let rows = arr.map(() => []);
for (let i = 0; i < arr.length; i++) {
const item = arr[i];
if (isObject(item)) {
for (let j = 0; j < fields.length; j++) {
let value = item[fields[j]];
if (Array.isArray(value)) {
rows[i][j] = _recur(value, tableDepth + 1)
} else if (isObject(value)) {
rows[i][j] = _recur(objectToArray(value), tableDepth + 1)
} else {
rows[i][j] = { isKey: fields[j] === '$_key', value }
}
}
} else {
rows[i][fields.length] = { isKey: false, value: item }
}
}
return tableToHtml(fields, rows, tableDepth, options)
}
return _recur(array)
}
function ensureSemicolon (style) {
if (typeof style === 'string' && style.length > 0 && style[style.length -1] !== ';') {
return style + ';'
}
return style
}
function getTableStyle(tableStyle, tableDepth) {
return `${tableDepth > 1 ? 'width: 100%;' : ''}${tableStyle}`.replace(/\n\s*/g, '')
}
function getTdStyle (tdStyle, tdKeyStyle, isKey) {
return `${isKey && tdKeyStyle ? `${ensureSemicolon(tdKeyStyle)}` : ''}${tdStyle}`.replace(/\n\s*/g, '')
}
function getThStyle (thStyle) {
return `${thStyle}`.replace(/\n\s*/g, '')
}
function tableToHtml (fields, rows, tableDepth, {
tableStyle = defaultTableStyle,
trStyle = defaultTrStyle,
thStyle = defaultThStyle,
tdKeyStyle = defaultTdKeyStyle,
tdStyle = defaultTdStyle,
formatCell,
} = {}) {
return `<table id="elastic_table" class="elastic_table" cellspacing="0" style="${getTableStyle(tableStyle, tableDepth)}">
<thead class="elastic_table_head">${fields
.filter(f => !f.startsWith('$_'))
.map(f => `<th class="elastic_table_th" style="${getThStyle(thStyle)}">${f}</th>`)
.join('')}</thead>
<tbody class="elastic_table_body">${rows
.map(row => {
let tds = '';
for (let i = 0; i < row.length; i++) {
const v = row[i] || '';
if (isObject(v)) {
tds += `<td class="elastic_table_td" style="${getTdStyle(tdStyle, tdKeyStyle, v.isKey)}">${
typeof formatCell === 'function' ? formatCell(v.value, v.isKey) : v.value
}</td>`
} else {
tds += `<td class="elastic_table_td" style="${getTdStyle(tdStyle)}">${v}</td>`
}
}
return `<tr class="elastic_table_tr" style="${trStyle}">${tds}</tr>`
})
.join('')}</tbody>
</table>`
}
</script>