当前位置: 首页 > news >正文

图书馆管理系统(三)基于jquery、ajax

任务3.4 借书还书页面

任务描述

这部分主要是制作借书还书的界面,这里我分别制作了两个网页分别用来借书和还书。此页面,也是通过获取books.txt内容然后添加到表格中,但是借还的操作没有添加到后端中去,只是一个简单的前端操作。

任务实施

3.4.1 借还的页面搭建

因为两者的整体框架是一样的不一样的点只有在借还操作这一部分是不同的,所以放在一块进行。

这里为借书操作为例:

整体布局就是左面导航栏,右边为主体部分内容

主体内容部分:

.main 包含一个表格,表格的头部定义了七个列:书名、作者、出版社、价格、内容摘要、借阅状态、操作

<tbody> 部分暂时为空,稍后将通过 JavaScript 动态填充数据。

导航栏部分:有三个导航链接:

“我的空间”:链接到用户个人页面。

“图书借阅”:当前所在页面。

“图书还回”:链接到图书还回的页面。

全部代码:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="./js/jQuery.js"></script><link rel="stylesheet" href="./css/borrow.css">
</head>
<style></style><body><div class="content"><div class="nav"><div class="nav-header"><img src="./img/user1.png" alt=""><h3>用户系统</h3></div><div class="nav-menu"><ul><li><a href="user.html">我的空间</a></li><li><a href="#">图书借阅</a></li><li><a href="repaid.html">图书还回</a></li></ul></div></div><div class="main"><table><thead><tr><th>书名</th><th>作者</th><th>出版社</th><th>价格</th><th>内容摘要</th><th>借阅状态</th><th>操作</th></tr></thead><tbody></tbody></table></div></div>
</body>
<script src="./js/borrow.js"></script>
</html>
而还书的部分只有这部分是不一样的<div class="nav-menu"><ul><li><a href="user.html">我的空间</a></li><li><a href="borrow.html">图书借阅</a></li><li><a href="#">图书还回</a></li></ul></div>
3.4.2 页面样式设置

这里样式设置部分不多说,还是以借书为例,全部代码:

*{margin: 0;padding: 0;
}
.nav {background-color: #2f2f2f;width: 20%;height: 100vh;float: left;
}
.nav-header {height: 6rem;display: flex;
}
.nav-header img {width: 6rem;height: 6rem;margin: 1rem 2rem;
}
.nav-header h3 {color: #fff;font-size: 2rem;margin-top: 1rem;text-align: center;line-height: 6rem;
}
.nav-menu {height: 80%;
}
.nav-menu ul {list-style: none;margin-top: 2rem;
}
.nav-menu ul li {margin-bottom: 1rem;text-indent: 2rem;
}
.nav-menu ul :hover{opacity: 0.9;
}
.nav-menu ul li a {color: #fff;text-decoration: none;font-size: 1.5rem;
} 
.main{background-color: cadetblue;border-radius: 1.5rem;width: 79%;height: 100%;position: absolute;left: 24rem;
}
.main table{border-collapse: collapse;width: 100%;margin-top: 2rem;text-align: center;
}
.main table th{background-color: #4CAF50;color: white;padding: 12px 16px;
}
.main table td{background-color: #78c37b;border: 1px solid #ddd;padding: 8px;
}
.main table td span{color: green;font-weight: bold;
}
.main table td button{background-color: #5fa862;color: white;border: none;border-radius: 5px;padding: 8px 16px;font-size: 16px;cursor: pointer;
}
.main table td button:hover{opacity: 0.8;
}

3.4.3 借还的功能实现

这里来两者这主要区别就是点击借书或还书时,转换的字体颜色不同。

点击结束或者还书的时候会有提示框并会有一个时间戳的提示。

讲解部分还是以借书为例:

首先利用 $.get 方法从 books.txt 文件中获取书籍数据。使用 $.each 遍历每一本书,并为每本书生成一行 <tr>,包括书名、作者、出版社、价格、内容摘要、借阅状态和借阅按钮。借阅状态初始设置为“未借阅”,并伴随一个“借阅”按钮。

然后使用事件代理 ($('tbody').on(...)) 来处理动态生成的借阅按钮的点击事件。

当按钮被点击时调用 getFormatDate 函数获取当前时间格式化字符串。找到当前行(使用 $(this).closest('tr')),并将 “借阅状态” 文本更改为“已借阅”,同时修改文本的颜色为红色(若是还书则初始页面字体为红色修改后则为绿色,以明确显示书籍的借阅状态。

弹出提示框显示借阅成功的信息和当前时间。

最后重要的部分就是获取当前时间的函数部分。

getFormatDate 函数用于获取当前的日期和时间,并进行格式化。

使用 Date 对象获取当前年份、月份、日期、小时和分钟,并确保它们都是两位数(例如:10、01)。

最终拼接字符串按照YYYY-MM-DD HH:mm的格式返回。

其中nowDate.getMonth():获取当前月份的索引(0-11)。

nowDate.getMonth() + 1 < 10 ? "0" + (nowDate.getMonth() + 1):检查月份是否小于 10,如果是,则在前面添加零以确保格式是“01”、“02”等。

nowDate.getDate()nowDate.getHours()nowDate.getMinutes()

与这个都是同理。

借书JS部分:

$.get('../books.txt', function (data) {var usres = JSON.parse(data);$.each(usres, function (i, book) {$('tbody').append(`<tr><td>${book.bookname}</td><td>${book.author}</td><td>${book.publisher}</td><td>${book.price}</td><td>${book.content}</td><td><span class="borrow-book">未借阅</span></td><td><button class="borrow-btn">借阅</button></td></tr>`)})
})
$('tbody').on('click', '.borrow-btn', function () {var str = getFormatDate();alert("借阅成功!当前时间:" + str);$(this).closest('tr').find('.borrow-book').text('已借阅').css('color', 'red');
})
function getFormatDate() {var nowDate = new Date();var year = nowDate.getFullYear();var month = nowDate.getMonth() + 1 < 10 ? "0" + (nowDate.getMonth() + 1) : nowDate.getMonth() + 1;var date = nowDate.getDate() < 10 ? "0" + nowDate.getDate() : nowDate.getDate();var hour = nowDate.getHours() < 10 ? "0" + nowDate.getHours() : nowDate.getHours();var minute = nowDate.getMinutes() < 10 ? "0" + nowDate.getMinutes() : nowDate.getMinutes();return year + "-" + month + "-" + date + " " + hour + ":" + minute;
}
还书JS部分:
$.get('../books.txt', function (data) {var usres = JSON.parse(data);$.each(usres, function (i, book) {$('tbody').append(`<tr><td>${book.bookname}</td><td>${book.author}</td><td>${book.publisher}</td><td>${book.price}</td><td>${book.content}</td><td><span class="borrow-book" style="color:red">未还回</span></td><td><button class="borrow-btn">还回</button></td></tr>`)})
})
$('tbody').on('click', '.borrow-btn', function () {var str = getFormatDate();alert("还书成功!当前时间:" + str);$(this).closest('tr').find('.borrow-book').text('已还回').css('color', 'green');})
function getFormatDate() {var nowDate = new Date();var year = nowDate.getFullYear();var month = nowDate.getMonth() + 1 < 10 ? "0" + (nowDate.getMonth() + 1) : nowDate.getMonth() + 1;var date = nowDate.getDate() < 10 ? "0" + nowDate.getDate() : nowDate.getDate();var hour = nowDate.getHours() < 10 ? "0" + nowDate.getHours() : nowDate.getHours();var minute = nowDate.getMinutes() < 10 ? "0" + nowDate.getMinutes() : nowDate.getMinutes();return year + "-" + month + "-" + date + " " + hour + ":" + minute ;
}

任务3.5 图书管理功能界面

任务描述

该任务可以说是整个项目中最重要的部分,即能够连接后端进行前后端的交互,包括新增图书,编辑图书,删除图书等等。以及还有翻页功能的实现。Server.js的编写。

任务实施

3.5.1 页面框架搭建

首先想到的是需要一个表格,将我们通过ajax访问并获取txt文本,然后把获取到的内容放到表格中,所以我们可以新建一个空表格,还有新建图书和编辑图书时的表单。以及一些按钮和超链接,例如新增图书按钮,翻页部分的超链接等等。

分析后即为:

主体内容:使用<body>标签包含整个页面的主体部分。

标题:使用<h2>标签显示“图书管理系统”。

图书表格:使用<table>标签布局图书信息,表头定义了书名、作者、出版社、出版日期、页数、价格、内容摘要和操作等字段。

分页导航:有按钮和链接用于新增图书、翻页和跳转至指定页数。

新增图书表单:包含一个ID为addform的表单,用于输入新图书信息,包括书名、作者、出版社、出版日期、页数、价格和内容摘要等。

编辑图书表单:类似于新增图书的表单,供编辑现有图书信息使用。

HTML具体代码:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>图书信息管理</title><link rel="stylesheet" href="/public/css/Admin-books.css"><script src="./js/jQuery.js"></script>
</head>
<body><div class="container"><h2>图书管理系统</h2><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 class="nav"><button id="add">新增图书</button><span class="total-records"></span>&nbsp;&nbsp;<span class="current-page">第1页</span><a href="#" id="first-page">第一页</a><a href="#" id='prev-page'>上一页</a><a href="#" id="next-page">下一页</a><a href="#" id="last-page">最后一页</a><span>跳转到第</span><input type="text" value="1" placeholder="页码"><span>页</span><button id="jump-to-page">确定</button></div></div><div class="addbook"><h2>新增图书</h2><form id="addform"><label for="bookname">书名:</label><input type="text" id="bookname" name="bookname"><br><br><label for="author">作者:</label><input type="text" id="author" name="author"><br><br><label for="publisher">出版社:</label><input type="text" id="publisher" name="publisher"><br><br><label for="publishdate">出版日期:</label><input type="date" id="publishdate" name="publishdate"><br><br><label for="page">页数:</label><input type="text" id="page" name="page"><br><br><label for="price">价格:</label><input type="text" id="price" name="price"><br><br><label for="content">内容摘要:</label><textarea id="content" name="content"></textarea><br><br><button type="submit" id="submit">提交</button><button id="close">关闭</button></form></div><div class="editbook"><h2>编辑图书</h2><form id="editform"><label for="bookname">书名:</label><input type="text" id="bookname" name="bookname"><br><br><label for="author">作者:</label><input type="text" id="author" name="author"><br><br><label for="publisher">出版社:</label><input type="text" id="publisher" name="publisher"><br><br><label for="publishdate">出版日期:</label><input type="date" id="publishdate" name="publishdate"><br><br><label for="page">页数:</label><input type="text" id="page" name="page"><br><br><label for="price">价格:</label><input type="text" id="price" name="price"><br><br><label for="content">内容摘要:</label><textarea id="content" name="content"></textarea><br><br><button type="submit" id="edit-submit">提交</button></form></div>
</body>
<script src="./js/Admin-books.js"></script>
</html>

3.5.2 页面样式设置

样式部分,主要就分为容器样式,主体内容样式,导航栏样式,链接样式等等。这里比较重要的是,我们需要先把新增图书和编辑图书隐藏掉,当我们点击相应按钮的时候再把他们分别显示出来。

CSS部分代码:

* {margin: 0;padding: 0;
}body {background-image: url(../img/Admin2.png);background-size: cover;
}.container {width: 70%;height: 20%;margin: 10rem auto;border: 1rem solid #adda8f;background-color: aliceblue;border-radius: 1rem;
}h2 {margin: 1rem;
}.container table {width: 100%;height: 100%;border: 0.1rem solid #000000;
}.container table thead {background-color: #f2f2f2;color: #000000;text-align: center;font-size: 1.5rem;
}
.container table tbody {background-color: #ffffff;color: #000000;text-indent: 1rem;font-size: 1.2rem;
}
.nav{width: 80%;margin: 1rem auto;
}
a{text-decoration: none;
}
input{width: 7rem;height: 1.5rem;
}
.addbook{width: 40%;margin: 1rem auto;border: 1rem solid #adda8f;background-color: aliceblue;border-radius: 1rem;position: absolute;top: 10%;left: 25%;display: none;
}
.editbook{width: 40%;margin: 1rem auto;border: 1rem solid #adda8f;background-color: aliceblue;border-radius: 1rem;position: absolute;top: 10%;left: 25%;display: none;
}
label{display: inline-block;width: 8rem;text-align: right;margin-right: 1rem;
}
textarea{width: 80%;height: 5rem;resize: none;
}
button{width: 6rem;height: 2rem;margin-left: 1rem;background-color: #008CBA;color: #ffffff;border: none;border-radius: 0.5rem;cursor: pointer;
}
td {max-width: 150px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; 
}

最终效果:

3.5.3 更新图书表格updateTable()函数

主要目的就是从 books.txt 的文件中获取书籍数据,并将其显示在 HTML 表格中。

这里首先定义了三个全局变量:

  1. books:一个空数组,用于存储书籍信息。
  2. currentPage:表示当前页码,初始值为 1。
  3. booksPerPage:每页显示的书籍数量,这里设置为 5。

首先先获取书籍,使用$.get() 方法从 books.txt 文件中获取数据。成功获取后,将数据解析为 JSON 对象,并将其赋值给 books 数组。最后调用 updateTable() 函数更新表格。

$.get('/books.txt', function (data) {

    var usres = JSON.parse(data);

    books = usres; // 将文件内容存入数组

    updateTable(); // 更新表格

});

下面开始进行更新表格函数的编写,首先要清空 <tbody> 的内容,以准备显示新的书籍数据。再定义了三个变量:

  1. 计算总页数:

const totalPages = Math.ceil(books.length / booksPerPage);

books.length 获取书籍的总数量(即数组长度),将其除以每页的书籍数量 booksPerPage(这里设为每页最多为5),然后使用 Math.ceil() 函数向上取整,以确保即使有一部分书籍也会增加到新的一页。

  1. 计算当前页的起始索引:

const start = (currentPage - 1) * booksPerPage;

根据当前页码 currentPage 计算当前页的起始索引。由于数组索引从 0 开始,所以需要将 currentPage 减去 1,然后乘以每页的书籍数量。这个值用于确定在 books 数组中从哪里开始取书籍。

  1. 计算当前页的结束索引:

const end = Math.min(start + booksPerPage, books.length);

start + booksPerPage 计算出当前页应显示的最后一个书籍的索引,但也可能会超过 books.length。因此,使用 Math.min() 函数确保结束索引不会超过实际书籍的数量。

再下一步,循环遍历当前页的书籍,从 start 索引开始,直到 end 索引(不包括 end),遍历当前页面应显示的书籍并获取当前书籍信息。然后再将遍历完的书籍,每部分对应的值插入到表格中。插入时使用的是jQuery 的 append() 方法。将每一本书的信息以一个新的表格行 (<tr>) 的形式添加到 <tbody> 中。每一列 (<td>) 显示书籍的不同属性。注意:其中包含两个链接,一个是 "编辑" 操作的链接,另一个是 "删除" 操作的链接。它们的 class 属性分别为 edit delete,可以用于后续的事件绑定,实现对书籍的编辑和删除功能。

let books = [];
let currentPage = 1;
const booksPerPage = 5;
// 获取books.txt文件内容
$.get('/books.txt', function (data) {var usres = JSON.parse(data);books = usres; // 将文件内容存入数组updateTable(); // 更新表格
});// 更新表格函数
function updateTable() {$('tbody').empty();const totalPages = Math.ceil(books.length / booksPerPage);const start = (currentPage - 1) * booksPerPage;const end = Math.min(start + booksPerPage, books.length);for (let i = start; i < end; i++) {const book = books[i];$('tbody').append(`<tr><td>${book.bookname}</td><td>${book.author}</td><td>${book.publisher}</td><td>${book.publishdate}</td><td>${book.page}</td><td>${book.price}</td><td>${book.content}</td><td><a href="#" class='edit'>编辑</a><a href="#" class='delete'>删除</a></td></tr>`);}

3.5.4 新增图书功能

我们首先进行新增图书功能的编写,首先先获取到对应所需要的元素,然后实现点击新增图书,该表单显示的操作。

var addbook = document.querySelector('.addbook');
var btn = document.querySelector('#add');
var close1 = document.querySelector('#close');
btn.addEventListener('click', function () {addbook.style.display = 'block';
})close1.addEventListener('click', function (e) {e.preventDefault();addbook.style.display = 'none';
})

该功能就编辑完成,此时点击新增图书,该表单就会显示出来。

接下来开始进行实现新增图书功能的操作,可以将新增的图书,不仅能够添加到浏览器的页面还能够添加到books.txt中去。

首先添加事件监听,当表单被提交时,会触发该事件。

在这个监听函数中获取表单数据,将表单中输入的数据提取出来,并存储在newbook对象中。

这个newbook对象,就是用来后面把新增的图书储存请求后端放到txt中的对象。

发送AJAX请求,使用jQuery的$.ajax()方法向后端发送HTTP请求。请求信息包括:

url: 发送请求的目标URL。

method: 请求的方法,这里使用POST。

contentType: 设置请求头为application/json,表示请求体内容为JSON格式。

data: 将newbook对象转换为JSON字符串,作为请求体发送。

并添加一个处理成功响应,若能成功响应,在回调中,将新书对象newbook添加到books数组中,调用updateTable()函数更新表格显示,并隐藏新增图书的表单。

这里的updateTable()函数将在后面进行编写,这个函数就是用来更新表格每当我们实现一个功能时,调用它来进行刷新。

处理错误响应,添加这个的目的就是我们在编写中难免会出现错误所以我们可以在当我们发生错误时,可以打印一下错误信息,并为之改错。使用error: 定义当请求失败时的回调函数。使用console.error()输出错误信息,便于调试。

Xhr:这是当 AJAX 请求发生错误时,错误回调函数的第一个参数。

新增图书代码:

document.getElementById('addform').addEventListener('submit', function (e) {e.preventDefault(); // 防止默认提交行为var newbook = {bookname: document.getElementById('bookname').value,author: document.getElementById('author').value,publisher: document.getElementById('publisher').value,publishdate: document.getElementById('publishdate').value,page: document.getElementById('page').value,price: document.getElementById('price').value,content: document.getElementById('content').value};// 使用 POST 方法,确保将数据作为请求体发送$.ajax({url: 'http://localhost:5501/addBook', // 后端处理的 URLmethod: 'POST',  // 使用 POST 方法contentType: 'application/json', // 设置请求头为 JSONdata: JSON.stringify(newbook), // 将对象转换为 JSON 字符串success: function () {books.push(newbook); // 将新书加入数组updateTable(); // 更新表格addbook.style.display = 'none'; // 隐藏新增表单},error: function (xhr) {console.error('添加图书失败:', xhr.responseText); // 输出错误信息}});
});

 

3.5.6 删除书籍功能

这部分主要想实现删除图书的功能,首先进行的是一个委托事件绑定。绑定一个点击事件到表格的 .delete 类元素上。当用户点击某个删除链接时,触发这个事件处理函数。点击删除链接时会触发一个弹窗,并提示用户是否删除图书,如果用户选择“确定”,则继续执行后续代码,否则不采取任何行动。

接线来进行若点击删除,下面要执行的代码,首先要知道是哪行在请求删除,所以使用 $(this).closest('tr') 获取当前链接所在的行 (<tr>)。这样可以找到与点击的删除链接对应的数据行。

知道是哪行了以后,由于获取到的书籍是在刚刚新建的数组中,所以要获取行的索引并加上当前页的书籍数量,以计算出在 books 数组中的实际索引位置。这是确保正确定位要删除的书籍。

最后开始与后端相交互,发送删除请求,使用 DELETE 方法向指定的 URL 发送删除请求。注意端口名,再添加一个删除图书回调,若请求成功,则从数组中删除对应的书籍。再删除表格对应的行,最后更新分页信息。若请求失败,则要打印一下错误信息以方便改错。

$("table").on('click', ".delete", function () {if (confirm("是否确定删除图书")) {var tr = $(this).closest('tr'); // 获取当前行var bookIndex = tr.index() + (currentPage - 1) * booksPerPage; // 计算索引$.ajax({url: 'http://localhost:5501/books/' + bookIndex,  // 确保URL正确method: 'DELETE', // 使用 DELETE 方法success: function (response) {// 删除成功books.splice(bookIndex, 1); // 从数组中移除对应的书籍tr.remove(); // 删除表格中的行updatePagination(Math.ceil(books.length / booksPerPage)); // 更新分页信息},error: function (xhr, status, error) {console.error('删除图书失败:', xhr.responseText); // 输出错误信息}});}
});

注意:更新分页信息是为后期翻页功能中输出信息当前共几本书的函数。 

3.5.7 编辑图书功能

第一步与前两个功能一样,都可以使用事件委托来进行编辑操作。同样的方法先获取当前所在行,在通过计算分页的页数以及计算出书籍在 books 数组中的实际索引,从而获取对应的书籍数据。

接下来在点击编辑后出现的表单中,进行填充表单。

填充表单之后,管理员即开始对其书籍信息进行编辑,等待编辑完事,并点击提交时就会进行下一步编辑表单提交时处理更新。还是使用表单提交事件。

解除对表单提交事件的所有先前绑定,并定义新的提交处理逻辑。

注意:然后需要获取更新后的书籍信息,就是更改完之后的表单中每项对应的值构建一个 updatedBook 对象,该对象还会用于请求后端时,写入的内容。获取之后开始向后端发起AJAX请求,使用 PUT 方法向服务器发送更新的书籍信息。同样的请求头设置为 application/json,发送的请求体为 updatedBook 对象的 JSON 字符串格式。

请求更新编辑成功后,将更新后的书籍信息存回 books 数组中,并调用 updateTable() 函数刷新表格内容。最后,隐藏编辑表单。

若请求失败,输出错误信息到控制台,便于后续的修改。

    $('tbody').on('click', '.edit', function () {var tr = $(this).closest('tr'); // 获取当前行var bookIndex = tr.index() + (currentPage - 1) * booksPerPage; // 更新索引以便正确指向var book = books[bookIndex]; // 获取对应的书籍数据editbook.style.display = 'block'; // 显示编辑表单// 填充编辑表单document.getElementById('editform').reset(); // 清空表单document.querySelector('#editform input[name="bookname"]').value = book.bookname;document.querySelector('#editform input[name="author"]').value = book.author;document.querySelector('#editform input[name="publisher"]').value = book.publisher;document.querySelector('#editform input[name="publishdate"]').value = book.publishdate;document.querySelector('#editform input[name="page"]').value = book.page;document.querySelector('#editform input[name="price"]').value = book.price;document.querySelector('#editform textarea[name="content"]').value = book.content;// 在编辑表单提交时处理更新$('#editform').off('submit').on('submit', function (event) {event.preventDefault(); // 防止默认提交行为var updatedBook = {bookname: document.querySelector('#editform input[name="bookname"]').value,author: document.querySelector('#editform input[name="author"]').value,publisher: document.querySelector('#editform input[name="publisher"]').value,publishdate: document.querySelector('#editform input[name="publishdate"]').value,page: document.querySelector('#editform input[name="page"]').value,price: document.querySelector('#editform input[name="price"]').value,content: document.querySelector('#editform textarea[name="content"]').value};// 向服务器发送PUT请求更新书籍信息$.ajax({url: 'http://localhost:5501/books/' + bookIndex, // 使用正确的URL及IDmethod: 'PUT',  // 将方法改为 PUTcontentType: 'application/json', // 设置请求头为 JSONdata: JSON.stringify(updatedBook), // 将对象转换为 JSON 字符串success: function (response) {// 更新数组中的数据books[bookIndex] = updatedBook; // 更新对应索引的书籍信息updateTable(); // 更新表格editbook.style.display = 'none'; // 隐藏编辑表单},error: function (xhr) {console.error('编辑图书失败:', xhr.responseText); // 输出错误信息}});});});// 更新分页信息updatePagination(totalPages);
}

3.5.8 翻页功能及更新分页信息(updatePagination

首先写一下更新的那些信息的函数,该函数接受参数 totalPages,更新页面上显示的总书籍数量和当前页码信息,确保管理员清楚现在的书籍数量。

  1. 翻到第一页:

当点击“第一页”按钮时,将 currentPage 设置为 1,并调用 updateTable() 更新表格内容,显示第一页的书籍。即会跳到第一页。

$('.nav #first-page').click(function () {currentPage = 1;updateTable();
});
  1. 翻到上一页:

点击“上一页”按钮时,如果当前页大于 1,则将 currentPage 减 1,并更新表格内容,显示上一页的书籍。

$('.nav #prev-page').click(function () {if (currentPage > 1) {currentPage--;updateTable();}
});
  1. 翻到下一页:

当点击“下一页”按钮时,首先计算总页数 totalPages。如果当前页小于总页数,则将 currentPage 加 1,并更新表格,显示下一页的书籍。

$('.nav #next-page').click(function () {const totalPages = Math.ceil(books.length / booksPerPage);if (currentPage < totalPages) {currentPage++;updateTable();}
});

  1. 翻到最后一页:

点击“最后一页”按钮时,直接将 currentPage 设置为最后一页的页码,然后更新表格以显示最后一页的书籍。

$('.nav #last-page').click(function () {currentPage = Math.ceil(books.length / booksPerPage);updateTable();
});
  1. 跳转到指定页:

当用户输入一个页码并点击“跳转”按钮时,首先通过 parseInt() 转换输入的值为整数。如果该页码大于 0 且小于等于总页数,则更新 currentPage,并调用 updateTable() 更新表格以显示相应的页。

$('.nav #jump-to-page').click(function () {const pageInput = parseInt($('.nav input[type="text"]').val());if (pageInput > 0 && pageInput <= Math.ceil(books.length / booksPerPage)) {currentPage = pageInput;updateTable();}
});

至此,图书管理的相关功能就写完了。

JS全部代码:

var addbook = document.querySelector('.addbook');
var container = document.querySelector('.container');
var close1 = document.querySelector('#close');
var btn = document.querySelector('#add');
var editbook = document.querySelector('.editbook');btn.addEventListener('click', function () {addbook.style.display = 'block';
})close1.addEventListener('click', function (e) {e.preventDefault();addbook.style.display = 'none';
})//分页功能
// 书籍数据数组// 新增图书
document.getElementById('addform').addEventListener('submit', function (e) {e.preventDefault(); // 防止默认提交行为var newbook = {bookname: document.getElementById('bookname').value,author: document.getElementById('author').value,publisher: document.getElementById('publisher').value,publishdate: document.getElementById('publishdate').value,page: document.getElementById('page').value,price: document.getElementById('price').value,content: document.getElementById('content').value};// 使用 POST 方法,确保将数据作为请求体发送$.ajax({url: 'http://localhost:5501/addBook', // 后端处理的 URLmethod: 'POST',  // 使用 POST 方法contentType: 'application/json', // 设置请求头为 JSONdata: JSON.stringify(newbook), // 将对象转换为 JSON 字符串success: function () {books.push(newbook); // 将新书加入数组updateTable(); // 更新表格addbook.style.display = 'none'; // 隐藏新增表单},error: function (xhr) {console.error('添加图书失败:', xhr.responseText); // 输出错误信息}});
});
let books = [];
let currentPage = 1;
const booksPerPage = 5;
// 获取books.txt文件内容
$.get('/books.txt', function (data) {var usres = JSON.parse(data);books = usres; // 将文件内容存入数组updateTable(); // 更新表格
});// 更新表格函数
function updateTable() {$('tbody').empty();const totalPages = Math.ceil(books.length / booksPerPage);const start = (currentPage - 1) * booksPerPage;const end = Math.min(start + booksPerPage, books.length);for (let i = start; i < end; i++) {const book = books[i];$('tbody').append(`<tr><td>${book.bookname}</td><td>${book.author}</td><td>${book.publisher}</td><td>${book.publishdate}</td><td>${book.page}</td><td>${book.price}</td><td>${book.content}</td><td><a href="#" class='edit'>编辑</a><a href="#" class='delete'>删除</a></td></tr>`);}// //编辑操作// 使用事件委托处理动态生成的元素$('tbody').on('click', '.edit', function () {var tr = $(this).closest('tr'); // 获取当前行var bookIndex = tr.index() + (currentPage - 1) * booksPerPage; // 更新索引以便正确指向var book = books[bookIndex]; // 获取对应的书籍数据editbook.style.display = 'block'; // 显示编辑表单// 填充编辑表单document.getElementById('editform').reset(); // 清空表单document.querySelector('#editform input[name="bookname"]').value = book.bookname;document.querySelector('#editform input[name="author"]').value = book.author;document.querySelector('#editform input[name="publisher"]').value = book.publisher;document.querySelector('#editform input[name="publishdate"]').value = book.publishdate;document.querySelector('#editform input[name="page"]').value = book.page;document.querySelector('#editform input[name="price"]').value = book.price;document.querySelector('#editform textarea[name="content"]').value = book.content;// 在编辑表单提交时处理更新$('#editform').off('submit').on('submit', function (event) {event.preventDefault(); // 防止默认提交行为var updatedBook = {bookname: document.querySelector('#editform input[name="bookname"]').value,author: document.querySelector('#editform input[name="author"]').value,publisher: document.querySelector('#editform input[name="publisher"]').value,publishdate: document.querySelector('#editform input[name="publishdate"]').value,page: document.querySelector('#editform input[name="page"]').value,price: document.querySelector('#editform input[name="price"]').value,content: document.querySelector('#editform textarea[name="content"]').value};// 向服务器发送PUT请求更新书籍信息$.ajax({url: 'http://localhost:5501/books/' + bookIndex, // 使用正确的URL及IDmethod: 'PUT',  // 将方法改为 PUTcontentType: 'application/json', // 设置请求头为 JSONdata: JSON.stringify(updatedBook), // 将对象转换为 JSON 字符串success: function (response) {// 更新数组中的数据books[bookIndex] = updatedBook; // 更新对应索引的书籍信息updateTable(); // 更新表格editbook.style.display = 'none'; // 隐藏编辑表单},error: function (xhr) {console.error('编辑图书失败:', xhr.responseText); // 输出错误信息}});});});// 更新分页信息updatePagination(totalPages);
}// 删除书籍
$("table").on('click', ".delete", function () {if (confirm("是否确定删除图书")) {var tr = $(this).closest('tr'); // 获取当前行var bookIndex = tr.index() + (currentPage - 1) * booksPerPage; // 计算索引$.ajax({url: 'http://localhost:5501/books/' + bookIndex,  // 确保URL正确method: 'DELETE', // 使用 DELETE 方法success: function (response) {// 删除成功books.splice(bookIndex, 1); // 从数组中移除对应的书籍tr.remove(); // 删除表格中的行updatePagination(Math.ceil(books.length / booksPerPage)); // 更新分页信息},error: function (xhr, status, error) {console.error('删除图书失败:', xhr.responseText); // 输出错误信息}});}
});
// 更新分页信息
function updatePagination(totalPages) {$('.nav .total-records').text(`共${books.length}本书`);$('.nav .current-page').text(`当前第${currentPage}页/共${totalPages}页`);
}// 翻页功能
$('.nav #first-page').click(function () {currentPage = 1;updateTable();
});$('.nav #prev-page').click(function () {if (currentPage > 1) {currentPage--;updateTable();}
});$('.nav #next-page').click(function () {const totalPages = Math.ceil(books.length / booksPerPage);if (currentPage < totalPages) {currentPage++;updateTable();}
});$('.nav #last-page').click(function () {currentPage = Math.ceil(books.length / booksPerPage);updateTable();
});$('.nav #jump-to-page').click(function () {const pageInput = parseInt($('.nav input[type="text"]').val());if (pageInput > 0 && pageInput <= Math.ceil(books.length / booksPerPage)) {currentPage = pageInput;updateTable();}
});

目前就差后端代码部分的编写了,加油坚持住下一章博客进行最后阶段的完成以及整合!!!

相关文章:

图书馆管理系统(三)基于jquery、ajax

任务3.4 借书还书页面 任务描述 这部分主要是制作借书还书的界面&#xff0c;这里我分别制作了两个网页分别用来借书和还书。此页面&#xff0c;也是通过获取books.txt内容然后添加到表格中&#xff0c;但是借还的操作没有添加到后端中去&#xff0c;只是一个简单的前端操作。…...

Nginx Location 配置块全解析与示例

Nginx Location 配置块全解析与示例 摘要&#xff1a; 本文深入探讨了 Nginx 中 location 配置块的功能、语法规则以及多种实际应用场景下的配置示例&#xff0c;旨在帮助读者全面理解并熟练掌握 location 配置块&#xff0c;以便在 Nginx 服务器配置中灵活运用&#xff0c;实…...

javalock(八)ReentrantReadWriteLock

ReentrantReadWriteLock: 同时实现了共享锁和排它锁。内部有一个sync&#xff0c;同时实现了tryAcquire/tryReleases、tryAcquireShared/tryReleasesShared&#xff0c;一共四个函数&#xff0c;然后ReentrantReadWriteLock内部还实现了一个ReadLock和一个WriteLock&#xff0c…...

反射和设计模式

一、反射 1. 相关概念 (1) 类的对象&#xff1a;基于定义好的一个类&#xff0c;创建该类的实例&#xff0c;即利用 new 创建的实例就为类的对象。 (2) 类对象&#xff1a;类加载的产物&#xff0c;封装了一个类的所有信息 ( 包名、类名、父类、接口、属性、方法、构造方…...

双指针---和为s的两个数字

这里写自定义目录标题 题目链接问题分析代码解决执行用时 题目链接 购物车内的商品价格按照升序记录于数组 price。请在购物车中找到两个商品的价格总和刚好是 target。若存在多种情况&#xff0c;返回任一结果即可。 问题分析 暴⼒解法&#xff0c;会超时 &#xff08;两层…...

LLaMA-Factory 单卡3080*2 deepspeed zero3 微调Qwen2.5-7B-Instruct

环境安装 git clone https://gitcode.com/gh_mirrors/ll/LLaMA-Factory.git 下载模型 pip install modelscope modelscope download --model Qwen/Qwen2.5-7B-Instruct --local_dir /root/autodl-tmp/models/Qwen/Qwen2.5-7B-Instruct 微调 llamafactory-cli train \--st…...

智慧农业云平台与水肥一体化:道品科技引领农业现代化新潮流

在当今科技飞速发展的时代&#xff0c;农业也正经历着一场深刻的变革。智慧农业云平台和水肥一体化技术的出现&#xff0c;为农业生产带来了前所未有的机遇和挑战。 一、智慧农业云平台&#xff1a;农业生产的 “智慧大脑” 智慧农业云平台就像是农业生产的 “智慧大脑”&…...

241207_MindNLP中的大模型微调

241207_基于MindNLP的大模型高效微调 现在的大模型体量非常庞大&#xff0c;全量微调所需要的算力也特别庞大&#xff0c;个人开发者没有条件微调。参数量达到7B的模型才刚刚有涌现能力&#xff0c;但是我们要微调7B的模型的话&#xff0c;就需要328G的显存&#xff0c;至少需…...

MongoDB、Mongoose使用教程

文章目录 一&#xff1a;MongoDB 简介1.1 什么是 MongoDB1.2 特点1.3 与关系数据库的区别&#xff1a;1.4 资源链接&#xff1a; 二&#xff1a;安装 MongoDB2.1 安装前的准备2.2 安装、启动 MongoDB2.3 创建用户 MongoDB 三、连接四&#xff1a;MongoDB 基础操作4.1 库操作&am…...

单片机:实现控制步进电机正反转(附带源码)

1. 步进电机概述 步进电机&#xff08;Step Motor&#xff09;是一种能够将电能转换为机械能的电动机。其独特之处在于能够精确地控制转动角度&#xff0c;因此被广泛应用于需要精确控制的场合&#xff0c;如打印机、机器人、数控机床、自动化设备等。 步进电机的转动是以“步…...

安装指南|OpenCSG Starship上架GitHub Marketplace

在代码开发的日常中&#xff0c;你是否常常被以下问题困扰&#xff1f; 代码审查耗时太长&#xff0c;拖慢项目进度&#xff1f; 审查质量参差不齐&#xff0c;一些关键问题被遗漏&#xff1f; 复杂代码变更看不懂&#xff0c;审查者需要大量时间理解意图&#xff1f; 别担…...

Excel设置生日自动智能提醒,公式可直接套用!

大家好&#xff0c;我是小鱼。 今天跟大家分享一个WPS表格中根据出生日期&#xff0c;设置生日提醒&#xff0c;并且根据距离生日天数自动标记数据颜色。简单又实用&#xff0c;一个公式轻松搞定&#xff01; 接下来我们先学习一下需要使用到的函数&#xff0c;然后再根据实例让…...

同步异步日志系统:前置知识

一、日志项目的介绍 1.1 为什么要有日志系统 1、⽣产环境的产品为了保证其稳定性及安全性是不允许开发⼈员附加调试器去排查问题&#xff0c;可以借助日志系统来打印⼀些⽇志帮助开发⼈员解决问题 为什么不直接printf打印在屏幕上呢&#xff1f;&#xff1f;因为现实中没有…...

微服务设计原则——功能设计

文章目录 1.ID生成2.数值精度3.DB操作4.性能测试5.版本兼容5.1 向旧兼容5.2 向新兼容 6.异步时序问题7.并发问题7.1 并发时序7.2 并发数据竞争 参考文献 1.ID生成 在分布式系统中&#xff0c;生成全局唯一ID是非常重要的需求&#xff0c;因为需要确保不同节点、服务或实例在并…...

低代码软件搭建自学的第一天——熟悉PyQt

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 学习计划第 1 步&#xff1a;环境搭建1.1 安装 Python1.2 安装 PyQt安装命令&#xff1a;验证安装&#xff1a; 第 2 步&#xff1a;PyQt 基础知识2.1 创建第一个窗…...

基于Python3编写的Golang程序多平台交叉编译自动化脚本

import argparse import os import shutil import sys from shutil import copy2from loguru import loggerclass GoBuild:"""一个用于构建跨平台执行文件的类。初始化函数&#xff0c;设置构建的主文件、生成的执行文件名称以及目标平台。:param f: 需要构建的…...

远程桌面连接

电脑A&#xff1a;使用机 电脑B&#xff1a;被控制的另一个 方法1&#xff1a; 在电脑B上操作 ①winr输入cmd进入命令行窗口&#xff0c;输入ipconfig查询本机地址 ②我的电脑/此电脑 右键点击“属性” ③选择屏幕右边“远程桌面” ④打开“启用远程桌面” ⑤打开设置&am…...

网络地址转换NAT

NAT(Network Address Translation) 方法于1994年提出。需要在专用网连接到因特网的路由器上安装NAT软件。装有NAT软件的路由器叫做NAT路由器&#xff0c;它至少有一个有效的外部全球地址IPG。 所有使用本地地址的主机在和外界通信时都要在NAT路由器上将其本地地址转换成外部全球…...

什么是CRM管理软件?CRM的基本概念、功能、选择标准、应用场景

什么是CRM管理软件&#xff1f; 嘿&#xff0c;大家好&#xff01;今天咱们聊聊一个在现代企业管理中非常重要的工具——CRM管理软件。CRM是Customer Relationship Management&#xff08;客户关系管理&#xff09;的缩写&#xff0c;简单来说&#xff0c;它就是一个帮助企业和…...

Python编程常用的19个经典案例

Python 的简洁和强大使其成为许多开发者的首选语言。本文将介绍36个常用的Python经典代码案例。这些示例覆盖了基础语法、常见任务、以及一些高级功能。 1. 列表推导式 fizz_buzz_list ["FizzBuzz" if i % 15 0 else "Fizz" if i % 3 0 else "Buzz…...

【Unity基础】AudioSource 常用方法总结

在 Unity 中&#xff0c;AudioSource 组件用于控制音频的播放和管理。以下是常用的 AudioSource 控制方法及其说明。 1. 播放和暂停音频 Play()&#xff1a;开始播放音频&#xff0c;如果是从暂停的地方继续播放&#xff0c;可以直接调用。Pause()&#xff1a;暂停当前播放的…...

CSS系列(25)-- 滚动优化详解

前端技术探索系列&#xff1a;CSS 滚动优化详解 &#x1f4dc; 致读者&#xff1a;探索流畅滚动的艺术 &#x1f44b; 前端开发者们&#xff0c; 今天我们将深入探讨 CSS 滚动优化&#xff0c;学习如何创建流畅、高性能的滚动体验。 平滑滚动 &#x1f680; 基础设置 /* …...

CST天线设计的六大核心特点:为天线分析提供完整解决方案!

CST Studio Suite 为天线设计提供了从最初的概念评估到最终的合规性测试所需的所有功能&#xff0c;确保天线设计在各种环境下实现稳定通信。这一套工具覆盖了所有重要的设计阶段&#xff0c;帮助设计师顺利完成从概念到成品的全过程。 下面我们来看一看CST电磁仿真中天线设计…...

Ubuntu下C语言操作kafka示例

目录 安装kafka&#xff1a; 安装librdkafka consumer Producer 测试运行 安装kafka&#xff1a; Ubuntu下Kafka安装及使用_ubuntu安装kafka-CSDN博客 安装librdkafka github地址&#xff1a;GitHub - confluentinc/librdkafka: The Apache Kafka C/C library $ apt in…...

怎么将pdf中的某一个提取出来?介绍几种提取PDF中页面的方法

怎么将pdf中的某一个提取出来&#xff1f;传统上&#xff0c;我们可能通过手动截取屏幕或使用PDF阅读器的复制功能来提取信息&#xff0c;但这种方法往往不够精确&#xff0c;且无法保留原文档的排版和格式。此外&#xff0c;很多时候我们需要提取的内容可能涉及多个页面、多个…...

HTTP接口报错详解与解决 200,500,403,408,404

前言&#xff1a; 仅做学习记录&#xff0c;侵删 背景 当后端编写接口时&#xff0c;经常需要对接口使用ApiFox或者PostMan进行测试&#xff0c;此时就会出现各种各样的报错&#xff0c;一般都会包括报错编码&#xff1a;200,400,401等。这个状态码一般是服务器所返回的包含…...

监控IP频繁登录服务器脚本

该脚本的作用是监控IP登录失败次数&#xff0c;如果某个IP的登录失败次数超过设定的最大次数&#xff0c;则阻止该IP的进一步登录尝试。通过iptables防火墙阻止连接&#xff0c;当一个IP尝试登录次数超过5次时&#xff0c;iptables会阻止来自该IP的所有连接 #!/bin/bashfuncti…...

分布式链路追踪-03-Jaeger、Zipkin、skywalking 中的 span 是如何设计的?

开源项目 auto-log 自动日志输出 Jaeger、Zipkin 中的 spanId 是如何生成的&#xff1f; 在 Jaeger 和 Zipkin 这两个分布式跟踪系统中&#xff0c;Span ID 是通过不同的方法生成的。 下面分别介绍它们的生成方式&#xff1a; Jaeger 中的 Span ID 生成&#xff1a; 在 Ja…...

【达梦数据库】获取对象DDL

目录 背景获取表的DDL其他 背景 在排查问题时总会遇到获取对象DDL的问题&#xff0c;因此做以下总结。 获取表的DDL 设置disql工具中显示LONG类型数据的最大长度&#xff0c;避免截断&#xff1a; SET LONG 9999获取DDL SELECT DBMS_METADATA.GET_DDL(TABLE,表名,模式名) …...

InnoDB和MyISAM引擎优缺点和区别

nnoDB和MyISAM是MySQL数据库中常用的两种存储引擎。它们各自具有不同的特性和优势&#xff0c;适用于不同的应用场景。 一、InnoDB引擎&#xff1a; 1、它有如下特性&#xff1a; 1)、支持事务&#xff08;ACID&#xff09; 2)、支持外键约束&#xff08;FOREIGN KEY const…...