可编辑表格
- 一、设计思路
- 二 、实现方法
- 三、js核心代码实现
一、设计思路
本次代码设计的可编辑表格,核心思路是将表格划分为多个模块,每个模块负责不同的功能,模块之间松耦合,方便复用和扩展。主要模块如下:
- 渲染表格模块:负责将JSON数据渲染成表格,包含表头和表体。
- 可编辑单元格模块:判断单元格是否可编辑,如果是在单击事件中显示输入框供编辑,编辑后更新数据源。
- 计算总分模块:在表头添加总分列,计算每行的总分并显示。
- 添加操作模块:在表头添加操作列,为每行添加删除按钮,点击后删除对应行并更新数据源。
- 数据校验模块:在编辑单元格时判断输入值是否在0-满分之间,不在则显示错误提示。以上模块围绕表格数据的展示、编辑与交互进行拆分,每个模块职责清晰,易于维护和扩展。
二 、实现方法
- 使用axios获取JSON数据,并在响应成功后调用渲染表格模块。
- 渲染表格模块:通过DOM操作,循环数据源渲染表头和表体。
- 可编辑单元格模块:在单元格点击事件中,判断是否为可编辑单元格,如果是则显示输入框,输入框失焦后获取值,判断是否在0-满分范围,如果是则更新数据源并重新渲染表格。
- 计算总分模块:为表头添加总分列,循环表体为每行添加总分单元格,计算每行科目分数总和并显示在总分单元格中。
- 添加操作模块:为表头添加操作列,循环表体为每行添加删除按钮,点击删除按钮后删除对应行并在数据源中删除对应数据。
- 数据校验模块:在可编辑单元格模块中,判断输入值是否在0-满分范围,不在则显示错误提示框。
三、js核心代码实现
- 获取成绩数据
function loadData() {
axios.get("./data.json").then((res) => {
data = res.data;
if (localStorage.getItem("data")) data = JSON.parse(localStorage.data);
else {
data = res.data;
localStorage.data = JSON.stringify(data);
}
sort.innerText = localStorage.sort || sort.innerText;
let tr = document.createElement("tr");
data.head.forEach((e) => {
let th = document.createElement("th");
th.innerText = e.item;
tr.appendChild(th);
});
thead.appendChild(tr);
data.students.forEach((e) => {
let body_tr = document.createElement("tr");
let sum = 0;
e.forEach((x) => {
let td = document.createElement("td");
td.innerText = x;
body_tr.appendChild(td);
if (typeof x == "number") sum += x;
});
e[e.length] = sum;
let td = document.createElement("td");
td.innerText = sum;
body_tr.appendChild(td);
tbody.appendChild(body_tr);
});
btnn();
addClick();
addConfigure();
List(); //显示第一页
});
}
2.添加表格点击事件
function addClick() {
let index = [];
data.head.forEach((e, i) => {
if (e.editable) index.push(i);
});
var trs = document.querySelectorAll("tbody tr");
trs.forEach((e, row) => {
e.querySelectorAll("td").forEach((x, i) => {
if (index.includes(i)) {
onHover(x);
x.onclick = function () {
let score = x.innerText;
input = document.createElement("input");
input.value = score;
if (i == 0) {
input.value = score.toString().padStart(3, "0");
}
x.innerText = "";
x.appendChild(input);
input.focus();
input.select();
input.onblur = function () {
if (
data.head[i].pattern &&
!RegExp(data.head[i].pattern).test(input.value)
) {
document.querySelector(".error").style.display = "block";
setTimeout(() => {
document.querySelector(".error").style.display = "none";
}, 2000);
} else {
document.querySelector(".error").style.display = "none";
if (i === 0) {
data.students[10 * newcurrentpage - (10 - row)][i] =
input.value;
} else {
data.students[10 * newcurrentpage - (10 - row)][i] =
Number(input.value) || input.value;
}
input.remove();
updataHtml();
}
};
input.onclick = function (e) {
e.stopPropagation();
};
};
}
});
});
}
3,、增添增加行和删除行的操作
//删除行
let ok = document.querySelector(".ok");
let error = document.querySelector(".error");
let del = document.querySelector(".delete");
let delBtn = document.querySelector(".del button");
let tag = false;
delBtn.addEventListener("click", () => {
let value = del.value;
data.students.forEach((e) => {
if (value === e[0]) {
tag = true;
nowpage = Math.floor((data.students.indexOf(e) + 1) / 10) + 1;
if ((data.students.indexOf(e) + 1) / 10 === nowpage - 1) {
nowpage--;
}
if (nowpage === totalpage) {
lastpageList.pop();
}
data.students.splice(data.students.indexOf(e), 1);
btnn(nowpage);
ok.style.display = "block";
setTimeout(() => {
ok.style.display = "none";
}, 2000);
updataHtml();
return 0;
}
});
if (!tag) {
error.style.display = "block";
setTimeout(() => {
error.style.display = "none";
}, 2000);
} else {
tag = false;
}
});
//增加行
let newdata = document.querySelector(".add");
newdata.onclick = () => {
let input = document.querySelector(".input_pop form");
input.innerHTML = "";
data.head.forEach((e) => {
if (e.editable == false && e.item != "总成绩") {
let div = document.createElement("div");
div.innerText = e.item + ":";
let put = document.createElement("input");
put.setAttribute("type", "text");
div.appendChild(put);
input.appendChild(div);
}
});