【LayUI】LayUI拓展组件:TreeSelect树形下拉选择器

LayUI拓展组件:TreeSelect树形下拉选择器

项目介绍

基于 layui 的树形下拉选择器。支持异步加载,提供点击回调函数,提供设置占位符、选中节点等方法。
组件下载地址:https://gitee.com/sang93/treeselect

效果图

在这里插入图片描述

使用示例
<input type="text" id="pidSelect" lay-filter="pidSelect" placeholder="选择父节点" class="layui-input">

<script>
    layui.use(['treeSelect'], function () {
        var treeSelect= layui.treeSelect;
            
            // 初始化下拉选择器
            treeSelect.render({
                // css选择器,推荐使用id
                elem: '#pidSelect',   
                // 请求地址
                data: '/system/menu/layui/tree', 
                // ajax请求方式:post/get
                type: 'post',  
                // 返回数据中主键的属性名称,默认值为id
                key: {
                    id: 'id',
                },
                // 节点点击回调函数
                click: function (d) {  
                    console.log(d);
                }
            });
            
            /* 
             *  手动设置占位符placeholder(不常用)
             *  第一个参数为lay-filter属性的值
             *  第二个参数为需要修改的提示内容
             */
            treeSelect.setTitle('pidSelect', '这里填写要改的内容');
            
            /* 
             *  选中节点(常用于更新时默认选中节点)
             *  第一个参数为lay-filter属性的值
             *  第二个参数为需要选中的节点的id
             */
            treeSelect.checkNode('pidSelect', 0);
    });
</script>

数据格式参考
[
  
  {
    "children": [
      {
        "name": "留言列表",
        "icon": "&#xe62d;",
        "id": 5,
        "spread": false
      },
      {
        "name": "发表留言",
        "icon": "&#xe61f;",
        "id": 6,
        "spread": false
      }
    ],
    "name": "评论",
    "icon": "&#xe6af;",
    "id": 4,
    "spread": false
  },
  {
    "children": [
      {
        "children": [
          {
            "name": "添加用户",
            "icon": "",
            "id": 40,
            "spread": false
          },
          {
            "name": "编辑用户",
            "icon": "",
            "id": 41,
            "spread": false
          },
          {
            "name": "删除用户",
            "icon": "",
            "id": 42,
            "spread": false
          }
        ],
        "name": "用户列表",
        "icon": "",
        "id": 8,
        "spread": false
      },
      {
        "name": "角色列表",
        "icon": "",
        "id": 11,
        "spread": false
      },
      {
        "children": [
          {
            "name": "添加权限",
            "icon": "",
            "id": 34,
            "spread": false
          },
          {
            "name": "编辑权限",
            "icon": "",
            "id": 37,
            "spread": false
          },
          {
            "name": "删除权限",
            "icon": "",
            "id": 38,
            "spread": false
          }
        ],
        "name": "所有权限",
        "icon": "",
        "id": 13,
        "spread": false
      },
      {
        "name": "操作日志",
        "icon": "&#xe705;",
        "id": 15,
        "spread": false
      }
    ],
    "name": "权限管理",
    "icon": "",
    "id": 10,
    "spread": false
  }
]

####组件模块源码



layui.define('tree', function (exports) {
    "use strict";

    var _MOD = 'treeSelect',
        treeData = {}, //全局树形数据缓存
        $ = layui.jquery,
        win = $(window),
        TreeSelect = function () {
            this.v = '1.0.0';
        };

    /**
     * 初始化下拉树选择框
     */
    TreeSelect.prototype.render = function (options) {
        console.log(options);
            // elem
        var elem = options.elem,
            // 请求地址
            data = options.data,
            // ajax请求方式:post/get
            type = options.type,
            // 节点点击回调
            click = options.click,
            // key.id: id对应的字段, key.pid: pid对应的字段, key.rootPid: 根节点的pid数值
            key = options.key,
            tmp = new Date().getTime(),
            treeInputId = 'treeSelect-input-' + tmp;

        var init = {
            tree: function () {
                $.ajax({
                    url: data,
                    type: type,
                    dataType: 'json',
                    success: function (d) {
                        treeData = d;
                        console.log(d);
                        layui.tree({
                            elem: '#treeSelect-ul-' + tmp,
                            nodes: d
                        });
                        init.removeLayTree();
                        init.setIndex(d, $(elem).next(), true);
                    }
                });
                return init;
            },
            removeLayTree: function () {
                $(elem).next().find('ul.layui-tree').remove();
            },
            setIndex: function (data, parentDom, isRoot) {
                var d = data;
                // 生成新的tree以便支持lay-index
                var tree = $('<ul>').addClass('layui-anim layui-anim-upbit');
                if (isRoot) {
                    tree.attr({
                        'id': 'treeSelect-ul-' + tmp
                    }).addClass('layui-tree layui-box');
                }
                for (var i = 0; i < d.length; i++) {
                    var obj = d[i];
                    var iSpread = '<i class="layui-icon layui-icon-triangle-r"></i>';
                    // 没有子节点,不需要图标
                    if (obj.children == null || obj.children.length == 0) iSpread = '';
                    var a = $('<a>');
                    var iBranch = '<i class="layui-icon layui-icon-file"></i>';
                    // 如果是根节点,不需要图标
                    if (isRoot)  iBranch = '';
                    var cite = $('<cite>').html(obj.name);
                    // 获取主键名称
                    var id;
                    if (key != null && key.id != null){
                        id = obj[key.id];
                    } else {
                        id = obj.id;
                    }
                    var li = $('<li>').attr('lay-index', id).append(iSpread).append(a.append(iBranch).append(cite));
                    if (obj.children != null && obj.children.length > 0){
                        init.setIndex(obj.children, li, false);
                    }
                    tree.append(li);
                }
                parentDom.append(tree);
            },
            input: function () {
                $(elem).hide();
                var $treeDiv = $('<div>').attr({
                            id: 'treeSelect-div-'+ tmp
                        }).addClass('layui-treeselect layui-unselect layui-form-select'),
                    placeholder = $(elem).attr('placeholder'),
                    $treeTitle = $('<div class="layui-select-title">').attr('id', 'treeSelect-title-' + tmp),
                    value = $(elem).val(),
                    $treeInput = $('<input>').attr({
                        placeholder: placeholder,
                        readonly: 'readonly',
                        type: 'text',
                        value: value,
                        id: treeInputId,
                    }).addClass('layui-input layui-unselect').click(function () { }),
                    $treeUl = $('<ul>').addClass('layui-anim layui-anim-upbit layui-tree layui-box').attr({
                            id: 'treeSelect-ul-' + tmp,
                        });
                $(elem).after($treeDiv.append($treeTitle.append($treeInput).append('<i class="layui-edge"></i>')).append($treeUl));
                init.tree().titleToggle().spreadToggle().select();

                return init;
            },
            style: function () {
                var style = '<style>' +
                    '.layui-treeselect .layui-tree{' +
                    '   display: none;\
                        position: absolute;\
                        left: 0;\
                        top: 42px;\
                        padding: 5px 0;\
                        z-index: 999;\
                        min-width: 100%;\
                        border: 1px solid #d2d2d2;\
                        max-height: 300px;\
                        overflow-y: auto;\
                        background-color: #fff;\
                        border-radius: 2px;\
                        box-shadow: 0 2px 4px rgba(0,0,0,.12);\
                        box-sizing: border-box;' +
                    '}' +
                    '.layui-tree-branch{display: none;}' +
                    '.layui-treeselect .layui-tree li>i.layui-icon{cursor: pointer;}' +
                    '.layui-form-selected .layui-tree{display: inline-block}</style>'
                $('head').append(style);
            },
            titleToggle: function () {
                init.event('click', '#treeSelect-title-' + tmp, function () {

                    var $treeUl = $('#treeSelect-div-' + tmp);
                    if ($treeUl.hasClass('layui-form-selected')) {
                        $treeUl.removeClass('layui-form-selected').addClass('layui-unselect');
                    } else {
                        $treeUl.addClass('layui-form-selected').removeClass('layui-unselect');
                    }
                });
                return init;
            },
            spreadToggle: function () {
                init.event('click', '.layui-treeselect .layui-tree li>i.layui-icon', function (e) {
                    //防止冒泡,修复在layui的form中的兼容性问题:点三角形,错误的隐藏下拉框
                    e.stopPropagation();
                    var ul = $(this).parent().find('ul').eq(0),
                        down = 'layui-icon-triangle-d',
                        right = 'layui-icon-triangle-r';
                    if (!ul.hasClass('layui-show')){
                        ul.addClass('layui-show');
                        $(this).addClass(down).removeClass(right);
                    } else {
                        ul.removeClass('layui-show');
                        $(this).addClass(right).removeClass(down);
                    }
                });
                return init;
            },
            select: function () {
                init.event('click', '.layui-treeselect ul li a', function () {
                    var cite = $(this).find('cite').html();
                    $('#' + treeInputId).val(cite);
                    $(elem).attr('value', $(this).parent().attr('lay-index'));
                    $('#treeSelect-div-' + tmp).removeClass('layui-form-selected').addClass('layui-unselect');
                    if (click) {
                        // 获取当前节点
                        var getThisNode = function(datas) {
                            var node = {};
                            for (var i = 0; i < datas.length; i++) {
                                var data = datas[i],
                                    name = data.name,
                                    href = data.href;
                                if (name === cite){
                                    node = data;
                                    break;
                                }

                                for (var j = 0; j < data.children.length; j++) {
                                    var child = data.children[j],
                                        cName = child.name;
                                    if (cName === cite) {
                                        node = child;
                                        break;
                                    }
                                }
                                
                            }
                            return node;
                        };
                        
                        click(getThisNode(treeData));
                    }
                });
                return init;
            },
            event: function (evt, elem, func) {
                $('body').on(evt, elem, func);
            }
        };
        init.input().style();
        return new TreeSelect();
    };

    /**
     * 设置提示文字
     * @param filter lay-filter属性
     * @param title 需要显示的提示内容
     * @returns {TreeSelect}
     */
    TreeSelect.prototype.setTitle = function (filter, title) {
        $('*[lay-filter='+ filter +']').next().find('input').attr('placeholder', title);
        return new TreeSelect();
    };

    /**
     * 选中节点
     * @param filter lay-filter属性
     * @param id 选中的id
     */
    TreeSelect.prototype.checkNode = function (filter, id) {
        var o = $('*[lay-filter='+ filter +']'),
            ts = o.next(),
            tsInput = ts.find('input'),
            li = ts.find('ul.layui-tree li[lay-index]');
        li.each(function (i, el) {
            var index = $(el).attr('lay-index');
            if (index == id) {
                var title = $(el).find('cite').eq(0).text();
                tsInput.val(title);
                o.val(index);
                return false;
            }
        })
    };



    var treeSelect = new TreeSelect();
    //暴露接口
    exports(_MOD, treeSelect);
})
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
您好!要实现在点击 input 标签时弹出下拉树形菜单,可以使用 layuitree 组件结合 input 组件来实现。下面是一个简单的示例代码: HTML: ```html <div class="layui-input-inline"> <input type="text" id="treeInput" lay-verify="required" placeholder="点击选择" autocomplete="off" class="layui-input"> </div> <div id="treeSelect" class="ztree" style="display: none;"></div> ``` JavaScript: ```javascript layui.use(['tree', 'form'], function() { var tree = layui.tree; var form = layui.form; // 模拟的下拉树形数据 var treeData = [ { name: "节点1", id: 1, children: [ { name: "节点1.1", id: 11 }, { name: "节点1.2", id: 12 } ] }, { name: "节点2", id: 2, children: [ { name: "节点2.1", id: 21 }, { name: "节点2.2", id: 22 } ] } ]; // 渲染树形菜单 tree.render({ elem: '#treeSelect', data: treeData, showLine: true, click: function(obj) { var node = obj.data; // 点击树节点时将节点名称赋值给 input 标签 $('#treeInput').val(node.name); // 隐藏树形菜单 $('#treeSelect').hide(); } }); // 点击 input 标签时显示树形菜单 $('#treeInput').on('click', function() { var inputOffset = $(this).offset(); $('#treeSelect').css({ left: inputOffset.left + 'px', top: (inputOffset.top + $(this).outerHeight()) + 'px' }).show(); }); // 点击其他地方隐藏树形菜单 $(document).on('click', function(e) { if (!$(e.target).is('#treeInput') && !$(e.target).is('#treeSelect')) { $('#treeSelect').hide(); } }); }); ``` 在上面的代码中,我们使用 layuitree 组件来渲染树形菜单,通过点击树节点将节点名称赋值给 input 标签,并隐藏树形菜单。点击 input 标签时,树形菜单会显示在 input 下方,点击其他地方则会隐藏树形菜单。 请注意,这只是一个简单示例,您可能需要根据实际需求进行进一步的定制和调整。希望对您有帮助!如果您还有任何问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值