时间筛选框树形显示

本文介绍了一种改进的时间类型筛选框实现方案,利用JQuery EasyUI Tree插件及moment.js,将时间筛选条件转化为树形结构以提高用户体验。文章详细展示了如何通过JavaScript操作DOM元素来实现这一功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

请添加图片描述

將時間類型的篩選框改成樹形顯示

改之前:

请添加图片描述

改之後:

请添加图片描述

用到了Jquery EasyUI的Tree

请添加图片描述

和moment.js
请添加图片描述
代码如下:

// 給表頭綁定右擊事件
var table = $("#" + headTableId + " th");

// 判断鼠标左/右击
table.mousedown(function (e) {
    if (3 === e.which) { // 鼠標右擊
        addSearchFrame($(this));
    } else if (1 === e.which) { // 鼠標左擊
        
    }
});

function addSearchFrame(obj) {
        let key;
        const index = obj.index();
        // 为了使弹窗过滤条件保存后禁用掉表头的右键点击
        if (obj.hasClass("not-right-click")) {
            return;
        }
        if (obj.attr("column-param")) {
            key = obj.attr("column-param");
        } else {
            key = obj.attr("data-param");
        }
        var filtrateBox = $(".filtrate-box");
        $.ajax({
            url: window.location.pathname.substr(window.location.pathname.lastIndexOf('/') + 1) + "?action=getAllHead",
            type: "post",
            data: {column: key},
            success: function (result) {
                var html = "";
                var year = "";
                var month = "";
                var day = "";
                let list = [];
                let dateList = [];
                var dateTree = [];
                result.forEach(function (data) {
                    if (data != null) {
                        let colunmResult = findValue(data, obj.attr("header-param"));
                        list.push(colunmResult);
                    }
                });

                if (key.contains('date') || key.contains('Date')) {
                    // 如果篩選條件是時間類型,就將list重組為樹形結構並顯示
                    html += "<ul id='tt1'></ul>"
                    let yearMap = {}
                    // 將2022/01/01這種單條時間,構造成jQuery-tree所需要的JSON數據格式
                    list.forEach(function (s) {
                        s = moment(s.toString(), "YYYY/MM/DD").format('YYYY年M月D日');
                        dateList.push(s);
                        year = s.substring(0, s.indexOf('年'));
                        month = s.substring(s.indexOf('年')+1, s.indexOf('月'));
                        day = s.substring(s.indexOf('月')+1, s.indexOf('日'));
                        /*yearMap = {
                            'y1': {
                                'M1': set['d1', 'd2'],
                                'M2': ['d1', 'd2']
                            },
                            'y2': {
                                
                            }
                        }*/
                        let monthMap = {}
                        if (yearMap[year]) {
                            monthMap = yearMap[year]
                        } else {
                            yearMap[year] = monthMap
                        }
                        
                        let daySet = new Set()
                        if (monthMap[month]) {
                            daySet = monthMap[month];
                        } else {
                            monthMap[month] = daySet;
                        }
                        daySet.add(day)
                    });
                    for (let year in yearMap) {
                        let yearObj = {
                            "id":year,
                            "text": year+"年",
                            "type": "year",
                            "iconCls":"icon-save",
                            "children": []
                        };
                        dateTree.push(yearObj)
                        for (let month in yearMap[year]) {
                            let monthObj = {
                                "id": month,
                                "text": month + "月",
                                "children": []
                            };
                            yearObj.children.push(monthObj)
                            for (let day of yearMap[year][month]) {
                                let dayObj = {
                                    "id": year + '-' + month + '-' + day,
                                    "text": day + "日",
                                }
                                monthObj.children.push(dayObj)
                            }
                        }
                    }
                    var innerHTML = "<div id='searchFilterDiv'>" +
                        "<input type='search' value='' size='35' placeholder='搜索' οnkeyup='searchFilterForDateTree()'>" +
                        "<span style='cursor:pointer'><i class='search_right' οnclick='searchFilterByInput()'></i></span>" +
                        "</div>" +
                        "<div class='filtrate'>" +
                        "<ul>" +
                        "<li><input type='checkbox' value='checkedAll' οnclick='allCheckedForTree()' id='allChecked'><span style='margin-left:15px'>全選</span></li>" +
                        html +
                        "</ul>" +
                        "</div>" +
                        "<div class='searchBtn'>" +
                        "<input class='btn' type='submit' name='submit' value='重置所有' οnclick='clearData()'>" +
                        "<input class='btn' type='submit' name='submit' value='確 定' οnclick='selectDataByDateTree(" + index + ")'>" +
                        "<input class='btn' type='button' name='cancel' value='取 消' οnclick='frameClose()'>" +
                        "</div>";
                } else {
                    list.forEach(function (s) {
                        let str = s;
                        if (typeof(s) === "string"){
                            str = s.replaceAll("\"","\&quot;").replaceAll("\'","\&apos;");
                        }
                        if(!(s == undefined || s==null || s=="")){
                            html += "<li><input type='checkbox' value=\"" + str + "\" name='filter' οnclick='unChecked()'>" +
                                "<span class='columnDesc'>" + s + "</span></li>";
                        }

                    });
                    var innerHTML = "<div id='searchFilterDiv'>" +
                        "<input type='search' value='' size='35' placeholder='搜索' οnkeyup='searchFilterByInput()'>" +
                        "<span style='cursor:pointer'><i class='search_right' οnclick='searchFilterByInput()'></i></span>" +
                        "</div>" +
                        "<div class='filtrate'>" +
                        "<ul>" +
                        "<li><input type='checkbox' value='checkedAll' οnclick='allChecked()' id='allChecked'><span style='margin-left:15px'>全選</span></li>" +
                        html +
                        "</ul>" +
                        "</div>" +
                        "<div class='searchBtn'>" +
                        "<input class='btn' type='submit' name='submit' value='重置所有' οnclick='clearData()'>" +
                        "<input class='btn' type='submit' name='submit' value='確 定' οnclick='selectData(" + index + ")'>" +
                        "<input class='btn' type='button' name='cancel' value='取 消' οnclick='frameClose()'>" +
                        "</div>";
                }
                
                // 初始化
                filtrateBox.text("");
                filtrateBox.append(innerHTML);
                // 將日期類型的json傳給easyui-tree插件來初始化數據
                addDataToTree(dateTree);
                // 对选中的过滤条件进行还原
                if (filterMap[key] != null) {
                    if (key.contains('date') || key.contains('Date')) {
                        var nodes = $('#tt1').tree('getChecked', 'unchecked'); //获取未选中的节点
                        nodes.forEach(s => {
                            var ifLeaf = $("#tt1").tree('isLeaf', s.target);
                            if (ifLeaf) {
                                filterMap[key].forEach(function (value) {
                                    value = moment(value.toString(), "YYYY/MM/DD").format('YYYY-M-D')
                                    if (value === s.id) {
                                        $("#tt1").tree('check', s.target);
                                    }
                                })
                            }
                        });
                        /**
                         * 使全選框也對應還原後的狀態來選擇是否勾選
                         */
                        let searchStr = $("#searchFilterDiv input[type='search']").val();
                        let allLength = $('#tt1').tree('getChecked', ['checked', 'unchecked', 'indeterminate']).length;

                        let checkedLength = $('#tt1').tree('getChecked').length;
                        if (searchStr !== "" && allLength !== checkedLength) {
                            $(".filtrate #allChecked").prop("checked", false);
                        } else {
                            $(".filtrate #allChecked").prop("checked", true);
                        }
                    } else {
                        $(".filtrate>ul").find("input").each(function () {
                            var domValue = $(this);
                            filterMap[key].forEach(function (value) {
                                if (value === domValue.val()) {
                                    domValue.attr("checked", "true");
                                }
                            })
                        });
                    }
                }
                filtrateBox.show();
                $("#searchFilterDiv input[type='search']").focus();
            }
        });
    }
    
    
    
    function addDataToTree(dateTreeJson) {
        // 初始化日期篩選框的數據
        $('#tt1').tree({
            data:dateTreeJson,
            method: "get",
            checkbox:true,
            cascadeCheck:true
        });
    }
    
    // 針對日期篩選框中的樹形複選框的全選和取消全選
    function allCheckedForTree() {
        var roots = $('#tt1').tree('getRoots');//返回tree的所有根节点数组
        var nodes = $('#tt1').tree('getChecked', 'unchecked'); //获取未选中的节点
        if (nodes.length > 0) {
            //全选
            for (var i = 0; i < roots.length; i++) {
                var node = $('#tt1').tree('find', roots[i].id);//查找节点
                $('#tt1').tree('check', node.target);//将得到的节点选中
            }
        } else {
            for (var i = 0; i < roots.length; i++) {
                var node = $('#tt1').tree('find', roots[i].id);
                $('#tt1').tree('uncheck', node.target);
            }
        }
    }
    
    (function ($) {
        $.extend($.fn.tree.methods, {
            /**
             * 扩展easyui tree的搜索方法
             * @param tree easyui tree的根DOM节点(UL节点)的jQuery对象
             * @param searchText 检索的文本
             * @param this-context easyui tree的tree对象
             */
            search: function (jqTree, searchText) {
                //easyui tree的tree对象。可以通过tree.methodName(jqTree)方式调用easyui tree的方法
                var tree = this;
                //获取所有的树节点
                var nodeList = getAllNodes(jqTree, tree);
                //如果没有搜索条件,则展示所有树节点
                searchText = $.trim(searchText);
                if (searchText == "") {
                    for (var i = 0; i < nodeList.length; i++) {
                        $(".tree-node-targeted", nodeList[i].target).removeClass("tree-node-targeted");
                        $(nodeList[i].target).show();
                    }
                    //展开已选择的节点(如果之前选择了)
                    var selectedNode = tree.getSelected(jqTree);
                    if (selectedNode) {
                        tree.expandTo(jqTree, selectedNode.target);
                    }
                    return;
                }
                //搜索匹配的节点并高亮显示
                var matchedNodeList = [];
                if (nodeList && nodeList.length > 0) {
                    var node = null;
                    for (var i = 0; i < nodeList.length; i++) {
                        node = nodeList[i];
                        if (isMatch(searchText, node.text)) {
                            matchedNodeList.push(node);
                        }
                    }
                    //隐藏所有节点
                    for (var i = 0; i < nodeList.length; i++) {
                        $(".tree-node-targeted", nodeList[i].target).removeClass("tree-node-targeted");
                        $(nodeList[i].target).hide();
                    }
                    //折叠所有节点
                    tree.collapseAll(jqTree);
                    //展示所有匹配的节点以及父节点      
                    for (var i = 0; i < matchedNodeList.length; i++) {
                        showMatchedNode(jqTree, tree, matchedNodeList[i]);
                    }
                }
            },
            /**
             * 展示节点的子节点(子节点有可能在搜索的过程中被隐藏了)
             * @param node easyui tree节点
             */
            showChildren: function (jqTree, node) {
                //easyui tree的tree对象。可以通过tree.methodName(jqTree)方式调用easyui tree的方法
                var tree = this;
                //展示子节点
                if (!tree.isLeaf(jqTree, node.target)) {
                    var children = tree.getChildren(jqTree, node.target);
                    if (children && children.length > 0) {
                        for (var i = 0; i < children.length; i++) {
                            if ($(children[i].target).is(":hidden")) {
                                $(children[i].target).show();
                            }
                        }
                    }
                }
            },
            /**
             * 将滚动条滚动到指定的节点位置,使该节点可见(如果有滚动条才滚动,没有滚动条就不滚动)
             * @param param {
             *  treeContainer: easyui tree的容器(即存在滚动条的树容器)。如果为null,则取easyui tree的根UL节点的父节点。
             *  targetNode: 将要滚动到的easyui tree节点。如果targetNode为空,则默认滚动到当前已选中的节点,如果没有选中的节点,则不滚动
             * }
             */
            scrollTo: function (jqTree, param) {
                //easyui tree的tree对象。可以通过tree.methodName(jqTree)方式调用easyui tree的方法
                var tree = this;
                //如果node为空,则获取当前选中的node
                var targetNode = param && param.targetNode ? param.targetNode : tree.getSelected(jqTree);
                if (targetNode != null) {
                    //判断节点是否在可视区域        
                    var root = tree.getRoot(jqTree);
                    var $targetNode = $(targetNode.target);
                    var container = param && param.treeContainer ? param.treeContainer : jqTree.parent();
                    var containerH = container.height();
                    var nodeOffsetHeight = $targetNode.offset().top - container.offset().top;
                    if (nodeOffsetHeight > (containerH - 30)) {
                        var scrollHeight = container.scrollTop() + nodeOffsetHeight - containerH + 30;
                        container.scrollTop(scrollHeight);
                    }
                }
            }
        });

        /**
         * 展示搜索匹配的节点
         */
        function showMatchedNode(jqTree, tree, node) {
            //展示所有父节点
            $(node.target).show();
            $(".tree-title", node.target).addClass("tree-node-targeted");
            var pNode = node;
            while ((pNode = tree.getParent(jqTree, pNode.target))) {
                $(pNode.target).show();
            }
            //展开到该节点
            tree.expandTo(jqTree, node.target);
            //如果是非叶子节点,需折叠该节点的所有子节点
            if (!tree.isLeaf(jqTree, node.target)) {
                tree.collapse(jqTree, node.target);
            }
        }

        /**
         * 判断searchText是否与targetText匹配
         * @param searchText 检索的文本
         * @param targetText 目标文本
         * @return true-检索的文本与目标文本匹配;否则为false.
         */
        function isMatch(searchText, targetText) {
            return $.trim(targetText) != "" && targetText.indexOf(searchText) != -1;
        }

        /**
         * 获取easyui tree的所有node节点
         */
        function getAllNodes(jqTree, tree) {
            var allNodeList = jqTree.data("allNodeList");
            if (!allNodeList) {
                var roots = tree.getRoots(jqTree);
                allNodeList = getChildNodeList(jqTree, tree, roots);
                jqTree.data("allNodeList", allNodeList);
            }
            return allNodeList;
        }

        /**
         * 定义获取easyui tree的子节点的递归算法
         */
        function getChildNodeList(jqTree, tree, nodes) {
            var childNodeList = [];
            if (nodes && nodes.length > 0) {
                var node = null;
                for (var i = 0; i < nodes.length; i++) {
                    node = nodes[i];
                    childNodeList.push(node);
                    if (!tree.isLeaf(jqTree, node.target)) {
                        var children = tree.getChildren(jqTree, node.target);
                        childNodeList = childNodeList.concat(getChildNodeList(jqTree, tree, children));
                    }
                }
            }
            return childNodeList;
        }
    })(jQuery);

    // 根據輸入框中的內容顯示樹形節點
    function searchFilterForDateTree() {
        var searchText = $("#searchFilterDiv input[ type='search' ] ").val();
        $("#tt1").tree("search", searchText);
    }
    
    // 根據選中的日期查詢相關數據
    function selectDataByDateTree(index) {
        if (toDoSelect) {
            let searchStr = $("#searchFilterDiv input[type='search']").val();
            /**
             * 在条件过滤框里选中的条件
             * @type {Array}
             */
            var checkedDomList = [];

            var checkedDom = $("#tt1").tree('getChecked');
            checkedDom.forEach(s => {
                var ifLeaf = $("#tt1").tree('isLeaf', s.target);
                if (ifLeaf) {
                    checkedDomList.push(moment(s.id.toString(), "YYYY-M-D").format('YYYY/MM/DD'));
                }
            });
            let allLength = $('#tt1').tree('getChecked', ['checked', 'unchecked', 'indeterminate']).length;
            
            let checkedLength = $('#tt1').tree('getChecked').length;
            if (searchStr !== "" && allLength !== checkedLength) {
                $(".filtrate #allChecked").prop("checked", false);
            }

            // 保存需要显示的tr和表头id
            if (checkedDomList.length > 0) {
                filterMap[headList[index]] = checkedDomList;
                saveHeadList[headList[index]] = headNameList[index];
            } else {
                delete filterMap[headList[index]];
                delete saveHeadList[headList[index]];
            }
            frameClose();
            saveFilterMap();
        } else {
            frameClose();
        }
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

| ⃢ ⃢ |

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值