从 json 数据动态生成 html table
generate html table dynamically from json data
我需要动态生成 html table 并在下面列出 driver_id。
它类似于 pivot,但问题是 zone_name 每天都在变化。
我正在使用 jquery 和 linq.js。
到目前为止我已经尝试过:
var data =
[
{
"ColorCode": "green",
"StatusName": "ACTIVE",
"rankId": 0,
"zone_name": "Zone A",
"driver_id": 100,
"zone_rank": 1,
"status_id": null,
"company_id": null,
"updated_on": null,
"Driver": null,
"login_status": null
},
{
"ColorCode": "yellow",
"StatusName": "BREAK",
"rankId": 0,
"zone_name": "Zone B",
"driver_id": 101,
"zone_rank": 1,
"status_id": null,
"company_id": null,
"updated_on": null,
"Driver": null,
"login_status": null
},
{
"ColorCode": "green",
"StatusName": "ACTIVE",
"rankId": 0,
"zone_name": "Zone A",
"driver_id": 102,
"zone_rank": 4,
"status_id": null,
"company_id": null,
"updated_on": null,
"Driver": null,
"login_status": null
}
]
var zTable = document.getElementById('tblZoneRank');
var allzones = Enumerable.From(data)
.Distinct(p => p.zone_name)
.Select(p => p.zone_name).ToArray();
$.each(allzones, function (i, item) {
var tr = document.createElement('tr');
var td = document.createElement("td");
var txt = document.createTextNode(item);
td.appendChild(txt);
tr.appendChild(td);
var childItem = Enumerable.From(data)
.Where(p => p.zone_name == item)
.ToArray();
$.each(childItem, function (j, citem) {
var ctd = document.createElement("td");
var ctxt = document.createTextNode(citem.driver_id);
ctd.appendChild(ctxt);
$(ctd).css('background-color', citem.ColorCode);
tr.appendChild(ctd);
});
zTable.appendChild(tr);
});
它以这种方式给我输出:
<table id="tblZoneRank">
<tr>
<td>Zone A</td>
<td style="background-color: rgb(0, 128, 0);">100</td>
<td style="background-color: rgb(0, 128, 0);">102</td>
</tr>
<tr>
<td>Zone B</td>
<td style="background-color: rgb(255, 255, 0);">101</td>
</tr>
</table>
但我需要这种格式的输出:
它应该显示 zone_name 作为列名,在 driver_id 下方,第一个 ID 应该是 zone_rank 1 和 2 等等。
我不熟悉 linq.js 所以我使用本机数组方法 Array#reduce()
和 Map
对象来创建独特的区域
const $table = $('#zoneTable');
// creates Map object with zone names as keys and arrays of jQuery objects(cells) as values
const zoneMap = data.reduce((map, item) => {
const col = map.get(item.zone_name) || [createCell(item.zone_name)];
col.push(createCell(item.driver_id, item.ColorCode));
return map.set(item.zone_name, col);
}, new Map());
// convert Map values to array of arrays. Each sub array is a table column
const colCells = [...zoneMap.values()];
const totalRows = Math.max(...colCells.map(e => e.length));
for (let i = 0; i < totalRows; i++) {
const rowCells = colCells.map(col => col[i] || createCell());// fill any missing with empty cell
const $row = $('<tr>').append(rowCells);
$table.append($row)
}
// helper function to create cells
function createCell(text = '', color = null) {
const $td = $('<td>').text(text);
return color ? $td.css('background-color', color) : $td;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="zoneTable"></table>
<script>
var data = [{
"ColorCode": "green",
"StatusName": "ACTIVE",
"rankId": 0,
"zone_name": "Zone A",
"driver_id": 100,
"zone_rank": 1,
"status_id": null,
"company_id": null,
"updated_on": null,
"Driver": null,
"login_status": null
},
{
"ColorCode": "yellow",
"StatusName": "BREAK",
"rankId": 0,
"zone_name": "Zone B",
"driver_id": 101,
"zone_rank": 1,
"status_id": null,
"company_id": null,
"updated_on": null,
"Driver": null,
"login_status": null
},
{
"ColorCode": "green",
"StatusName": "ACTIVE",
"rankId": 0,
"zone_name": "Zone A",
"driver_id": 102,
"zone_rank": 4,
"status_id": null,
"company_id": null,
"updated_on": null,
"Driver": null,
"login_status": null
}
]
</script>
因此,根据我从您的问题中收集到的信息,您正在尝试按区域对数据项进行分组,然后将它们输出到 table 中,其中列是区域。 Linq.js 可以很好地处理这个问题,只是在将数据行转换为列时会遇到一些问题。
const zTable = $('#tblZoneRank');
const rows = Enumerable.From(data)
.GroupBy(p => p.zone_name, p =>
$('<td></td>')
.css({'background-color': p.ColorCode})
.text(p.driver_id)
)
.Let(buildRows)
.Select(rs =>
$('<tr></tr>').append(rs)
);
rows.ForEach(r => r.appendTo(zTable));
function buildRows(gs) {
const header = gs.Select(g =>
$('<th></th>').text(g.Key())
).ToArray();
const rows = Enumerable.RepeatWithFinalize(
() => gs.Select(g => g.GetEnumerator()).ToArray(),
es => es.forEach(e => e.Dispose())
)
.Select(es => es.map(e => [e.MoveNext(), e.Current()]))
.TakeWhile(xs => xs.reduce((a, x) => a || x[0], false))
.Select(xs => xs.map(x => x[0] ? x[1] : $('<td></td>')));
return Enumerable.Return(header).Concat(rows);
}
我需要动态生成 html table 并在下面列出 driver_id。 它类似于 pivot,但问题是 zone_name 每天都在变化。 我正在使用 jquery 和 linq.js。
到目前为止我已经尝试过:
var data =
[
{
"ColorCode": "green",
"StatusName": "ACTIVE",
"rankId": 0,
"zone_name": "Zone A",
"driver_id": 100,
"zone_rank": 1,
"status_id": null,
"company_id": null,
"updated_on": null,
"Driver": null,
"login_status": null
},
{
"ColorCode": "yellow",
"StatusName": "BREAK",
"rankId": 0,
"zone_name": "Zone B",
"driver_id": 101,
"zone_rank": 1,
"status_id": null,
"company_id": null,
"updated_on": null,
"Driver": null,
"login_status": null
},
{
"ColorCode": "green",
"StatusName": "ACTIVE",
"rankId": 0,
"zone_name": "Zone A",
"driver_id": 102,
"zone_rank": 4,
"status_id": null,
"company_id": null,
"updated_on": null,
"Driver": null,
"login_status": null
}
]
var zTable = document.getElementById('tblZoneRank');
var allzones = Enumerable.From(data)
.Distinct(p => p.zone_name)
.Select(p => p.zone_name).ToArray();
$.each(allzones, function (i, item) {
var tr = document.createElement('tr');
var td = document.createElement("td");
var txt = document.createTextNode(item);
td.appendChild(txt);
tr.appendChild(td);
var childItem = Enumerable.From(data)
.Where(p => p.zone_name == item)
.ToArray();
$.each(childItem, function (j, citem) {
var ctd = document.createElement("td");
var ctxt = document.createTextNode(citem.driver_id);
ctd.appendChild(ctxt);
$(ctd).css('background-color', citem.ColorCode);
tr.appendChild(ctd);
});
zTable.appendChild(tr);
});
它以这种方式给我输出:
<table id="tblZoneRank">
<tr>
<td>Zone A</td>
<td style="background-color: rgb(0, 128, 0);">100</td>
<td style="background-color: rgb(0, 128, 0);">102</td>
</tr>
<tr>
<td>Zone B</td>
<td style="background-color: rgb(255, 255, 0);">101</td>
</tr>
</table>
但我需要这种格式的输出:
它应该显示 zone_name 作为列名,在 driver_id 下方,第一个 ID 应该是 zone_rank 1 和 2 等等。
我不熟悉 linq.js 所以我使用本机数组方法 Array#reduce()
和 Map
对象来创建独特的区域
const $table = $('#zoneTable');
// creates Map object with zone names as keys and arrays of jQuery objects(cells) as values
const zoneMap = data.reduce((map, item) => {
const col = map.get(item.zone_name) || [createCell(item.zone_name)];
col.push(createCell(item.driver_id, item.ColorCode));
return map.set(item.zone_name, col);
}, new Map());
// convert Map values to array of arrays. Each sub array is a table column
const colCells = [...zoneMap.values()];
const totalRows = Math.max(...colCells.map(e => e.length));
for (let i = 0; i < totalRows; i++) {
const rowCells = colCells.map(col => col[i] || createCell());// fill any missing with empty cell
const $row = $('<tr>').append(rowCells);
$table.append($row)
}
// helper function to create cells
function createCell(text = '', color = null) {
const $td = $('<td>').text(text);
return color ? $td.css('background-color', color) : $td;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="zoneTable"></table>
<script>
var data = [{
"ColorCode": "green",
"StatusName": "ACTIVE",
"rankId": 0,
"zone_name": "Zone A",
"driver_id": 100,
"zone_rank": 1,
"status_id": null,
"company_id": null,
"updated_on": null,
"Driver": null,
"login_status": null
},
{
"ColorCode": "yellow",
"StatusName": "BREAK",
"rankId": 0,
"zone_name": "Zone B",
"driver_id": 101,
"zone_rank": 1,
"status_id": null,
"company_id": null,
"updated_on": null,
"Driver": null,
"login_status": null
},
{
"ColorCode": "green",
"StatusName": "ACTIVE",
"rankId": 0,
"zone_name": "Zone A",
"driver_id": 102,
"zone_rank": 4,
"status_id": null,
"company_id": null,
"updated_on": null,
"Driver": null,
"login_status": null
}
]
</script>
因此,根据我从您的问题中收集到的信息,您正在尝试按区域对数据项进行分组,然后将它们输出到 table 中,其中列是区域。 Linq.js 可以很好地处理这个问题,只是在将数据行转换为列时会遇到一些问题。
const zTable = $('#tblZoneRank');
const rows = Enumerable.From(data)
.GroupBy(p => p.zone_name, p =>
$('<td></td>')
.css({'background-color': p.ColorCode})
.text(p.driver_id)
)
.Let(buildRows)
.Select(rs =>
$('<tr></tr>').append(rs)
);
rows.ForEach(r => r.appendTo(zTable));
function buildRows(gs) {
const header = gs.Select(g =>
$('<th></th>').text(g.Key())
).ToArray();
const rows = Enumerable.RepeatWithFinalize(
() => gs.Select(g => g.GetEnumerator()).ToArray(),
es => es.forEach(e => e.Dispose())
)
.Select(es => es.map(e => [e.MoveNext(), e.Current()]))
.TakeWhile(xs => xs.reduce((a, x) => a || x[0], false))
.Select(xs => xs.map(x => x[0] ? x[1] : $('<td></td>')));
return Enumerable.Return(header).Concat(rows);
}