Skip to content

Commit 9d995e7

Browse files
authored
Merge pull request #1 from blackWins/blackWins-change
optimize UI performance
2 parents f3fad16 + b5f3164 commit 9d995e7

File tree

2 files changed

+148
-127
lines changed

2 files changed

+148
-127
lines changed

README.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
# select2tree
22
extend select2 for treeview. 扩展select2,使它可以树形展示,可以缩放。
33

4-
<a href="http://runjs.cn/detail/bezljwvl" target="_blank">See demo</a>
5-
64
# 使用方法
75
* 与select2用法一致,只是在使用时$('select').select2()变成了$('select').select2tree()。
86
* option标签中指定parent属性即可实现树形展示,支持数据源乱序,展示下拉选项时将自动排序。
@@ -14,8 +12,8 @@ This is plugin for tree representation select2's dropdown. It allows any levels
1412
Parent option should be referenced in children via ``parent`` attribute. You should set it like parent's ``value`` attribute - ``parent="parent_value_attribute"``.
1513

1614
### Example
15+
![image](https://github.com/blackWins/select2tree/assets/34080651/93299959-bcad-436d-a781-b0a1e9d11a38)
1716

18-
[Look at demo](http://runjs.cn/detail/bezljwvl)
1917

2018
This files are required for correct working:
2119
```
@@ -56,8 +54,6 @@ If you want to apply some values at the begining, use select2's event triggering
5654

5755
### Пример использования
5856

59-
[Посмотреть демо](http://runjs.cn/detail/bezljwvl)
60-
6157
Минимально необходимые файлы для работы плагина:
6258

6359
```

select2tree.js

Lines changed: 147 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -1,130 +1,155 @@
1-
(function($) {
2-
$.fn.select2tree = function(options) {
3-
var defaults = {
4-
language: "zh-CN",
5-
theme: "bootstrap"
6-
};
7-
var opts = $.extend(defaults, options);
8-
opts.templateResult = function(data, container) {
9-
if(data.element) {
10-
//insert span element and add 'parent' property
11-
var $wrapper = $("<span></span><span>" + data.text + "</span>");
12-
var $element = $(data.element);
13-
$(container).attr("val", $element.val())
14-
if($element.attr("parent")) {
15-
$(container).attr("parent", $element.attr("parent"));
16-
}
17-
return $wrapper;
18-
} else {
19-
return data.text;
20-
}
21-
};
22-
23-
$(this).select2(opts).on("select2:open", open);
24-
};
1+
(function ($) {
252

26-
function moveOption(id) {
27-
if(id) {
28-
$(".select2-results__options li[parent=" + id + "]").insertAfter(".select2-results__options li[val=" + id + "]");
29-
$(".select2-results__options li[parent=" + id + "]").each(function() {
30-
moveOption($(this).attr("val"));
31-
});
32-
} else {
33-
$(".select2-results__options li:not([parent])").appendTo(".select2-results__options ul");
34-
$(".select2-results__options li:not([parent])").each(function() {
35-
moveOption($(this).attr("val"));
36-
});
37-
}
38-
}
3+
let icon = {
4+
type: "fa",
5+
expand: "fa-chevron-right",
6+
collapse: "fa-chevron-down"
7+
};
398

40-
//deal switch action
41-
function switchAction(id, open) {
42-
$(".select2-results__options li[parent='" + id + "']").each(function() {
43-
switchAction($(this).attr("val"), open);
44-
});
45-
if(open) {
46-
$(".select2-results__options li[val=" + id + "] span[class]:eq(0)").removeClass("glyphicon-chevron-right").addClass("glyphicon-chevron-down");
47-
$(".select2-results__options li[parent='" + id + "']").slideDown();
48-
} else {
49-
$(".select2-results__options li[val=" + id + "] span[class]:eq(0)").addClass("glyphicon-chevron-right").removeClass("glyphicon-chevron-down");
50-
$(".select2-results__options li[parent='" + id + "']").slideUp();
51-
}
52-
}
9+
$.fn.select2tree = function (options) {
10+
var defaults = { language: "zh-CN", theme: "bootstrap" };
11+
var opts = $.extend(defaults, options);
12+
opts.templateResult = templateResult;
13+
opts.templateSelection = templateSelection;
14+
$(this).select2(opts).on("select2:open", open);
15+
};
5316

54-
//get the level of li
55-
function getLevel(id) {
56-
var level = 0;
57-
while($(".select2-results__options li[parent][val='" + id + "']").length > 0) {
58-
id = $(".select2-results__options li[val='" + id + "']").attr("parent");
59-
level++;
60-
}
61-
return level;
62-
}
17+
function templateSelection(selection, $this) {
18+
var selectid = $this[0].id.split('-').slice(1, -1).join('-');
19+
var v = $('#' + selectid).val(), arr = [];
20+
if (v == '' || v == null || !v || v.indexOf(',') > 0) return selection.text;
21+
do {
22+
var node = $('#' + selectid + ' option[value=' + v + ']');
23+
if (node.length != 1) {
24+
break;
25+
}
26+
v = node.attr('parent');
27+
arr.push(node.text());
28+
} while (true)
29+
return arr.length == 0 ? selection.text : arr.reverse().join('/ ');
30+
}
6331

64-
function open() {
65-
setTimeout(function() {
66-
moveOption();
32+
function templateResult(data, container) {
33+
if (data.element) {
34+
//insert span element and add 'parent' property
35+
var $wrapper = $("<span style='width: 16px;height: 16px;'></span><span>" + data.text + "</span>");
36+
var $element = $(data.element);
37+
$(container).attr("val", $element.val())
38+
if ($element.attr("parent")) {
39+
$(container).attr("parent", $element.attr("parent"));
40+
}
41+
return $wrapper;
42+
} else {
43+
return data.text;
44+
}
45+
}
6746

68-
$(".select2-results__options li").each(function() {
69-
var $this = $(this);
70-
//loop li add some classes and properties
71-
if($this.attr("parent")) {
72-
$(this).siblings("li[val=" + $this.attr("parent") + "]").find("span:eq(0)").addClass("glyphicon glyphicon-chevron-down switch").css({
73-
"padding": "0 10px",
74-
"cursor": "default"
75-
});
76-
$(this).siblings("li[val=" + $this.attr("parent") + "]").find("span:eq(1)").css("font-weight", "bold");
77-
}
78-
//add gap for children
79-
// if(!$this.attr("style")) {
80-
// var paddingLeft = getLevel($this.attr("val")) * 2;
81-
// $("li[parent='" + $this.attr("parent") + "']").css("padding-left", paddingLeft + "em");
82-
// }
83-
if(!$this.attr("style")) {
84-
var paddingLeft = getLevel($this.attr("val")) * 2;
85-
$("li[parent='" + $this.attr("parent") + "']").css("padding-left", paddingLeft + "em").css("display","none");
86-
}
87-
});
47+
function processElements(selector, process) {
48+
$(selector).each(function () {
49+
process($(this));
50+
});
51+
}
8852

89-
//override mousedown for collapse/expand
90-
$(".switch").mousedown(function() {
91-
switchAction($(this).parent().attr("val"), $(this).hasClass("glyphicon-chevron-right"));
92-
event.stopPropagation();
93-
});
53+
function moveOption(id) {
54+
var selector = id ? ".select2-results__options li[parent=" + id + "]" : ".select2-results__options li:not([parent])";
55+
if (id) {
56+
$(selector).insertAfter(".select2-results__options li[val=" + id + "]");
57+
}
58+
else {
59+
$(selector).appendTo(".select2-results__options ul");
60+
}
61+
processElements(selector, function ($element) {
62+
moveOption($element.attr("val"));
63+
});
64+
}
65+
//deal switch action
66+
function switchAction(id, open) {
67+
var $target = $(".select2-results__options li[val=" + id + "]");
68+
if (open) {
69+
$target.find("span[class]:eq(0)").removeClass(icon.expand).addClass(icon.collapse);
70+
$(".select2-results__options li[parent='" + id + "']").slideDown();
71+
} else {
72+
$target.find("span[class]:eq(0)").removeClass(icon.collapse).addClass(icon.expand);
73+
$(".select2-results__options li[parent='" + id + "']").slideUp();
74+
processElements(".select2-results__options li[parent='" + id + "']", function ($element) {
75+
switchAction($element.attr("val"), open);
76+
});
77+
}
78+
}
79+
//get the level of li
80+
function getLevel(id) {
81+
var level = 0;
82+
var elements = $(".select2-results__options li[parent]");
83+
while (elements.filter("[val='" + id + "']").length > 0) {
84+
id = elements.filter("[val='" + id + "']").attr("parent");
85+
level++;
86+
}
87+
return level;
88+
}
9489

95-
//override mouseup to nothing
96-
$(".switch").mouseup(function() {
97-
return false;
98-
});
99-
100-
//Expand the selected values to radio mode only
101-
$(".select2-selection").off("mouseup");
102-
$(".select2-selection").mouseup(function () {
103-
var ariaowns = $(this).attr('aria-owns');
104-
if (!ariaowns || ariaowns == null) return;
105-
var selectid = ariaowns.split('-')[1];
106-
//get current value
107-
var val = $('#' + selectid).val();
108-
109-
if (val == '' || val == null || !val || val.indexOf(',') > 0) return;
110-
111-
var pval = [];
112-
do {
113-
var p = $('#' + selectid + ' option[value=' + val + ']').attr('parent');
114-
if (p == '' || !p)
115-
break;
116-
pval.push(p);
117-
val = p;
118-
} while (true)
119-
120-
if (pval.length > 0) {
121-
for (var i in pval.reverse()) {
122-
switchAction(pval[i], true);
123-
}
124-
}
125-
event.stopPropagation();
126-
});
127-
128-
}, 0);
129-
}
90+
function open(event) {
91+
setTimeout(function () {
92+
moveOption();
93+
setClass(event);
94+
//override mousedown for collapse/expand
95+
$(".switch").mousedown(switchMouseDown);
96+
//override mouseup to nothing
97+
$(".switch").mouseup(switchMouseUp);
98+
}, 0);
99+
}
100+
101+
function getSlideDownValues(id) {
102+
var v = $('#' + id).val(), arr = [];
103+
if (v == '' || v == null || !v || v.indexOf(',') > 0) return null;
104+
arr.push(v);
105+
do {
106+
var p = $('#' + id + ' option[value=' + v + ']').attr('parent');
107+
if (p == '' || !p) {
108+
break;
109+
}
110+
v = p;
111+
arr.push(p);
112+
} while (true)
113+
114+
return arr;
115+
}
116+
117+
function setClass(event) {
118+
var slideDownItems = getSlideDownValues(event.currentTarget.id);
119+
//loop li add some classes and properties
120+
$(".select2-results__options li").each(function () {
121+
var $this = $(this);
122+
var parent = $this.attr("parent");
123+
var close = slideDownItems
124+
&& $this.attr("parent")
125+
&& !(slideDownItems.indexOf($this.attr("val")) != -1 || slideDownItems.indexOf(parent) != -1);
126+
//add gap for children
127+
if (!$this.attr("style")) {
128+
var paddingLeft = getLevel($this.attr("val")) * 2;
129+
processElements("li[parent='" + parent + "']", function ($element) {
130+
$element.css({ "padding-left": paddingLeft + "em" });
131+
});
132+
}
133+
if (close) {
134+
$this.hide();
135+
}
136+
if (parent) {
137+
var $siblings = $this.siblings("li[val=" + parent + "]");
138+
$siblings.find("span:eq(0)").addClass(icon.type + " switch " + (close ? icon.expand : icon.collapse)).css({ "margin-right": "4px", "cursor": "default" });
139+
$siblings.find("span:eq(1)").css("font-weight", "bold");
140+
}
141+
else {
142+
143+
}
144+
});
145+
}
146+
147+
function switchMouseDown(event) {
148+
switchAction($(this).parent().attr("val"), $(this).hasClass(icon.expand));
149+
event.stopPropagation();
150+
}
151+
152+
function switchMouseUp() {
153+
return false;
154+
}
130155
})(jQuery);

0 commit comments

Comments
 (0)