将行跨度分配给表并根据父行将它们分组时,我遇到了问题。我已经尝试找到一些解决方案,但是大多数解决方案是合并相同的值而不是将它们分组。
var data =
[
{
"LEVEL_1": "LEVEL 1",
"LEVEL_2": "LEVEL 1.1",
"LEVEL_3": "LEVEL 1.1.1",
},
{
"LEVEL_1": "LEVEL 1",
"LEVEL_2": "LEVEL 1.2",
"LEVEL_3": "LEVEL 1.2.1",
},
{
"LEVEL_1": "LEVEL 1",
"LEVEL_2": "LEVEL 1.2",
"LEVEL_3": "LEVEL 1.2.2",
},
{
"LEVEL_1": "LEVEL 2",
"LEVEL_2": "LEVEL 2.1",
"LEVEL_3": "LEVEL 2.1.1",
},
{
"LEVEL_1": "LEVEL 2",
"LEVEL_2": "LEVEL 2.1",
"LEVEL_3": "LEVEL 2.1.2",
},
{
"LEVEL_1": "LEVEL 2",
"LEVEL_2": "LEVEL 2.2",
"LEVEL_3": "LEVEL 2.2.1",
},
{
"LEVEL_1": "LEVEL 2",
"LEVEL_2": "LEVEL 2.2",
"LEVEL_3": "LEVEL 2.2.2",
}
];
var tableStr = '';
$.each(data, function(index, value) {
tableStr += '<tr>' +
'<td>'+value.LEVEL_1+'</td>'+
'<td>'+value.LEVEL_2+'</td>'+
'<td>'+value.LEVEL_3+'</td>'+
'</tr>';
});
$('#user tbody').html(tableStr);
table {
border-collapse: collapse;
}
td {
padding: 20px;
border: 1px solid black;
text-align: center;
}
th {
padding: 20px;
border: 1px solid black;
text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="user">
<thead>
<tr>
<th>LEVEL 1</th>
<th>LEVEL 2</th>
<th>LEVEL 3</th>
</tr>
<tr>
</tr>
</thead>
<tbody>
</tbody>
</table>
我总是发现一个结果,它从一开始就起作用。但是当我添加另一个级别但相同的数据时,它总是像这样
从Ajax请求提供的JSON数据已经这样给出了。我是否需要修改JSON数据并将其分组?或者可以使用给定的JSON数据完成此操作?如何使用Jquery和JSON数据完成此操作?预先感谢
答案 0 :(得分:1)
借助此question,我设法合并了第一级。
var data = [{
"LEVEL_1": "LEVEL 1",
"LEVEL_2": "LEVEL 1.1",
"LEVEL_3": "LEVEL 1.1.1",
},
{
"LEVEL_1": "LEVEL 1",
"LEVEL_2": "LEVEL 1.2",
"LEVEL_3": "LEVEL 1.2.1",
},
{
"LEVEL_1": "LEVEL 1",
"LEVEL_2": "LEVEL 1.2",
"LEVEL_3": "LEVEL 1.2.2",
},
{
"LEVEL_1": "LEVEL 2",
"LEVEL_2": "LEVEL 2.1",
"LEVEL_3": "LEVEL 2.1.1",
},
{
"LEVEL_1": "LEVEL 2",
"LEVEL_2": "LEVEL 2.1",
"LEVEL_3": "LEVEL 2.1.2",
},
{
"LEVEL_1": "LEVEL 2",
"LEVEL_2": "LEVEL 2.2",
"LEVEL_3": "LEVEL 2.2.1",
},
{
"LEVEL_1": "LEVEL 2",
"LEVEL_2": "LEVEL 2.2",
"LEVEL_3": "LEVEL 2.2.2",
}
];
for (i = 0; i < data.length; i++) {
var l1 = data[i].LEVEL_1;
data[i].rowspan = 1;
for (j = i + 1; j < data.length; j++) {
var l2 = data[j].LEVEL_1;
if (l1 == l2) {
data[i].rowspan += 1;
} else {
break;
}
}
i = j - 1;
}
var tableStr = '';
$.each(data, function(index, value) {
if (value.rowspan > 1) {
tableStr += '<tr>' +
'<td rowspan="' + value.rowspan + '">' + value.LEVEL_1 + '</td>' +
'<td>' + value.LEVEL_2 + '</td>' +
'<td>' + value.LEVEL_3 + '</td>' +
'</tr>';
} else {
tableStr += '<tr>' +
'<td>' + value.LEVEL_2 + '</td>' +
'<td>' + value.LEVEL_3 + '</td>' +
'</tr>';
}
});
$('#user tbody').html(tableStr);
table {
border-collapse: collapse;
}
td {
padding: 20px;
border: 1px solid black;
text-align: center;
}
th {
padding: 20px;
border: 1px solid black;
text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="user">
<thead>
<tr>
<th>LEVEL 1</th>
<th>LEVEL 2</th>
<th>LEVEL 3</th>
</tr>
<tr>
</tr>
</thead>
<tbody>
</tbody>
</table>
答案 1 :(得分:0)
我为您提供解决方案。它可能不是最优雅的,但可以使用
首先,我将数据从JSON转换为一个嵌套对象,该对象计算较低级别项的出现。
第二步是遍历该嵌套对象并相应地创建表,tr和td,并将步骤1中的计数值用作rowspan
属性值。
我什至不需要jQuery,只需要VanillaJS。
console.clear();
var data = [
{
LEVEL_1: "LEVEL 1",
LEVEL_2: "LEVEL 1.1",
LEVEL_3: "LEVEL 1.1.1"
},
{
LEVEL_1: "LEVEL 1",
LEVEL_2: "LEVEL 1.2",
LEVEL_3: "LEVEL 1.2.1"
},
{
LEVEL_1: "LEVEL 1",
LEVEL_2: "LEVEL 1.2",
LEVEL_3: "LEVEL 1.2.2"
},
{
LEVEL_1: "LEVEL 2",
LEVEL_2: "LEVEL 2.1",
LEVEL_3: "LEVEL 2.1.1"
},
{
LEVEL_1: "LEVEL 2",
LEVEL_2: "LEVEL 2.1",
LEVEL_3: "LEVEL 2.1.2"
},
{
LEVEL_1: "LEVEL 2",
LEVEL_2: "LEVEL 2.2",
LEVEL_3: "LEVEL 2.2.1"
},
{
LEVEL_1: "LEVEL 2",
LEVEL_2: "LEVEL 2.2",
LEVEL_3: "LEVEL 2.2.2"
}
];
const transformData = (data) => {
let t = {};
data.forEach((item, index, source) => {
let l1 = item.LEVEL_1,
l2 = item.LEVEL_2,
l3 = item.LEVEL_3;
t[l1] = t[l1] || {text: l1, content: {}, count: 0};
t[l1].content[l2] = t[l1].content[l2] || {text: l2, content: {}, count: 0};
t[l1].content[l2].content[l3] = t[l1].content[l2].content[l3] || {text: l3, content: {}, count: 0};
t[l1].count++
t[l1].content[l2].count++
t[l1].content[l2].content[l3].count++
})
return t;
}
const transformDataTable = (tdata) => {
const table = document.createElement('table');
for (l1 in tdata) {
const td1 = document.createElement('th')
td1.textContent = tdata[l1].text;
td1.setAttribute('rowspan', tdata[l1].count)
let done1 = false;
for (l2 in tdata[l1].content) {
const td2 = document.createElement('td')
td2.textContent = tdata[l1].content[l2].text;
td2.setAttribute('rowspan', tdata[l1].content[l2].count)
let done2 = false;
for (l3 in tdata[l1].content[l2].content) {
const td3 = document.createElement('td')
td3.textContent = tdata[l1].content[l2].content[l3].text;
td3.setAttribute('rowspan', tdata[l1].content[l2].content[l3].count)
const tr = document.createElement('tr')
!done1 && tr.appendChild(td1) && (done1 = true);
!done2 && tr.appendChild(td2) && (done2 = true);
tr.appendChild(td3);
table.appendChild(tr);
}
}
}
return table;
}
const tdata = transformData(data);
const table = transformDataTable(tdata);
document.body.appendChild(table)
table {
border-collapse: collapse;
}
td,
th {
padding: 20px;
border: 1px solid black;
text-align: center;
}
通过一些修改,您可以自己对每个列进行排序
console.clear();
var data = [
{
LEVEL_1: "LEVEL 3",
LEVEL_2: "LEVEL 3.1",
LEVEL_3: "LEVEL 3.1.1"
},
{
LEVEL_1: "LEVEL 1",
LEVEL_2: "LEVEL 1.1",
LEVEL_3: "LEVEL 1.1.1"
},
{
LEVEL_1: "LEVEL 1",
LEVEL_2: "LEVEL 1.2",
LEVEL_3: "LEVEL 1.2.1"
},
{
LEVEL_1: "LEVEL 1",
LEVEL_2: "LEVEL 1.2",
LEVEL_3: "LEVEL 1.2.2"
},
{
LEVEL_1: "LEVEL 2",
LEVEL_2: "LEVEL 2.1",
LEVEL_3: "LEVEL 2.1.1"
},
{
LEVEL_1: "LEVEL 3",
LEVEL_2: "LEVEL 3.1",
LEVEL_3: "LEVEL 3.1.2"
},
{
LEVEL_1: "LEVEL 2",
LEVEL_2: "LEVEL 2.1",
LEVEL_3: "LEVEL 2.1.2"
},
{
LEVEL_1: "LEVEL 2",
LEVEL_2: "LEVEL 2.2",
LEVEL_3: "LEVEL 2.2.1"
},
{
LEVEL_1: "LEVEL 2",
LEVEL_2: "LEVEL 2.2",
LEVEL_3: "LEVEL 2.2.2"
},
{
LEVEL_1: "LEVEL 2",
LEVEL_2: "LEVEL 2.2",
LEVEL_3: "LEVEL 2.2.3"
}
];
const transformData = (data) => {
let t = {};
data.forEach((item, index, source) => {
let l1 = item.LEVEL_1,
l2 = item.LEVEL_2,
l3 = item.LEVEL_3;
t[l1] = t[l1] || {text: l1, content: {}, count: 0};
t[l1].content[l2] = t[l1].content[l2] || {text: l2, content: {}, count: 0};
t[l1].content[l2].content[l3] = t[l1].content[l2].content[l3] || {text: l3, content: {}, count: 0};
t[l1].count++
t[l1].content[l2].count++
t[l1].content[l2].content[l3].count++
})
return t;
}
const transformDataTable = (tdata, sort = (a,b) => b-a, sort1 = sort, sort2 = sort1) => {
const table = document.createElement('table');
for (l1 of Object.keys(tdata).sort(sort)) {
const td1 = document.createElement('th')
td1.textContent = tdata[l1].text;
td1.setAttribute('rowspan', tdata[l1].count)
let done1 = false;
for (l2 of Object.keys(tdata[l1].content).sort(sort1)) {
const td2 = document.createElement('td')
td2.textContent = tdata[l1].content[l2].text;
td2.setAttribute('rowspan', tdata[l1].content[l2].count)
let done2 = false;
for (l3 of Object.keys(tdata[l1].content[l2].content).sort(sort2)) {
const td3 = document.createElement('td')
td3.textContent = tdata[l1].content[l2].content[l3].text;
td3.setAttribute('rowspan', tdata[l1].content[l2].content[l3].count)
const tr = document.createElement('tr')
!done1 && tr.appendChild(td1) && (done1 = true);
!done2 && tr.appendChild(td2) && (done2 = true);
tr.appendChild(td3);
table.appendChild(tr);
}
}
}
return table;
}
const asc = (a,b) => b-a
const desc = (a,b) => a-b
const tdata = transformData(data);
const table = transformDataTable(tdata, desc, asc);
document.body.appendChild(table)
table {
border-collapse: collapse;
}
td,
th {
padding: 20px;
border: 1px solid black;
text-align: center;
}
答案 2 :(得分:0)
我将其分为两个步骤:1.从输入数据生成树状结构以允许行跨计数; 2.绘制表的行和列。
整个代码尽可能通用,以避免硬编码的列数。
我还添加了一个动态表头。如果在数据结构中添加另一列,则HTML表标题也会被更新。例如,可以使用相同的代码添加第四级,例如"LEVEL_4": "LEVEL 1.2.2.1"
到一行或多行。
var data = [
{
"LEVEL_1": "LEVEL 1",
"LEVEL_2": "LEVEL 1.1",
"LEVEL_3": "LEVEL 1.1.1"
},
{
"LEVEL_1": "LEVEL 1",
"LEVEL_2": "LEVEL 1.2",
"LEVEL_3": "LEVEL 1.2.1"
},
{
"LEVEL_1": "LEVEL 1",
"LEVEL_2": "LEVEL 1.2",
"LEVEL_3": "LEVEL 1.2.2"
},
{
"LEVEL_1": "LEVEL 2",
"LEVEL_2": "LEVEL 2.1",
"LEVEL_3": "LEVEL 2.1.1"
},
{
"LEVEL_1": "LEVEL 2",
"LEVEL_2": "LEVEL 2.1",
"LEVEL_3": "LEVEL 2.1.2"
},
{
"LEVEL_1": "LEVEL 2",
"LEVEL_2": "LEVEL 2.2",
"LEVEL_3": "LEVEL 2.2.1"
},
{
"LEVEL_1": "LEVEL 2",
"LEVEL_2": "LEVEL 2.2",
"LEVEL_3": "LEVEL 2.2.2"
}
];
/**
* Generate rows and columns for the table using the JSON data.
*
* @param {Object} data
* @param {HTMLTableSectionElement} tableBody
* @param {HTMLTableSectionElement} tableHead
*/
function setTableContent(data, tableBody, tableHead) {
/* The rowspan is stored here depending on the label of each column */
var columnRowspans = {};
var columnHeadings = {};
/**
* Translate the data into a tree-like structure
*
* @param {JSON} data
* @return {Array}
*/
function translateData(data) {
var rows = [];
/* Iterate over each row in the dataset */
data.forEach(function (row) {
var columns = [],
label;
/* Find the individual columns */
for (var key in row) {
/* Store the columns header */
columnHeadings[key] = true;
label = row[key];
/* Skip those columns that were already added */
if (columnRowspans[label]) {
columnRowspans[label]++;
continue;
}
columns.push(label);
columnRowspans[label] = 1;
}
rows.push(columns);
});
return rows;
}
/* Template string used for a single field in the table */
var cellTemplate = '<td rowspan="{rowspan}">{content}</td>';
/* Output */
var html = '';
translateData(data).forEach(function (row, index) {
html += '<tr>';
row.forEach(function (columnLabel) {
/* Use the stored rowspans here to generate columns */
html += cellTemplate
.replace('{rowspan}', columnRowspans[columnLabel])
.replace('{content}', columnLabel);
});
html += '</tr>';
});
if (tableBody instanceof HTMLTableSectionElement) {
tableBody.innerHTML = html;
}
if (tableHead instanceof HTMLTableSectionElement) {
var thead = '<tr>';
Object.keys(columnHeadings).forEach(function (heading) {
thead += '<th>' + heading.replace('_', ' ') + '</th>';
});
thead += '</tr>';
tableHead.innerHTML = thead;
}
}
setTableContent(data, document.querySelector('#user tbody'), document.querySelector('#user thead'));
table {
border-collapse: collapse;
}
td {
padding: 20px;
border: 1px solid black;
text-align: center;
}
th {
padding: 20px;
border: 1px solid black;
text-align: center;
}
<table id="user">
<thead>
</thead>
<tbody>
</tbody>
</table>