目录
1.设计思路
1.1可编辑表格的具体要求
(1)页面中的数据表格根据实际情况对部分数据进行修改
(2)当点击表格中可编辑数据时,在当前单元格中显示文本框并在其中显示原数据,从而为用户提供修改该数据的输入域
- 在编辑模式下点击文本框之外的任何区域即可确认输入
- 在编辑模式下输入数据不符合要求时,应该给出适当的提示,并强制更改后方可确认输入
(3)应用要求
配置参数应该包括表格可编辑列、验证规则、样式等可配置项,并提供默认配置
1.2改进后的可编辑表格的具体要求
在1.1可编辑表格的项目基础上进行改进配置
(1)表格中要显示的数据来自服务器,由JSON格式表示
(2)通过以上JSON格式的数据生成可编辑表格,并且能灵活可编辑的数据列
(3)能分别为不同的可编辑列提供验证规则
(4)能配置和实现数据行的可删除操作
(5)数据修改能直接映射到从JSON生成的数据对象(即页面上的数据修改能通过到JSON数据)
2.核心代码及注解
(1)数据中有几列数据是需要正则表达式的配置项,例如性别需要验证男女,语数英的验证规则是0-150,理综的数据验证是0-300
以下是具体的正则表达式:
let Regnum = /^(1[0-4][0-9]|150)$|^([1-9][0-9])$|^[0-9]$/; //正则表达式判断0-150
let Regsex = /^(男|女){1}$/; //正则表达式判断性别
let Regnum_300 = /^([1-2][0-9][0-9]|300)$|^([1-9][0-9])$|^[0-9]$/; //正则表达式判断0-300
(2)数据更新、验证规则的封装函数-与正则表达式相结合
// 3.数据更新、验证规则——updateCell
function updateCell(element, Reg) {
if (document.getElementsByClassName("new_input").length == 0) {
// 获取当前数据
let old_value = element.innerText;
element.innerHTML = "";
// 创建新元素input
var input = document.createElement("input");
input.value = old_value;
input.setAttribute("class", "new_input");
input.type = "text";
element.appendChild(input);
input.focus();
// 失去焦点时——确认修改
input.onblur = function () {
// this.value = parseFloat(this.value);
console.log(this.value);
console.log(this.type);
// 判断是否符合修改规则
/* if (isNaN(this.value)) {
this.value = old_value;
} else { */
if (!Reg.test(this.value)) {
console.log("error", this.value, Reg);
this.value = old_value;
// 错误提示
alert("不符合规则");
this.classList.remove("new_input");
return;
} else {
element.innerHTML = this.value;
}
// }
// document.querySelector(".new_input").remove();
};
} else {
console.log("ERROR-input.length!=0");
}
}
3.具体页面展示
当点击删除按钮的时候,对应行会被删除,同时对应的JSON数据也会删除
从性别到理综这些列的单元格都可以进行修改
4.实现方法(完整代码)
可编辑表格.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style></style>
<link rel="stylesheet" href="./index.css" />
</head>
<body>
<div class="form">
<table class="table">
<thead>
<tr>
<th>学号</th>
<th>姓名</th>
<th>性别</th>
<th>语文</th>
<th>数学</th>
<th>英语</th>
<th>理综</th>
<th>操作</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<script></script>
<script src="./axios.js"></script>
<script src="./index-(1).js"></script>
</body>
</html>
index.css样式
* {
text-align: center;
padding: 0%;
/* margin: auto; */
/* margin-top: 100px; */
font-size: 25px;
}
form {
display: flex;
justify-content: center;
}
table,
th,
td {
border: solid 4px;
border-color: black;
border-collapse: collapse;
}
th,
td {
width: 200px;
height: 60px;
}
th {
background-color: #ccc;
}
td input {
border: 0;
width: 100%;
height: 100%;
}
index-(1).js
// 配置项
let jsonData = "";
let editable = [2, 3, 4, 5, 6]; //可编辑的列数 第 3 4 5 6列
let Regnum = /^(1[0-4][0-9]|150)$|^([1-9][0-9])$|^[0-9]$/; //正则表达式判断
let Regsex = /^(男|女){1}$/; //正则表达式判断性别
let Regnum_300 = /^([1-2][0-9][0-9]|300)$|^([1-9][0-9])$|^[0-9]$/; //正则表达式判断0-300
// console.log(Regsex.test("男"));
// 渲染界面
const baseUrl = " http://localhost:3000/t_grades";
//设置默认地址
axios.defaults.baseURL = baseUrl;
//创建axios实例 instance
const instance = axios.create({
//该地址为默认的地址
baseURL: "http://localhost:3000/t_grades",
});
function getEnrollments() {
instance.get("http://localhost:3000/t_grades").then((res) => {
const Table = document.querySelector(".table");
Table.tBodies[0].innerHTML = "";
const jsonData = res.data; // 响应数据
console.log(res.data, 2);
var trs = "";
jsonData.forEach((item) => {
// 从关联表中获取学生姓名和课程名称
const studentId = item.id;
const studentName = item.Student_name;
const studentSex = item.Student_sex;
const chinese = item.Chinese_score;
const math = item.Math_score;
const english = item.English_score;
const consolidation = item.consolidation_score;
// 创建一行表格,并将选课数据添加到其中
const row = `<tr>
<td>${studentId}</td>
<td>${studentName}</td>
<td>${studentSex}</td>
<td>${chinese}</td>
<td>${math}</td>
<td>${english}</td>
<td>${consolidation}</td>
<td><button class='delete' id = ${item.id}>删除</button></td>
</tr>`;
// 将这一行添加到表格中
trs += row;
});
Table.tBodies[0].innerHTML = trs;
handleOper();
setEditable(editable);
totalTable();
last();
});
}
getEnrollments();
function handleOper() {
const delButtons = document.querySelectorAll(".delete");
delButtons.forEach((one) => {
one.addEventListener("click", function (e) {
console.log(e.target, 1123);
const id = e.target.getAttribute("id");
axios
.delete(`/${id}`)
.then((res) => {
console.log(res.data);
getEnrollments();
})
.catch((err) => {
console.error(err);
});
});
});
// delButtons.forEach((element) => {
// element.onclick = function () {
// console.log(this, 1);
// this.parentNode.parentNode.remove();
// };
// });
}
// 1.设置可编辑单元格——setEditable
function setEditable(editable) {
let table = document.querySelector("table");
var row_num = table.rows.length; // 获取表格行数
for (let i = 1; i < row_num; i++) {
let column_num = table.rows[i].cells; //获取表格列数
let e = editable;
editable.forEach((element) => {
column_num[element].setAttribute("name", "editable");
});
}
// click(); //点击时
}
function totalTable() {
//封装函数
// 2.点击单元格
function click() {
let editcells = document.getElementsByName("editable");
console.log(editcells, 1);
for (let i = 0; i < editcells.length; i++) {
if (i == 0 || i == 5 || i == 10 || i == 15) {
editcells[i].onclick = function () {
updateCell(this, Regsex);
};
} else if (i == 4 || i == 9 || i == 14 || 19) {
editcells[i].onclick = function () {
updateCell(this, Regnum_300);
};
} else {
editcells[i].onclick = function () {
updateCell(this, Regnum);
};
}
}
}
last = click;
// 3.数据更新、验证规则——updateCell
function updateCell(element, Reg) {
if (document.getElementsByClassName("new_input").length == 0) {
// 获取当前数据
let old_value = element.innerText;
element.innerHTML = "";
// 创建新元素input
var input = document.createElement("input");
input.value = old_value;
input.setAttribute("class", "new_input");
input.type = "text";
element.appendChild(input);
input.focus();
// 失去焦点时——确认修改
input.onblur = function () {
// this.value = parseFloat(this.value);
console.log(this.value);
console.log(this.type);
// 判断是否符合修改规则
/* if (isNaN(this.value)) {
this.value = old_value;
} else { */
if (!Reg.test(this.value)) {
console.log("error", this.value, Reg);
this.value = old_value;
// 错误提示
alert("不符合规则");
this.classList.remove("new_input");
return;
} else {
element.innerHTML = this.value;
}
// }
// document.querySelector(".new_input").remove();
};
} else {
console.log("ERROR-input.length!=0");
}
}
}
table.json(在table.json的文件夹中启动cmd,输入json-server table.json命令行来启动JSON数据)
{
"t_title": [
{ "title_name": "学号" },
{ "title_name": "姓名" },
{ "title_name": "性别" },
{ "title_name": "语文" },
{ "title_name": "数学" },
{ "title_name": "英语" },
{ "title_name": "理综" }
],
"t_grades": [
{
"id": 1,
"Student_name": "小王",
"Student_sex": "女",
"Chinese_score": 98,
"Math_score": 98,
"English_score": 99,
"consolidation_score": 210
},
{
"id": 2,
"Student_name": "小张",
"Student_sex": "女",
"Chinese_score": 90,
"Math_score": 95,
"English_score": 80,
"consolidation_score": 180
},
{
"id": 3,
"Student_name": "小黄",
"Student_sex": "男",
"Chinese_score": 85,
"Math_score": 89,
"English_score": 90,
"consolidation_score": 200
},
{
"id": 4,
"Student_name": "小李",
"Student_sex": "男",
"Chinese_score": 89,
"Math_score": 97,
"English_score": 100,
"consolidation_score": 175
}
]
}