博客列表 >将一个项目改成无刷新分页,添加异步加载,实现信息记录的编辑与删除等功能

将一个项目改成无刷新分页,添加异步加载,实现信息记录的编辑与删除等功能

lus菜
lus菜原创
2021年03月04日 12:05:08754浏览

一. 先创建数据表并操作

  1. //数据表操作
  2. create table staffs (
  3. sid int unsigned auto_increment not null primary key,
  4. name varchar(20) not null comment '姓名',
  5. gender enum('male','female') not null comment '性别',
  6. email varchar(150) not null comment '邮箱',
  7. birthday date not null comment '生日',
  8. create_at timestamp not null default current_timestamp comment '创建日期',
  9. update_at timestamp not null default current_timestamp on update current_timestamp comment '更新日期'
  10. ) engine = innodb auto_increment=1 collate = utf8mb4_unicode_ci;
  11. // 创建 staffs 表 并插入数据
  12. insert staffs (name,gender,salary,email,birthday)
  13. values ('Lee','male',4500,'lee@php.cn','1983-02-10');
  14. insert staffs set name='King', gender='male',salary=8899,
  15. email='king@qq.com', birthday='1988-09-23';
  16. insert staffs (name,gender, salary, email,birthday) values
  17. ('king','male',6500,'king@php.cn','1992-10-29'),
  18. ('amy','female',7800,'amy@163.com','1998-10-22'),
  19. ('betty','female',9800,'betty@qq.com','1953-10-19'),
  20. ('jack','male',12500,'jack@php.cn', '1977-10-24'),
  21. ('marry','female',15800,'marry@php.cn', '1990-01-08'),
  22. ('alice','female',8600,'alice@php.cn','1989-09-18'),
  23. ('admin','male',16600,'admin@php.cn','1989-09-18'),
  24. ('lisa','female',13500,'lisa@qq.com','1983-09-13'),
  25. ('peter','male',9600,'peter@163.com','1993-09-29'),
  26. ('linda','female',5600,'linda@163.com','1993-09-29');

二. 新建一个html文件用来渲染前端页面: staff.html

staff.html样式代码:

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  7. <title>员工管理系统</title>
  8. <!-- 导入公共css样式代码 -->
  9. <link rel="stylesheet" href="style.css" />
  10. </head>
  11. <body>
  12. <table>
  13. <caption>
  14. 员工管理系统
  15. </caption>
  16. <thead>
  17. <tr>
  18. <td>编号</td>
  19. <td>姓名</td>
  20. <td>性别</td>
  21. <td>工资</td>
  22. <td>邮箱</td>
  23. <td>生日</td>
  24. <td>入职时间</td>
  25. <td>操作</td>
  26. </tr>
  27. </thead>
  28. <!-- 数据渲染区域 -->
  29. <tbody></tbody>
  30. </table>
  31. <!-- 分页渲染区域 -->
  32. <p></p>
  33. <!-- 模态框编辑区域 -->
  34. <div class="modal">
  35. <div class="modal-drop"></div>
  36. <div class="modal-body">
  37. <button class="close">关闭</button>
  38. <form action="" name="editform">
  39. <table>
  40. <caption>
  41. 员工信息编辑
  42. </caption>
  43. <tbody>
  44. <tr>
  45. <td>姓名</td>
  46. <td><input type="text" value="" name="name" id="name" /></td>
  47. </tr>
  48. <tr>
  49. <td>性别</td>
  50. <td>
  51. <select name="gender" id="gender">
  52. <option value="male" selected></option>
  53. <option value="female"></option>
  54. </select>
  55. </td>
  56. </tr>
  57. <tr>
  58. <td>工资</td>
  59. <td><input type="text" value="" name="salary" id="salary" /></td>
  60. </tr>
  61. <tr>
  62. <td>邮箱</td>
  63. <td><input type="text" value="" name="email" id="email" /></td>
  64. </tr>
  65. <tr>
  66. <td>生日</td>
  67. <td><input type="text" value="" name="birthday" id="birthday" /></td>
  68. </tr>
  69. <tr>
  70. <td colspan="2"><button class="save">保存</button></td>
  71. </tr>
  72. </tbody>
  73. </table>
  74. </form>
  75. </div>
  76. </div>
  77. <!-- 模态框样式代码 -->
  78. <style>
  79. /* 模态框初始化隐藏 */
  80. .modal {
  81. display: none;
  82. }
  83. /* 遮盖层 */
  84. .modal .modal-drop {
  85. position: fixed;
  86. background-color: rgb(0, 0, 0, 0.5);
  87. top: 0;
  88. left: 0;
  89. right: 0;
  90. bottom: 0;
  91. }
  92. .modal .modal-body {
  93. position: fixed;
  94. background-color: #fff;
  95. padding: 1em;
  96. overflow: hidden;
  97. max-width: 25em;
  98. max-height: 20em;
  99. /* 水平垂直自动居中 */
  100. top: 0;
  101. left: 0;
  102. right: 0;
  103. bottom: 0;
  104. margin: auto;
  105. }
  106. /* 关闭按钮 */
  107. .modal .modal-body .close {
  108. position: absolute;
  109. top: 1.1em;
  110. right: 1.5em;
  111. width: 3em;
  112. height: 1.5em;
  113. }
  114. </style>
  115. <!-- 导入外部js文件 -->
  116. <script src="staff.js"></script>
  117. </body>
  118. </html>

导入默认公共style.css样式代码:

  1. * {
  2. margin: 0;
  3. padding: 0;
  4. box-sizing: border-box;
  5. color: #555;
  6. }
  7. body {
  8. display: flex;
  9. flex-direction: column;
  10. align-items: center;
  11. }
  12. /*表格样式*/
  13. table {
  14. width: 90%;
  15. border: 1px solid;
  16. border-collapse: collapse;
  17. text-align: center;
  18. }
  19. table caption {
  20. font-size: 1.2rem;
  21. margin: 10px;
  22. }
  23. table td,
  24. table th {
  25. border: 1px solid;
  26. padding: 5px;
  27. }
  28. table tr:hover {
  29. background-color: #eee;
  30. }
  31. table thead tr:only-of-type {
  32. background-color: lightcyan;
  33. }
  34. table button {
  35. width: 56px;
  36. height: 26px;
  37. }
  38. table button:last-of-type {
  39. color: red;
  40. }
  41. table button {
  42. cursor: pointer;
  43. margin: 0 3px;
  44. }
  45. /*分页条样式*/
  46. body > p {
  47. display: flex;
  48. }
  49. p > a {
  50. text-decoration: none;
  51. color: #555;
  52. border: 1px solid #888;
  53. padding: 5px 10px;
  54. margin: 10px 2px;
  55. }
  56. .active {
  57. background-color: seagreen;
  58. color: white;
  59. border: 1px solid seagreen;
  60. }

再加上staff.js文件样式代码:

  1. // 页面载入完成时默认渲染第一页数据
  2. window.onload = function () {
  3. select(1);
  4. };
  5. // 编辑和删除记录
  6. document.querySelector("table:first-of-type tbody").addEventListener("click", (ev) => {
  7. // 获取记录 id
  8. const id = ev.target.parentNode.parentNode.querySelector("td").textContent * 1;
  9. // 操作类型
  10. switch (ev.target.textContent) {
  11. case "编辑":
  12. // 显示模态框
  13. document.querySelector(".modal").style.display = "block";
  14. // 点击关闭按钮,关闭模态框
  15. document.querySelector(".modal .close").addEventListener("click", (eve) => {
  16. document.querySelector(".modal").style.display = "none";
  17. });
  18. // 点击编辑按钮,关闭模态框
  19. document.querySelector(".modal .save").addEventListener("click", (eve) => {
  20. document.querySelector(".modal").style.display = "none";
  21. });
  22. // 点击模态框之外区域也关闭模态框
  23. document.querySelector(".modal .modal-drop").addEventListener("click", (eve) => {
  24. document.querySelector(".modal").style.display = "none";
  25. });
  26. // 获取数据
  27. let name = ev.target.parentNode.parentNode.querySelector("td:nth-of-type(2)").textContent;
  28. let gender = ev.target.parentNode.parentNode.querySelector("td:nth-of-type(3)").textContent;
  29. let salary = ev.target.parentNode.parentNode.querySelector("td:nth-of-type(4)").textContent * 1;
  30. let email = ev.target.parentNode.parentNode.querySelector("td:nth-of-type(5)").textContent;
  31. let birthday = ev.target.parentNode.parentNode.querySelector("td:nth-of-type(6)").textContent;
  32. // console.log(id, name, gender, salary, email, birthday);
  33. // 渲染到模态框
  34. document.getElementById("name").value = name;
  35. document.getElementById("gender").value = gender;
  36. document.getElementById("salary").value = salary;
  37. document.getElementById("email").value = email;
  38. document.getElementById("birthday").value = birthday;
  39. // 编辑事件
  40. document.querySelector(".modal .save").addEventListener("click", (eve) => {
  41. // 禁止默认提交
  42. eve.preventDefault();
  43. // 获取模态框编辑数据
  44. name = document.getElementById("name").value;
  45. gender = document.getElementById("gender").value;
  46. salary = document.getElementById("salary").value;
  47. email = document.getElementById("email").value;
  48. birthday = document.getElementById("birthday").value;
  49. // console.log(id, name, gender, salary, email, birthday);
  50. // 创建对象
  51. let xhr = new XMLHttpRequest();
  52. // 配置参数
  53. xhr.open("post", "staff.php?action=update&id=" + id);
  54. // 处理请求
  55. xhr.onload = () => {
  56. // console.log(xhr.response);
  57. // 更新数据写回页面
  58. ev.target.parentNode.parentNode.querySelector("td:nth-of-type(2)").textContent = name;
  59. ev.target.parentNode.parentNode.querySelector("td:nth-of-type(3)").textContent = gender;
  60. ev.target.parentNode.parentNode.querySelector("td:nth-of-type(4)").textContent = salary;
  61. ev.target.parentNode.parentNode.querySelector("td:nth-of-type(5)").textContent = email;
  62. ev.target.parentNode.parentNode.querySelector("td:nth-of-type(6)").textContent = birthday;
  63. };
  64. // 发送请求
  65. xhr.send(new FormData(document.forms.namedItem("editform")));
  66. });
  67. break;
  68. case "删除":
  69. if (confirm("确认删除编号 " + id + " 记录?")) {
  70. // 创建对象
  71. let xhr = new XMLHttpRequest();
  72. // 配置参数
  73. xhr.open("get", "staff.php?action=delete&id=" + id);
  74. // 处理请求
  75. xhr.onload = () => {
  76. // 删除节点
  77. ev.target.parentNode.parentNode.remove();
  78. };
  79. // 发送请求
  80. xhr.send(null);
  81. }
  82. break;
  83. }
  84. });
  85. // 查
  86. function select(page = 1) {
  87. // 创建对象
  88. const xhr = new XMLHttpRequest();
  89. // 配置参数
  90. xhr.open("get", "staff.php?action=select&page=" + page);
  91. // 处理请求
  92. xhr.onload = () => {
  93. // json 格式数据解析为 js 对象
  94. // console.log(xhr.response);
  95. let res = JSON.parse(xhr.response);
  96. let pages = res.pages;
  97. let staffs = res.staffs;
  98. // 渲染数据
  99. document.querySelector("table:first-of-type tbody").innerHTML = get_datas(staffs);
  100. // 渲染分页
  101. document.querySelector("p:first-of-type").innerHTML = get_pages(page, pages);
  102. };
  103. // 发送请求
  104. xhr.send(null);
  105. }
  106. // 无刷新分页
  107. document.querySelector("p:first-of-type").addEventListener("click", (ev) => {
  108. // 禁用默认跳转
  109. ev.preventDefault();
  110. // 点击当前激活页,无效点击
  111. if (ev.target.classList.contains("active")) return;
  112. // 去掉原激活样式
  113. [...ev.currentTarget.children].forEach((ele) => ele.classList.remove("active"));
  114. // 当前页添加激活样式
  115. ev.target.classList.add("active");
  116. let url = ev.target.href,
  117. page;
  118. // 获取页码
  119. if (url.indexOf("?") !== -1) {
  120. page = url.split("=")[1];
  121. } else {
  122. page = 1;
  123. }
  124. // 渲染点击页的数据
  125. select(page);
  126. });
  127. // 渲染数据
  128. function get_datas(datas) {
  129. let str = "";
  130. for (let i = 0; i < datas.length; i++) {
  131. str += "<tr>";
  132. str += "<td>" + datas[i]["id"] + "</td>";
  133. str += "<td>" + datas[i]["name"] + "</td>";
  134. str += "<td>" + datas[i]["gender"] + "</td>";
  135. str += "<td>" + datas[i]["salary"] + "</td>";
  136. str += "<td>" + datas[i]["email"] + "</td>";
  137. str += "<td>" + datas[i]["birthday"] + "</td>";
  138. str += "<td>" + datas[i]["create_at"] + "</td>";
  139. str += "<td><button>编辑</button><button>删除</button></td>";
  140. str += "</tr>";
  141. }
  142. return str;
  143. }
  144. // 分页数据
  145. function get_pages(page = 1, pages) {
  146. let paginate = "";
  147. let active = "";
  148. // 首页|上一页
  149. if (page <= 1) page = 1;
  150. if (page !== 1) {
  151. paginate += '<a href="' + document.URL + '?p=1">首页</a>';
  152. paginate += '<a href="' + document.URL + "?p=" + Math.max(1, page - 1) + '">上一页</a>';
  153. }
  154. // 高亮分页
  155. for (i = 1; i <= pages; i++) {
  156. active = "";
  157. if (page == i) active = ' class="active"';
  158. paginate += '<a href="' + document.URL + "?p=" + i + '"' + active + ">" + i + "</a>";
  159. }
  160. // 下一页|尾页
  161. if (page >= pages) page = pages;
  162. if (page !== pages) {
  163. paginate += '<a href="' + document.URL + "?p=" + Math.min(page + 1, pages) + '">下一页</a>';
  164. paginate += '<a href="' + document.URL + "?p=" + pages + '">尾页</a>';
  165. }
  166. return paginate;
  167. }

最后由后端staff.php进行操作:

  1. <?php
  2. $config = [
  3. 'type' => 'mysql',
  4. 'host' => '127.0.0.1',
  5. 'dbname' => 'phpedu',
  6. 'port' => '3306',
  7. 'charset' => 'utf8mb4',
  8. 'username' => 'root',
  9. 'password' => 'root',
  10. ];
  11. extract($config);
  12. $dsn = sprintf('%s:host=%s;dbname=%s;port=%s;charset=%s', $type, $host, $dbname, $port, $charset);
  13. try {
  14. $pdo = new PDO($dsn, $username, $password);
  15. // 设置结果集的返回类型
  16. $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
  17. // var_dump($pdo,'连接成功');
  18. } catch (PDOException $e) {
  19. die('连接失败:' . $e->getMessage());
  20. }
  21. // 每页显示记录数
  22. $action = $_GET['action'] ?? 'select';
  23. $page = $_GET['page'] ?? 1;
  24. switch ($action) {
  25. // 增
  26. case 'add':
  27. break;
  28. // 删
  29. case 'delete':
  30. die(del_data($pdo, $_GET['id'] ?? 0));
  31. break;
  32. // 改
  33. case 'update':
  34. $id = $_GET['id'] ?? 0;
  35. $name = $_POST['name'];
  36. $gender = $_POST['gender'];
  37. $salary = $_POST['salary'];
  38. $email = $_POST['email'];
  39. $birthday = $_POST['birthday'];
  40. die(update_data($pdo, $id, $name, $gender, $salary, $email, $birthday));
  41. break;
  42. // 查
  43. case 'select':
  44. die(get_datas($pdo, $page));
  45. }
  46. // 更新记录
  47. function update_data($pdo, $id, $name, $gender, $salary, $email, $birthday)
  48. {
  49. if ($id) {
  50. $sql = "UPDATE staffs SET name = :name, gender = :gender, salary = :salary, email = :email, birthday = :birthday WHERE id = :id";
  51. $stmt = $pdo->prepare($sql);
  52. $stmt->bindParam(':id', $id, PDO::PARAM_INT);
  53. $stmt->bindParam(':name', $name, PDO::PARAM_STR);
  54. $stmt->bindParam(':gender', $gender, PDO::PARAM_STR);
  55. $stmt->bindParam(':salary', $salary, PDO::PARAM_INT);
  56. $stmt->bindParam(':email', $email, PDO::PARAM_STR);
  57. $stmt->bindParam(':birthday', $birthday, PDO::PARAM_STR);
  58. $stmt->execute();
  59. if ($stmt->rowCount() > 0) {
  60. return '更新成功!';
  61. }
  62. }
  63. return '更新错误!';
  64. }
  65. // 删除记录
  66. function del_data($pdo, $id = 0)
  67. {
  68. if ($id) {
  69. $sql = "DELETE FROM staffs WHERE id = :id";
  70. $stmt = $pdo->prepare($sql);
  71. $stmt->bindParam(':id', $id, PDO::PARAM_INT);
  72. $stmt->execute();
  73. if ($stmt->rowCount() > 0) {
  74. return '删除成功!';
  75. }
  76. }
  77. return '删除错误!';
  78. }
  79. // 数据总页数
  80. function get_pages($pdo, $page = 1, $num = 5)
  81. {
  82. // 总页数
  83. $num = 5;
  84. $offset = ($page - 1) * $num;
  85. $sql = "SELECT CEIL(COUNT(1)/{$num}) total FROM staffs";
  86. $pages = $pdo->query($sql)->fetch()['total'];
  87. return $pages;
  88. }
  89. // 每页显示数
  90. function get_datas($pdo, $page = 1, $num = 5)
  91. {
  92. // 获取总页数
  93. $pages = get_pages($pdo);
  94. // 每页显示的数据
  95. $offset = ($page - 1) * $num;
  96. $sql = "SELECT * FROM `staffs` LIMIT {$offset}, {$num}";
  97. $stmt = $pdo->prepare($sql);
  98. $stmt->execute();
  99. $staffs = $stmt->fetchAll();
  100. $staffs = $pdo->query($sql)->fetchAll();
  101. return json_encode(['pages' => $pages, 'staffs' => $staffs]);
  102. }

效果预览:

使用Ajax无刷新分页效果预览:

对编号14的员工数据进行编辑,把姓名改为中文且工资过万效果预览:

编辑成功效果预览:

删除编号13的员工数据效果预览:

删除成功后效果预览:

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议