我有一个JSON数据,我试图从中创建一个HTML表以及一个下拉列表,但是面临呈现表和下拉列表的问题。
我的JSON:
[
{
"Category name": "juce",
"Category Data": [
{
"Item Code": "1234",
"Item Name": "juce1",
"Quantity": "0"
}
]
},
{
"Category name": "juce",
"Category Data": [
{
"Item Code": "1234",
"Item Name": "juce2",
"Quantity": "0"
}
]
},
{
"Category name": "rice",
"Category Data": [
{
"Item Code": "1234",
"Item Name": "rice1",
"Quantity": "0"
}
]
},
{
"Category name": "rice",
"Category Data": [
{
"Item Code": "1234",
"Item Name": "juce2",
"Quantity": "0"
}
]
},
{
"Category name": "roti",
"Category Data": [
{
"Item Code": "1234",
"Item Name": "roti1",
"Quantity": "0"
}
]
},
{
"Category name": "roti",
"Category Data": [
{
"Item Code": "1234",
"Item Name": "juce2",
"Quantity": "0"
}
]
}
]
我正在尝试制作一个HTML表格,该表格外部有下拉菜单,名为Category Name。
就像我的JSON一样,我在下拉列表中有想要的类别名称,以及其他数据(如HTML表格中的数据)。
当用户单击下拉列表中的任何类别时,HTML表将仅根据该类别名称进行填充。
“数量”此字段是可编辑的,将由用户
输入我正在尝试的代码段:
function addTable(tableData) {
var col = Object.keys(tableData[0]);
var countNum = col.filter(i => !isNaN(i)).length;
var num = col.splice(0, countNum);
col = col.concat(num);
var table = document.createElement("table");
var tr = table.insertRow(-1); // TABLE ROW.
var colNum = col.length; //to improve the speed
for (var i = 0; i < colNum + 1; i++) {
var th = document.createElement("th"); // TABLE HEADER.
if (i >= colNum) {
th.innerHTML = "Quantity";
tr.appendChild(th);
tr.classList.add("text-center");
tr.classList.add("head")
} else {
th.innerHTML = col[i];
tr.appendChild(th);
tr.classList.add("text-center");
tr.classList.add("head")
}
}
for (var i = 0; i < tableData.length; i++) {
tr = table.insertRow(-1);
for (var j = 0; j < col.length + 1; j++) {
let tabCell = tr.insertCell(-1);
var hiddenField = document.createElement("input");
hiddenField.style.display = "none";
var tabledata = tableData[i][col[j]];
if (i > -1 && j >= colNum) {
var quantityField = document.createElement("input");
quantityField.style.border = "none";
quantityField.style["text-align"] = "center";
quantityField.setAttribute('name', 'Quantity');
quantityField.setAttribute('autocomplete', 'on');
quantityField.setAttribute('value', '0');
quantityField.setAttribute('type', 'number');
quantityField.setAttribute('required', 'required');
quantityField.classList.add("dataReset");
tabCell.appendChild(quantityField);
} else {
if (tableData[i]['Item Code'] === tableData[i][col[j]]) {
tabCell.innerHTML = tabledata;
hiddenField.setAttribute('name', 'Item_Code');
hiddenField.setAttribute('value', tabledata);
tabCell.appendChild(hiddenField);
}
if (tableData[i]['Item Name'] === tableData[i][col[j]]) {
tabCell.innerHTML = tabledata;
hiddenField.setAttribute('name', 'Item_Name');
hiddenField.setAttribute('value', tabledata);
tabCell.appendChild(hiddenField);
}
if (j > 1)
tabCell.classList.add("text-right");
}
}
}
var divContainer = document.getElementById("HourlysalesSummary");
divContainer.innerHTML = "";
divContainer.appendChild(table);
table.classList.add("table");
table.classList.add("table-striped");
table.classList.add("table-bordered");
table.classList.add("table-hover");
}
addTable(tableData);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form action="www.google.com" id="form1">
<div class="row position-relative">
<div class="col-lg-4">
<h5 id="commonHeader">Category</h5>
<select class="test" id="CategoryName" name="categoryCode">
<option>All</option> <!-- this also i want to populate with the JSON DATA not statically,except All -->
<option>juce</option>
<option>rice</option>
<option>roti</option>
</select>
</div>
</div>
<hr style="border: 1px solid black">
<div class="table-responsive">
<table class="w-100" id=HourlysalesSummary></table>
</div>
<div>
<button type="submit" id="save">
<i class="fas fa-save"></i> Save
</button>
</div>
</form>
但是我没有得到结果。
我只有一个JSON,我想做所有事情来填充下拉列表,并且当用户选择“类别”来填充表时也要进行过滤。
答案 0 :(得分:0)
明智的选择一个实用程序库(例如Underscore或Lodash),以使数组操作更容易一些。在此示例中,我使用了Lodash。
var data = []/ //enter your array of data here instead of empty array
var dataArray = []; //this will hold a collection of Category Names
for (datum of data) {
console.log(datum);
dataArray.push(datum["Category name"]);
}
uniqueArrayForDropdown = _.sortedUniq(dataArray); //only save unique category names
现在,当有人选择类别名称时,您可以使用以下函数过滤data
对象(此处将rice
设置为静态,但您可以将其更改为所选的值从下拉列表中):
//this is the simple example with static data
data.filter(function(item) {return item["Category name"] === "rice";})
您可以通过设置创建类似于以下内容的函数并设置更改事件以执行filterSelection()
来应用它:
// this is a dynamic function that reads the selected value from the
// DOM and applies the filter accordingly
function filterSelection() {
var e = document.getElementById("CategoryName");
var selectedCategory = e.options[e.selectedIndex].value;
var filteredData = data.filter(function(item) {return item["Category name"] === selectedCategory;})
drawTable(filteredData); //you need to write the drawTable method
}
只要表逻辑正确,就可以绘制filteredData
数组; filteredData
包含与过滤条件匹配的data
个对象的子集。
答案 1 :(得分:0)
对于该项目,最好分步骤进行。我看到一些步骤:
请考虑以下代码。
var tData = [{
"Category name": "juce",
"Category Data": [{
"Item Code": "1234",
"Item Name": "juce1",
"Quantity": "0"
}]
},
{
"Category name": "juce",
"Category Data": [{
"Item Code": "1234",
"Item Name": "juce2",
"Quantity": "0"
}]
},
{
"Category name": "rice",
"Category Data": [{
"Item Code": "1234",
"Item Name": "rice1",
"Quantity": "0"
}]
},
{
"Category name": "rice",
"Category Data": [{
"Item Code": "1234",
"Item Name": "juce2",
"Quantity": "0"
}]
},
{
"Category name": "roti",
"Category Data": [{
"Item Code": "1234",
"Item Name": "roti1",
"Quantity": "0"
}]
},
{
"Category name": "roti",
"Category Data": [{
"Item Code": "1234",
"Item Name": "juce2",
"Quantity": "0"
}]
}
];
$(function() {
function getCatNames(arr) {
var names = [];
$.each(arr, function(key, obj) {
names.push(obj['Category name']);
});
var unique = names.filter((v, i, a) => a.indexOf(v) === i);
return unique;
}
function updateFilter(obj, d) {
var catOpts = getCatNames(d);
obj.html("");
obj.append("<option>All</option>");
$.each(catOpts, function(k, v) {
$("<option>").html(v).appendTo(obj);
});
}
function filterSelection(obj) {
var s = $("#CategoryName option:selected").val();
if (s == "All") {
$("tbody tr", obj).show();
return;
}
$("tbody tr", obj).each(function(ind, el) {
var cat = $("td:eq(0)", el).text().trim();
if (cat != s) {
$(el).hide();
} else {
$(el).show();
}
});
}
function makeTableHead(obj, data) {
if (obj.find("thead").length === 0) {
$("<thead>").prependTo(obj);
}
var row = $("<tr>").appendTo($("thead", obj));
$.each(data[0], function(k, v) {
console.log(k, v);
if (k == "Category name") {
$("<th>", {
class: "text-center head"
}).html(k).appendTo(row);
} else {
$.each(v[0], function(j, x) {
$("<th>", {
class: "text-center head"
}).html(j).appendTo(row);
});
}
});
}
function makeTableBody(obj, data, qnty) {
if (qnty == undefined) {
qnty = true;
}
if (obj.find("tbody").length === 0) {
$("<tbody>").appendTo(obj);
}
$.each(data, function(k, v) {
var row = $("<tr>", {
class: "item-" + k
}).appendTo($("tbody", obj));
var n = $("<td>", {
class: "text-center cat-name"
}).html(v['Category name']).appendTo(row);
$("<input>", {
type: "hidden",
name: "cat-name[]",
value: v['Category name']
}).appendTo(n);
var itc = $("<td>", {
class: "text-center item-code"
}).appendTo(row);
itc.html(v['Category Data'][0]['Item Code']);
$("<input>", {
type: "hidden",
name: "item_code",
value: v['Category Data'][0]['Item Code']
}).appendTo(itc);
var itn = $("<td>", {
class: "text-center item-name"
}).appendTo(row);
itn.html(v['Category Data'][0]['Item Name']);
$("<input>", {
type: "hidden",
name: "item_name",
value: v['Category Data'][0]['Item Name']
}).appendTo(itn);
if (qnty) {
var q = $("<td>", {
class: "cat-qnty"
}).appendTo(row);
$("<input>", {
name: "Quantity",
autocomplete: "on",
value: v['Category Data'][0].Quantity,
type: "number",
class: "dataReset"
}).css({
border: "none",
"text-align": "center",
width: "4em"
}).appendTo(q);
}
});
}
function addTable(tableData, tbl) {
if (tbl == undefined) {
tbl = $("<table>", {
id: "HourlysalesSummary"
});
}
//var col = Object.keys(tableData[0]);
//var countNum = col.length;
makeTableHead(tbl, tableData);
makeTableBody(tbl, tableData);
var divContainer = $("#HourlysalesSummary").parent();
divContainer.html(tbl);
tbl.addClass("table table-striped table-bordered table-hover");
}
updateFilter($("#CategoryName"), tData);
addTable(tData, $("#HourlysalesSummary"));
$("#CategoryName").change(function() {
filterSelection($("#HourlysalesSummary"));
});
});
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form action="www.google.com" id="form1">
<div class="row position-relative">
<div class="col-lg-4">
<h5 id="commonHeader">Category</h5>
<select class="test" id="CategoryName" name="categoryCode">
<option>All</option>
<option>juce</option>
<option>rice</option>
<option>roti</option>
</select>
</div>
</div>
<hr style="border: 1px solid black">
<div class="table-responsive">
<table class="w-100" id="HourlysalesSummary">
<thead></thead>
<tbody></tbody>
</table>
</div>
<div>
<button type="submit" id="save"><i class="fas fa-save"></i> Save</button>
</div>
</form>
如您所见,我创建了以下功能:
addTable( data )
makeTableHead( object, data, quantity )
makeTableBody( object, data, quantity )
updateFilter( object, data )
getCatNames( data )
filterSelection( object )
使用<thead>
和<tbody>
可以在您具有更多动态表主体内容时有所帮助。如果您进行更改或加载新数据,则可能只需要对新数据运行makeTableBody($("#HourlysalesSummary"), tData);
。
我将很多代码切换到了jQuery。如果可能的话,我不喜欢混合。这也使我们可以更多地使用$.each()
,这对数组和对象数据确实很有帮助。
希望这会有所帮助。