用script去做前端html表格分页/排序

前言:

掘弃掉与后端交互做分页和互导,有利有弊吧; 在小数据的时候,如果不停来回朝服务端发送请求,会造成堵塞.于是,放弃了之前的前后端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 %}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/155376.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何通过 wireshark 捕获 C# 上传的图片

一&#xff1a;背景 1. 讲故事 这些天计划好好研究下tcp/ip&#xff0c;以及socket套接字&#xff0c;毕竟工控中设计到各种交互协议&#xff0c;如果只是模模糊糊的了解&#xff0c;对分析此类dump还是非常不利的&#xff0c;而研究协议最好的入手点就是用抓包工具 wireshar…

Trigger替换Demo

maven工程 pom依赖 <dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.2.1</version> </dependency> import org.quartz.Job; import org.quartz.JobExecutionContext; imp…

2023.11.16 hivesql高阶函数之开窗函数

目录 1.开窗函数的定义 2.数据准备 3.开窗函数之排序 需求:用三种排序方法查询学生的语文成绩排名,并降序显示 4.开窗函数分组 需求:按照科目来分类,使用三种排序方式来排序学生的成绩 5.聚合函数与分组配合使用 6.聚合函数同时和分组以及排序关键字配合使用 --需求1&…

设置float浮动

用途&#xff1a;用来实现并行。常用在div等块元素并行显示。 设置右浮动代码&#xff1a;float: right; 设置左浮动代码&#xff1a;float: left; 注意&#xff1a; 1.要浮动&#xff0c;所有盒子都要设置浮动。 2.行内元素如span&#xff0c;添加了float属性过后宽度和高…

iOS学习 --- Xcode 15 下载iOS_17.0.1_Simulator失败解决方法

1.去开发者官网下载安装包 https://developer.apple.com/download/all/?qiOS%2017 使用浏览器下载。 2.打开终端通过命令添加到xcode 命令如下&#xff1a; sudo xcode-select -s /Applications/Xcode.app(输入开始密码)xcodebuild -runFirstLaunch (等待一小会)xcrun simctl…

【LabVIEW学习】2.for,while,事件

1.for实例&#xff08;随机输出数据100次&#xff09; 结果&#xff1a; 2.while实例&#xff08;i<50灯亮&#xff0c;大于之后灯灭&#xff09; 结果&#xff1a;&#xff08;先亮后灭&#xff09; 3.事件结构的实例&#xff08;点击按钮数据增加&#xff09;事件监听应该…

解决 requests 2.28.x 版本 SSL 错误

最近&#xff0c;在使用requests 2.28.1版本进行HTTP post传输时&#xff0c;您可能遇到了一个问题&#xff0c;即SSL验证失败并显示错误消息(Caused by SSLError(SSLCertVerificationError(1, [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get loc…

用归并排序算法merge_sort( )求解 逆序对的数量 降低时间复杂度为 nlogn

题目简述 给定一个序列有n个数&#xff0c;求n个数中逆序对的个数&#xff0c;逆序对的定义&#xff1a;i < j && a[i] > a[j]。 输入格式 第一行包含一个整数n。 第二行包含 n 个整数&#xff08;所有整数均在1~1e9范围内&#xff09;&#xff0c;表示整数数…

京东联盟flutter插件使用方法

目录 1.京东联盟官网注册申请步骤略~2.安卓端插件配置&#xff1a;3.IOS端插件配置4.其它配置5.京东OAuth授权 文档地址&#xff1a;https://baiyuliang.blog.csdn.net/article/details/134444104 京东联盟flutter插件地址&#xff1a;https://pub.dev/packages/jdkit 1.京东联…

卷积神经网络(CNN)衣服图像分类的实现

文章目录 前期工作1. 设置GPU&#xff08;如果使用的是CPU可以忽略这步&#xff09;我的环境&#xff1a; 2. 导入数据3.归一化4.调整图片格式5. 可视化 二、构建CNN网络模型三、编译模型四、训练模型五、预测六、模型评估 前期工作 1. 设置GPU&#xff08;如果使用的是CPU可以…

Python+Selenium WebUI自动化框架 -- 基础操作封装

前言&#xff1a; 封装Selenium基本操作&#xff0c;让所有页面操作一键调用&#xff0c;让UI自动化框架脱离高成本、低效率时代&#xff0c;将用例的重用性贯彻到极致&#xff0c;让烦人的PO模型变得无所谓&#xff0c;让一个测试小白都能编写并实现自动化。 知识储备前提&a…

IDEA 快捷键汇总

目录 1、altinsert 2、ctrl/ 3、altenter 4、alt回车 5、ctrlD 6、ctrlaltL 7、ctrl点击 8、alt左键向下拉 9、ctrlaltv 10、ctrlaltwint 1、altinsert 快速创建代码&#xff0c;可以快速创建类中get set tostring等方法 2、ctrl/ 单行注释 3、altenter…

Elasticsearch 8.9 Bulk批量给索引增加数据源码

一、相关API的handler二、RestBulkAction&#xff0c;组装bulkRequest调用TransportBulkAction三、TransportBulkAction 会把数据分发到数据该到的数据节点1、把数据按分片分组&#xff0c;按分片分组数据再发送到指定的数据节点(1) 计算此文档发往哪个分片1)根据索引是否是分区…

三菱FX3U小项目—自锁控制与故障报警

目录 一、项目描述 二、IO口分配 三、项目程序 四、总结 一、项目描述 当按下启动按钮时&#xff0c;电机通电运转&#xff0c;当按下停止按钮时&#xff0c;电动机断电停止&#xff1b;当设备检修旋钮得电时&#xff0c;电动机停止并且故障指示灯闪烁1s&#xff1b;当电动…

算法通关村第九关-黄金挑战二叉树较难问题

将有序数组转换为二叉搜索树 描述 : 给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你将其转换为一棵 高度平衡 二叉搜索树。 高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。 题目 : LeetCode 10…

基于SSM的智慧养老平台设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

简单的用Python实现一下,采集某牙视频,多个视频翻页下载

前言 表弟自从学会了Python&#xff0c;每天一回家就搁那爬视频&#xff0c;不知道的以为是在学习&#xff0c;结果我昨天好奇看了一眼&#xff0c;好家伙&#xff0c;在那爬某牙舞蹈区&#xff0c;太过分了&#xff01; 为了防止表弟做坏事&#xff0c;我连忙找了个凳子坐下&…

MySql 数据库初始化,创建用户,创建数据库,授权

登录MySQL&#xff08;使用管理员账户&#xff09; mysql -u root -p 设置用户 -- 创建用户并设置密码 CREATE USER user_name% IDENTIFIED BY user_password;-- 删除用户 drop user user_name; 设置数据库 -- 创建数据库 CREATE DATABASE database_name;-- 删除数据库 DR…

计算机网络:网络层ARP协议

在实现IP通信时使用了两个地址&#xff1a;IP地址&#xff08;网络层地址&#xff09;和MAC地址&#xff08;数据链路层地址&#xff09; 问题&#xff1a;已知一个机器&#xff08;主机或路由器&#xff09;的IP地址&#xff0c;如何找到相应的MAC地址&#xff1f; 为了解决…

【Dolphinscheduler3.1.1】二次开发本地启动项目(前端+后端)

背景说明 由于业务的定制化开发&#xff0c;需要对Dolphinscheduler进行二次开发&#xff0c;现将项目的启动步骤记录如下。 一、 基础软件安装(必装项请自行安装) Maven: v3.5&#xff0c;配阿里云仓库地址即可 Node: v16. MySQL (5.7系列) : 两者任选其一即可 JDK (1.8)…