diff --git a/README.md b/README.md index c6d67cd..dec1d5a 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ # select2tree extend select2 for treeview. 扩展select2,使它可以树形展示,可以缩放。 -See demo - # 使用方法 * 与select2用法一致,只是在使用时$('select').select2()变成了$('select').select2tree()。 * option标签中指定parent属性即可实现树形展示,支持数据源乱序,展示下拉选项时将自动排序。 @@ -14,8 +12,8 @@ This is plugin for tree representation select2's dropdown. It allows any levels Parent option should be referenced in children via ``parent`` attribute. You should set it like parent's ``value`` attribute - ``parent="parent_value_attribute"``. ### Example +![image](https://github.com/blackWins/select2tree/assets/34080651/93299959-bcad-436d-a781-b0a1e9d11a38) -[Look at demo](http://runjs.cn/detail/bezljwvl) This files are required for correct working: ``` @@ -56,8 +54,6 @@ If you want to apply some values at the begining, use select2's event triggering ### Пример использования -[Посмотреть демо](http://runjs.cn/detail/bezljwvl) - Минимально необходимые файлы для работы плагина: ``` diff --git a/package.json b/package.json new file mode 100644 index 0000000..be22e73 --- /dev/null +++ b/package.json @@ -0,0 +1,24 @@ +{ + "name": "select2tree", + "version": "1.0.0", + "description": "extend select2 for treeview", + "main": "select2tree.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/blackWins/select2tree.git" + }, + "keywords": [ + "select2tree", + "select2", + "tree" + ], + "author": "blackwinds", + "license": "ISC", + "bugs": { + "url": "https://github.com/blackWins/select2tree/issues" + }, + "homepage": "https://github.com/blackWins/select2tree#readme" +} diff --git a/select2tree.js b/select2tree.js index 5ee8d51..7ca6fe9 100644 --- a/select2tree.js +++ b/select2tree.js @@ -1,101 +1,155 @@ -(function($) { - $.fn.select2tree = function(options) { - var defaults = { - language: "zh-CN", - theme: "bootstrap" - }; - var opts = $.extend(defaults, options); - opts.templateResult = function(data, container) { - if(data.element) { - //insert span element and add 'parent' property - var $wrapper = $("" + data.text + ""); - var $element = $(data.element); - $(container).attr("val", $element.val()) - if($element.attr("parent")) { - $(container).attr("parent", $element.attr("parent")); - } - return $wrapper; - } else { - return data.text; - } - }; - - $(this).select2(opts).on("select2:open", open); - }; +(function ($) { - function moveOption(id) { - if(id) { - $(".select2-results__options li[parent=" + id + "]").insertAfter(".select2-results__options li[val=" + id + "]"); - $(".select2-results__options li[parent=" + id + "]").each(function() { - moveOption($(this).attr("val")); - }); - } else { - $(".select2-results__options li:not([parent])").appendTo(".select2-results__options ul"); - $(".select2-results__options li:not([parent])").each(function() { - moveOption($(this).attr("val")); - }); - } - } + let icon = { + type: "fa", + expand: "fa-chevron-right", + collapse: "fa-chevron-down" + }; - //deal switch action - function switchAction(id, open) { - $(".select2-results__options li[parent='" + id + "']").each(function() { - switchAction($(this).attr("val"), open); - }); - if(open) { - $(".select2-results__options li[val=" + id + "] span[class]:eq(0)").removeClass("glyphicon-chevron-right").addClass("glyphicon-chevron-down"); - $(".select2-results__options li[parent='" + id + "']").slideDown(); - } else { - $(".select2-results__options li[val=" + id + "] span[class]:eq(0)").addClass("glyphicon-chevron-right").removeClass("glyphicon-chevron-down"); - $(".select2-results__options li[parent='" + id + "']").slideUp(); - } - } + $.fn.select2tree = function (options) { + var defaults = { language: "zh-CN", theme: "bootstrap" }; + var opts = $.extend(defaults, options); + opts.templateResult = templateResult; + opts.templateSelection = templateSelection; + $(this).select2(opts).on("select2:open", open); + }; - //get the level of li - function getLevel(id) { - var level = 0; - while($(".select2-results__options li[parent][val='" + id + "']").length > 0) { - id = $(".select2-results__options li[val='" + id + "']").attr("parent"); - level++; - } - return level; - } + function templateSelection(selection, $this) { + var selectid = $this[0].id.split('-').slice(1, -1).join('-'); + var v = $('#' + selectid).val(), arr = []; + if (v == '' || v == null || !v || v.indexOf(',') > 0) return selection.text; + do { + var node = $('#' + selectid + ' option[value=' + v + ']'); + if (node.length != 1) { + break; + } + v = node.attr('parent'); + arr.push(node.text()); + } while (true) + return arr.length == 0 ? selection.text : arr.reverse().join('/ '); + } - function open() { - setTimeout(function() { - moveOption(); + function templateResult(data, container) { + if (data.element) { + //insert span element and add 'parent' property + var $wrapper = $("" + data.text + ""); + var $element = $(data.element); + $(container).attr("val", $element.val()) + if ($element.attr("parent")) { + $(container).attr("parent", $element.attr("parent")); + } + return $wrapper; + } else { + return data.text; + } + } - $(".select2-results__options li").each(function() { - var $this = $(this); - //loop li add some classes and properties - if($this.attr("parent")) { - $(this).siblings("li[val=" + $this.attr("parent") + "]").find("span:eq(0)").addClass("glyphicon glyphicon-chevron-down switch").css({ - "padding": "0 10px", - "cursor": "default" - }); - $(this).siblings("li[val=" + $this.attr("parent") + "]").find("span:eq(1)").css("font-weight", "bold"); - } - //add gap for children - // if(!$this.attr("style")) { - // var paddingLeft = getLevel($this.attr("val")) * 2; - // $("li[parent='" + $this.attr("parent") + "']").css("padding-left", paddingLeft + "em"); - // } - if(!$this.attr("style")) { - var paddingLeft = getLevel($this.attr("val")) * 2; - $("li[parent='" + $this.attr("parent") + "']").css("padding-left", paddingLeft + "em").css("display","none"); - } - }); + function processElements(selector, process) { + $(selector).each(function () { + process($(this)); + }); + } - //override mousedown for collapse/expand - $(".switch").mousedown(function() { - switchAction($(this).parent().attr("val"), $(this).hasClass("glyphicon-chevron-right")); - event.stopPropagation(); - }); + function moveOption(id) { + var selector = id ? ".select2-results__options li[parent=" + id + "]" : ".select2-results__options li:not([parent])"; + if (id) { + $(selector).insertAfter(".select2-results__options li[val=" + id + "]"); + } + else { + $(selector).appendTo(".select2-results__options ul"); + } + processElements(selector, function ($element) { + moveOption($element.attr("val")); + }); + } + //deal switch action + function switchAction(id, open) { + var $target = $(".select2-results__options li[val=" + id + "]"); + if (open) { + $target.find("span[class]:eq(0)").removeClass(icon.expand).addClass(icon.collapse); + $(".select2-results__options li[parent='" + id + "']").slideDown(); + } else { + $target.find("span[class]:eq(0)").removeClass(icon.collapse).addClass(icon.expand); + $(".select2-results__options li[parent='" + id + "']").slideUp(); + processElements(".select2-results__options li[parent='" + id + "']", function ($element) { + switchAction($element.attr("val"), open); + }); + } + } + //get the level of li + function getLevel(id) { + var level = 0; + var elements = $(".select2-results__options li[parent]"); + while (elements.filter("[val='" + id + "']").length > 0) { + id = elements.filter("[val='" + id + "']").attr("parent"); + level++; + } + return level; + } - //override mouseup to nothing - $(".switch").mouseup(function() { - return false; - }); - }, 0); - } + function open(event) { + setTimeout(function () { + moveOption(); + setClass(event); + //override mousedown for collapse/expand + $(".switch").mousedown(switchMouseDown); + //override mouseup to nothing + $(".switch").mouseup(switchMouseUp); + }, 0); + } + + function getSlideDownValues(id) { + var v = $('#' + id).val(), arr = []; + if (v == '' || v == null || !v || v.indexOf(',') > 0) return null; + arr.push(v); + do { + var p = $('#' + id + ' option[value=' + v + ']').attr('parent'); + if (p == '' || !p) { + break; + } + v = p; + arr.push(p); + } while (true) + + return arr; + } + + function setClass(event) { + var slideDownItems = getSlideDownValues(event.currentTarget.id); + //loop li add some classes and properties + $(".select2-results__options li").each(function () { + var $this = $(this); + var parent = $this.attr("parent"); + var close = slideDownItems + && $this.attr("parent") + && !(slideDownItems.indexOf($this.attr("val")) != -1 || slideDownItems.indexOf(parent) != -1); + //add gap for children + if (!$this.attr("style")) { + var paddingLeft = getLevel($this.attr("val")) * 2; + processElements("li[parent='" + parent + "']", function ($element) { + $element.css({ "padding-left": paddingLeft + "em" }); + }); + } + if (close) { + $this.hide(); + } + if (parent) { + var $siblings = $this.siblings("li[val=" + parent + "]"); + $siblings.find("span:eq(0)").addClass(icon.type + " switch " + (close ? icon.expand : icon.collapse)).css({ "margin-right": "4px", "cursor": "default" }); + $siblings.find("span:eq(1)").css("font-weight", "bold"); + } + else { + + } + }); + } + + function switchMouseDown(event) { + switchAction($(this).parent().attr("val"), $(this).hasClass(icon.expand)); + event.stopPropagation(); + } + + function switchMouseUp() { + return false; + } })(jQuery);