1. 程式人生 > >無限層級選單

無限層級選單

無限層級選單

先展示html:

<nav class="navbar navbar-default navbar-static-top">
        <div class="navbar-default sidebar" role="navigation">
            <div class="sidebar-nav navbar-collapse">
                <ul class="nav" id="side-menu">
                    <li class="sidebar-search">
                        <div class="input-group custom-search-form" style="display: flex">
                            <input type="text" class="form-control" placeholder="Search...">
                            <span class="input-group-btn" style="align-self: flex-start;">
                                <button class="btn btn-default" type="button" style="margin: 0 0 0 10px">
                                    <i class="fa fa-search"></i>
                                </button>
                            </span>
                        </div>
                    </li>
                </ul>
            </div>
        </div>
    </nav>

進入頁面,初始化請求後臺資料,載入最外層選單:

packageAjax({url:'operations/getOrgData?parentId=0',type:"GET",data:'',dataType:'json'},function(data){//初始化
        if (data && data.code === 0 ) {
            var seldvel = '';
            for (let index = 0; index < data.item.length; index++) {
                seldvel+='<li class="action" data-uuid = '+data.item[index].orgUuid+'><input type = "checkbox" name = "groupUuids" class = "chbox" style = "z-index:999"/><a href="javascript:void(0)"><i class="fa arrow fa-fw"></i>'+data.item[index].name+'</a></li>'
                
            }
            $('#side-menu').append(seldvel);
            $('#side-menu').metisMenu();
        }else{
            var seldvel = '<div style="text-align:center;color:red">'+data.message+'</div>'
            $('#side-menu').append(seldvel);
        }
        $('.chbox').click(function(evt){
            // 阻止冒泡
            evt.stopPropagation();
            if($(this).prop("checked")){
                $(this).prop("checked",true);
                $(this).siblings().find('.chbox').prop("checked",true);
            }else{
                $(this).prop("checked",false);
                $(this).siblings().find('.chbox').prop("checked",false);
            }
        });
    }) 

當然packageAjax函式是自己封裝的:

 $(function() {
            var packageAjax = function(params,callback){ //ajax請求資料
                var _url = params.url,
                    _type = params.type,
                    _data = params.data,
                    _dataType = params.dataType,
                    _timeOut = 10000;

                $.ajax({
                    url: _url,
                    type: _type,
                    data: _data,
                    dataType: _dataType,
                    // timeout: _timeOut,
                    success:function(data){
                        callback(data);
                    },
                    error:function(data){
                        alert(data.message)
                    },
                    complete:function(xhr,status){
                        xhr=null;
                    }
                })
            }

然後給初始化加載出來的選單新增點選事件,每點選一次從後臺獲取當前選單下的子選單,其中包括選單的checkbox選中狀態都會根據父級選單的選中與否,子集選單自動生成。也對選中父級子集全選,子集有未選中父級disabled等選單選擇的幾種狀態:

$('#side-menu').on('click','a',function(e){
        var orgUuid = $(this).parent().attr('data-uuid');
        var that = this;
        if (!$(that).data('clicked')) { 
            $('#side-menu').metisMenu('dispose');
            packageAjax({url:'operations/getOrgData?parentId='+orgUuid,type:"GET",data:'',dataType:'json'},function(data){//拉子資料
            // packageAjax({url:'./li.json',type:"GET",data:'',dataType:'json'},function(data){
                var seldvel = '';
                for (let index = 0; index < data.item.length; index++) {
                    seldvel+='<li class="action" data-uuid = '+data.item[index].orgUuid+'><input type = "checkbox" name = "groupUuids" class = "chbox" style = "z-index:999"/><a href="javascript:void(0)"><i class="fa arrow fa-fw"></i>'+data.item[index].name+'</a></li>'
                    
                }
                var uldvel = '<ul class="nav nav-second-level" style="display:none;">'+seldvel+'</ul>'
                $(that).parent().append(uldvel);
                if ($(that).siblings('.chbox').prop("checked")) { //根據父級是否選中子集展示不同狀態
                    $(that).next().find('.chbox').prop("checked",true)
                } else {
                    $(that).next().find('.chbox').prop("checked",false)
                }
                $(that).parent().children('ul').show(500)
                $(that).parent().addClass('mm-active');
                $(that).attr('aria-expanded','true');
                $(that).parent().children('ul').addClass('mm-collapse').addClass('mm-show');
                // $('#side-menu').metisMenu();
                $('.chbox').click(function(evt){ //點選選擇和取消
                    // 阻止冒泡
                    evt.stopPropagation();
                    if($(this).prop("checked")){
                        $(this).prop("checked",true);
                        $(this).siblings().find('.chbox').prop("checked",true);
                    }else{
                        $(this).prop("checked",false);
                        $(this).siblings().find('.chbox').prop("checked",false);
                    }
                    var _siblings = $(this).parent().siblings().children('.chbox')
                    var result1 = true;
                    var result2 = true;
                    var result3 = true;

                    for (let index = 0; index < _siblings.length; index++) {
                        result1 = result1 &&  $(_siblings[index]).prop("checked"); //其他的都選中
                        result2 = result2 && !$(_siblings[index]).prop("checked"); //其他的都不選中
                        result3 = result3 && $(_siblings[index]).prop("checked"); //父級選中,子集有未選中的
                    }
                    if (!$(this).prop("checked")) { //有一個未選中,父級disabled
                        $(this).parent().parent().prevAll('.chbox').attr('disabled','disabled');
                        
                        if (result2) { //所有的都未選中
                            $(this).parent().parent().prevAll('.chbox').removeAttr('disabled'); 
                            $(this).parent().parent().prevAll('.chbox').prop("checked",false);
                        }
                    } else{
                        if (result1) { //所有的都選中
                            $(this).parent().parent().prevAll('.chbox').removeAttr('disabled'); 
                            $(this).parent().parent().prevAll('.chbox').prop("checked",true);
                        }
                        if (!result3) {//父級選中,子集有未選中的
                            $(this).parent().parent().prevAll('.chbox').attr('disabled','disabled');
                        }
                    }
                });
                $('#side-menu').metisMenu();
                // $(that).find('a').css({'color':'red'})
            })
            $(that).data('clicked', true); 
    
        } else{
            $('#side-menu').metisMenu();
            // $(that).find('a').removeAttr('color')
        }
        return false;
    });

引入的外掛:

<link rel="stylesheet" href="./bootstrap/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="./font-awesome-4.7.0/font-awesome-4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="./metismenu/dist/metisMenu.min.css">
<link rel="stylesheet" href="./css.css">
<script src="http://code.jquery.com/jquery.js"></script>
<script src="./bootstrap/bootstrap/js/bootstrap.min.js"></script>
<script src="./metismenu/dist/metisMenu.min.js"></script>

整個程式碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" href="./bootstrap/bootstrap/css/bootstrap.min.css">
    <link rel="stylesheet" href="./font-awesome-4.7.0/font-awesome-4.7.0/css/font-awesome.min.css">
    <link rel="stylesheet" href="./metismenu/dist/metisMenu.min.css">
    <link rel="stylesheet" href="./css.css">
    <script src="http://code.jquery.com/jquery.js"></script>
    <script src="./bootstrap/bootstrap/js/bootstrap.min.js"></script>
    <script src="./metismenu/dist/metisMenu.min.js"></script>
    <title>Document</title>
</head>
<body>
    <nav class="navbar navbar-default navbar-static-top">
        <div class="navbar-default sidebar" role="navigation">
            <div class="sidebar-nav navbar-collapse">
                <ul class="nav" id="side-menu">
                    <li class="sidebar-search">
                        <div class="input-group custom-search-form" style="display: flex">
                            <input type="text" class="form-control" placeholder="Search...">
                            <span class="input-group-btn" style="align-self: flex-start;">
                                <button class="btn btn-default" type="button" style="margin: 0 0 0 10px">
                                    <i class="fa fa-search"></i>
                                </button>
                            </span>
                        </div>
                    </li>
                </ul>
            </div>
        </div>
    </nav>
    <script type="text/javascript">
       
        $(function() {
            var packageAjax = function(params,callback){ //ajax請求資料
        var _url = params.url,
            _type = params.type,
            _data = params.data,
            _dataType = params.dataType,
            _timeOut = 10000;

        $.ajax({
            url: _url,
            type: _type,
            data: _data,
            dataType: _dataType,
            // timeout: _timeOut,
            success:function(data){
                callback(data);
            },
            error:function(data){
                // alert(data.message)
            },
            complete:function(xhr,status){
                xhr=null;//導致原因是每次傳送ajax會new一個新的xhr物件,ajax完成後銷燬即可
            }
        })
    }
    packageAjax({url:'operations/getOrgData?parentId=0',type:"GET",data:'',dataType:'json'},function(data){//初始化
    // packageAjax({url:'./nav.json',type:"GET",data:'',dataType:'json'},function(data){
        if (data && data.code === 0 ) {
            var seldvel = '';
            for (let index = 0; index < data.item.length; index++) {
                seldvel+='<li class="action" data-uuid = '+data.item[index].orgUuid+'><input type = "checkbox" name = "groupUuids" class = "chbox" style = "z-index:999"/><a href="javascript:void(0)"><i class="fa arrow fa-fw"></i>'+data.item[index].name+'</a></li>'
                
            }
            $('#side-menu').append(seldvel);
            $('#side-menu').metisMenu();
        }else{
            var seldvel = '<div style="text-align:center;color:red">'+data.message+'</div>'
            $('#side-menu').append(seldvel);
        }
        $('.chbox').click(function(evt){
            // 阻止冒泡
            evt.stopPropagation();
            if($(this).prop("checked")){
                $(this).prop("checked",true);
                $(this).siblings().find('.chbox').prop("checked",true);
            }else{
                $(this).prop("checked",false);
                $(this).siblings().find('.chbox').prop("checked",false);
            }
        });
    }) 
    $('#side-menu').on('click','a',function(e){
        var orgUuid = $(this).parent().attr('data-uuid');
        var that = this;
        if (!$(that).data('clicked')) { 
            $('#side-menu').metisMenu('dispose');
            packageAjax({url:'operations/getOrgData?parentId='+orgUuid,type:"GET",data:'',dataType:'json'},function(data){//拉子資料
            // packageAjax({url:'./li.json',type:"GET",data:'',dataType:'json'},function(data){
                var seldvel = '';
                for (let index = 0; index < data.item.length; index++) {
                    seldvel+='<li class="action" data-uuid = '+data.item[index].orgUuid+'><input type = "checkbox" name = "groupUuids" class = "chbox" style = "z-index:999"/><a href="javascript:void(0)"><i class="fa arrow fa-fw"></i>'+data.item[index].name+'</a></li>'
                    
                }
                var uldvel = '<ul class="nav nav-second-level" style="display:none;">'+seldvel+'</ul>'
                $(that).parent().append(uldvel);
                if ($(that).siblings('.chbox').prop("checked")) { //根據父級是否選中子集展示不同狀態
                    $(that).next().find('.chbox').prop("checked",true)
                } else {
                    $(that).next().find('.chbox').prop("checked",false)
                }
                $(that).parent().children('ul').show(500)
                $(that).parent().addClass('mm-active');
                $(that).attr('aria-expanded','true');
                $(that).parent().children('ul').addClass('mm-collapse').addClass('mm-show');
                // $('#side-menu').metisMenu();
                $('.chbox').click(function(evt){ //點選選擇和取消
                    // 阻止冒泡
                    evt.stopPropagation();
                    if($(this).prop("checked")){
                        $(this).prop("checked",true);
                        $(this).siblings().find('.chbox').prop("checked",true);
                    }else{
                        $(this).prop("checked",false);
                        $(this).siblings().find('.chbox').prop("checked",false);
                    }
                    var _siblings = $(this).parent().siblings().children('.chbox')
                    var result1 = true;
                    var result2 = true;
                    var result3 = true;

                    for (let index = 0; index < _siblings.length; index++) {
                        result1 = result1 &&  $(_siblings[index]).prop("checked"); //其他的都選中
                        result2 = result2 && !$(_siblings[index]).prop("checked"); //其他的都不選中
                        result3 = result3 && $(_siblings[index]).prop("checked"); //父級選中,子集有未選中的
                    }
                    if (!$(this).prop("checked")) { //有一個未選中,父級disabled
                        $(this).parent().parent().prevAll('.chbox').attr('disabled','disabled');
                        
                        if (result2) { //所有的都未選中
                            $(this).parent().parent().prevAll('.chbox').removeAttr('disabled'); 
                            $(this).parent().parent().prevAll('.chbox').prop("checked",false);
                        }
                    } else{
                        if (result1) { //所有的都選中
                            $(this).parent().parent().prevAll('.chbox').removeAttr('disabled'); 
                            $(this).parent().parent().prevAll('.chbox').prop("checked",true);
                        }
                        if (!result3) {//父級選中,子集有未選中的
                            $(this).parent().parent().prevAll('.chbox').attr('disabled','disabled');
                        }
                    }
                });
                $('#side-menu').metisMenu();
                // $(that).find('a').css({'color':'red'})
            })
            $(that).data('clicked', true); 
    
        } else{
            $('#side-menu').metisMenu();
            // $(that).find('a').removeAttr('color')
        }
        return false;
    });

        })
       
        </script>
</body>
</html>