django-fast-treenode 1.1.3__py3-none-any.whl → 2.0.0__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- {django_fast_treenode-1.1.3.dist-info → django_fast_treenode-2.0.0.dist-info}/METADATA +156 -46
- django_fast_treenode-2.0.0.dist-info/RECORD +41 -0
- {django_fast_treenode-1.1.3.dist-info → django_fast_treenode-2.0.0.dist-info}/WHEEL +1 -1
- treenode/__init__.py +0 -7
- treenode/admin.py +327 -82
- treenode/apps.py +20 -3
- treenode/cache.py +231 -0
- treenode/docs/Documentation +130 -54
- treenode/forms.py +75 -19
- treenode/managers.py +260 -48
- treenode/models/__init__.py +7 -0
- treenode/models/classproperty.py +24 -0
- treenode/models/closure.py +168 -0
- treenode/models/factory.py +71 -0
- treenode/models/proxy.py +650 -0
- treenode/static/treenode/css/tree_widget.css +62 -0
- treenode/static/treenode/css/treenode_admin.css +106 -0
- treenode/static/treenode/js/tree_widget.js +161 -0
- treenode/static/treenode/js/treenode_admin.js +171 -0
- treenode/templates/admin/export_success.html +26 -0
- treenode/templates/admin/tree_node_changelist.html +11 -0
- treenode/templates/admin/tree_node_export.html +27 -0
- treenode/templates/admin/tree_node_import.html +27 -0
- treenode/templates/widgets/tree_widget.css +23 -0
- treenode/templates/widgets/tree_widget.html +21 -0
- treenode/urls.py +34 -0
- treenode/utils/__init__.py +4 -0
- treenode/utils/base36.py +35 -0
- treenode/utils/exporter.py +141 -0
- treenode/utils/importer.py +296 -0
- treenode/version.py +11 -1
- treenode/views.py +102 -2
- treenode/widgets.py +49 -27
- django_fast_treenode-1.1.3.dist-info/RECORD +0 -33
- treenode/compat.py +0 -8
- treenode/factory.py +0 -68
- treenode/models.py +0 -668
- treenode/static/select2tree/.gitkeep +0 -1
- treenode/static/select2tree/select2tree.css +0 -176
- treenode/static/select2tree/select2tree.js +0 -181
- treenode/static/treenode/css/treenode.css +0 -85
- treenode/static/treenode/js/treenode.js +0 -201
- treenode/templates/widgets/.gitkeep +0 -1
- treenode/templates/widgets/attrs.html +0 -7
- treenode/templates/widgets/options.html +0 -1
- treenode/templates/widgets/select2tree.html +0 -22
- treenode/tests.py +0 -3
- {django_fast_treenode-1.1.3.dist-info → django_fast_treenode-2.0.0.dist-info}/LICENSE +0 -0
- {django_fast_treenode-1.1.3.dist-info → django_fast_treenode-2.0.0.dist-info}/top_level.txt +0 -0
- /treenode/{docs → templates/admin}/.gitkeep +0 -0
@@ -1,176 +0,0 @@
|
|
1
|
-
/*!
|
2
|
-
* Select2-to-Tree CSS 1.1.1
|
3
|
-
* https://github.com/clivezhg/select2-to-tree
|
4
|
-
*/
|
5
|
-
.s2-to-tree * {
|
6
|
-
box-sizing: border-box;
|
7
|
-
}
|
8
|
-
|
9
|
-
.s2-to-tree .select2-results__option.l1 {
|
10
|
-
margin-left: 1.0em;
|
11
|
-
font-size: 1em;
|
12
|
-
}
|
13
|
-
.s2-to-tree .select2-results__option.l2 {
|
14
|
-
margin-left: 1.8em;
|
15
|
-
font-size: 0.95em;
|
16
|
-
}
|
17
|
-
.s2-to-tree .select2-results__option.l3 {
|
18
|
-
margin-left: 2.6em;
|
19
|
-
font-size: 0.91em;
|
20
|
-
}
|
21
|
-
.s2-to-tree .select2-results__option.l4 {
|
22
|
-
margin-left: 3.4em;
|
23
|
-
font-size: 0.87em;
|
24
|
-
}
|
25
|
-
.s2-to-tree .select2-results__option.l5 {
|
26
|
-
margin-left: 4.2em;
|
27
|
-
font-size: 0.83em;
|
28
|
-
}
|
29
|
-
.s2-to-tree .select2-results__option.l6 {
|
30
|
-
margin-left: 4.9em;
|
31
|
-
font-size: 0.8em;
|
32
|
-
}
|
33
|
-
.s2-to-tree .select2-results__option.l7 {
|
34
|
-
margin-left: 5.7em;
|
35
|
-
font-size: 0.77em;
|
36
|
-
}
|
37
|
-
.s2-to-tree .select2-results__option.l8 {
|
38
|
-
margin-left: 6.4em;
|
39
|
-
font-size: 0.75em;
|
40
|
-
}
|
41
|
-
|
42
|
-
.s2-to-tree .select2-dropdown[dir*="rtl"] .select2-results__option.l1 {
|
43
|
-
margin-right: 1.0em;
|
44
|
-
}
|
45
|
-
.s2-to-tree .select2-dropdown[dir*="rtl"] .select2-results__option.l2 {
|
46
|
-
margin-right: 1.8em;
|
47
|
-
}
|
48
|
-
.s2-to-tree .select2-dropdown[dir*="rtl"] .select2-results__option.l3 {
|
49
|
-
margin-right: 2.6em;
|
50
|
-
}
|
51
|
-
.s2-to-tree .select2-dropdown[dir*="rtl"] .select2-results__option.l4 {
|
52
|
-
margin-right: 3.4em;
|
53
|
-
}
|
54
|
-
.s2-to-tree .select2-dropdown[dir*="rtl"] .select2-results__option.l5 {
|
55
|
-
margin-right: 4.2em;
|
56
|
-
}
|
57
|
-
.s2-to-tree .select2-dropdown[dir*="rtl"] .select2-results__option.l6 {
|
58
|
-
margin-right: 4.9em;
|
59
|
-
}
|
60
|
-
.s2-to-tree .select2-dropdown[dir*="rtl"] .select2-results__option.l7 {
|
61
|
-
margin-right: 5.7em;
|
62
|
-
}
|
63
|
-
.s2-to-tree .select2-dropdown[dir*="rtl"] .select2-results__option.l8 {
|
64
|
-
margin-right: 6.4em;
|
65
|
-
}
|
66
|
-
|
67
|
-
.s2-to-tree li.select2-results__option.non-leaf .expand-collapse:hover {
|
68
|
-
color: red !important;
|
69
|
-
cursor: pointer;
|
70
|
-
}
|
71
|
-
|
72
|
-
|
73
|
-
.s2-to-tree li.select2-results__option.non-leaf .expand-collapse:before { /* no :: in IE8 */
|
74
|
-
content: "+";
|
75
|
-
position: absolute;
|
76
|
-
display: inline-block;
|
77
|
-
width: 12px;
|
78
|
-
height: 12px;
|
79
|
-
border-radius: 2px;
|
80
|
-
line-height: 13px;
|
81
|
-
font-size: 12px;
|
82
|
-
font-weight: normal;
|
83
|
-
text-align: center;
|
84
|
-
vertical-align: top;
|
85
|
-
left: -0.55em;
|
86
|
-
top: 0.5em;
|
87
|
-
color: #FFFFFF;
|
88
|
-
background-color: #999999;
|
89
|
-
}
|
90
|
-
|
91
|
-
.a-leaf{
|
92
|
-
display: inline-block;
|
93
|
-
}
|
94
|
-
|
95
|
-
.a-leaf:before { /* no :: in IE8 */
|
96
|
-
content: "+";
|
97
|
-
position: absolute;
|
98
|
-
display: inline-block;
|
99
|
-
width: 12px;
|
100
|
-
height: 12px;
|
101
|
-
border-radius: 2px;
|
102
|
-
line-height: 13px;
|
103
|
-
font-size: 12px;
|
104
|
-
font-weight: normal;
|
105
|
-
text-align: center;
|
106
|
-
vertical-align: top;
|
107
|
-
left: -0.55em;
|
108
|
-
top: 0.5em;
|
109
|
-
color: #ffffff;
|
110
|
-
background-color: #dddddd;
|
111
|
-
}
|
112
|
-
|
113
|
-
.s2-to-tree .select2-dropdown[dir*="rtl"] li.select2-results__option.non-leaf .expand-collapse:before {
|
114
|
-
right: -0.55em;
|
115
|
-
}
|
116
|
-
.s2-to-tree li.select2-results__option.non-leaf.opened .expand-collapse:before {
|
117
|
-
content: "̶ ";
|
118
|
-
line-height: 11px;
|
119
|
-
font-size: 11px;
|
120
|
-
text-align: center;
|
121
|
-
vertical-align: top;
|
122
|
-
/*right: -0.6em;*/
|
123
|
-
}
|
124
|
-
|
125
|
-
.s2-to-tree .select2-results__option[aria-disabled="true"] .expand-collapse {
|
126
|
-
color: black;
|
127
|
-
}
|
128
|
-
|
129
|
-
.s2-to-tree .item-label {
|
130
|
-
display: inline-block;
|
131
|
-
margin-left: 0.5em;
|
132
|
-
padding: 3px;
|
133
|
-
width: calc(100% - 11px); /* IE8 will fit the content */
|
134
|
-
}
|
135
|
-
.s2-to-tree .select2-dropdown[dir*="rtl"] .item-label {
|
136
|
-
margin-right: 0.5em;
|
137
|
-
}
|
138
|
-
|
139
|
-
.s2-to-tree li.select2-results__option {
|
140
|
-
position: relative;
|
141
|
-
padding: 0px;
|
142
|
-
height: auto;
|
143
|
-
overflow-y: hidden;
|
144
|
-
}
|
145
|
-
|
146
|
-
.s2-to-tree li.select2-results__option[data-pup] {
|
147
|
-
display: none;
|
148
|
-
}
|
149
|
-
.s2-to-tree li.select2-results__option[data-pup].showme {
|
150
|
-
display: block;
|
151
|
-
overflow-y: visible;
|
152
|
-
}
|
153
|
-
|
154
|
-
.s2-to-tree.select2-container .select2-results__option--highlighted[aria-selected] > span.item-label {
|
155
|
-
background-color: #5897fb;
|
156
|
-
color: white;
|
157
|
-
}
|
158
|
-
.s2-to-tree.select2-container li.select2-results__option[aria-selected="true"] > span.item-label {
|
159
|
-
background-color: #ddd;
|
160
|
-
}
|
161
|
-
|
162
|
-
.s2-to-tree.select2-container li.select2-results__option--highlighted[aria-selected],
|
163
|
-
.s2-to-tree.select2-container li.select2-results__option[aria-selected="true"] {
|
164
|
-
background-color: inherit;
|
165
|
-
color: inherit;
|
166
|
-
}
|
167
|
-
|
168
|
-
.s2-to-tree li.select2-results__option.l1 {
|
169
|
-
display: block;
|
170
|
-
overflow-y: visible;
|
171
|
-
}
|
172
|
-
|
173
|
-
.s2-to-tree.searching-result li.select2-results__option {
|
174
|
-
height: auto;
|
175
|
-
display: block;
|
176
|
-
}
|
@@ -1,181 +0,0 @@
|
|
1
|
-
/*!
|
2
|
-
* Select2-to-Tree 1.1.1
|
3
|
-
* https://github.com/clivezhg/select2-to-tree
|
4
|
-
*/
|
5
|
-
window.addEventListener("load", function() {
|
6
|
-
(function ($) {
|
7
|
-
$.fn.select2ToTree = function (options) {
|
8
|
-
var opts = $.extend({}, options);
|
9
|
-
|
10
|
-
if (opts.treeData) {
|
11
|
-
buildSelect(opts.treeData, this);
|
12
|
-
}
|
13
|
-
|
14
|
-
opts._templateResult = opts.templateResult;
|
15
|
-
opts.templateResult = function (data, container) {
|
16
|
-
var label = data.text;
|
17
|
-
if (typeof opts._templateResult === "function") {
|
18
|
-
label = opts._templateResult(data, container);
|
19
|
-
}
|
20
|
-
var $iteme = $("<span class='item-label'></span>").append(label);
|
21
|
-
if (data.element) {
|
22
|
-
var ele = data.element;
|
23
|
-
container.setAttribute("data-val", ele.value);
|
24
|
-
if (ele.className) container.className += " " + ele.className;
|
25
|
-
if (ele.getAttribute("data-pup")) {
|
26
|
-
container.setAttribute("data-pup", ele.getAttribute("data-pup"));
|
27
|
-
}
|
28
|
-
if ($(container).hasClass("non-leaf")) {
|
29
|
-
return $.merge($('<span class="expand-collapse" onmouseup="expColMouseupHandler(event);"></span>'), $iteme);
|
30
|
-
}
|
31
|
-
else {
|
32
|
-
return $.merge($('<span class="a-leaf"></span>'), $iteme);
|
33
|
-
}
|
34
|
-
}
|
35
|
-
return $iteme;
|
36
|
-
};
|
37
|
-
|
38
|
-
window.expColMouseupHandler = function (evt) {
|
39
|
-
toggleSubOptions(evt.target || evt.srcElement);
|
40
|
-
/* prevent Select2 from doing "select2:selecting","select2:unselecting","select2:closing" */
|
41
|
-
evt.stopPropagation ? evt.stopPropagation() : evt.cancelBubble = true;
|
42
|
-
evt.preventDefault ? evt.preventDefault() : evt.returnValue = false;
|
43
|
-
}
|
44
|
-
|
45
|
-
var s2inst = this.select2(opts);
|
46
|
-
|
47
|
-
s2inst.on("select2:open", function (evt) {
|
48
|
-
var s2data = s2inst.data("select2");
|
49
|
-
s2data.$dropdown.addClass("s2-to-tree");
|
50
|
-
s2data.$dropdown.removeClass("searching-result");
|
51
|
-
var $allsch = s2data.$dropdown.find(".select2-search__field").add(
|
52
|
-
s2data.$container.find(".select2-search__field")
|
53
|
-
);
|
54
|
-
$allsch.off("input", inputHandler);
|
55
|
-
$allsch.on("input", inputHandler);
|
56
|
-
});
|
57
|
-
|
58
|
-
/* Show search result options even if they are collapsed */
|
59
|
-
function inputHandler(evt) {
|
60
|
-
var s2data = s2inst.data("select2");
|
61
|
-
if ($(this).val().trim().length > 0) {
|
62
|
-
s2data.$dropdown.addClass("searching-result");
|
63
|
-
}
|
64
|
-
else {
|
65
|
-
s2data.$dropdown.removeClass("searching-result");
|
66
|
-
}
|
67
|
-
}
|
68
|
-
|
69
|
-
return s2inst;
|
70
|
-
};
|
71
|
-
|
72
|
-
/* Build the Select Option elements */
|
73
|
-
function buildSelect(treeData, $el) {
|
74
|
-
|
75
|
-
/* Support the object path (eg: `item.label`) for 'valFld' & 'labelFld' */
|
76
|
-
function readPath(object, path) {
|
77
|
-
var currentPosition = object;
|
78
|
-
for (var j = 0; j < path.length; j++) {
|
79
|
-
var currentPath = path[j];
|
80
|
-
if (currentPosition[currentPath]) {
|
81
|
-
currentPosition = currentPosition[currentPath];
|
82
|
-
continue;
|
83
|
-
}
|
84
|
-
return 'MISSING';
|
85
|
-
}
|
86
|
-
return currentPosition;
|
87
|
-
}
|
88
|
-
|
89
|
-
function buildOptions(dataArr, curLevel, pup) {
|
90
|
-
var labelPath;
|
91
|
-
if (treeData.labelFld && treeData.labelFld.split('.').length> 1){
|
92
|
-
labelPath = treeData.labelFld.split('.');
|
93
|
-
}
|
94
|
-
var idPath;
|
95
|
-
if (treeData.valFld && treeData.valFld.split('.').length > 1) {
|
96
|
-
idPath = treeData.valFld.split('.');
|
97
|
-
}
|
98
|
-
|
99
|
-
for (var i = 0; i < dataArr.length; i++) {
|
100
|
-
var data = dataArr[i] || {};
|
101
|
-
var $opt = $("<option></option>");
|
102
|
-
if (labelPath) {
|
103
|
-
$opt.text(readPath(data, labelPath));
|
104
|
-
} else {
|
105
|
-
$opt.text(data[treeData.labelFld || "text"]);
|
106
|
-
}
|
107
|
-
if (idPath) {
|
108
|
-
$opt.val(readPath(data, idPath));
|
109
|
-
} else {
|
110
|
-
$opt.val(data[treeData.valFld || "id"]);
|
111
|
-
}
|
112
|
-
if (data[treeData.selFld || "selected"] && String(data[treeData.selFld || "selected"]) === "true") {
|
113
|
-
$opt.prop("selected", data[treeData.selFld || "selected"]);
|
114
|
-
}
|
115
|
-
if($opt.val() === "") {
|
116
|
-
$opt.prop("disabled", true);
|
117
|
-
$opt.val(getUniqueValue());
|
118
|
-
}
|
119
|
-
$opt.addClass("l" + curLevel);
|
120
|
-
if (pup) $opt.attr("data-pup", pup);
|
121
|
-
$el.append($opt);
|
122
|
-
var inc = data[treeData.incFld || "inc"];
|
123
|
-
if (inc && inc.length > 0) {
|
124
|
-
$opt.addClass("non-leaf");
|
125
|
-
buildOptions(inc, curLevel+1, $opt.val());
|
126
|
-
}
|
127
|
-
} // end 'for'
|
128
|
-
} // end 'buildOptions'
|
129
|
-
|
130
|
-
buildOptions(treeData.dataArr, 1, "");
|
131
|
-
if (treeData.dftVal) $el.val(treeData.dftVal);
|
132
|
-
}
|
133
|
-
|
134
|
-
var uniqueIdx = 1;
|
135
|
-
function getUniqueValue() {
|
136
|
-
return "autoUniqueVal_" + uniqueIdx++;
|
137
|
-
}
|
138
|
-
|
139
|
-
function toggleSubOptions(target) {
|
140
|
-
$(target.parentNode).toggleClass("opened");
|
141
|
-
showHideSub(target.parentNode);
|
142
|
-
}
|
143
|
-
|
144
|
-
function escapeAttributeValue(value) {
|
145
|
-
if (!value.includes("\\'") && !value.includes('\\\\')) {
|
146
|
-
value = value.replace(/'/g, "\\'").replace(/\\/g, '\\\\');
|
147
|
-
}
|
148
|
-
return value;
|
149
|
-
}
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
function showHideSub(ele) {
|
154
|
-
var curEle = ele;
|
155
|
-
var $options = $(ele).parent(".select2-results__options");
|
156
|
-
var shouldShow = true;
|
157
|
-
do {
|
158
|
-
var pup = escapeAttributeValue($(curEle).attr("data-pup") || "");
|
159
|
-
curEle = null;
|
160
|
-
if (pup) {
|
161
|
-
var pupEle = $options.find(".select2-results__option[data-val='" + pup + "']");
|
162
|
-
if (pupEle.length > 0) {
|
163
|
-
if (!pupEle.eq(0).hasClass("opened")) {
|
164
|
-
$(ele).removeClass("showme");
|
165
|
-
shouldShow = false;
|
166
|
-
break;
|
167
|
-
}
|
168
|
-
curEle = pupEle[0];
|
169
|
-
}
|
170
|
-
}
|
171
|
-
} while (curEle);
|
172
|
-
if (shouldShow) $(ele).addClass("showme");
|
173
|
-
|
174
|
-
var val = escapeAttributeValue($(ele).attr("data-val") || "");
|
175
|
-
$options.find(".select2-results__option[data-pup='" + val + "']").each(function () {
|
176
|
-
showHideSub(this);
|
177
|
-
});
|
178
|
-
}
|
179
|
-
|
180
|
-
})(django.jQuery);
|
181
|
-
});
|
@@ -1,85 +0,0 @@
|
|
1
|
-
.treenode {
|
2
|
-
white-space: nowrap;
|
3
|
-
font-weight: bold;
|
4
|
-
margin-left: 2px;
|
5
|
-
}
|
6
|
-
|
7
|
-
a > .treenode {
|
8
|
-
margin-left: 0px;
|
9
|
-
}
|
10
|
-
|
11
|
-
.treenode-row {
|
12
|
-
white-space: nowrap;
|
13
|
-
}
|
14
|
-
|
15
|
-
.treenode-indentation {
|
16
|
-
font-weight: normal;
|
17
|
-
color: #999999;
|
18
|
-
display: inline-block;
|
19
|
-
margin-right: 5px;
|
20
|
-
}
|
21
|
-
|
22
|
-
.treenode-accordion .treenode-indentation {
|
23
|
-
display: none;
|
24
|
-
}
|
25
|
-
|
26
|
-
.treenode-accordion .treenode-accordion-button {
|
27
|
-
width: 11px;
|
28
|
-
height: 11px;
|
29
|
-
display: inline-block;
|
30
|
-
position: relative;
|
31
|
-
background-color: #999999;
|
32
|
-
color: #FFFFFF;
|
33
|
-
border-radius: 2px;
|
34
|
-
margin-right: 10px;
|
35
|
-
margin-bottom: -2px;
|
36
|
-
}
|
37
|
-
|
38
|
-
.treenode-accordion .treenode-accordion-button .vertical-line,
|
39
|
-
.treenode-accordion .treenode-accordion-button .horizontal-line {
|
40
|
-
position: absolute;
|
41
|
-
background-color: #FFFFFF;
|
42
|
-
pointer-events: none;
|
43
|
-
}
|
44
|
-
|
45
|
-
.treenode-accordion .treenode-accordion-button .vertical-line {
|
46
|
-
top: 3px;
|
47
|
-
bottom: 3px;
|
48
|
-
width: 1px;
|
49
|
-
left: 5px;
|
50
|
-
}
|
51
|
-
|
52
|
-
.treenode-accordion .treenode-accordion-button .horizontal-line {
|
53
|
-
top: 5px;
|
54
|
-
left: 3px;
|
55
|
-
right: 3px;
|
56
|
-
height: 1px;
|
57
|
-
}
|
58
|
-
|
59
|
-
.treenode-accordion.treenode-no-depth .treenode-accordion-button {
|
60
|
-
pointer-events: none;
|
61
|
-
cursor: default;
|
62
|
-
opacity: 0.2;
|
63
|
-
}
|
64
|
-
|
65
|
-
.treenode-accordion.treenode-expanded .treenode-accordion-button .vertical-line {
|
66
|
-
display: none;
|
67
|
-
}
|
68
|
-
|
69
|
-
.treenode-accordion.treenode-hide {
|
70
|
-
display: none !important;
|
71
|
-
}
|
72
|
-
|
73
|
-
/*.treenode-accordion.treenode-hide:not(.treenode-root) {
|
74
|
-
display: none !important;
|
75
|
-
}*/
|
76
|
-
|
77
|
-
.treenode-breadcrumbs {
|
78
|
-
font-weight: normal;
|
79
|
-
color: #888888;
|
80
|
-
}
|
81
|
-
|
82
|
-
.treenode-breadcrumbs:after {
|
83
|
-
content: " / ";
|
84
|
-
color: #CCCCCC;
|
85
|
-
}
|
@@ -1,201 +0,0 @@
|
|
1
|
-
/** global: django */
|
2
|
-
|
3
|
-
(function($) {
|
4
|
-
|
5
|
-
$(document).ready(function()
|
6
|
-
{
|
7
|
-
var rowsExpandedDataKeyPrefix = 'treenode_admin_accordion_state_for';
|
8
|
-
var rowsExpandedDataKeySuffix = '';
|
9
|
-
var rowsExpandedDataKey = '';
|
10
|
-
var rowsExpandedDataSep = ',';
|
11
|
-
|
12
|
-
function loadAccordionExpandedRows()
|
13
|
-
{
|
14
|
-
// TODO: add option to expand all on load
|
15
|
-
var rowEl;
|
16
|
-
var rowSel;
|
17
|
-
var rowsExpandedData = (localStorage.getItem(rowsExpandedDataKey) || '');
|
18
|
-
var rowsExpanded = rowsExpandedData.split(rowsExpandedDataSep);
|
19
|
-
for (var i = 0, j = rowsExpanded.length; i < j; i++) {
|
20
|
-
rowSel = '.treenode-accordion[data-treenode-pk="' + rowsExpanded[i] + '"]';
|
21
|
-
rowEl = $(rowSel);
|
22
|
-
rowEl.addClass('treenode-expanded');
|
23
|
-
rowEl.trigger('treenode-expand');
|
24
|
-
}
|
25
|
-
}
|
26
|
-
|
27
|
-
function saveAccordionExpandedRows()
|
28
|
-
{
|
29
|
-
var rowPk;
|
30
|
-
var rowsExpanded = [];
|
31
|
-
$('.treenode-accordion.treenode-expanded').each(function(){
|
32
|
-
rowPk = $(this).attr('data-treenode-pk');
|
33
|
-
rowsExpanded.push(rowPk);
|
34
|
-
});
|
35
|
-
var rowsExpandedData = rowsExpanded.join(rowsExpandedDataSep);
|
36
|
-
localStorage.setItem(rowsExpandedDataKey, rowsExpandedData);
|
37
|
-
}
|
38
|
-
|
39
|
-
function updateAccordionEvenOddRows()
|
40
|
-
{
|
41
|
-
$('.treenode-accordion').not('.treenode-hide').each(function(index, element){
|
42
|
-
$(this).removeClass('row1');
|
43
|
-
$(this).removeClass('row2');
|
44
|
-
// update rows even/odd class
|
45
|
-
if ((index % 2) === 0) {
|
46
|
-
$(this).addClass('row1');
|
47
|
-
} else {
|
48
|
-
$(this).addClass('row2');
|
49
|
-
}
|
50
|
-
});
|
51
|
-
}
|
52
|
-
|
53
|
-
function expandAccordionRow(target)
|
54
|
-
{
|
55
|
-
var rowPk = target.attr('data-treenode-pk');
|
56
|
-
var rowSel = '[data-treenode-parent="' + rowPk + '"]';
|
57
|
-
var rowEl = $('.treenode-accordion').filter(rowSel);
|
58
|
-
if (!target.hasClass('treenode-hide')) {
|
59
|
-
rowEl.removeClass('treenode-hide');
|
60
|
-
}
|
61
|
-
rowEl.each(function(){
|
62
|
-
if ($(this).hasClass('treenode-expanded')) {
|
63
|
-
$(this).trigger('treenode-expand');
|
64
|
-
}
|
65
|
-
});
|
66
|
-
}
|
67
|
-
|
68
|
-
function collapseAccordionRow(target)
|
69
|
-
{
|
70
|
-
var rowPk = target.attr('data-treenode-pk');
|
71
|
-
var rowSel = '[data-treenode-parent="' + rowPk + '"]';
|
72
|
-
var rowEl = $('.treenode-accordion').filter(rowSel);
|
73
|
-
rowEl.addClass('treenode-hide');
|
74
|
-
rowEl.trigger('treenode-collapse');
|
75
|
-
}
|
76
|
-
|
77
|
-
function toggleAccordionRow(target)
|
78
|
-
{
|
79
|
-
if (target.hasClass('treenode-accordion')) {
|
80
|
-
if (target.hasClass('treenode-expanded')) {
|
81
|
-
target.removeClass('treenode-expanded');
|
82
|
-
target.trigger('treenode-collapse');
|
83
|
-
} else {
|
84
|
-
target.addClass('treenode-expanded');
|
85
|
-
target.trigger('treenode-expand');
|
86
|
-
}
|
87
|
-
|
88
|
-
updateAccordionEvenOddRows();
|
89
|
-
saveAccordionExpandedRows();
|
90
|
-
}
|
91
|
-
}
|
92
|
-
|
93
|
-
function init()
|
94
|
-
{
|
95
|
-
$('.treenode').each(function(){
|
96
|
-
|
97
|
-
var scope = $(this);
|
98
|
-
|
99
|
-
var rowType = scope.attr('data-treenode-type');
|
100
|
-
var rowPk = scope.attr('data-treenode-pk');
|
101
|
-
var rowAccordion = scope.attr('data-treenode-accordion');
|
102
|
-
var rowDepth = scope.attr('data-treenode-depth');
|
103
|
-
var rowLevel = scope.attr('data-treenode-level');
|
104
|
-
var rowParentPk = scope.attr('data-treenode-parent');
|
105
|
-
|
106
|
-
// add treenode attributes to row
|
107
|
-
var rowEl = scope.closest('tr');
|
108
|
-
rowEl.attr('data-treenode-type', rowType);
|
109
|
-
rowEl.attr('data-treenode-accordion', rowAccordion);
|
110
|
-
rowEl.attr('data-treenode-parent', rowParentPk);
|
111
|
-
rowEl.attr('data-treenode-level', rowLevel);
|
112
|
-
rowEl.attr('data-treenode-depth', rowDepth);
|
113
|
-
rowEl.attr('data-treenode-pk', rowPk);
|
114
|
-
|
115
|
-
// remove original attributes
|
116
|
-
scope.removeAttr('data-treenode-type');
|
117
|
-
scope.removeAttr('data-treenode-pk');
|
118
|
-
scope.removeAttr('data-treenode-accordion');
|
119
|
-
scope.removeAttr('data-treenode-depth');
|
120
|
-
scope.removeAttr('data-treenode-level');
|
121
|
-
scope.removeAttr('data-treenode-parent');
|
122
|
-
|
123
|
-
if (rowsExpandedDataKeySuffix === '') {
|
124
|
-
rowsExpandedDataKeySuffix = rowType;
|
125
|
-
}
|
126
|
-
|
127
|
-
if (rowsExpandedDataKey === '') {
|
128
|
-
rowsExpandedDataKey = String(rowsExpandedDataKeyPrefix + '_' + rowsExpandedDataKeySuffix);
|
129
|
-
}
|
130
|
-
|
131
|
-
rowAccordion = Boolean(parseInt(rowAccordion, 10));
|
132
|
-
rowDepth = parseInt(rowDepth, 10);
|
133
|
-
|
134
|
-
rowEl.addClass('treenode-row');
|
135
|
-
|
136
|
-
if (rowAccordion) {
|
137
|
-
rowEl.addClass('treenode-accordion');
|
138
|
-
if (rowDepth === 0) {
|
139
|
-
rowEl.addClass('treenode-no-depth');
|
140
|
-
}
|
141
|
-
} else {
|
142
|
-
return;
|
143
|
-
}
|
144
|
-
|
145
|
-
rowEl.bind('treenode-expand', function(e){
|
146
|
-
e.preventDefault();
|
147
|
-
expandAccordionRow(rowEl);
|
148
|
-
return false;
|
149
|
-
});
|
150
|
-
|
151
|
-
rowEl.bind('treenode-collapse', function(e){
|
152
|
-
e.preventDefault();
|
153
|
-
collapseAccordionRow(rowEl);
|
154
|
-
return false;
|
155
|
-
});
|
156
|
-
|
157
|
-
// create accordion button and move level tabs before it
|
158
|
-
var rowAnchor = scope.closest('a');
|
159
|
-
|
160
|
-
var rowToggleButtonHTML = '';
|
161
|
-
rowToggleButtonHTML += '<a class="treenode-accordion-button" href="#">';
|
162
|
-
rowToggleButtonHTML += '<span class="vertical-line"></span>';
|
163
|
-
rowToggleButtonHTML += '<span class="horizontal-line"></span>';
|
164
|
-
rowToggleButtonHTML += '</a>';
|
165
|
-
|
166
|
-
var rowToggleButtonEl = $(rowToggleButtonHTML);
|
167
|
-
rowToggleButtonEl.css('margin-left', (25 * (rowLevel - 1)));
|
168
|
-
rowToggleButtonEl.insertBefore(rowAnchor);
|
169
|
-
rowToggleButtonEl.click(function(e){
|
170
|
-
e.preventDefault();
|
171
|
-
toggleAccordionRow(rowEl);
|
172
|
-
return false;
|
173
|
-
});
|
174
|
-
|
175
|
-
// on init hide row if it has a parent
|
176
|
-
if (rowParentPk && rowParentPk !== '') {
|
177
|
-
rowEl.addClass('treenode-hide');
|
178
|
-
}
|
179
|
-
|
180
|
-
// $('.treenode-row').each(function(){
|
181
|
-
// var rowEl = $(this);
|
182
|
-
// var rowParentPk = rowEl.attr('data-treenode-parent');
|
183
|
-
// if (Boolean(rowParentPk)) {
|
184
|
-
// rowEl.addClass('treenode-hide');
|
185
|
-
// var rowParentSel = '[data-treenode-pk="' + rowParentPk + '"]';
|
186
|
-
// var rowParentEl = $('.treenode-row').filter(rowParentSel);
|
187
|
-
// if (rowParentEl.length == 0) {
|
188
|
-
// rowEl.addClass('treenode-root');
|
189
|
-
// }
|
190
|
-
// }
|
191
|
-
// });
|
192
|
-
});
|
193
|
-
}
|
194
|
-
|
195
|
-
init();
|
196
|
-
loadAccordionExpandedRows();
|
197
|
-
updateAccordionEvenOddRows();
|
198
|
-
saveAccordionExpandedRows();
|
199
|
-
});
|
200
|
-
|
201
|
-
}(django.jQuery || window.jQuery));
|
@@ -1 +0,0 @@
|
|
1
|
-
|
@@ -1 +0,0 @@
|
|
1
|
-
<option value="{{ widget.value }}" {% if widget.parent %}data-pup="{{widget.parent}}"{% endif %} class="l{% if widget.level %}{{widget.level}} {% if not widget.leaf %} non-leaf{% endif %}{% else %}1{% endif %}" {% include "django/forms/widgets/attrs.html" %}>{{ widget.label }}</option>
|
@@ -1,22 +0,0 @@
|
|
1
|
-
<select name="{{ widget.name }}"{% include "widgets/attrs.html" %}>
|
2
|
-
{% for group_name, group_choices, group_index in widget.optgroups %}
|
3
|
-
{% if group_name %}
|
4
|
-
<optgroup label="{{ group_name }}">
|
5
|
-
{% endif %}
|
6
|
-
{% for option in group_choices %}
|
7
|
-
{% include option.template_name with widget=option %}
|
8
|
-
{% endfor %}
|
9
|
-
{% if group_name %}
|
10
|
-
</optgroup>
|
11
|
-
{% endif %}
|
12
|
-
{% endfor %}
|
13
|
-
</select>
|
14
|
-
|
15
|
-
<script>
|
16
|
-
|
17
|
-
window.addEventListener("load", function() {
|
18
|
-
(function($) {
|
19
|
-
$("#id_{{ widget.name }}").select2ToTree();
|
20
|
-
})(django.jQuery);
|
21
|
-
});
|
22
|
-
</script>
|
treenode/tests.py
DELETED
File without changes
|
File without changes
|
File without changes
|