bootstrap - selectree树形结构下拉框

1、首先导入Bootstrap js、样式

<script src="/static/common/ztree/js/jquery.ztree.all.js" type="text/javascript" charset="utf-8">script>
<script src="/static/exp/treeselect/selectree.js">script>

bootstrap - selectree树形结构下拉框_第1张图片

2、引入的 selectree.js (这是固定代码,哪里有变动我会详细说明)

(function ($) {
    "use strict";
    //default selecttree
    var defaultOptions = {
        width: 'auto',
        height: '300px',
        isSimpleNode: true, //是否启用简单的节点属性(id,ame),次配置是form表单传递到后台的参数值,数据通过json传递
        pIcon: '',
        cIcon: '',
        debug: false,
        data: [{
            id: '111111',
            name: "父节点1",
            children: [
                {id: '22222', name: "子节点1"},
                {id: '33333', name: "子节点2"}
            ]
        }]
    }
    //define some global dom
    var SelectTree = function (element, options) {
        this.options = options;
        this.$element = $(element);
        this.$containner = $('
'
); this.$ztree = $('
    '
    ); this.$pInput = $(''); // 这里为隐藏域数据 id='nodes',选中的数都存储在这。 } //prototype method SelectTree.prototype = { constructor: SelectTree, init: function () { var that = this, st = this.$element; // style that.$containner.css({'display': 'inline-block', 'position': 'relative'}); that.$ztree.css({ 'position': 'absolute', 'z-index': 10000, 'border-radius': '3px', 'border': '1px #ccc solid', 'overflow': 'auto', 'background': '#fff', 'margin-top': '30px' }); that.$ztree.css({'width': this.options.width || that.defaultOptions.width}); that.$ztree.css({'height': this.options.height || taht.defaultOptions.height}); // dom if (that.$element.data('pname')) { that.$pInput.attr('name', that.$element.data('pname')); } if (that.$element.attr('name')) { that.$element.removeAttr('name'); } that.$ztree.attr('id', 'selectTree-ztree'); that.$ztree.css('display', 'none'); that.$element.attr('readonly', 'readonly'); st.wrap(that.$containner); st.after(that.$pInput); st.after(that.$ztree); //listener that.$element.bind('click', function (e) { that.$ztree.toggle(); }); //ztree //listener this.options.ztree.setting.callback = { onCheck: function (event, treeId, treeNode) { return that._onSelectTreeCheck(event, treeId, treeNode); } } $.fn.zTree.init(that.$ztree, this.options.ztree.setting, this.options.ztree.data); // this 这个东西啊你理解成 它是当前选中的数据 赋给 selectttt ,aaaa 这是一个function 往下看 aaaa.selectttt(this); }, _onSelectTreeCheck: function (event, treeId, treeNode) { var that = this; //获得所有选中节点 var pValue = '', text = ''; var treeObj = $.fn.zTree.getZTreeObj(that.$ztree.attr('id')); console.log(treeObj) if (treeObj) { var nodes = treeObj.getCheckedNodes(true); if (this.options.debug) { console.log("选中的节点:"); console.log(nodes); } for (var i = 0; i < nodes.length; i++) { if (nodes[i].isParent) { text = text + nodes[i].name + ':'; } else { text = text + nodes[i].name + ','; } } if (this.options.isSimpleNode) { nodes = common._transformToSimpleNodes(nodes); } if (this.options.debug) { console.log("提交到表单的数据结构:"); console.log(JSON.stringify(nodes)); } // nodes数据 从这赋给隐藏域input(id='nodes') that.$pInput.val(JSON.stringify(nodes)); text = text ? text.substr(0, text.length - 1) : ''; that.$element.val(text); that.$element.attr('title', text); } } } var common = { //这里组织默认参数,用户传过来的参数,ztree的一些固定参数 _getSelectTreeOptions: function (options) { options = options ? options : {}; return { width: options.width || defaultOptions.width, height: options.height || defaultOptions.height, isSimpleNode: options.isSimpleNode || defaultOptions.isSimpleNode, pIcon: options.pIcon || defaultOptions.pIcon, cIcon: options.cIcon || defaultOptions.cIcon, debug: options.debug || defaultOptions.debug, ztree: { data: options.data || defaultOptions.data, setting: { check: { enable: true, chkStyle: "checkbox", chkboxType: {"Y": "ps", "N": "ps"} } } } } }, //转换ztree为简单的节点,只包含id,name _transformToSimpleNodes: function (nodes) { var newNodes = []; if (nodes instanceof Array) { for (var i = 0; i < nodes.length; i++) { var pNode = nodes[i].getParentNode(); var node = {}; node.pId = pNode ? pNode.id : null; node.id = nodes[i].id; node.name = nodes[i].name; newNodes.push(node); } } return newNodes; } } $.fn.selectTree = function (options) { var data = new SelectTree(this, common._getSelectTreeOptions(options)); return data.init(); } $.fn.selectTree.Constructor = SelectTree; // 为什么这有一个aaaa?他的作用是用来回显你当前选中的数据,回显展示在input输入框内 ,这个是需求问题,如果不需要回显,可以忽略这段代码 var aaaa ={ selectttt:function (e) { debugger var that = e; //获得所有选中节点 var pValue = '', text = ''; var treeObj = $.fn.zTree.getZTreeObj(that.$ztree.attr('id')); console.log(treeObj) if (treeObj) { var nodes = treeObj.getCheckedNodes(true); if (that.options.debug) { console.log("选中的节点:"); console.log(nodes); } for (var i = 0; i < nodes.length; i++) { if (nodes[i].isParent) { text = text + nodes[i].name + ':'; } else { text = text + nodes[i].name + ','; } } if (that.options.isSimpleNode) { nodes = common._transformToSimpleNodes(nodes); } if (that.options.debug) { console.log("提交到表单的数据结构:"); console.log(JSON.stringify(nodes)); } that.$pInput.val(JSON.stringify(nodes)); text = text ? text.substr(0, text.length - 1) : ''; that.$element.val(text); that.$element.attr('title', text); } } } })(jQuery)

    3、HTML 页面中接收数据

    // 通过id = selectree, 赋值数据到div中
    <script type="text/javascript">
        $(function() {
            var nodes = [{
                id: '111111',
                name: "父节点1",
                children: [
                    { id: '22222', name: "子节点1" },
                    { id: '33333', name: "子节点2" }
                ]
            }];
            $("#selectree").selectTree({
                isSimpleNode: true,
                debug: true,
                data: JSON.parse('${data}') // 后台查询的数据 返回为data
            }); 
        });
    </script>
    
    // input框在页面上展示数据
    <div class="col-md-3">
        <div class="input-group">
            <span class="input-group-addon" id="zh_box">部门</span>
            <input type="text"  autocomplete="off"
            class="input-sm form-control"  id="selectree"/>
        </div>
    </div>
    
    // 从Selectree.js nodes 中获取选中的数据,传到后台作为查询条件使用
    var nos =  $('#nodes').val(); // 通过nodes 拿到
        if(nos!="") {
            var nodesJson = eval('(' + $('#nodes').val() + ')');// 转换成字符串
            var deptIds = '';
            if (nodesJson != null && nodesJson.length > 0) { // 进行遍历存储到deptIdS中 返回到后台
                for (var i = 0; i < nodesJson.length; i++) {
                    deptIds += nodesJson[i].id + ',';
                }
            }
            if (nodesJson != null && nodesJson.length > 0) {
                url += "&dement=" + deptIds // 传到后台 dement 作为查询条件
            }
        }
    

    4、前台说完了,咱们主要来看后台代码的实现,如何返回json数据,是通过什么方式 继续往下看

    后台代码

     1、Controller
            // 我这个是通过权限控制的:dept当前登录人有哪些部门,dement默认所有部门
            List<SysDepartment> dment = iSysDepartmentService.findDepartmentTreeList(dept, dement);
            // dment 查询出所部门数据
            modelAndView.addObject("data", JSON.toJSONString(dment));//部门下拉框,返回页面data
    2、service
        	List<SysDepartment> findDepartmentTreeList(DepartmentAllPo<SysDepartmentVo> dept, String dement);
    3、serviceImpl
    	   // 当前部门全查询 ,递归查询
            @Override
            public List<SysDepartment> findDepartmentTreeList(DepartmentAllPo<SysDepartmentVo> dept, String dement) {
                List<SysDepartment> firstDepart = null;
                if(dept != null){
                // 遍历一级菜单
                    List<SysDepartment> deptList = sysDepartmentMapper.selectList(new QueryWrapper<SysDepartment>().lambda().in(SysDepartment::getId,dept.getDepts()).eq(SysDepartment::getIsDelete,0));
                    for (SysDepartment d:deptList) {// 遍历判断当前默认全部选中,或者选中进行查询
                        if(StringUtils.isBlank(dement) || StringUtils.indexOf(dement,d.getId())>-1){
                            d.setChecked(true); // 选中状态
                        }
                    }
            // 查询一级数据
            firstDepart = deptList.stream().filter(o -> StringUtils.equals(o.getParentId(),"0")).sorted(Comparator.comparing(SysDepartment::getDepartmentLevel)).collect(Collectors.toList());
                    for (SysDepartment o : firstDepart) {
                        fullChild(o,deptList);// 子级数据存储到fullChild
                    }
                }
                return firstDepart;
            }
            
    	// 递归查询树形结构
        private void fullChild(SysDepartment o, List<SysDepartment> deptList) {
            // 查询上级部门与它父级部门的ID是否相同
            List<SysDepartment> clist = deptList.stream().filter(d->StringUtils.equals(d.getParentId(),o.getId())).collect(Collectors.toList());
            if(clist.isEmpty()){// 如果为空不执行任何操作
    
            }else{// 遍历多级树形结构
                o.setChirldList(clist);
                for (SysDepartment c:clist) {
                    fullChild(c,deptList);
                }
            }
        }
    
    

    5、树形结构 以及 结构数据格式

    bootstrap - selectree树形结构下拉框_第2张图片
    在这里插入图片描述

    6、json数据格式

    [{"pId":null,"id":"b18163ce656911e99d9200163e2e7cd0","name":"润兴科技"},{"pId":"b18163ce656911e99d9200163e2e7cd0","id":"163869757257f5050285a3330f53e514","name":"市场运营部"},{"pId":"b18163ce656911e99d9200163e2e7cd0","id":"2d9f849249bd859b6e0281a54504e7cb","name":"人力行政部"},{"pId":"b18163ce656911e99d9200163e2e7cd0","id":"9fa5921e170654f932865e1adfa497f7","name":"总经理办公室"},{"pId":"b18163ce656911e99d9200163e2e7cd0","id":"bdf8691f38e5e1a84b50c2ad002b828c","name":"研发部"},{"pId":"bdf8691f38e5e1a84b50c2ad002b828c","id":"5eab5513531e6c25a2f1a83a14bd6dfb","name":"市局研发"},{"pId":"bdf8691f38e5e1a84b50c2ad002b828c","id":"793122a044131109b71decb2ab95321c","name":"研发中心"},{"pId":"bdf8691f38e5e1a84b50c2ad002b828c","id":"fbf41954c2fbc5b2dbf0e6021b35b6ac","name":"测试部"},{"pId":"b18163ce656911e99d9200163e2e7cd0","id":"d395473b953d37a88b43fb79840e80d4","name":"物联网事业部"},{"pId":"b18163ce656911e99d9200163e2e7cd0","id":"f1ec10683d539eaae6a626d8eeb634c2","name":"政府事业部"},{"pId":"b18163ce656911e99d9200163e2e7cd0","id":"f9a6b6bccb77db27e9c4af26c520704c","name":"经营财务部"}]
    

    你可能感兴趣的:(bootstrap,-)