前言:
掘弃掉与后端交互做分页和互导,有利有弊吧; 在小数据的时候,如果不停来回朝服务端发送请求,会造成堵塞.于是,放弃了之前的前后端ajax方式去请求分页表格,使用script去弄一个,降低服务器的压力;
整体思路图:
代码构造:
{% extends "order_header_same.html" %}
{% block body %}
<style>
.small-select {
height: 20px;
padding: 1px 3px;
font-size: 12px;
line-height: 1;
}
.small-select.selected {
background-color: #31b0d5; /* 自定义选中状态的背景颜色 */
}
</style>
<style>
nav.pagination-nav {
width: 100%;
display: flex;
justify-content: center;
}
</style>
<div class="container">
<div class="table-responsive">
<div style="margin-bottom: 10px">
<a class="btn btn-primary" href="/order/create">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>添 加</a>
</div>
<table class="table table-striped">
<thead>
<tr>
<th>订单ID</th>
<th>订单URL</th>
<th>
订单数量
<select onchange="sortTable(this, 2)" class="small-select" id="orderQtySelect">
<option value="N">- - -</option>
<option value="asc">升序</option>
<option value="desc">降序</option>
</select>
</th>
<th>
状态
<select onchange="filterTable(this)" class="small-select unique-class-or-id" id="statusSelect">
<option value="all">全 部</option>
<option value="1">等 待</option>
<option value="2">正在运行</option>
<option value="3">完 成</option>
<option value="4">失 败</option>
<option value="5">未 知</option>
</select>
</th>
<th>
创建时间
<select onchange="sortTableByDate(this, 4)" class="small-select" id="createTimeSelect">
<option value="N"> - - - </option>
<option value="asc">升序</option>
<option value="desc">降序</option>
</select>
</th>
</tr>
</thead>
<tbody>
{% for item in data_list %}
<tr>
<th>{{ item.id }}</th>
<th>{{ item.url }}</th>
<th>{{ item.count }}</th>
<th data-status="{{ item.status }}">
<span class="label label-{{ status_dict[item.status].col }}">
{{ status_dict[item.status].sta }}
</span>
</th>
<th>{{ item.created_time }}</th>
</tr>
{% endfor %}
</tbody>
</table>
<!-- 分页控制 -->
<nav class="pagination-nav" aria-label="Table pagination">
<ul class="pagination justify-content-center">
<li class="page-item disabled">
<a class="page-link" href="#" tabindex="-1">上一页</a>
</li>
<li class="page-item active">
<a class="page-link" href="#">1</a>
</li>
<li class="page-item">
<a class="page-link" href="#">2</a>
</li>
<li class="page-item">
<a class="page-link" href="#">3</a>
</li>
<li class="page-item">
<a class="page-link" href="#">下一页</a>
</li>
</ul>
</nav>
</div>
</div>
<script>
// 根据状态栏,进行分页; 首次登陆的时候,默认全部可见,当点击状态栏的时候,就会更新页数等;
var rowsPerPage = 8; // 每页显示的行数
var numberOfPages; // 总页数
var filteredRowCount; // 筛选后的行数
function updatePagination() {
numberOfPages = Math.ceil(filteredRowCount / rowsPerPage); // 根据每页行数计算总页数
if (numberOfPages == 0) {
numberOfPages = 1; // 至少有一页,即使没有数据
}
setupPagination(numberOfPages); // 设置分页控件
displayData(1); // 显示第一页的数据
}
function setupPagination(totalPages) {
var paginationUl = document.querySelector('.pagination'); // 获取分页控件的 ul 元素
paginationUl.innerHTML = ''; // 清空分页控件内的内容
paginationUl.innerHTML +=
`<li class="page-item" id="prevPage"><a class="page-link" href="#" onclick="changePage(-1)">上一页</a></li>`; // 添加上一页按钮
for (var page = 1; page <= totalPages; page++) {
var isActive = page === 1 ? "active" : ""; // 第一页添加 active 类
var li = `<li class="page-item ${isActive}"><a class="page-link" href="#" onclick="displayData(${page})">${page}</a></li>`; // 创建页码按钮
paginationUl.innerHTML += li; // 添加页码按钮到分页控件
}
paginationUl.innerHTML +=
`<li class="page-item" id="nextPage"><a class="page-link" href="#" onclick="changePage(1)">下一页</a></li>`; // 添加下一页按钮
togglePrevNextButtons(1); // 切换前一页和后一页按钮状态
}
function displayData(pageNumber) {
var table = document.querySelector(".table"); // 获取表格
var displayedRows = document.querySelectorAll(".table tbody tr.displayed"); // 获取(filterTable)筛选后显示的行
if (displayedRows.length === 0) {
// 如果没有筛选后的显示行,可以设定默认行为或终止函数的执行
// return; // 终止函数的执行
// 或者设定默认行为,例如显示所有行
displayedRows = document.querySelectorAll(".table tbody tr");
}
var start = (pageNumber - 1) * rowsPerPage; // 计算起始索引
var end = start + rowsPerPage; // 计算结束索引
for (var j = 0; j < displayedRows.length; j++) {
displayedRows[j].style.display = j >= start && j < end ? "" : "none"; // 根据索引显示或隐藏行
}
var paginationItems = document.querySelectorAll(".pagination .page-item"); // 获取分页按钮元素
paginationItems.forEach(item => {
item.classList.remove("active"); // 移除所有按钮的 active 类
});
paginationItems[pageNumber].classList.add("active"); // 当前页按钮添加 active 类
togglePrevNextButtons(pageNumber); // 切换前一页和后一页按钮状态
}
function togglePrevNextButtons(currentPage) {
var prevPage = document.getElementById("prevPage"); // 获取前一页按钮
var nextPage = document.getElementById("nextPage"); // 获取后一页按钮
prevPage.classList.toggle("disabled", currentPage === 1); // 如果当前页为第一页,则禁用前一页按钮
nextPage.classList.toggle("disabled", currentPage === numberOfPages || numberOfPages === 0); // 如果当前页为最后一页(或没有数据),则禁用后一页按钮
}
function changePage(step) {
var currentPage = document.querySelector(".pagination .active a").textContent; // 获取当前页码
currentPage = parseInt(currentPage, 10) + step; // 转换为数字并添加页面移动步长
currentPage = Math.max(1, Math.min(numberOfPages, currentPage)); // 确保当前页在有效范围内
displayData(currentPage); // 显示指定页的数据
}
function filterTable(select) {
var filterValue = select.value; // 获取筛选条件
var table = document.querySelector(".table"); // 获取表格
var tr = table.getElementsByTagName("tr"); // 获取所有行
var quan = 0; // 初始化符合筛选条件的行数
for (var i = 1; i < tr.length; i++) {
var td = tr[i].getElementsByTagName("th")[3]; // 获取状态列
if (td) {
var statusValue = td.getAttribute("data-status"); // 获取状态值
if (filterValue === "all" || statusValue == filterValue) {
tr[i].style.display = ""; // 显示行
tr[i].classList.add("displayed"); // 添加"displayed"类以标记可见行
quan++;
} else {
tr[i].style.display = "none"; // 隐藏行
tr[i].classList.remove("displayed"); // 移除"displayed"类以标记隐藏行
}
}
}
filteredRowCount = quan; // 更新筛选后的行数
updatePagination(); // 更新分页
var statusSelect = document.getElementById("statusSelect");
statusSelect.classList.add("selected");
select.classList.add("selected"); // 添加选中样式
}
// 窗口加载完成后,进行筛选和分页
window.onload = function () {
var displayedRows = document.querySelectorAll(".table tbody tr"); // 获取初始时的所有行
filteredRowCount = displayedRows.length; // 设置初始筛选后的行数为所有行数
updatePagination(); // 更新分页
};
</script>
<script>
// region订单数量栏的升降序排列
function sortTable(select, n) {
var table, rows, switching, i, x, y, shouldSwitch;
var dir = select.value; // 取得选中的排序方式
table = document.querySelector(".table");
switching = true;
// 无需再确定排序的方向,因为已由下拉框提供
while (switching) {
switching = false;
rows = table.rows;
for (i = 1; i < (rows.length - 1); i++) {
shouldSwitch = false;
x = rows[i].getElementsByTagName("TH")[n];
y = rows[i + 1].getElementsByTagName("TH")[n];
if (dir == "asc") {
if (parseInt(x.innerHTML) > parseInt(y.innerHTML)) {
shouldSwitch = true;
break;
}
} else if (dir == "desc") {
if (parseInt(x.innerHTML) < parseInt(y.innerHTML)) {
shouldSwitch = true;
break;
}
}
}
if (shouldSwitch) {
rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
switching = true;
}
}
//激活'订单数量'栏就变色
var orderQtySelect = document.getElementById("orderQtySelect");
orderQtySelect.classList.add("selected");
select.classList.add("selected"); // 添加选中样式
// 重置其他选择框为无序状态
var createTimeSelect = document.getElementById("createTimeSelect");
createTimeSelect.value = "N"; // 设置为"- - -"选项
createTimeSelect.classList.remove("selected");
}
//endregion
// region 创建时间 栏上的 升降序排列
function convertDateTime(dateTimeStr) {
// 将日期时间字符串分割成日期和时间
var parts = dateTimeStr.split(' ');
var dateParts = parts[0].split('-');
var timeParts = parts[1].split(':');
// 构建一个新的日期对象
return new Date(dateParts[0], dateParts[1] - 1, dateParts[2], timeParts[0], timeParts[1], timeParts[2]);
}
function sortTableByDate(select, columnIndex) {
var table = select.parentNode.parentNode.parentNode.parentNode;
var tbody = table.tBodies[0];
var rows = Array.from(tbody.rows);
// 根据选择框来决定排序方式(升序或降序)
var sortOrder = select.value;
// 实际的排序逻辑
rows.sort(function(a, b) {
// 对于每一行,提取并转换日期时间字符串,然后使用日期比较
var dateA = convertDateTime(a.cells[columnIndex].textContent.trim());
var dateB = convertDateTime(b.cells[columnIndex].textContent.trim());
// 根据排序顺序返回比较结果
return sortOrder === 'asc' ? dateA - dateB : dateB - dateA;
});
// 将排序过的行重新添加到tbody中
rows.forEach(function(row) {
tbody.appendChild(row);
});
// 激活'时间'栏就变色
var createTimeSelect = document.getElementById("createTimeSelect");
createTimeSelect.classList.add("selected");
select.classList.add("selected"); // 添加选中样式
// 重置其他选择框为无序状态
var orderQtySelect = document.getElementById("orderQtySelect");
orderQtySelect.value = "N"; // 设置为"- - -"选项
orderQtySelect.classList.remove("selected");
}
//endregion
</script>
{% endblock %}