案例 图书管理-渲染-添加-删除-编辑

86 阅读1分钟
<!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>
  <!-- 引入 lib 目录下的 bootstrap 样式表 -->
  <link rel="stylesheet" href="./lib/bootstrap-v4.6.0.css" />
  <style>
    :root {
      font-size: 15px;
    }

    body {
      padding-top: 15px;
    }
  </style>
</head>

<body>
  <!-- 栅格系统 -->
  <div class="container-fluid">
    <!-- <button class="btn-success loadBook">加载图书数据</button> -->
    <!-- 栅格系统中的一行 -->
    <div class="row">
      <div class="col-sm-8">
        <table class="table table-bordered table-striped table-dark table-hover text-center">
          <thead>
            <!-- 表头行 -->
            <tr>
              <th scope="col">Id</th>
              <th scope="col">书名</th>
              <th scope="col">作者</th>
              <th scope="col">出版社</th>
              <th scope="col">操作</th>
            </tr>
          </thead>
          <tbody>
            <!-- 表格中的每一行 -->
            <!-- <tr>
              <th scope="row">xxx</th>
              <td>xxx</td>
              <td>xxx</td>
              <td>xxx</td>
              <td>
                <button type="button" class="btn btn-link btn-sm">
                  删除
                </button>
              </td> -->
            </tr>
          </tbody>
        </table>
      </div>

      <!-- 右侧的添加区域,占了 4 列 -->
      <div class="col-sm-4">
        <!-- 添加图书的卡片 -->
        <div class="card text-white bg-secondary sticky-top">
          <div class="card-header">添加新图书</div>
          <form class="card-body bg-light" id="addForm">
            <!-- 书名 -->
            <div class="input-group mb-3">
              <div class="input-group-prepend">
                <span class="input-group-text">书名</span>
              </div>
              <input type="text" class="form-control bookname" placeholder="请输入图书名称" name="bookname" />
            </div>
            <!-- 作者 -->
            <div class="input-group mb-3">
              <div class="input-group-prepend">
                <span class="input-group-text">作者</span>
              </div>
              <input type="text" class="form-control" placeholder="请输入作者名字" name="author" />
            </div>
            <!-- 出版社 -->
            <div class="input-group mb-3">
              <div class="input-group-prepend">
                <span class="input-group-text">出版社</span>
              </div>
              <input type="text" class="form-control" placeholder="请输入出版社名称" name="publisher" />
            </div>
            <!-- 添加按钮 -->
            <button class="btn btn-dark btnadd" type="submit">添加</button>
          </form>
        </div>
      </div>
    </div>
  </div>

  <!-- 编辑 模态框 :作为body的直接子元素-->
  <div class="modal fade" id="editModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
    <div class="modal-dialog">
      <div class="modal-content">
        <div class="modal-header">
          <h5 class="modal-title" id="exampleModalLabel">编辑</h5>
          <button type="button" class="close" data-dismiss="modal" aria-label="Close">
            <span aria-hidden="true">&times;</span>
          </button>
        </div>
        <div class="modal-body">
          <form class="card-body bg-light" id="addForm">
            <!-- 书名 -->
            <div class="input-group mb-3">
              <div class="input-group-prepend">
                <span class="input-group-text">书名</span>
              </div>
              <input type="text" class="form-control bookname" placeholder="请输入图书名称" name="editbookname" />
            </div>
            <!-- 作者 -->
            <div class="input-group mb-3">
              <div class="input-group-prepend">
                <span class="input-group-text">作者</span>
              </div>
              <input type="text" class="form-control" placeholder="请输入作者名字" name="editauthor" />
            </div>
            <!-- 出版社 -->
            <div class="input-group mb-3">
              <div class="input-group-prepend">
                <span class="input-group-text">出版社</span>
              </div>
              <input type="text" class="form-control" placeholder="请输入出版社名称" name="editpublisher" />
            </div>
          </form>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-secondary" data-dismiss="modal">
            取消
          </button>
          <button type="button" class="btn btn-primary btnConfirm">
            确定修改
          </button>
        </div>
      </div>
    </div>
  </div>

  <script src="./lib/axios.js"></script>
  <script src="./lib/jquery.js"></script>
  <!-- 引入bootstrap.js -->
  <script src="./lib/bootstrap-4.6.1-dist/js/bootstrap.js"></script>


  <script>
    // 获取元素
    // let loadBook = document.querySelector('.loadBook')
    let tbody = document.querySelector('tbody')
    let btnadd = document.querySelector('.btnadd')
    // 获取添加图书时的元素:属性选择器:querySelector('元素?[属性=值]')
    let bookname = document.querySelector('[name=bookname]')
    let author = document.querySelector('[name=author]')
    let publisher = document.querySelector('[name=publisher]')
    // 获取编辑时的元素
    let editbookname = document.querySelector('[name=editbookname]')
    let editauthor = document.querySelector('[name=editauthor]')
    let editpublisher = document.querySelector('[name=editpublisher]')
    let btnConfirm = document.querySelector('.btnConfirm')

    // 实现图书列表的渲染
    function init() {
      // 页面一加载就不用处理事件了
      // loadBook.addEventListener('click', function () {
      // 接口
      axios({
        url: 'http://www.itcbc.com:3006/api/getbooks',
        method: 'get'
      }).then(res => {
        // 以后请求完毕之后,一定要将返回结果打印
        // 一定要分析数据,找到自己的需要的数据
        console.log(res.data.data)//打印
        // 遍历+拼接
        let str = ''
        // let list = res.data.data
        // ↓
        res.data.data.forEach((value, index) => {
          str += `<tr>
          <th scope="row">${index + 1}</th>
          <td>${value.bookname}</td>
          <td>${value.author}</td>
          <td>${value.publisher}</td>
          <td>
            <button data-id='${value.id}'
               type="button" 
               class="btn btn-link btn-sm btndel">
                删除
            </button>
            <button data-id='${value.id}'  
                data-bookname='${value.bookname}'
                data-author='${value.author}'
                data-publisher='${value.publisher}' 
                type="button"
                class="btn btn-link btn-sm btnedit">
                编辑
            </button>
          </td>
          </tr>`
        })
        tbody.innerHTML = str
      })

    }
    init()
    // 实现图书的添加 接口是:添加图书
    btnadd.addEventListener('click', function (e) {
      //阻止submit默认提交行为
      e.preventDefault()
      // 收集数据,一定要参照后台接口(以前是参照模拟数据)
      // 发起请求(以前是添加到数组,进行本地存储)
      axios({
        url: "http://www.itcbc.com:3006/api/addbook",//接口注意不要调错了
        // 参阅文档接口POST方式需要带参请求,查阅axios中文文档POST带参需要data
        method: 'POST',//单词写错了,相当于没有设置 请求方式
        // put,patch,post的参数需要使用data来设置
        data: {
          bookname: bookname.value,
          author: author.value,
          publisher: publisher.value
        }
      }).then(result => {
        console.log(result)//打印
        alert(result.data.message)// 弹出跳转框
        init()
      })
    })

    // 图书删除
    // 删除元素是动态生成的元素,所以一定要是用委托的方式绑定事件
    // 委托事件的绑定:1.添加已存在的非动态的父容器
    //                2.如何做到操作指定的圆度才处理呢?e.target
    tbody.addEventListener('click', function (e) {
      //contains:判断元素是否汗指定的名称的样式,如果有就返回true
      if (e.target.classList.contains('btndel')) {
        // 发起ajax请求
        // 第一步是获取当前想删除的图书id
        // 两种方式:1.传递参数(这里传不了)2.先存储在获取
        // dataset :data-deta-的自定义属性值得获取通过dataset,它获取到一个对象
        let id = e.target.dataset.id
        console.log(id)//打印
        // 第二部是发起ajax请求
        // dataset参数的传递方式和get一样
        axios({// 接口
          // url: 'http://www.itcbc.com:3006/api/delbook?id=' + id,
          url: 'http://www.itcbc.com:3006/api/delbook',
          params: { id },
          method: 'delete'
        }).then(result => {
          console.log(result)// 打印查看
          alert('删除成功')// 弹框提示
          init()// 重新渲染
        })
      }
    })
    // 定义一个全局id,用于编辑时的使用
    let Id
    // 在事件处理函数中获取编辑按钮中的自定义属性数据进行填充
    // 单机列表中的编辑仅仅是弹出模态框,填充默认数据
    tbody.addEventListener('click', function (e) {
      // 判断
      if (e.target.classList.contains('btnedit')) {
        // 使用js方式弹出模态框
        $('#editModal').modal('show')
        // 填充数据
        // 获取我要渲染的数组,有两种方式
        // 1.传递参数 
        // 2.先存储在获取 
        let data = e.target.dataset
        // 将当前数据的id存储到全局变量
        id = data.id
        alert(id)
        editbookname.value = data.bookname
        editauthor.value = data.author
        editpublisher.value = data.publisher
      }
    })
    // 实现编辑功能--单机模态框中的单机修改按钮(不是动态元素没必要加委托)
    // - 在列表中的编辑按钮中添加id的自定义属性存储
    // - 在列表中的编辑按钮的单击事件中获取id,存储到全局变量
    // - 在编辑确定按钮的事件中使用id做为参数传递给服务器,实现编辑
    btnConfirm.addEventListener('click', function () {
      let data = {  // 1.收集数据 
        id: id,// 使用全局id作为编辑时的参数id
        bookname: bookname.value,
        author: author.value,
        publisher: publisher.value
      }
      console.log(data) // 打印
      // 端口// 2.发起ajax请求 
      axios({
        url: 'http://www.itcbc.com:3006/api/updatebook',
        // post,put,patch的 参数传递都是使用data选项
        method: 'PUT',
        data
      }).then(result => {
        alert('编辑成功')
        $('#editModal').modal('hide') // 关闭模态框
        init()// 重新渲染
        // // 判断
        // if (result.data.status == 0) {
        //   alert(result.data.message)
        //   bookname.value = author.value = publisher.value = ''
        //   $('#myModal').modal('hide')
        //   // 重新渲染列表结构
        //   init()
        // } else {
        //   alert('图书编辑失败')
        // }
      })
    })
  </script>
</body>

</html>