登录  /  注册
博主信息
博文 70
粉丝 1
评论 0
访问量 50221
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
静态单页-项目数据-无刷新分页-增删改...
葡萄枝子
原创
708人浏览过

静态单页-项目数据-无刷新分页-增删改…

  1. 将项目改造成无刷新分页,前端用Ajax实现数据异步加载
  2. 实现记录的编辑与删除功能,想一下如何优雅的实现它

1. 往 staffs 表添加默认数据

  1. insert staffs (name,gender, salary, email,birthday) values
  2. ('king','male',6500,'king@php.cn','1992-10-29'),
  3. ('amy','female',7800,'amy@163.com','1998-10-22'),
  4. ('betty','female',9800,'betty@qq.com','1953-10-19'),
  5. ('jack','male',12500,'jack@php.cn', '1977-10-24'),
  6. ('marry','female',15800,'marry@php.cn', '1990-01-08'),
  7. ('alice','female',8600,'alice@php.cn','1989-09-18'),
  8. ('admin','male',16600,'admin@php.cn','1989-09-18'),
  9. ('lisa','female',13500,'lisa@qq.com','1983-09-13'),
  10. ('peter','male',9600,'peter@163.com','1993-09-29'),
  11. ('linda','female',5600,'linda@163.com','1993-09-29');

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

3. 引入的 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. }

4. 引入的 0226.js 文件代码

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

5. 后端处理 handle.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. // ...
  28. break;
  29. // 删
  30. case 'delete':
  31. die(del_data($pdo, $_GET['id'] ?? 0));
  32. break;
  33. // 改
  34. case 'update':
  35. $id = $_GET['id'] ?? 0;
  36. $name = $_POST['name'];
  37. $gender = $_POST['gender'];
  38. $salary = $_POST['salary'];
  39. $email = $_POST['email'];
  40. $birthday = $_POST['birthday'];
  41. die(update_data($pdo, $id, $name, $gender, $salary, $email, $birthday));
  42. break;
  43. // 查
  44. case 'select':
  45. die(get_datas($pdo, $page));
  46. }
  47. // 更新记录
  48. function update_data($pdo, $id, $name, $gender, $salary, $email, $birthday)
  49. {
  50. if ($id) {
  51. $sql = "UPDATE staffs SET name = :name, gender = :gender, salary = :salary, email = :email, birthday = :birthday WHERE id = :id";
  52. $stmt = $pdo->prepare($sql);
  53. $stmt->bindParam(':id', $id, PDO::PARAM_INT);
  54. $stmt->bindParam(':name', $name, PDO::PARAM_STR);
  55. $stmt->bindParam(':gender', $gender, PDO::PARAM_STR);
  56. $stmt->bindParam(':salary', $salary, PDO::PARAM_INT);
  57. $stmt->bindParam(':email', $email, PDO::PARAM_STR);
  58. $stmt->bindParam(':birthday', $birthday, PDO::PARAM_STR);
  59. $stmt->execute();
  60. if ($stmt->rowCount() > 0) {
  61. return '更新成功!';
  62. }
  63. }
  64. return '更新错误!';
  65. }
  66. // 删除记录
  67. function del_data($pdo, $id = 0)
  68. {
  69. if ($id) {
  70. $sql = "DELETE FROM staffs WHERE id = :id";
  71. $stmt = $pdo->prepare($sql);
  72. $stmt->bindParam(':id', $id, PDO::PARAM_INT);
  73. $stmt->execute();
  74. if ($stmt->rowCount() > 0) {
  75. return '删除成功!';
  76. }
  77. }
  78. return '删除错误!';
  79. }
  80. // 数据总页数
  81. function get_pages($pdo, $page = 1, $num = 5)
  82. {
  83. // 总页数
  84. $num = 5;
  85. $offset = ($page - 1) * $num;
  86. $sql = "SELECT CEIL(COUNT(1)/{$num}) total FROM staffs";
  87. $pages = $pdo->query($sql)->fetch()['total'];
  88. return $pages;
  89. }
  90. // 每页显示数
  91. function get_datas($pdo, $page = 1, $num = 5)
  92. {
  93. // 获取总页数
  94. $pages = get_pages($pdo);
  95. // 每页显示的数据
  96. $offset = ($page - 1) * $num;
  97. $sql = "SELECT * FROM `staffs` LIMIT {$offset}, {$num}";
  98. $stmt = $pdo->prepare($sql);
  99. $stmt->execute();
  100. $staffs = $stmt->fetchAll();
  101. $staffs = $pdo->query($sql)->fetchAll();
  102. return json_encode(['pages' => $pages, 'staffs' => $staffs]);
  103. }

运行 0226.html 附图

效果图

  • 点击第 3 页,ajax 翻页

ajax翻页

  • 点击编号是 14 倒数第2个记录,模态框编辑

模态框编辑

  • 修改姓名 peter 为 test 性别为女,保存,信息无刷新回滚页面

编辑信息

  • 删除刚修改的姓名为 test 的记录,单击确认

删除记录

  • 编号为 14 的记录,已无刷新删除

无刷新删除

批改老师:天蓬老师天蓬老师

批改状态:合格

老师批语:完成的相当棒,已经有一个项目的雏形了
本博文版权归博主所有,转载请注明地址!如有侵权、违法,请联系admin@php.cn举报处理!
全部评论 文明上网理性发言,请遵守新闻评论服务协议
0条评论
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2024 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号

  • 登录PHP中文网,和优秀的人一起学习!
    全站2000+教程免费学