博客列表 >Ajax数据异步加载、无刷新分页、编辑与删除功能

Ajax数据异步加载、无刷新分页、编辑与删除功能

吳
原创
2021年03月03日 12:37:04977浏览

ajax无刷新分页与编辑删除功能

  • 无刷新分页

  • 删除功能

删除前:

删除后:

  • 编辑功能

编辑前:用户ID43

编辑后:用户ID43

  • 文件:index.php
  1. <?php
  2. session_start();
  3. ?>
  4. <!DOCTYPE html>
  5. <html lang="en">
  6. <head>
  7. <meta charset="UTF-8">
  8. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  9. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  10. <title>用户管理系统</title>
  11. <link rel="stylesheet" href="style.css">
  12. </head>
  13. <body>
  14. <table>
  15. <caption>用户管理 <span class="tips" style="color:red;font-size:10px;"></span></caption>
  16. <thead>
  17. <tr>
  18. <td>UID</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="md">
  32. <div class="md-drop"></div>
  33. <div class="md-body">
  34. <button class="close">关闭</button>
  35. <form action="" name="editform">
  36. <h2>编辑用户</h2>
  37. <div class="md-login">
  38. <label for="name">姓名:</label>
  39. <input type="text" name="name" id="name" value="">
  40. <label for="email">邮箱:</label>
  41. <input type="email" name="email" id="email" value="">
  42. <button class="save">保存</button>
  43. </div>
  44. </form>
  45. </div>
  46. </div>
  47. <!-- 模态框样式 -->
  48. <style>
  49. /* 模态框初始化隐藏 */
  50. .md {
  51. display: none;
  52. }
  53. /* 遮罩层 */
  54. .md .md-drop {
  55. position: fixed;
  56. background-color: rgb(0, 0, 0, .5);
  57. top: 0;
  58. left: 0;
  59. right: 0;
  60. bottom: 0;
  61. }
  62. .md .md-body {
  63. position: fixed;
  64. background-color: lightcyan;
  65. padding: 1em;
  66. overflow: hidden;
  67. max-width: 25em;
  68. max-height: 20em;
  69. /* 水平垂直居中 */
  70. top: 0;
  71. left: 0;
  72. right: 0;
  73. bottom: 0;
  74. margin: auto;
  75. border-radius: 10px;
  76. }
  77. /* 关闭按钮 */
  78. .md .md-body .close {
  79. float: right;
  80. height: 2.5em;
  81. width: 3em;
  82. border: 0;
  83. border-radius: 0.5em;
  84. outline: none;
  85. background-color: rgb(1, 231, 135);
  86. }
  87. .md .md-login {
  88. display: grid;
  89. gap: 1em;
  90. margin-top: 20px;
  91. }
  92. </style>
  93. <script src="ajax.js"></script>
  94. </body>
  95. </html>
  • css样式文件: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. }
  • 文件:ajax.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 sid = ev.target.parentNode.parentNode.querySelector('td').textContent * 1;
  9. const tips = document.querySelector('.tips');
  10. // 操作类型
  11. switch (ev.target.textContent) {
  12. case '编辑':
  13. // 显示模态框
  14. document.querySelector('.md').style.display = 'block';
  15. // 点击关闭按钮
  16. document.querySelector('.md .close').addEventListener('click',(eve) => {
  17. document.querySelector('.md').style.display = 'none';
  18. });
  19. // 点击模态框之外区域
  20. document.querySelector('.md .md-drop').addEventListener('click',(eve) => {
  21. document.querySelector('.md').style.display = 'none';
  22. });
  23. // 获取数据
  24. let name = ev.target.parentNode.parentNode.querySelector('td:nth-of-type(2)').textContent;
  25. let email = ev.target.parentNode.parentNode.querySelector('td:nth-of-type(3)').textContent;
  26. // 渲染到模态框
  27. document.getElementById('name').value = name;
  28. document.getElementById('email').value = email;
  29. // 编辑事件
  30. document.querySelector('.md .save').addEventListener('click',(eve) => {
  31. // 禁止默认提交
  32. eve.preventDefault();
  33. // 获取模态框数据
  34. name = document.getElementById('name').value;
  35. email = document.getElementById('email').value;
  36. // 创建对象
  37. let xhr = new XMLHttpRequest();
  38. // 配置参数
  39. xhr.open('post','api.php?action=update&sid=' + sid);
  40. xhr.responseType = 'json';
  41. // 处理请求
  42. xhr.onload = () => {
  43. // 更新数据写会页面
  44. tips.innerHTML = xhr.response.msg;
  45. if (xhr.response.status === 1 ) {
  46. document.querySelector('.md').style.display = 'none';
  47. ev.target.parentNode.parentNode.querySelector('td:nth-of-type(2)').textContent = name;
  48. ev.target.parentNode.parentNode.querySelector('td:nth-of-type(3)').textContent = email;
  49. setTimeout(() => tips.innerHTML = null,2000);
  50. }
  51. };
  52. xhr.send(new FormData(document.forms.namedItem('editform')));
  53. });
  54. break;
  55. case '删除':
  56. if (confirm('确认删除UID:' + sid + '用户?')) {
  57. // 创建对象
  58. let xhr = new XMLHttpRequest();
  59. // 配置参数
  60. xhr.open('get','api.php?action=delete&sid=' + sid);
  61. xhr.responseType = 'json';
  62. // 处理请求
  63. xhr.onload = () => {
  64. tips.innerHTML = xhr.response.msg;
  65. if (xhr.response.status === 1) {
  66. // 删除节点
  67. ev.target.parentNode.parentNode.remove();
  68. setTimeout(() => tips.innerHTML = null,2000);
  69. }
  70. };
  71. // 发送请求
  72. xhr.send(null);
  73. }
  74. break;
  75. }
  76. })
  77. function select(page = 1) {
  78. // 创建对象
  79. const xhr = new XMLHttpRequest();
  80. // 配置参数
  81. xhr.open('get', 'api.php?action=select&page=' + page);
  82. // 处理请求
  83. xhr.onload = () => {
  84. // console.log(xhr.response);
  85. let res = JSON.parse(xhr.response);
  86. let pages = res.pages;
  87. let users = res.users;
  88. // 渲染数据
  89. document.querySelector('table:first-of-type tbody').innerHTML = get_datas(users);
  90. // 渲染分页
  91. document.querySelector('p:first-of-type').innerHTML = pags(page,pages);
  92. }
  93. // 发送请求
  94. xhr.send(null);
  95. }
  96. // 渲染数据
  97. function get_datas(datas) {
  98. let str = '';
  99. for (let i = 0; i < datas.length; i++) {
  100. str += '<tr>';
  101. str += '<td>' + datas[i]['sid'] + '</td>';
  102. str += '<td>' + datas[i]['name'] + '</td>';
  103. str += '<td>' + datas[i]['email'] + '</td>';
  104. str += '<td>' + datas[i]['create_at'] + '</td>';
  105. str += '<td><button>编辑</button><button>删除</button></td>';
  106. str += '</tr>';
  107. }
  108. return str;
  109. }
  110. // 无刷新分页
  111. document.querySelector('p:first-of-type').addEventListener('click',ev => {
  112. // 禁用默认跳转
  113. ev.preventDefault();
  114. // 点击当前激活页,无效点击
  115. if (ev.target.classList.contains('active')) return;
  116. // 去掉激活样式
  117. [...ev.currentTarget.children].forEach(ele => ele.classList.remove('active'));
  118. // 当前页添加激活样式
  119. ev.target.classList.add('active');
  120. let url = ev.target.href,page;
  121. // 获取页码
  122. if (url.indexOf('?') !== -1) {
  123. page = url.split('=')[1];
  124. } else {
  125. page = 1;
  126. }
  127. select(page);
  128. })
  129. // 分页数据
  130. function pags (page = 1,pages) {
  131. let pag = '';
  132. let active = '';
  133. // 首页和上一页
  134. if (page <= 1) page =1;
  135. if (page != 1) {
  136. pag += '<a href="'+ document.URL + '?p=1">首页</a>';
  137. pag += '<a href="'+ document.URL + '?p=' + Math.max(1,page - 1) +'">上一页</a>';
  138. }
  139. // 高亮分页
  140. for (i = 1; i <= pages; i++ ) {
  141. active = '';
  142. if (page == i) active = 'class="active"';
  143. pag += '<a href="' + document.URL + '?p=' + i + '"' + active + '>' + i + '</a>';
  144. }
  145. // 下一页和尾页
  146. if (page >= pages) page = pages;
  147. if (page !== pages) {
  148. pag += '<a href="' + document.URL + '?p=' + Math.min(page + 1,pages) + '">下一页</a>'
  149. pag += '<a href="' + document.URL + '?p=' + pages +'">尾页</a>'
  150. }
  151. return pag;
  152. }
  • 文件:api.php
  1. $config = [
  2. 'type' => 'mysql',
  3. 'host' => '127.0.0.1',
  4. 'dbname' => 'phpedu',
  5. 'username' => 'root',
  6. 'password' => '123456',
  7. ];
  8. extract($config);
  9. $dsn = sprintf('%s:host=%s;dbname=%s;',$type,$host,$dbname);
  10. try {
  11. $pdo = new PDO($dsn,$username,$password);
  12. // 设置结果集返回类型
  13. $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE,PDO::FETCH_ASSOC);
  14. // var_dump($pdo,'连接成功');
  15. } catch (PDOException $e){
  16. die('连接失败:'. $e->getMessage());
  17. }
  18. // 页码通过get请求
  19. $page = $_GET['page'] ?? 1;
  20. $action = $_GET['action'] ?? 'select';
  21. switch ($action) {
  22. // 查询
  23. case 'select':
  24. die(get_datas($pdo,$page));
  25. break;
  26. // 删
  27. case 'delete':
  28. die(del_data($pdo,$_GET['sid'] ?? 0));
  29. break;
  30. // 更新
  31. case 'update':
  32. $sid = $_GET['sid'] ?? 0;
  33. $name = $_POST['name'];
  34. $email = $_POST['email'];
  35. die(update_data($pdo,$sid,$name,$email));
  36. break;
  37. }
  38. // 更新
  39. function update_data($pdo,$sid,$name,$email) {
  40. if ($sid) {
  41. $sql = "UPDATE users SET name=:name, email=:email WHERE sid = :sid;";
  42. $stmt = $pdo->prepare($sql);
  43. $stmt->bindParam(':sid',$sid,PDO::PARAM_INT);
  44. $stmt->bindParam(':name',$name,PDO::PARAM_STR);
  45. $stmt->bindParam(':email',$email,PDO::PARAM_STR);
  46. $stmt->execute();
  47. if($stmt->rowCount() > 0) {
  48. return json_encode(['status' => 1,'msg' => '更新成功!']);
  49. }
  50. }
  51. return json_encode(['status' => 0,'msg' => '未知错误!']);
  52. }
  53. // 删除
  54. function del_data($pdo,$sid = 0) {
  55. if ($sid) {
  56. $sql = "DELETE FROM users WHERE sid = :sid;";
  57. $stmt = $pdo->prepare($sql);
  58. $stmt->bindParam(':sid',$sid,PDO::PARAM_INT);
  59. $stmt->execute();
  60. if ($stmt->rowCount() > 0) {
  61. return json_encode(['status' => 1,'msg' => '删除成功!']);
  62. }
  63. }
  64. return json_encode(['status' => 0,'msg' => '未知错误!']);
  65. }
  66. // 获取总页数
  67. function get_pages($pdo,$page = 1,$num = 5) {
  68. // 总页数
  69. $num = 5;
  70. $offset = ($page - 1 ) * $num;
  71. $sql = "SELECT CEIL(COUNT(1)/{$num}) total FROM users";
  72. $pages = $pdo->query($sql)->fetch()['total'];
  73. return $pages;
  74. }
  75. function get_datas($pdo,$page = 1, $num = 5) {
  76. // 获取总页数
  77. $pages = get_pages($pdo);
  78. // 每页显示数据
  79. $offset = ($page - 1) * $num;
  80. $sql = "SELECT * FROM `users` LIMIT {$offset},{$num}";
  81. $stmt = $pdo->prepare($sql);
  82. $stmt->execute();
  83. $users = $stmt->fetchAll();
  84. $users = $pdo->query($sql)->fetchall();
  85. return json_encode(['pages' => $pages, 'users' => $users]);
  86. }
声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议