我想为表格创建过滤器。该表是从数组生成的。我创建了复选框,但现在遇到了麻烦。
我已经搜索了很多,但是找不到解决方案。
我想根据生成的复选框过滤表数据,但是我不知道如何将它们全部连接在一起。我不知道如何从表中收集对象,该对象将与复选框的值匹配,以便取消选择给定类型后可以过滤表中的行。
我尝试使用 event.target.getAttribute('data-filter'),但是在过滤数组以匹配事件方面存在问题。
是否有可能仅使用纯JavaScript进行类似的设置?
这是我的代码:
let array= [
{
"name": "John",
"surname": "XYZ",
"department": "IT"
},
{
"name": "John",
"surname": "XYZ",
"department": "accountancy"
},
]
function generateTableHead(table, data) {
let thead = table.createTHead();
let row = thead.insertRow();
for (let key of data) {
let th = document.createElement("th");
let text = document.createTextNode(key);
th.appendChild(text);
row.appendChild(th);
}
}
function generateTable(table, data) {
for (let element of data) {
let row = table.insertRow();
for (key in element) {
let cell = row.insertCell();
let text = document.createTextNode(element[key]);
cell.appendChild(text);
}
}
}
let table = document.querySelector("table");
let data = Object.keys(array[0]);
generateTable(table, array);
generateTableHead(table, data);
// FILTER: checkboxes
const getDepartments = array.map(function (element) {
return [element.department].join('');
});
let departmentFilters = [...new Set(getDepartments)];
let createFilters = function () {
box = document.querySelector('#filterType');
box.innerHTML = departmentFilters.map(function (department) {
let checkboxes = '<label>' +
'<input type="checkbox" data-filter="' + department + '" checked>' + department +
'</label>';
return checkboxes;
}).join('');
};
答案 0 :(得分:1)
您可以尝试这样:
const array = [{
"name": "John",
"surname": "XYZ",
"department": "IT"
},
{
"name": "John",
"surname": "XYZ",
"department": "accountancy"
},
{
"name": "Paul",
"surname": "XYZ",
"department": "Chemistry"
}
];
const table = document.querySelector("#tblClass");
const data = Object.keys(array[0]);
let filters = [];
function generateTableHead(table, data) {
const thead = table.createTHead();
const row = thead.insertRow();
for (const key of data) {
const th = document.createElement("th");
const [first, ...rest] = key;
const heading = `${first.toUpperCase()}${rest.join('')}`;
const text = document.createTextNode(heading);
th.appendChild(text);
row.appendChild(th);
}
}
function generateTable(table, data) {
for (let i = 1; i < table.rows.length;)
table.deleteRow(i);
for (const element of data) {
const row = table.insertRow();
for (const key in element) {
const cell = row.insertCell();
const text = document.createTextNode(element[key]);
cell.appendChild(text);
}
}
}
function onDepartmentChange(event) {
const currentDepartment = event.currentTarget.value;
let filteredArray = [];
if (this.checked) {
filters.push(currentDepartment);
} else {
filters = filters.filter(x => x !== currentDepartment);
}
if (filters.length === 0) {
filteredArray = array;
generateTable(table, filteredArray);
return;
}
filteredArray = array.filter(x => filters.some(y => y === x.department));
generateTable(table, filteredArray);
}
generateTable(table, array);
generateTableHead(table, data);
document.querySelectorAll('[name=deptFilter]')
.forEach(x => x.addEventListener('change', onDepartmentChange));
<table id="tblClass">
</table>
<br>
<label>Filter by department:
<br>
<span>
<input name="deptFilter" type="checkbox" value ="IT"/> IT
<input name="deptFilter" type="checkbox" value ="accountancy" /> Accountancy
<input name="deptFilter" type="checkbox" value ="None" /> None
</span>
</label>
答案 1 :(得分:1)
演示中评论的更改的详细信息
let array = [{
"name": "Jane",
"surname": "Doe",
"department": "IT"
},
{
"name": "John",
"surname": "Doe",
"department": "Finance"
},
{
"name": "Darth",
"surname": "Vader",
"department": "Sith Lord"
}
];
const table = document.querySelector("table");
const filters = document.querySelector('#filterType');
function generateTable(table, array) {
let row, cell;
array.forEach(function(obj) {
row = table.insertRow();
/*
Object.entries returns an array of key/value pairs of
an object
To access kv pairs, detsructure each pair: [key, value]
Each cell is assigned 'data-key' with value
*/
for (let [key, value] of Object.entries(obj)) {
cell = row.insertCell()
let text = document.createTextNode(value);
cell.appendChild(text);
cell.dataset.key = value;
}
});
// generateTableHead is called on return
let keys = Object.keys(array[0]);
return generateTableHead(table, keys);
}
function generateTableHead(table, keys) {
let thead = table.createTHead();
let row = thead.insertRow();
for (let key of keys) {
let th = document.createElement("th");
let text = document.createTextNode(key);
th.appendChild(text);
row.appendChild(th);
}
}
/*
Pass the name of header and the array
The return is an array of values under the given key (header)
*/
function getKey(target, array) {
let keyArray = array.map(function(obj) {
for (let [key, value] of Object.entries(obj)) {
if (key === target) {
return value;
}
}
});
/*
A fieldset is created with id of key
The array of values is passed to createFilters on return
*/
filters.insertAdjacentHTML('beforeend', `<fieldset id='${target}'><legend>${target}</legend></fieldset>`)
createFilters(keyArray);
}
/*
A Set of the given array is converted back into an array
of unique values
Each checkbox is inserted into the newest fieldset
*/
function createFilters(array) {
let set = Array.from(new Set([...array]));
set.forEach(function(name) {
let chk = `<label><input type="checkbox" data-filter="${name}" checked>${name}</label>`;
filters.lastElementChild.insertAdjacentHTML('beforeend', chk);
});
};
/*
This is the callback function called whenever a checkbox is
checked or unchecked.
The checked/unchecked checkbox (e.target) determines which cell is affected by comparing data-key and data-filter attribute values.
*/
function filterKey(e) {
const tgt = e.target;
let name = tgt.dataset.filter;
let keys = document.querySelectorAll(`[data-key="${name}"]`);
for (let cell of keys) {
if (tgt.checked) {
cell.closest('tr').classList.remove('off');
} else {
cell.closest('tr').classList.add('off');
}
}
}
generateTable(table, array);
/*
Pass any applicable key (header) and create a new filter
*/
// Uncomment any or all
// getKey('name', array);
// getKey('surname', array);
getKey('department', array);
// Register the form to the change event
filters.onchange = filterKey;
.off {
visibility: collapse;
}
<form id='filterType'></form>
<table></table>