tail-select-rails 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Readme.md +2 -1
- data/app/assets/javascripts/tail.select.js +1567 -523
- data/app/assets/stylesheets/tail.select.css +383 -181
- metadata +2 -3
- data/app/assets/javascripts/tail.select.min.js +0 -11
@@ -1,603 +1,1647 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
1
|
+
/*
|
2
|
+
| tail.select - The vanilla solution to make your HTML select fields AWESOME!
|
3
|
+
| @file ./js/tail.select.js
|
4
|
+
| @author SamBrishes <sam@pytes.net>
|
5
|
+
| @version 0.5.16 - Beta
|
6
|
+
|
|
7
|
+
| @website https://github.com/pytesNET/tail.select
|
8
|
+
| @license X11 / MIT License
|
9
|
+
| @copyright Copyright © 2014 - 2019 SamBrishes, pytesNET <info@pytes.net>
|
10
10
|
*/
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
11
|
+
;(function(root, factory){
|
12
|
+
if(typeof define === "function" && define.amd){
|
13
|
+
define(function(){ return factory(root); });
|
14
|
+
} else if(typeof module === "object" && module.exports){
|
15
|
+
module.exports = factory(root);
|
16
|
+
} else {
|
17
|
+
if(typeof root.tail === "undefined"){
|
18
|
+
root.tail = {};
|
19
|
+
}
|
20
|
+
root.tail.select = factory(root);
|
21
|
+
|
22
|
+
// jQuery Support
|
23
|
+
if(typeof jQuery !== "undefined"){
|
24
|
+
jQuery.fn.tailselect = function(o){
|
25
|
+
var r = [], i;
|
26
|
+
this.each(function(){ if((i = tail.select(this, o)) !== false){ r.push(i); } });
|
27
|
+
return (r.length === 1)? r[0]: (r.length === 0)? false: r;
|
28
|
+
};
|
29
|
+
}
|
30
|
+
|
31
|
+
// MooTools Support
|
32
|
+
if(typeof MooTools !== "undefined"){
|
33
|
+
Element.implement({ tailselect: function(o){ return new tail.select(this, o); } });
|
34
|
+
}
|
35
|
+
}
|
36
|
+
}(window, function(root){
|
37
|
+
"use strict";
|
38
|
+
var w = root, d = root.document;
|
39
|
+
|
40
|
+
// Internal Helper Methods
|
41
|
+
function cHAS(el, name){
|
42
|
+
return (el && "classList" in el)? el.classList.contains(name): false;
|
43
|
+
}
|
44
|
+
function cADD(el, name){
|
45
|
+
return (el && "classList" in el)? el.classList.add(name): undefined;
|
46
|
+
}
|
47
|
+
function cREM(el, name){
|
48
|
+
return (el && "classList" in el)? el.classList.remove(name): undefined;
|
49
|
+
}
|
50
|
+
function trigger(el, event, opt){
|
51
|
+
if(CustomEvent && CustomEvent.name){
|
52
|
+
var ev = new CustomEvent(event, opt);
|
53
|
+
} else {
|
54
|
+
var ev = d.createEvent("CustomEvent");
|
55
|
+
ev.initCustomEvent(event, !!opt.bubbles, !!opt.cancelable, opt.detail);
|
56
|
+
}
|
57
|
+
return el.dispatchEvent(ev);
|
58
|
+
}
|
59
|
+
function clone(obj, rep){
|
60
|
+
if(typeof Object.assign === "function"){
|
61
|
+
return Object.assign({}, obj, rep || {});
|
62
|
+
}
|
63
|
+
var clone = Object.constructor();
|
64
|
+
for(var key in obj){
|
65
|
+
clone[key] = (key in rep)? rep[key]: obj[key];
|
66
|
+
}
|
67
|
+
return clone;
|
68
|
+
}
|
69
|
+
function create(tag, classes){
|
70
|
+
var r = d.createElement(tag);
|
71
|
+
r.className = (classes && classes.join)? classes.join(" "): classes || "";
|
72
|
+
return r;
|
73
|
+
}
|
74
|
+
|
75
|
+
/*
|
76
|
+
| SELECT CONSTRUCTOR
|
77
|
+
| @since 0.5.16 [0.3.0]
|
78
|
+
*/
|
79
|
+
var select = function(el, config){
|
80
|
+
el = (typeof el === "string")? d.querySelectorAll(el): el;
|
81
|
+
if(el instanceof NodeList || el instanceof HTMLCollection || el instanceof Array){
|
82
|
+
for(var _r = [], l = el.length, i = 0; i < l; i++){
|
83
|
+
_r.push(new select(el[i], clone(config, {})));
|
84
|
+
}
|
85
|
+
return (_r.length === 1)? _r[0]: ((_r.length === 0)? false: _r);
|
86
|
+
}
|
87
|
+
if(!(el instanceof Element) || !(this instanceof select)){
|
88
|
+
return !(el instanceof Element)? false: new select(el, config);
|
89
|
+
}
|
90
|
+
|
91
|
+
// Check Element
|
92
|
+
if(select.inst[el.getAttribute("data-tail-select")]){
|
93
|
+
return select.inst[el.getAttribute("data-tail-select")];
|
94
|
+
}
|
95
|
+
if(el.getAttribute("data-select")){
|
96
|
+
var test = JSON.parse(el.getAttribute("data-select").replace(/\'/g, '"'));
|
97
|
+
if(test instanceof Object){
|
98
|
+
config = clone(config, test); // This is a unofficial function ;3
|
99
|
+
}
|
100
|
+
}
|
101
|
+
|
102
|
+
// Get Element Options
|
103
|
+
var placeholder = el.getAttribute("placeholder") || el.getAttribute("data-placeholder"),
|
104
|
+
fb1 = "bindSourceSelect", fb2 = "sourceHide"; // Fallbacks
|
105
|
+
config = (config instanceof Object)? config: {};
|
106
|
+
config.multiple = ("multiple" in config)? config.multiple: el.multiple;
|
107
|
+
config.disabled = ("disabled" in config)? config.disabled: el.disabled;
|
108
|
+
config.placeholder = placeholder || config.placeholder || null;
|
109
|
+
config.width = (config.width === "auto")? el.offsetWidth + 50: config.width;
|
110
|
+
config.sourceBind = (fb1 in config)? config[fb1]: config.sourceBind || false;
|
111
|
+
config.sourceHide = (fb2 in config)? config[fb2]: config.sourceHide || true;
|
112
|
+
config.multiLimit = (config.multiLimit >= 0)? config.multiLimit: Infinity;
|
113
|
+
|
114
|
+
|
115
|
+
// Init Instance
|
116
|
+
this.e = el;
|
117
|
+
this.id = ++select.count;
|
118
|
+
this.con = clone(select.defaults, config);
|
119
|
+
this.events = {};
|
120
|
+
select.inst["tail-" + this.id] = this;
|
121
|
+
return this.init().bind();
|
122
|
+
}, options;
|
123
|
+
select.version = "0.5.16";
|
124
|
+
select.status = "beta";
|
125
|
+
select.count = 0;
|
126
|
+
select.inst = {};
|
127
|
+
|
128
|
+
/*
|
129
|
+
| STORAGE :: DEFAULT OPTIONS
|
130
|
+
*/
|
131
|
+
select.defaults = {
|
132
|
+
animate: true, // [0.3.0] Boolean
|
133
|
+
classNames: null, // [0.2.0] Boolean, String, Array, null
|
134
|
+
csvOutput: false, // [0.3.4] Boolean
|
135
|
+
csvSeparator: ",", // [0.3.4] String
|
136
|
+
descriptions: false, // [0.3.0] Boolean
|
137
|
+
deselect: false, // [0.3.0] Boolean
|
138
|
+
disabled: false, // [0.5.0] Boolean
|
139
|
+
height: 350, // [0.2.0] Integer, null
|
140
|
+
hideDisabled: false, // [0.3.0] Boolean
|
141
|
+
hideSelected: false, // [0.3.0] Boolean
|
142
|
+
items: {}, // [0.3.0] Object
|
143
|
+
locale: "en", // [0.5.0] String
|
144
|
+
linguisticRules: { // [0.5.9] Object
|
145
|
+
"е": "ё",
|
146
|
+
"a": "ä",
|
147
|
+
"o": "ö",
|
148
|
+
"u": "ü",
|
149
|
+
"ss": "ß"
|
150
|
+
},
|
151
|
+
multiple: false, // [0.2.0] Boolean
|
152
|
+
multiLimit: Infinity, // [0.3.0] Integer, Infinity
|
153
|
+
multiPinSelected: false, // [0.5.0] Boolean
|
154
|
+
multiContainer: false, // [0.3.0] Boolean, String
|
155
|
+
multiShowCount: true, // [0.3.0] Boolean
|
156
|
+
multiShowLimit: false, // [0.5.0] Boolean
|
157
|
+
multiSelectAll: false, // [0.4.0] Boolean
|
158
|
+
multiSelectGroup: true, // [0.4.0] Boolean
|
159
|
+
openAbove: null, // [0.3.0] Boolean, null
|
160
|
+
placeholder: null, // [0.2.0] String, null
|
161
|
+
search: false, // [0.3.0] Boolean
|
162
|
+
searchConfig: [ // [0.5.13] Array
|
163
|
+
"text", "value"
|
164
|
+
],
|
165
|
+
searchFocus: true, // [0.3.0] Boolean
|
166
|
+
searchMarked: true, // [0.3.0] Boolean
|
167
|
+
searchMinLength: 1, // [0.5.13] Integer
|
168
|
+
searchDisabled: true, // [0.5.5] Boolean
|
169
|
+
sortItems: false, // [0.3.0] String, Function, false
|
170
|
+
sortGroups: false, // [0.3.0] String, Function, false
|
171
|
+
sourceBind: false, // [0.5.0] Boolean
|
172
|
+
sourceHide: true, // [0.5.0] Boolean
|
173
|
+
startOpen: false, // [0.3.0] Boolean
|
174
|
+
stayOpen: false, // [0.3.0] Boolean
|
175
|
+
width: null, // [0.2.0] Integer, String, null
|
176
|
+
cbComplete: undefined, // [0.5.0] Function
|
177
|
+
cbEmpty: undefined, // [0.5.0] Function
|
178
|
+
cbLoopItem: undefined, // [0.4.0] Function
|
179
|
+
cbLoopGroup: undefined // [0.4.0] Function
|
180
|
+
};
|
181
|
+
|
182
|
+
/*
|
183
|
+
| STORAGE :: STRINGS
|
184
|
+
*/
|
185
|
+
select.strings = {
|
186
|
+
de: {
|
187
|
+
all: "Alle",
|
188
|
+
none: "Keine",
|
189
|
+
empty: "Keine Optionen verfügbar",
|
190
|
+
emptySearch: "Keine Optionen gefunden",
|
191
|
+
limit: "Keine weiteren Optionen wählbar",
|
192
|
+
placeholder: "Wähle eine Option...",
|
193
|
+
placeholderMulti: "Wähle bis zu :limit Optionen...",
|
194
|
+
search: "Tippen zum suchen",
|
195
|
+
disabled: "Dieses Feld ist deaktiviert"
|
196
|
+
},
|
197
|
+
en: {
|
198
|
+
all: "All",
|
199
|
+
none: "None",
|
200
|
+
empty: "No Options available",
|
201
|
+
emptySearch: "No Options found",
|
202
|
+
limit: "You can't select more Options",
|
203
|
+
placeholder: "Select an Option...",
|
204
|
+
placeholderMulti: "Select up to :limit Options...",
|
205
|
+
search: "Type in to search...",
|
206
|
+
disabled: "This Field is disabled"
|
207
|
+
},
|
208
|
+
es: {
|
209
|
+
all: "Todos",
|
210
|
+
none: "Ninguno",
|
211
|
+
empty: "No hay opciones disponibles",
|
212
|
+
emptySearch: "No se encontraron opciones",
|
213
|
+
limit: "No puedes seleccionar mas opciones",
|
214
|
+
placeholder: "Selecciona una opción...",
|
215
|
+
placeholderMulti: "Selecciona hasta :límite de opciones...",
|
216
|
+
search: "Escribe dentro para buscar...",
|
217
|
+
disabled: "Este campo esta deshabilitado"
|
218
|
+
},
|
219
|
+
fi: {
|
220
|
+
all: "Kaikki",
|
221
|
+
none: "Ei mitään",
|
222
|
+
empty: "Ei vaihtoehtoja",
|
223
|
+
emptySearch: "Etsimääsi vaihtoehtoa ei löytynyt",
|
224
|
+
limit: "Muita vaihtoehtoja ei voi valita",
|
225
|
+
placeholder: "Valitse...",
|
226
|
+
placeholderMulti: "Valitse maksimissaan :limit...",
|
227
|
+
search: "Hae tästä...",
|
228
|
+
disabled: "Kenttä on poissa käytöstä"
|
229
|
+
},
|
230
|
+
fr: {
|
231
|
+
all: "Tous",
|
232
|
+
none: "Aucun",
|
233
|
+
empty: "Aucune option disponible",
|
234
|
+
emptySearch: "Aucune option trouvée",
|
235
|
+
limit: "Aucune autre option sélectionnable",
|
236
|
+
placeholder: "Choisissez une option...",
|
237
|
+
placeholderMulti: "Choisissez jusqu'à :limit option(s)...",
|
238
|
+
search: "Rechercher...",
|
239
|
+
disabled: "Ce champs est désactivé"
|
240
|
+
},
|
241
|
+
it: {
|
242
|
+
all: "Tutti",
|
243
|
+
none: "Nessuno",
|
244
|
+
empty: "Nessuna voce disponibile",
|
245
|
+
emptySearch: "Nessuna voce trovata",
|
246
|
+
limit: "Non puoi selezionare più Voci",
|
247
|
+
placeholder: "Seleziona una Voce",
|
248
|
+
placeholderMulti: "Selezione limitata a :limit Voci...",
|
249
|
+
search: "Digita per cercare...",
|
250
|
+
disabled: "Questo Campo è disabilitato"
|
251
|
+
},
|
252
|
+
no: {
|
253
|
+
all: "Alle",
|
254
|
+
none: "Ingen",
|
255
|
+
empty: "Ingen valg tilgjengelig",
|
256
|
+
emptySearch: "Ingen valg funnet",
|
257
|
+
limit: "Du kan ikke velge flere",
|
258
|
+
placeholder: "Velg...",
|
259
|
+
placeholderMulti: "Velg opptil :limit...",
|
260
|
+
search: "Søk...",
|
261
|
+
disabled: "Dette feltet er deaktivert"
|
262
|
+
},
|
263
|
+
pt_BR: {
|
264
|
+
all: "Todas",
|
265
|
+
none: "Nenhuma",
|
266
|
+
empty: "Nenhuma opção disponível",
|
267
|
+
emptySearch: "Nenhuma opção encontrada",
|
268
|
+
limit: "Não é possível selecionar outra opção",
|
269
|
+
placeholder: "Escolha uma opção ...",
|
270
|
+
placeholderMulti: "Escolha até: :limit opção(ões) ...",
|
271
|
+
search: "Buscar ...",
|
272
|
+
disabled: "Campo desativado"
|
273
|
+
},
|
274
|
+
ru: {
|
275
|
+
all: "Все",
|
276
|
+
none: "Ничего",
|
277
|
+
empty: "Нет доступных вариантов",
|
278
|
+
emptySearch: "Ничего не найдено",
|
279
|
+
limit: "Вы не можете выбрать больше вариантов",
|
280
|
+
placeholder: "Выберите вариант...",
|
281
|
+
placeholderMulti: function(args){
|
282
|
+
var strings = ["варианта", "вариантов", "вариантов"], cases = [2, 0, 1, 1, 1, 2], num = args[":limit"];
|
283
|
+
var string = strings[(num%100 > 4 && num%100 < 20)? 2: cases[(num%10 < 5)? num%10: 5]];
|
284
|
+
return "Выбор до :limit " + string + " ...";
|
285
|
+
},
|
286
|
+
search: "Начните набирать для поиска ...",
|
287
|
+
disabled: "Поле отключено"
|
288
|
+
},
|
289
|
+
tr: {
|
290
|
+
all: "Tümü",
|
291
|
+
none: "Hiçbiri",
|
292
|
+
empty: "Seçenek yok",
|
293
|
+
emptySearch: "Seçenek bulunamadı",
|
294
|
+
limit: "Daha fazla Seçenek seçemezsiniz",
|
295
|
+
placeholder: "Bir Seçenek seçin...",
|
296
|
+
placeholderMulti: "En fazla :limit Seçenek seçin...",
|
297
|
+
search: "Aramak için yazın...",
|
298
|
+
disabled: "Bu Alan kullanılamaz"
|
299
|
+
},
|
300
|
+
modify: function(locale, id, string){
|
301
|
+
if(!(locale in this)){
|
302
|
+
return false;
|
303
|
+
}
|
304
|
+
if((id instanceof Object)){
|
305
|
+
for(var key in id){
|
306
|
+
this.modify(locale, key, id[key]);
|
307
|
+
}
|
49
308
|
} else {
|
50
|
-
|
309
|
+
this[locale][id] = (typeof string === "string")? string: this[locale][id];
|
310
|
+
}
|
311
|
+
return true;
|
312
|
+
},
|
313
|
+
register: function(locale, object){
|
314
|
+
if(typeof locale !== "string" || !(object instanceof Object)){
|
315
|
+
return false;
|
316
|
+
}
|
317
|
+
this[locale] = object;
|
318
|
+
return true;
|
319
|
+
}
|
320
|
+
};
|
321
|
+
|
322
|
+
/*
|
323
|
+
| TAIL.SELECT HANDLER
|
324
|
+
*/
|
325
|
+
select.prototype = {
|
326
|
+
/*
|
327
|
+
| INERNAL :: TRANSLATE
|
328
|
+
| @since 0.5.8 [0.5.8]
|
329
|
+
*/
|
330
|
+
_e: function(string, replace, def){
|
331
|
+
if(!(string in this.__)){
|
332
|
+
return (!def)? string: def;
|
51
333
|
}
|
52
334
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
335
|
+
var string = this.__[string];
|
336
|
+
if(typeof string === "function"){
|
337
|
+
string = string.call(this, replace);
|
338
|
+
}
|
339
|
+
if(typeof replace === "object"){
|
340
|
+
for(var key in replace){
|
341
|
+
string = string.replace(key, replace[key]);
|
342
|
+
}
|
343
|
+
}
|
344
|
+
return string;
|
345
|
+
},
|
346
|
+
|
347
|
+
/*
|
348
|
+
| INTERNAL :: INIT SELECT FIELD
|
349
|
+
| @since 0.5.13 [0.3.0]
|
350
|
+
*/
|
351
|
+
init: function(){
|
352
|
+
var self = this, classes = ["tail-select"], con = this.con,
|
353
|
+
regexp = /^[0-9.]+(?:cm|mm|in|px|pt|pc|em|ex|ch|rem|vw|vh|vmin|vmax|\%)$/i;
|
354
|
+
|
355
|
+
// Init ClassNames
|
356
|
+
var c = (con.classNames === true)? this.e.className: con.classNames;
|
357
|
+
classes.push((c && c.push)? c.join(" "): (c && c.split)? c: "no-classes");
|
358
|
+
if(con.hideSelected){ classes.push("hide-selected"); }
|
359
|
+
if(con.hideDisabled){ classes.push("hide-disabled"); }
|
360
|
+
if(con.multiLimit == 0){ classes.push("disabled"); }
|
361
|
+
if(con.multiple){ classes.push("multiple"); }
|
362
|
+
if(con.deselect){ classes.push("deselect"); }
|
363
|
+
if(con.disabled){ classes.push("disabled"); }
|
364
|
+
|
365
|
+
// Init Variables
|
366
|
+
this.__ = clone(select.strings.en, select.strings[con.locale] || {});
|
367
|
+
this._init = true;
|
368
|
+
this._query = false;
|
369
|
+
this.select = create("DIV", classes);
|
370
|
+
this.label = create("DIV", "select-label");
|
371
|
+
this.dropdown = create("DIV", "select-dropdown");
|
372
|
+
this.search = create("DIV", "dropdown-search");
|
373
|
+
this.csvInput = create("INPUT", "select-search");
|
374
|
+
|
375
|
+
// Build :: Select
|
376
|
+
if(this.e.getAttribute("tabindex") !== null){
|
377
|
+
this.select.setAttribute("tabindex", this.e.getAttribute("tabindex"));
|
378
|
+
} else {
|
379
|
+
this.select.setAttribute("tabindex", 0);
|
380
|
+
}
|
381
|
+
if(con.width && regexp.test(con.width)){
|
382
|
+
this.select.style.width = con.width;
|
383
|
+
} else if(con.width && !isNaN(parseFloat(con.width, 10))){
|
384
|
+
this.select.style.width = con.width + "px";
|
385
|
+
}
|
58
386
|
|
59
|
-
//
|
60
|
-
|
61
|
-
|
387
|
+
// Build :: Label
|
388
|
+
this.label.addEventListener("click", function(event){
|
389
|
+
self.toggle.call(self, self.con.animate);
|
62
390
|
});
|
391
|
+
this.select.appendChild(this.label);
|
63
392
|
|
64
|
-
//
|
65
|
-
|
66
|
-
|
67
|
-
}
|
393
|
+
// Build :: Dropdown
|
394
|
+
if(!isNaN(parseInt(con.height, 10))){
|
395
|
+
this.dropdown.style.maxHeight = parseInt(con.height, 10) + "px";
|
396
|
+
}
|
397
|
+
if(con.search){
|
398
|
+
this.search.innerHTML = '<input type="text" class="search-input" />';
|
399
|
+
this.search.children[0].placeholder = this._e("search");
|
400
|
+
this.search.children[0].addEventListener("input", function(event){
|
401
|
+
self.query.call(self, (this.value.length > con.searchMinLength)? this.value: undefined);
|
402
|
+
});
|
403
|
+
this.dropdown.appendChild(this.search);
|
404
|
+
}
|
405
|
+
this.select.appendChild(this.dropdown);
|
406
|
+
|
407
|
+
// Build :: CSV Input
|
408
|
+
this.csvInput.type = "hidden";
|
409
|
+
if(con.csvOutput){
|
410
|
+
this.csvInput.name = this.e.name;
|
411
|
+
this.e.removeAttribute("name");
|
412
|
+
this.select.appendChild(this.csvInput);
|
413
|
+
}
|
68
414
|
|
69
|
-
//
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
const toggleAllCheckbox = document.createElement("input");
|
80
|
-
toggleAllCheckbox.type = "checkbox";
|
81
|
-
toggleAllCheckbox.value = strings.all || "All";
|
82
|
-
toggleAllCheckbox.addEventListener("change", () =>
|
83
|
-
toggleAll(originalSelect, toggleAllCheckbox)
|
84
|
-
);
|
85
|
-
|
86
|
-
const toggleAllLabel = document.createElement("label");
|
87
|
-
toggleAllLabel.textContent = strings.all || "All";
|
88
|
-
toggleAllLabel.classList.add("all");
|
89
|
-
toggleAllLabel.appendChild(toggleAllCheckbox);
|
90
|
-
|
91
|
-
// Create uncheck-all button
|
92
|
-
const uncheckAllButton = document.createElement("button");
|
93
|
-
uncheckAllButton.type = 'button';
|
94
|
-
uncheckAllButton.textContent = strings.none || "None";
|
95
|
-
uncheckAllButton.classList.add("uncheck");
|
96
|
-
uncheckAllButton.addEventListener("click", () =>
|
97
|
-
uncheckAll(originalSelect)
|
98
|
-
);
|
99
|
-
|
100
|
-
if (opts.multiCounter) {
|
101
|
-
// Create counter
|
102
|
-
const counter = document.createElement("span");
|
103
|
-
counter.textContent = "0";
|
104
|
-
counter.classList.add("tail--counter");
|
105
|
-
|
106
|
-
customDropdown.appendChild(counter);
|
107
|
-
}
|
108
|
-
|
109
|
-
// Create nested list
|
110
|
-
const nestedList = document.createElement("div");
|
111
|
-
nestedList.classList.add("tail--nested-dropdown");
|
112
|
-
nestedList.style.display = "none"; // Initially hide the list
|
113
|
-
|
114
|
-
customDropdown.appendChild(searchInput);
|
115
|
-
customDropdown.appendChild(tailFloatingToolbar);
|
116
|
-
customDropdown.appendChild(nestedList);
|
117
|
-
|
118
|
-
tailFloatingToolbar.appendChild(toggleAllLabel);
|
119
|
-
tailFloatingToolbar.appendChild(uncheckAllButton);
|
120
|
-
|
121
|
-
// Insert custom dropdown after the original select
|
122
|
-
originalSelect.insertAdjacentElement("afterend", customDropdown);
|
123
|
-
|
124
|
-
// Create ul element for displaying selected options as pills
|
125
|
-
const selectedOptionsList = document.createElement("ul");
|
126
|
-
selectedOptionsList.classList.add("tail--selected-options-list");
|
127
|
-
|
128
|
-
if (opts.multiTags) {
|
129
|
-
if (originalSelect.multiple) {
|
130
|
-
// Insert selectedOptionsList as the next sibling of customDropdown
|
131
|
-
customDropdown.insertAdjacentElement(
|
132
|
-
"afterend",
|
133
|
-
selectedOptionsList
|
134
|
-
);
|
135
|
-
}
|
136
|
-
}
|
137
|
-
//
|
138
|
-
|
139
|
-
function buildNestedList() {
|
140
|
-
const fragment = document.createDocumentFragment();
|
141
|
-
|
142
|
-
const optgroups = originalSelect.getElementsByTagName(
|
143
|
-
"optgroup"
|
144
|
-
);
|
145
|
-
|
146
|
-
if (optgroups.length > 0) {
|
147
|
-
for (let i = 0; i < optgroups.length; i++) {
|
148
|
-
const optgroup = optgroups[i];
|
149
|
-
const optgroupItem = document.createElement("div");
|
150
|
-
optgroupItem.classList.add("tail--optgroup");
|
151
|
-
|
152
|
-
// Create label for optgroup
|
153
|
-
const optgroupLabel = document.createElement("label");
|
154
|
-
|
155
|
-
// Create checkbox for optgroup
|
156
|
-
const optgroupCheckbox = document.createElement(
|
157
|
-
"input"
|
158
|
-
);
|
159
|
-
optgroupCheckbox.type = "checkbox";
|
160
|
-
optgroupCheckbox.value = optgroup.label;
|
161
|
-
optgroupCheckbox.addEventListener("change", () =>
|
162
|
-
toggleOptgroup(optgroupCheckbox)
|
163
|
-
);
|
164
|
-
optgroupLabel.appendChild(optgroupCheckbox);
|
165
|
-
|
166
|
-
// Label text for optgroup
|
167
|
-
const optgroupLabelText = document.createElement(
|
168
|
-
"span"
|
169
|
-
);
|
170
|
-
optgroupLabelText.textContent = optgroup.label;
|
171
|
-
optgroupLabelText.classList.add("tail--optgroup-label");
|
172
|
-
optgroupLabel.appendChild(optgroupLabelText);
|
173
|
-
|
174
|
-
optgroupItem.appendChild(optgroupLabel);
|
175
|
-
|
176
|
-
// Nested options list
|
177
|
-
const nestedOptionsList = document.createElement("div");
|
178
|
-
|
179
|
-
// Add ARIA attributes to the nested options list
|
180
|
-
nestedOptionsList.setAttribute("role", "listbox");
|
181
|
-
nestedOptionsList.classList.add("tail--nested-dropdown-list");
|
182
|
-
const options = optgroup.getElementsByTagName("option");
|
183
|
-
|
184
|
-
for (let j = 0; j < options.length; j++) {
|
185
|
-
const option = options[j];
|
186
|
-
const optionItem = document.createElement("div");
|
187
|
-
optionItem.classList.add("tail--nested-dropdown-item");
|
188
|
-
|
189
|
-
// Create checkbox for option
|
190
|
-
const optionCheckbox = document.createElement(
|
191
|
-
"input"
|
192
|
-
);
|
193
|
-
optionCheckbox.type = "checkbox";
|
194
|
-
optionCheckbox.value = option.textContent;
|
195
|
-
|
196
|
-
// Create label for option
|
197
|
-
const optionLabel = document.createElement("label");
|
198
|
-
|
199
|
-
// Label for option text
|
200
|
-
const optionLabelText = document.createElement(
|
201
|
-
"span"
|
202
|
-
);
|
203
|
-
optionLabelText.textContent = option.textContent;
|
204
|
-
|
205
|
-
// Option description
|
206
|
-
if (option.dataset.description) {
|
207
|
-
optionLabelText.innerHTML += `<small>${option.dataset.description}</small>`;
|
208
|
-
}
|
209
|
-
|
210
|
-
// Check it
|
211
|
-
if (option.selected && option.hasAttribute('selected')) {
|
212
|
-
optionCheckbox.checked = true;
|
213
|
-
updateCounter(originalSelect);
|
214
|
-
updateCustomTextInput(originalSelect);
|
215
|
-
}
|
216
|
-
|
217
|
-
//
|
218
|
-
|
219
|
-
optionLabel.appendChild(optionCheckbox);
|
220
|
-
optionLabel.appendChild(optionLabelText);
|
221
|
-
|
222
|
-
optionItem.appendChild(optionLabel);
|
223
|
-
|
224
|
-
nestedOptionsList.appendChild(optionItem);
|
225
|
-
}
|
415
|
+
// Prepare Container
|
416
|
+
if(con.multiple && con.multiContainer){
|
417
|
+
if(d.querySelector(con.multiContainer)){
|
418
|
+
this.container = d.querySelector(con.multiContainer);
|
419
|
+
this.container.className += " tail-select-container";
|
420
|
+
} else if(con.multiContainer === true){
|
421
|
+
this.container = this.label;
|
422
|
+
this.container.className += " tail-select-container";
|
423
|
+
}
|
424
|
+
}
|
226
425
|
|
227
|
-
|
228
|
-
|
229
|
-
|
426
|
+
// Prepare Options
|
427
|
+
this.options = new options(this.e, this);
|
428
|
+
for(var l = this.e.options.length, i = 0; i < l; i++){
|
429
|
+
this.options.set(this.e.options[i], false);
|
430
|
+
}
|
431
|
+
for(var key in con.items){
|
432
|
+
if(typeof con.items[key] === "string"){
|
433
|
+
con.items[key] = {value: con.items[key]};
|
434
|
+
}
|
435
|
+
this.options.add(con.items[key].key || key, con.items[key].value,
|
436
|
+
con.items[key].group, con.items[key].selected,
|
437
|
+
con.items[key].disabled, con.items[key].description);
|
438
|
+
}
|
439
|
+
this.query();
|
440
|
+
|
441
|
+
// Append and Return
|
442
|
+
if(this.e.nextElementSibling){
|
443
|
+
this.e.parentElement.insertBefore(this.select, this.e.nextElementSibling);
|
444
|
+
} else {
|
445
|
+
this.e.parentElement.appendChild(this.select);
|
446
|
+
}
|
447
|
+
if(con.sourceHide){
|
448
|
+
if(this.e.style.display == "none"){
|
449
|
+
this.select.style.display = "none";
|
450
|
+
this.e.setAttribute("data-select-hidden", "display");
|
451
|
+
} else if(this.e.style.visibility == "hidden"){
|
452
|
+
this.select.style.visibiltiy = "hidden";
|
453
|
+
this.e.setAttribute("data-select-hidden", "visibility");
|
230
454
|
} else {
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
455
|
+
this.e.style.display = "none";
|
456
|
+
this.e.setAttribute("data-select-hidden", "0");
|
457
|
+
}
|
458
|
+
}
|
459
|
+
this.e.setAttribute("data-tail-select", "tail-" + this.id);
|
460
|
+
if(self.con.startOpen){
|
461
|
+
this.open(con.animate);
|
462
|
+
}
|
463
|
+
(con.cbComplete || function(){ }).call(this, this.select);
|
464
|
+
return (this._init = false)? this: this;
|
465
|
+
},
|
466
|
+
|
467
|
+
/*
|
468
|
+
| INTERNAL :: EVENT LISTENER
|
469
|
+
| @since 0.5.13 [0.3.0]
|
470
|
+
*/
|
471
|
+
bind: function(){
|
472
|
+
var self = this;
|
473
|
+
|
474
|
+
// Keys Listener
|
475
|
+
d.addEventListener("keydown", function(event){
|
476
|
+
var key = (event.keyCode || event.which), opt, inner, e, temp, tmp;
|
477
|
+
var space = (key == 32 && self.select === document.activeElement);
|
478
|
+
if(!space && (!cHAS(self.select, "active") || [13, 27, 38, 40].indexOf(key) < 0)){
|
479
|
+
return false;
|
480
|
+
}
|
481
|
+
event.preventDefault();
|
482
|
+
event.stopPropagation();
|
256
483
|
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
updateCustomTextInput(originalSelect);
|
262
|
-
}
|
263
|
-
//
|
484
|
+
// Space
|
485
|
+
if(key === 32){
|
486
|
+
return self.open(self.con.animate);
|
487
|
+
}
|
264
488
|
|
265
|
-
|
266
|
-
|
489
|
+
// Enter || Escape
|
490
|
+
if(key == 13){
|
491
|
+
if((opt = self.dropdown.querySelector(".dropdown-option.hover:not(.disabled)"))){
|
492
|
+
self.options.select.call(self.options, opt);
|
493
|
+
}
|
494
|
+
}
|
495
|
+
if(key == 27 || key == 13){
|
496
|
+
return self.close(self.con.animate);
|
497
|
+
}
|
267
498
|
|
268
|
-
|
499
|
+
// Top || Down
|
500
|
+
if((opt = self.dropdown.querySelector(".dropdown-option.hover:not(.disabled)"))){
|
501
|
+
cREM(opt, "hover"); e = [((key == 40)? "next": "previous") + "ElementSibling"];
|
502
|
+
do {
|
503
|
+
if((temp = opt[e]) !== null && opt.tagName == "LI"){
|
504
|
+
opt = temp;
|
505
|
+
} else if((temp = opt.parentElement[e]) !== null && temp.children.length > 0 && temp.tagName == "UL"){
|
506
|
+
opt = temp.children[(key == 40)? 0: temp.children.length-1];
|
507
|
+
} else {
|
508
|
+
opt = false;
|
509
|
+
}
|
510
|
+
if(opt && (!cHAS(opt, "dropdown-option") || cHAS(opt, "disabled"))){
|
511
|
+
continue;
|
512
|
+
}
|
513
|
+
break;
|
514
|
+
} while(true);
|
515
|
+
}
|
516
|
+
if(!opt && key == 40){
|
517
|
+
opt = self.dropdown.querySelector(".dropdown-option:not(.disabled)");
|
518
|
+
} else if(!opt && key == 38){
|
519
|
+
tmp = self.dropdown.querySelectorAll(".dropdown-option:not(.disabled)");
|
520
|
+
opt = tmp[tmp.length - 1];
|
521
|
+
}
|
522
|
+
if(opt && (inner = self.dropdown.querySelector(".dropdown-inner"))){
|
523
|
+
var pos = (function(el){
|
524
|
+
var _r = {top: el.offsetTop, height: el.offsetHeight};
|
525
|
+
while((el = el.parentElement) != inner){
|
526
|
+
_r.top += el.offsetTop;
|
527
|
+
}
|
528
|
+
return _r;
|
529
|
+
})(opt);
|
530
|
+
cADD(opt, "hover");
|
531
|
+
inner.scrollTop = Math.max(0, pos.top - (pos.height * 2));
|
532
|
+
}
|
533
|
+
return true;
|
534
|
+
});
|
535
|
+
|
536
|
+
// Close
|
537
|
+
d.addEventListener("click", function(ev){
|
538
|
+
if(!cHAS(self.select, "active") || cHAS(self.select, "idle")){ return false; }
|
539
|
+
if(self.con.stayOpen === true){ return false; }
|
269
540
|
|
270
|
-
|
541
|
+
var targets = [self.e, self.select, self.container];
|
542
|
+
for(var l = targets.length, i = 0; i < l; i++){
|
543
|
+
if(targets[i] && (targets[i].contains(ev.target) || targets[i] == ev.target)){
|
544
|
+
return false;
|
271
545
|
}
|
546
|
+
if(!ev.target.parentElement){ return false; }
|
272
547
|
}
|
548
|
+
return self.close.call(self, self.con.animate);
|
549
|
+
});
|
273
550
|
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
551
|
+
// Bind Source Select
|
552
|
+
if(!this.con.sourceBind){
|
553
|
+
return true;
|
554
|
+
}
|
555
|
+
this.e.addEventListener("change", function(event){
|
556
|
+
if(event.detail != undefined){
|
557
|
+
return false;
|
558
|
+
}
|
559
|
+
event.preventDefault();
|
560
|
+
event.stopPropagation();
|
561
|
+
if(!this.multiple && this.selectedIndex){
|
562
|
+
self.options.select.call(self.options, this.options[this.selectedIndex]);
|
563
|
+
} else {
|
564
|
+
var u = [].concat(self.options.selected);
|
565
|
+
var s = [].filter.call(this.querySelectorAll("option:checked"), function(item){
|
566
|
+
if(u.indexOf(item) >= 0){
|
567
|
+
u.splice(u.indexOf(item), 1);
|
568
|
+
return false;
|
569
|
+
}
|
570
|
+
return true;
|
571
|
+
});
|
572
|
+
self.options.walk.call(self.options, "unselect", u);
|
573
|
+
self.options.walk.call(self.options, "select", s);
|
574
|
+
}
|
575
|
+
});
|
576
|
+
return true;
|
577
|
+
},
|
578
|
+
|
579
|
+
/*
|
580
|
+
| INTERNAL :: INTERNAL CALLBACK
|
581
|
+
| @since 0.5.14 [0.3.0]
|
582
|
+
*/
|
583
|
+
callback: function(item, state, _force){
|
584
|
+
var rkey = item.key.replace(/('|\\)/g, "\\$1"),
|
585
|
+
rgrp = item.group.replace(/('|\\)/g, "\\$1"),
|
586
|
+
rsel = "[data-key='" + rkey + "'][data-group='" + rgrp + "']";
|
587
|
+
if(state == "rebuild"){ return this.query(); }
|
588
|
+
|
589
|
+
// Set Element-Item States
|
590
|
+
var element = this.dropdown.querySelector(rsel);
|
591
|
+
if(element && ["select", "disable"].indexOf(state) >= 0){
|
592
|
+
cADD(element, (state == "select"? "selected": "disabled"));
|
593
|
+
} else if(element && ["unselect", "enable"].indexOf(state) >= 0){
|
594
|
+
cREM(element, (state == "unselect"? "selected": "disabled"));
|
595
|
+
}
|
280
596
|
|
281
|
-
|
282
|
-
|
597
|
+
// Handle
|
598
|
+
this.update(item);
|
599
|
+
return (_force === true)? true: this.trigger("change", item, state);
|
600
|
+
},
|
601
|
+
|
602
|
+
/*
|
603
|
+
| INTERNAL :: TRIGGER EVENT HANDLER
|
604
|
+
| @since 0.5.2 [0.4.0]
|
605
|
+
*/
|
606
|
+
trigger: function(event){
|
607
|
+
if(this._init){ return false; }
|
608
|
+
var obj = {bubbles: false, cancelable: true, detail: {args: arguments, self: this}};
|
609
|
+
if(event == "change" && arguments[2] && arguments[2].indexOf("select") >= 0){
|
610
|
+
trigger(this.e, "input", obj);
|
611
|
+
trigger(this.e, "change", obj);
|
283
612
|
}
|
613
|
+
trigger(this.select, "tail::" + event, obj);
|
284
614
|
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
615
|
+
var args = [], pass;
|
616
|
+
Array.prototype.map.call(arguments, function(item, i){
|
617
|
+
if(i > 0){ args.push(item); }
|
618
|
+
});
|
619
|
+
(this.events[event] || []).forEach(function(item){
|
620
|
+
pass = [].concat(args);
|
621
|
+
pass.push(item.args || null);
|
622
|
+
(item.cb || function(){ }).apply(obj.detail.self, pass);
|
623
|
+
});
|
624
|
+
return true;
|
625
|
+
},
|
626
|
+
|
627
|
+
/*
|
628
|
+
| INTERNAL :: CALCULATE DROPDOWN
|
629
|
+
| @since 0.5.4 [0.5.0]
|
630
|
+
*/
|
631
|
+
calc: function(){
|
632
|
+
var clone = this.dropdown.cloneNode(true), height = this.con.height, search = 0,
|
633
|
+
inner = this.dropdown.querySelector(".dropdown-inner");
|
634
|
+
|
635
|
+
// Calculate Dropdown Height
|
636
|
+
clone = this.dropdown.cloneNode(true);
|
637
|
+
clone.style.cssText = "height:auto;min-height:auto;max-height:none;opacity:0;display:block;visibility:hidden;";
|
638
|
+
clone.style.maxHeight = this.con.height + "px";
|
639
|
+
clone.className += " cloned";
|
640
|
+
this.dropdown.parentElement.appendChild(clone);
|
641
|
+
height = (height > clone.clientHeight)? clone.clientHeight: height;
|
642
|
+
if(this.con.search){
|
643
|
+
search = clone.querySelector(".dropdown-search").clientHeight;
|
644
|
+
}
|
645
|
+
this.dropdown.parentElement.removeChild(clone);
|
646
|
+
|
647
|
+
// Calculate Viewport
|
648
|
+
var pos = this.select.getBoundingClientRect(),
|
649
|
+
bottom = w.innerHeight-(pos.top+pos.height),
|
650
|
+
view = ((height+search) > bottom)? pos.top > bottom: false;
|
651
|
+
if(this.con.openAbove === true || (this.con.openAbove !== false && view)){
|
652
|
+
view = true, height = Math.min((height), pos.top-10);
|
653
|
+
cADD(this.select, "open-top");
|
654
|
+
} else {
|
655
|
+
view = false, height = Math.min((height), bottom-10);
|
656
|
+
cREM(this.select, "open-top");
|
657
|
+
}
|
658
|
+
if(inner){
|
659
|
+
this.dropdown.style.maxHeight = height + "px";
|
660
|
+
inner.style.maxHeight = (height-search) + "px";
|
661
|
+
}
|
662
|
+
return this;
|
663
|
+
},
|
664
|
+
|
665
|
+
/*
|
666
|
+
| API :: QUERY OPTIONS
|
667
|
+
| @since 0.5.13 [0.5.0]
|
668
|
+
*/
|
669
|
+
query: function(search, conf){
|
670
|
+
var item, tp, ul, li, a1, a2; // Pre-Definition
|
671
|
+
var self = this, con = this.con, g = "getAttribute"; // Shorties
|
672
|
+
var root = create("DIV", "dropdown-inner"), // Contexts
|
673
|
+
func = (!search)? "walker": "finder",
|
674
|
+
args = (!search)? [con.sortItems, con.sortGroups]: [search, conf];
|
675
|
+
|
676
|
+
// Option Walker
|
677
|
+
this._query = (typeof search === "string")? search: false;
|
678
|
+
while(item = this.options[func].apply(this.options, args)){
|
679
|
+
if(!ul || (ul && ul[g]("data-group") !== item.group)){
|
680
|
+
tp = (con.cbLoopGroup || this.cbGroup).call(this, item.group, search, root);
|
681
|
+
if(tp instanceof Element){
|
682
|
+
ul = tp;
|
683
|
+
ul.setAttribute("data-group", item.group);
|
684
|
+
root.appendChild(ul);
|
685
|
+
} else { break; }
|
686
|
+
}
|
290
687
|
|
291
|
-
|
292
|
-
|
293
|
-
|
688
|
+
// Create Item
|
689
|
+
if((li = (con.cbLoopItem || this.cbItem).call(this, item, ul, search, root)) === null){
|
690
|
+
continue;
|
691
|
+
}
|
692
|
+
if(li === false){ break; }
|
693
|
+
li.setAttribute("data-key", item.key);
|
694
|
+
li.setAttribute("data-group", item.group);
|
695
|
+
li.addEventListener("click", function(event){
|
696
|
+
if(!this.hasAttribute("data-key")){ return false; }
|
697
|
+
var key = this[g]("data-key"), group = this[g]("data-group") || "#";
|
698
|
+
if(self.options.toggle.call(self.options, key, group)){
|
699
|
+
if(self.con.stayOpen === false && !self.con.multiple){
|
700
|
+
self.close.call(self, self.con.animate);
|
701
|
+
}
|
702
|
+
}
|
294
703
|
});
|
704
|
+
ul.appendChild(li);
|
705
|
+
}
|
706
|
+
|
707
|
+
// Empty
|
708
|
+
var count = root.querySelectorAll("*[data-key]").length;
|
709
|
+
if(count == 0){
|
710
|
+
(this.con.cbEmpty || function(element){
|
711
|
+
var li = create("SPAN", "dropdown-empty");
|
712
|
+
li.innerText = this._e("empty");
|
713
|
+
element.appendChild(li);
|
714
|
+
}).call(this, root, search);
|
295
715
|
}
|
296
716
|
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
);
|
717
|
+
// Select All
|
718
|
+
if(count > 0 && con.multiple && con.multiLimit == Infinity && con.multiSelectAll){
|
719
|
+
a1 = create("BUTTON", "tail-all"), a2 = create("BUTTON", "tail-none");
|
720
|
+
a1.innerText = this._e("all");
|
721
|
+
a1.addEventListener("click", function(event){
|
722
|
+
event.preventDefault();
|
723
|
+
var options = self.dropdown.querySelectorAll(".dropdown-inner .dropdown-option");
|
724
|
+
self.options.walk.call(self.options, "select", options);
|
725
|
+
})
|
726
|
+
a2.innerText = this._e("none");
|
727
|
+
a2.addEventListener("click", function(event){
|
728
|
+
event.preventDefault();
|
729
|
+
var options = self.dropdown.querySelectorAll(".dropdown-inner .dropdown-option");
|
730
|
+
self.options.walk.call(self.options, "unselect", options);
|
731
|
+
})
|
732
|
+
|
733
|
+
// Add Element
|
734
|
+
li = create("SPAN", "dropdown-action");
|
735
|
+
li.appendChild(a1);
|
736
|
+
li.appendChild(a2);
|
737
|
+
root.insertBefore(li, root.children[0]);
|
738
|
+
}
|
301
739
|
|
302
|
-
|
303
|
-
|
304
|
-
|
740
|
+
// Add and Return
|
741
|
+
var data = this.dropdown.querySelector(".dropdown-inner");
|
742
|
+
this.dropdown[(data? "replace": "append") + "Child"](root, data);
|
743
|
+
if(cHAS(this.select, "active")){
|
744
|
+
this.calc();
|
745
|
+
}
|
746
|
+
return this.updateCSV().updateLabel();
|
747
|
+
},
|
748
|
+
|
749
|
+
/*
|
750
|
+
| API :: CALLBACK -> CREATE GROUP
|
751
|
+
| @since 0.5.8 [0.4.0]
|
752
|
+
*/
|
753
|
+
cbGroup: function(group, search){
|
754
|
+
var ul = create("UL", "dropdown-optgroup"), self = this, a1, a2;
|
755
|
+
if(group == "#"){ return ul; }
|
756
|
+
ul.innerHTML = '<li class="optgroup-title"><b>' + group + '</b></li>';
|
757
|
+
if(this.con.multiple && this.con.multiLimit == Infinity && this.con.multiSelectAll){
|
758
|
+
a1 = create("BUTTON", "tail-none"), a2 = create("BUTTON", "tail-all");
|
759
|
+
a1.innerText = this._e("none");
|
760
|
+
a1.addEventListener("click", function(event){
|
761
|
+
event.preventDefault();
|
762
|
+
var grp = this.parentElement.parentElement.getAttribute("data-group");
|
763
|
+
self.options.all.call(self.options, "unselect", grp);
|
764
|
+
});
|
765
|
+
a2.innerText = this._e("all");
|
766
|
+
a2.addEventListener("click", function(event){
|
767
|
+
event.preventDefault();
|
768
|
+
var grp = this.parentElement.parentElement.getAttribute("data-group");
|
769
|
+
self.options.all.call(self.options, "select", grp);
|
305
770
|
});
|
771
|
+
ul.children[0].appendChild(a1);
|
772
|
+
ul.children[0].appendChild(a2);
|
773
|
+
}
|
774
|
+
return ul;
|
775
|
+
},
|
776
|
+
|
777
|
+
/*
|
778
|
+
| API :: CALLBACK -> CREATE ITEM
|
779
|
+
| @since 0.5.13 [0.4.0]
|
780
|
+
*/
|
781
|
+
cbItem: function(item, optgroup, search){
|
782
|
+
var li = create("LI", "dropdown-option" + (item.selected? " selected": "") + (item.disabled? " disabled": ""));
|
783
|
+
|
784
|
+
// Inner Text
|
785
|
+
if(search && search.length > 0 && this.con.searchMarked){
|
786
|
+
search = this.options.applyLinguisticRules(search);
|
787
|
+
li.innerHTML = item.value.replace(new RegExp("(" + search + ")", "i"), "<mark>$1</mark>");
|
788
|
+
} else {
|
789
|
+
li.innerText = item.value;
|
790
|
+
}
|
306
791
|
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
792
|
+
// Inner Description
|
793
|
+
if(this.con.descriptions && item.description){
|
794
|
+
li.innerHTML += '<span class="option-description">' + item.description + '</span>';
|
795
|
+
}
|
796
|
+
return li;
|
797
|
+
},
|
798
|
+
|
799
|
+
/*
|
800
|
+
| API :: UPDATE EVERYTHING
|
801
|
+
| @since 0.5.0 [0.5.0]
|
802
|
+
*/
|
803
|
+
update: function(item){
|
804
|
+
return this.updateLabel().updateContainer(item).updatePin(item).updateCSV(item);
|
805
|
+
},
|
806
|
+
|
807
|
+
/*
|
808
|
+
| API :: UPDATE LABEL
|
809
|
+
| @since 0.5.8 [0.5.0]
|
810
|
+
*/
|
811
|
+
updateLabel: function(label){
|
812
|
+
if(this.container == this.label && this.options.selected.length > 0){
|
813
|
+
if(this.label.querySelector(".label-inner")){
|
814
|
+
this.label.removeChild(this.label.querySelector(".label-inner"));
|
815
|
+
}
|
816
|
+
if(this.label.querySelector(".label-count")){
|
817
|
+
this.label.removeChild(this.label.querySelector(".label-count"));
|
313
818
|
}
|
819
|
+
return this;
|
314
820
|
}
|
315
|
-
|
316
|
-
|
317
|
-
if
|
318
|
-
|
821
|
+
var c = this.con, len = this.options.selected.length, limit;
|
822
|
+
if(typeof label !== "string"){
|
823
|
+
if(c.disabled){
|
824
|
+
label = "disabled";
|
825
|
+
} else if(this.dropdown.querySelectorAll("*[data-key]").length == 0){
|
826
|
+
label = "empty" + (cHAS(this.select, "in-search")? "Search": "");
|
827
|
+
} else if(c.multiLimit <= len){
|
828
|
+
label = "limit";
|
829
|
+
} else if(!c.multiple && this.options.selected.length > 0){
|
830
|
+
label = this.options.selected[0].innerText;
|
831
|
+
} else if(typeof c.placeholder === "string"){
|
832
|
+
label = c.placeholder;
|
319
833
|
} else {
|
320
|
-
|
321
|
-
const optionCheckboxes = nestedList.querySelectorAll(
|
322
|
-
'.tail--nested-dropdown-item input[type="checkbox"]'
|
323
|
-
);
|
324
|
-
optionCheckboxes.forEach((cb) => (cb.checked = false));
|
325
|
-
checkbox.checked = true;
|
326
|
-
updateOriginalOptionState(originalSelect, checkbox);
|
327
|
-
}
|
328
|
-
}
|
329
|
-
|
330
|
-
function toggleOptgroup(optgroupCheckbox) {
|
331
|
-
const isChecked = optgroupCheckbox.checked;
|
332
|
-
const nestedOptionsList = optgroupCheckbox
|
333
|
-
.closest(".tail--optgroup")
|
334
|
-
.querySelector(".tail--nested-dropdown-list");
|
335
|
-
const optionCheckboxes = nestedOptionsList.querySelectorAll(
|
336
|
-
'input[type="checkbox"]'
|
337
|
-
);
|
338
|
-
|
339
|
-
optionCheckboxes.forEach((checkbox) => {
|
340
|
-
checkbox.checked = isChecked;
|
341
|
-
toggleOption(checkbox); // Call toggleOption for individual options
|
342
|
-
});
|
343
|
-
|
344
|
-
if (!originalSelect.multiple) {
|
345
|
-
// For single-select, uncheck all other checkboxes in the same optgroup
|
346
|
-
const customDropdown = originalSelect.closest(
|
347
|
-
".tail-select"
|
348
|
-
);
|
349
|
-
if (customDropdown) {
|
350
|
-
const otherOptgroupCheckboxes = customDropdown.querySelectorAll(
|
351
|
-
'.tail--nested-dropdown-item input[type="checkbox"]'
|
352
|
-
);
|
353
|
-
|
354
|
-
otherOptgroupCheckboxes.forEach((cb) => {
|
355
|
-
if (cb !== optgroupCheckbox) {
|
356
|
-
cb.checked = false;
|
357
|
-
updateOriginalOptionState(originalSelect, cb);
|
358
|
-
}
|
359
|
-
});
|
360
|
-
}
|
834
|
+
label = "placeholder" + (c.multiple && c.multiLimit < Infinity? "Multi": "");
|
361
835
|
}
|
362
|
-
|
363
|
-
updateOriginalOptionState(originalSelect, optgroupCheckbox);
|
364
836
|
}
|
365
837
|
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
838
|
+
// Set HTML
|
839
|
+
label = this._e(label, {":limit": c.multiLimit}, label);
|
840
|
+
label = '<span class="label-inner">' + label + '</span>',
|
841
|
+
limit = (c.multiShowLimit && c.multiLimit < Infinity);
|
842
|
+
if(c.multiple && c.multiShowCount){
|
843
|
+
label = '<span class="label-count">:c</span>' + label;
|
844
|
+
label = label.replace(":c", len + (limit? (" / " + c.multiLimit): ""));
|
845
|
+
}
|
846
|
+
this.label.innerHTML = label;
|
847
|
+
return this;
|
848
|
+
},
|
849
|
+
|
850
|
+
/*
|
851
|
+
| API :: UPDATE CONTAINER
|
852
|
+
| @since 0.5.0 [0.5.0]
|
853
|
+
*/
|
854
|
+
updateContainer: function(item){
|
855
|
+
if(!this.container || !this.con.multiContainer){
|
856
|
+
return this;
|
857
|
+
}
|
858
|
+
var s = "[data-group='" + item.group + "'][data-key='" + item.key + "']";
|
859
|
+
if(this.container.querySelector(s)){
|
860
|
+
if(!item.selected){
|
861
|
+
this.container.removeChild(this.container.querySelector(s));
|
862
|
+
}
|
863
|
+
return this;
|
864
|
+
}
|
370
865
|
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
866
|
+
// Create Item
|
867
|
+
if(item.selected){
|
868
|
+
var self = this, hndl = create("DIV", "select-handle");
|
869
|
+
hndl.innerText = item.value;
|
870
|
+
hndl.setAttribute("data-key", item.key);
|
871
|
+
hndl.setAttribute("data-group", item.group);
|
872
|
+
hndl.addEventListener("click", function(event){
|
873
|
+
event.preventDefault();
|
874
|
+
event.stopPropagation();
|
875
|
+
var key = this.getAttribute("data-key"), grp = this.getAttribute("data-group");
|
876
|
+
self.options.unselect.call(self.options, key, grp);
|
375
877
|
});
|
878
|
+
this.container.appendChild(hndl);
|
879
|
+
}
|
880
|
+
return this;
|
881
|
+
},
|
882
|
+
|
883
|
+
/*
|
884
|
+
| API :: UPDATE PIN POSITION
|
885
|
+
| @since 0.5.3 [0.5.0]
|
886
|
+
*/
|
887
|
+
updatePin: function(item){
|
888
|
+
var inner = this.dropdown.querySelector(".dropdown-inner ul"),
|
889
|
+
option = "li[data-key='" + item.key + "'][data-group='" + item.group + "']";
|
890
|
+
if(!this.con.multiPinSelected || !inner || this._query !== false){
|
891
|
+
return this;
|
376
892
|
}
|
377
893
|
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
);
|
389
|
-
|
390
|
-
if (option) {
|
391
|
-
if (checkbox.checked) {
|
392
|
-
option.selected = true;
|
393
|
-
} else {
|
394
|
-
option.selected = false;
|
894
|
+
// Create Item
|
895
|
+
option = this.dropdown.querySelector(option);
|
896
|
+
if(item.selected){
|
897
|
+
inner.insertBefore(option, inner.children[0]);
|
898
|
+
} else {
|
899
|
+
var grp = this.dropdown.querySelector("ul[data-group='" + item.group + "']"),
|
900
|
+
prev = this.options[item.index-1], found = false;
|
901
|
+
while(prev && prev.group == item.group){
|
902
|
+
if(found = grp.querySelector("li[data-key='" + prev.key + "']")){
|
903
|
+
break;
|
395
904
|
}
|
396
|
-
|
397
|
-
// Trigger change event for the original select
|
398
|
-
const event = new Event("change", { bubbles: true });
|
399
|
-
originalSelect.dispatchEvent(event);
|
905
|
+
prev = this.options[prev.index-1];
|
400
906
|
}
|
401
|
-
|
402
|
-
|
403
|
-
const selectedOptions = Array.from(
|
404
|
-
originalSelect.options
|
405
|
-
).filter((opt) => opt.selected);
|
406
|
-
|
407
|
-
// Update the search input value with the selected option text
|
408
|
-
if (!originalSelect.multiple) {
|
409
|
-
if (selectedOptions.length > 0 && searchInput) {
|
410
|
-
searchInput.value = selectedOptions[0].textContent;
|
411
|
-
} else {
|
412
|
-
searchInput.value = ""; // Clear the search input if no option is selected
|
413
|
-
}
|
907
|
+
if(found && found.nextElementSibling){
|
908
|
+
grp.insertBefore(option, found.nextElementSibling);
|
414
909
|
} else {
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
910
|
+
grp.appendChild(option);
|
911
|
+
}
|
912
|
+
}
|
913
|
+
return this;
|
914
|
+
},
|
915
|
+
|
916
|
+
/*
|
917
|
+
| API :: UPDATE CSV INPUT
|
918
|
+
| @since 0.5.0 [0.5.0]
|
919
|
+
*/
|
920
|
+
updateCSV: function(item){
|
921
|
+
if(!this.csvInput || !this.con.csvOutput){
|
922
|
+
return this;
|
923
|
+
}
|
924
|
+
for(var selected = [], l = this.options.selected.length, i = 0; i < l; i++){
|
925
|
+
selected.push(this.options.selected[i].value);
|
926
|
+
}
|
927
|
+
this.csvInput.value = selected.join(this.con.csvSeparator || ",");
|
928
|
+
return this;
|
929
|
+
},
|
930
|
+
|
931
|
+
/*
|
932
|
+
| PUBLIC :: OPEN DROPDOWN
|
933
|
+
| @since 0.5.0 [0.3.0]
|
934
|
+
*/
|
935
|
+
open: function(animate){
|
936
|
+
if(cHAS(this.select, "active") || cHAS(this.select, "idle") || this.con.disabled){
|
937
|
+
return false;
|
938
|
+
}
|
939
|
+
this.calc();
|
940
|
+
|
941
|
+
// Final Function
|
942
|
+
var final = function(){
|
943
|
+
cADD(self.select, "active");
|
944
|
+
cREM(self.select, "idle");
|
945
|
+
this.dropdown.style.height = "auto";
|
946
|
+
this.dropdown.style.overflow = "visible";
|
947
|
+
this.label.removeAttribute("style");
|
948
|
+
if(this.con.search && this.con.searchFocus){
|
949
|
+
this.dropdown.querySelector("input").focus();
|
950
|
+
}
|
951
|
+
this.trigger.call(this, "open");
|
952
|
+
}, self = this, e = this.dropdown.style;
|
953
|
+
|
954
|
+
// Open
|
955
|
+
if(animate !== false){
|
956
|
+
this.label.style.zIndex = 25;
|
957
|
+
this.dropdown.style.cssText += "height:0;display:block;overflow:hidden;";
|
958
|
+
cADD(self.select, "idle");
|
959
|
+
(function animate(){
|
960
|
+
var h = parseInt(e.height, 10), m = parseInt(e.maxHeight, 10);
|
961
|
+
if(h >= m){
|
962
|
+
return final.call(self);
|
963
|
+
}
|
964
|
+
e.height = ((h+50 > m)? m: h+50) + "px";
|
965
|
+
setTimeout(animate, 20);
|
966
|
+
})();
|
967
|
+
} else {
|
968
|
+
e.cssText = "height:" + e.maxHeight + ";display:block;overflow:hidden;";
|
969
|
+
final.call(this);
|
970
|
+
}
|
971
|
+
return this;
|
972
|
+
},
|
973
|
+
|
974
|
+
/*
|
975
|
+
| PUBLIC :: CLOSE DROPDOWN
|
976
|
+
| @since 0.5.0 [0.3.0]
|
977
|
+
*/
|
978
|
+
close: function(animate){
|
979
|
+
if(!cHAS(this.select, "active") || cHAS(this.select, "idle")){
|
980
|
+
return false;
|
981
|
+
}
|
982
|
+
var final = function(){
|
983
|
+
cREM(this.select, "active");
|
984
|
+
cREM(this.select, "idle");
|
985
|
+
this.dropdown.removeAttribute("style");
|
986
|
+
this.dropdown.querySelector(".dropdown-inner").removeAttribute("style");
|
987
|
+
this.trigger.call(this, "close");
|
988
|
+
}, self = this, e = this.dropdown;
|
989
|
+
|
990
|
+
// Close
|
991
|
+
if(animate !== false){
|
992
|
+
cADD(this.select, "idle");
|
993
|
+
this.dropdown.style.overflow = "hidden";
|
994
|
+
(function animate(){
|
995
|
+
if((parseInt(e.offsetHeight, 10)-50) <= 0){
|
996
|
+
return final.call(self);
|
428
997
|
}
|
998
|
+
e.style.height = (parseInt(e.offsetHeight, 10)-50) + "px";
|
999
|
+
setTimeout(animate, 20);
|
1000
|
+
})();
|
1001
|
+
} else {
|
1002
|
+
final.call(this);
|
1003
|
+
}
|
1004
|
+
return this;
|
1005
|
+
},
|
1006
|
+
|
1007
|
+
/*
|
1008
|
+
| PUBLIC :: TOGGLE DROPDOWN
|
1009
|
+
| @since 0.5.0 [0.3.0]
|
1010
|
+
*/
|
1011
|
+
toggle: function(animate){
|
1012
|
+
if(cHAS(this.select, "active")){
|
1013
|
+
return this.close(animate);
|
1014
|
+
}
|
1015
|
+
return !cHAS(this.select, "idle")? this.open(animate): this;
|
1016
|
+
},
|
1017
|
+
|
1018
|
+
/*
|
1019
|
+
| PUBLIC :: REMOVE SELECT
|
1020
|
+
| @since 0.5.3 [0.3.0]
|
1021
|
+
*/
|
1022
|
+
remove: function(){
|
1023
|
+
this.e.removeAttribute("data-tail-select");
|
1024
|
+
if(this.e.hasAttribute("data-select-hidden")){
|
1025
|
+
if(this.e.getAttribute("data-select-hidden") == "0"){
|
1026
|
+
this.e.style.removeProperty("display");
|
429
1027
|
}
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
1028
|
+
this.e.removeAttribute("data-select-hidden");
|
1029
|
+
}
|
1030
|
+
Array.prototype.map.call(this.e.querySelectorAll("[data-select-option='add']"), function(item){
|
1031
|
+
item.parentElement.removeChild(item);
|
1032
|
+
})
|
1033
|
+
Array.prototype.map.call(this.e.querySelectorAll("[data-select-optgroup='add']"), function(item){
|
1034
|
+
item.parentElement.removeChild(item);
|
1035
|
+
})
|
1036
|
+
this.e.name = (this.csvInput.hasAttribute("name"))? this.csvInput.name: this.e.name;
|
1037
|
+
if(this.select.parentElement){
|
1038
|
+
this.select.parentElement.removeChild(this.select);
|
1039
|
+
}
|
1040
|
+
if(this.container){
|
1041
|
+
var handles = this.container.querySelectorAll(".select-handle");
|
1042
|
+
for(var l = handles.length, i = 0; i < l; i++){
|
1043
|
+
this.container.removeChild(handles[i]);
|
440
1044
|
}
|
1045
|
+
}
|
1046
|
+
return this;
|
1047
|
+
},
|
1048
|
+
|
1049
|
+
/*
|
1050
|
+
| PUBLIC :: RELOAD SELECT
|
1051
|
+
| @since 0.5.0 [0.3.0]
|
1052
|
+
*/
|
1053
|
+
reload: function(){
|
1054
|
+
return this.remove().init();
|
1055
|
+
},
|
1056
|
+
|
1057
|
+
/*
|
1058
|
+
| PUBLIC :: GET|SET CONFIG
|
1059
|
+
| @since 0.5.15 [0.4.0]
|
1060
|
+
*/
|
1061
|
+
config: function(key, value, rebuild){
|
1062
|
+
if(key instanceof Object){
|
1063
|
+
for(var k in key){ this.config(k, key[k], false); }
|
1064
|
+
return this.reload()? this.con: this.con;
|
1065
|
+
}
|
1066
|
+
if(key === void 0){
|
1067
|
+
return this.con;
|
1068
|
+
} else if(!(key in this.con)){
|
1069
|
+
return false;
|
1070
|
+
}
|
441
1071
|
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
1072
|
+
// Set | Return
|
1073
|
+
if(value === void 0){
|
1074
|
+
return this.con[key];
|
1075
|
+
}
|
1076
|
+
this.con[key] = value;
|
1077
|
+
if(rebuild !== false){
|
1078
|
+
this.reload();
|
1079
|
+
}
|
1080
|
+
return this;
|
1081
|
+
},
|
1082
|
+
enable: function(update){
|
1083
|
+
cREM(this.select, "disabled");
|
1084
|
+
this.e.disabled = false;
|
1085
|
+
this.con.disabled = false;
|
1086
|
+
return (update === false)? this: this.reload();
|
1087
|
+
},
|
1088
|
+
disable: function(update){
|
1089
|
+
cADD(this.select, "disabled");
|
1090
|
+
this.e.disabled = true;
|
1091
|
+
this.con.disabled = true;
|
1092
|
+
return (update === false)? this: this.reload();
|
1093
|
+
},
|
1094
|
+
|
1095
|
+
/*
|
1096
|
+
| PUBLIC :: CUSTOM EVENT LISTENER
|
1097
|
+
| @since 0.5.0 [0.4.0]
|
1098
|
+
*/
|
1099
|
+
on: function(event, callback, args){
|
1100
|
+
if(["open", "close", "change"].indexOf(event) < 0 || typeof callback !== "function"){
|
1101
|
+
return false;
|
1102
|
+
}
|
1103
|
+
if(!(event in this.events)){
|
1104
|
+
this.events[event] = [];
|
1105
|
+
}
|
1106
|
+
this.events[event].push({cb: callback, args: (args instanceof Array)? args: []});
|
1107
|
+
return this;
|
1108
|
+
},
|
1109
|
+
|
1110
|
+
/*
|
1111
|
+
| PUBLIC :: VALUE
|
1112
|
+
| @since 0.5.13 [0.5.13]
|
1113
|
+
*/
|
1114
|
+
value: function(){
|
1115
|
+
if(this.options.selected.length == 0){
|
1116
|
+
return null;
|
1117
|
+
}
|
1118
|
+
if(this.con.multiple){
|
1119
|
+
return this.options.selected.map(function(opt){
|
1120
|
+
return opt.value;
|
1121
|
+
});
|
1122
|
+
}
|
1123
|
+
return this.options.selected[0].value;
|
1124
|
+
}
|
1125
|
+
};
|
1126
|
+
|
1127
|
+
/*
|
1128
|
+
| OPTIONS CONSTRUCTOR
|
1129
|
+
| @since 0.5.12 [0.3.0]
|
1130
|
+
*/
|
1131
|
+
options = select.options = function(select, parent){
|
1132
|
+
if(!(this instanceof options)){
|
1133
|
+
return new options(select, parent);
|
1134
|
+
}
|
1135
|
+
this.self = parent;
|
1136
|
+
this.element = select;
|
1137
|
+
this.length = 0;
|
1138
|
+
this.selected = [];
|
1139
|
+
this.disabled = [];
|
1140
|
+
this.items = {"#": {}};
|
1141
|
+
this.groups = {};
|
1142
|
+
return this;
|
1143
|
+
}
|
449
1144
|
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
1145
|
+
/*
|
1146
|
+
| TAIL.OPTIONS HANDLER
|
1147
|
+
*/
|
1148
|
+
options.prototype = {
|
1149
|
+
/*
|
1150
|
+
| INTERNAL :: REPLACE TYPOs
|
1151
|
+
| @since 0.5.0 [0.3.0]
|
1152
|
+
*/
|
1153
|
+
_r: function(state){
|
1154
|
+
return state.replace("disabled", "disable").replace("enabled", "enable")
|
1155
|
+
.replace("selected", "select").replace("unselected", "unselect");
|
1156
|
+
},
|
1157
|
+
|
1158
|
+
/*
|
1159
|
+
| GET AN EXISTING OPTION
|
1160
|
+
| @since 0.5.7 [0.3.0]
|
1161
|
+
*/
|
1162
|
+
get: function(key, grp){
|
1163
|
+
var g = "getAttribute";
|
1164
|
+
if(typeof key === "object" && key.key && key.group){
|
1165
|
+
grp = key.group || grp;
|
1166
|
+
key = key.key;
|
1167
|
+
} else if(key instanceof Element){
|
1168
|
+
if(key.tagName == "OPTION"){
|
1169
|
+
grp = key.parentElement.label || "#";
|
1170
|
+
key = key.value || key.innerText;
|
1171
|
+
} else if(key.hasAttribute("data-key")){
|
1172
|
+
grp = key[g]("data-group") || key.parentElement[g]("data-group") || "#";
|
1173
|
+
key = key[g]("data-key");
|
454
1174
|
}
|
1175
|
+
} else if(typeof key !== "string"){
|
1176
|
+
return false;
|
455
1177
|
}
|
1178
|
+
key = (/^[0-9]+$/.test(key))? "_" + key: key;
|
1179
|
+
return (grp in this.items)? this.items[grp][key]: false;
|
1180
|
+
},
|
1181
|
+
|
1182
|
+
/*
|
1183
|
+
| SET AN EXISTING OPTION
|
1184
|
+
| @since 0.5.15 [0.3.0]
|
1185
|
+
*/
|
1186
|
+
set: function(opt, rebuild){
|
1187
|
+
var key = opt.value || opt.innerText, grp = opt.parentElement.label || "#";
|
1188
|
+
if(!(grp in this.items)){
|
1189
|
+
this.items[grp] = {};
|
1190
|
+
this.groups[grp] = opt.parentElement;
|
1191
|
+
}
|
1192
|
+
if(key in this.items[grp]){
|
1193
|
+
return false;
|
1194
|
+
}
|
1195
|
+
var id = (/^[0-9]+$/.test(key))? "_" + key: key;
|
456
1196
|
|
457
|
-
|
458
|
-
|
459
|
-
|
1197
|
+
// Validate Selection
|
1198
|
+
var con = this.self.con;
|
1199
|
+
if(con.multiple && this.selected.length >= con.multiLimit){
|
1200
|
+
opt.selected = false;
|
1201
|
+
}
|
1202
|
+
if(opt.selected && con.deselect && (!opt.hasAttribute("selected") || con.multiLimit == 0)){
|
1203
|
+
opt.selected = false;
|
1204
|
+
opt.parentElement.selectedIndex = -1;
|
1205
|
+
}
|
460
1206
|
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
);
|
465
|
-
|
466
|
-
|
1207
|
+
// Sanitize Description
|
1208
|
+
if(opt.hasAttribute("data-description")){
|
1209
|
+
var span = create("SPAN");
|
1210
|
+
span.innerHTML = opt.getAttribute("data-description");
|
1211
|
+
opt.setAttribute("data-description", span.innerHTML);
|
1212
|
+
}
|
467
1213
|
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
1214
|
+
// Add Item
|
1215
|
+
this.items[grp][id] = {
|
1216
|
+
key: key,
|
1217
|
+
value: opt.text,
|
1218
|
+
description: opt.getAttribute("data-description") || null,
|
1219
|
+
group: grp,
|
1220
|
+
option: opt,
|
1221
|
+
optgroup: (grp != "#")? this.groups[grp]: undefined,
|
1222
|
+
selected: opt.selected,
|
1223
|
+
disabled: opt.disabled,
|
1224
|
+
hidden: opt.hidden || false
|
1225
|
+
};
|
1226
|
+
this.length++;
|
1227
|
+
if(opt.selected){ this.select(this.items[grp][id]); }
|
1228
|
+
if(opt.disabled){ this.disable(this.items[grp][id]); }
|
1229
|
+
return (rebuild)? this.self.callback(this.items[grp][key], "rebuild"): true;
|
1230
|
+
},
|
1231
|
+
|
1232
|
+
/*
|
1233
|
+
| CREATE A NEW OPTION
|
1234
|
+
| @since 0.5.13 [0.3.0]
|
1235
|
+
*/
|
1236
|
+
add: function(key, value, group, selected, disabled, description, rebuild){
|
1237
|
+
if(key instanceof Object){
|
1238
|
+
for(var k in key){
|
1239
|
+
this.add(key[k].key || k, key[k].value, key[k].group, key[k].selected, key[k].disabled, key[k].description, false);
|
1240
|
+
}
|
1241
|
+
return this.self.query();
|
1242
|
+
}
|
1243
|
+
if(this.get(key, group)){
|
1244
|
+
return false;
|
1245
|
+
}
|
475
1246
|
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
);
|
486
|
-
const hasVisibleNestedCheckboxes =
|
487
|
-
nestedCheckboxes.length > 0;
|
488
|
-
|
489
|
-
// Show the parent li only if the checkbox or a visible nested checkbox is present
|
490
|
-
optgroupItem.style.display =
|
491
|
-
optionCheckbox.style.display === "inline-block" ||
|
492
|
-
hasVisibleNestedCheckboxes
|
493
|
-
? "block"
|
494
|
-
: "none";
|
495
|
-
});
|
1247
|
+
// Check Group
|
1248
|
+
group = (typeof group === "string")? group: "#";
|
1249
|
+
if(group !== "#" && !(group in this.groups)){
|
1250
|
+
var optgroup = create("OPTGROUP");
|
1251
|
+
optgroup.label = group;
|
1252
|
+
optgroup.setAttribute("data-select-optgroup", "add");
|
1253
|
+
this.element.appendChild(optgroup);
|
1254
|
+
this.items[group] = {};
|
1255
|
+
this.groups[group] = optgroup;
|
496
1256
|
}
|
497
1257
|
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
1258
|
+
// Validate Selection
|
1259
|
+
if(this.self.con.multiple && this.selected.length >= this.self.con.multiLimit){
|
1260
|
+
selected = false;
|
1261
|
+
}
|
1262
|
+
disabled = !!disabled;
|
1263
|
+
|
1264
|
+
// Create Option
|
1265
|
+
var option = d.createElement("OPTION");
|
1266
|
+
option.value = key;
|
1267
|
+
option.selected = selected;
|
1268
|
+
option.disabled = disabled;
|
1269
|
+
option.innerText = value;
|
1270
|
+
option.setAttribute("data-select-option", "add");
|
1271
|
+
if(description && description.length > 0){
|
1272
|
+
option.setAttribute("data-description", description);
|
1273
|
+
}
|
504
1274
|
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
1275
|
+
// Add Option and Return
|
1276
|
+
((group == "#")? this.element: this.groups[group]).appendChild(option);
|
1277
|
+
return this.set(option, rebuild);
|
1278
|
+
},
|
1279
|
+
|
1280
|
+
/*
|
1281
|
+
| MOVE AN EXISTING OPTION
|
1282
|
+
| @since 0.5.0 [0.5.0]
|
1283
|
+
*/
|
1284
|
+
move: function(item, group, new_group, rebuild){
|
1285
|
+
if(!(item = this.get(item, group))){ return false; }
|
1286
|
+
|
1287
|
+
// Create Group
|
1288
|
+
if(new_group !== "#" && !(new_group in this.groups)){
|
1289
|
+
var optgroup = create("OPTGROUP");
|
1290
|
+
optgroup.label = new_group;
|
1291
|
+
this.element.appendChild(optgroup);
|
1292
|
+
this.items[new_group] = {};
|
1293
|
+
this.groups[new_group] = optgroup;
|
1294
|
+
this.groups[new_group].appendChild(item.option);
|
511
1295
|
}
|
512
1296
|
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
1297
|
+
// Move To Group
|
1298
|
+
delete this.items[item.group][item.key];
|
1299
|
+
item.group = new_group;
|
1300
|
+
item.optgroup = this.groups[new_group] || undefined;
|
1301
|
+
this.items[new_group][item.key] = item;
|
1302
|
+
return (rebuild)? this.self.query(): true;
|
1303
|
+
},
|
1304
|
+
|
1305
|
+
/*
|
1306
|
+
| REMOVE AN EXISTING OPTION
|
1307
|
+
| @since 0.5.7 [0.3.0]
|
1308
|
+
*/
|
1309
|
+
remove: function(item, group, rebuild){
|
1310
|
+
if(!(item = this.get(item, group))){ return false; }
|
1311
|
+
if(item.selected){ this.unselect(item); }
|
1312
|
+
if(item.disabled){ this.enable(item); }
|
1313
|
+
|
1314
|
+
// Remove Data
|
1315
|
+
item.option.parentElement.removeChild(item.option);
|
1316
|
+
var id = (/^[0-9]+$/.test(item.key))? "_" + item.key: item.key;
|
1317
|
+
delete this.items[item.group][id];
|
1318
|
+
this.length--;
|
1319
|
+
|
1320
|
+
// Remove Optgroup
|
1321
|
+
if(Object.keys(this.items[item.group]).length === 0){
|
1322
|
+
delete this.items[item.group];
|
1323
|
+
delete this.groups[item.group];
|
1324
|
+
}
|
1325
|
+
return (rebuild)? this.self.query(): true;
|
1326
|
+
},
|
1327
|
+
|
1328
|
+
/*
|
1329
|
+
| CHECK AN EXISTING OPTION
|
1330
|
+
| @since 0.5.0 [0.3.0]
|
1331
|
+
*/
|
1332
|
+
is: function(state, key, group){
|
1333
|
+
var state = this._r(state), item = this.get(key, group);
|
1334
|
+
if(!item || ["select", "unselect", "disable", "enable"].indexOf(state) < 0){
|
1335
|
+
return null;
|
1336
|
+
}
|
1337
|
+
if(state == "disable" || state == "enable"){
|
1338
|
+
return (state == "disable")? item.disabled: !item.disabled;
|
1339
|
+
} else if(state == "select" || state == "unselect"){
|
1340
|
+
return (state == "select")? item.selected: !item.selected;
|
1341
|
+
}
|
1342
|
+
return false;
|
1343
|
+
},
|
1344
|
+
|
1345
|
+
/*
|
1346
|
+
| INTERACT WITH AN OPTION
|
1347
|
+
| @since 0.5.3 [0.3.0]
|
1348
|
+
*/
|
1349
|
+
handle: function(state, key, group, _force){
|
1350
|
+
var item = this.get(key, group), state = this._r(state);
|
1351
|
+
if(!item || ["select", "unselect", "disable", "enable"].indexOf(state) < 0){
|
1352
|
+
return null;
|
1353
|
+
}
|
519
1354
|
|
1355
|
+
// Disable || Enable
|
1356
|
+
if(state == "disable" || state == "enable"){
|
1357
|
+
if(!(item.option in this.disabled) && state == "disable"){
|
1358
|
+
this.disabled.push(item.option);
|
1359
|
+
} else if((item.option in this.disabled) && state == "enable"){
|
1360
|
+
this.disabled.splice(this.disabled.indexOf(item.option), 1);
|
1361
|
+
}
|
1362
|
+
item.disabled = (state == "disable");
|
1363
|
+
item.option.disabled = (state == "disable");
|
1364
|
+
return this.self.callback.call(this.self, item, state);
|
1365
|
+
}
|
520
1366
|
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
1367
|
+
// Select || Unselect
|
1368
|
+
var dis = (cHAS(this.self.select, "disabled") || item.disabled || item.option.disabled),
|
1369
|
+
lmt = (this.self.con.multiple && this.self.con.multiLimit <= this.selected.length),
|
1370
|
+
sgl = (!this.self.con.multiple && this.selected.indexOf(item.option) > 0),
|
1371
|
+
del = (this.self.con.multiLimit == 0 && this.self.con.deselect == true),
|
1372
|
+
uns = (!this.self.con.multiple && !this.self.con.deselect && _force !== true);
|
1373
|
+
if(state == "select"){
|
1374
|
+
if(dis || lmt || del || sgl){
|
1375
|
+
return false;
|
1376
|
+
}
|
1377
|
+
if(!this.self.con.multiple){
|
1378
|
+
for(var i in this.selected){
|
1379
|
+
this.unselect(this.selected[i], undefined, true);
|
527
1380
|
}
|
1381
|
+
}
|
1382
|
+
if(this.selected.indexOf(item.option) < 0){
|
1383
|
+
this.selected.push(item.option);
|
1384
|
+
}
|
1385
|
+
} else if(state == "unselect"){
|
1386
|
+
if(dis || uns){
|
1387
|
+
return false;
|
1388
|
+
}
|
1389
|
+
this.selected.splice(this.selected.indexOf(item.option), 1);
|
1390
|
+
}
|
1391
|
+
item.selected = (state == "select");
|
1392
|
+
item.option.selected = (state == "select");
|
1393
|
+
item.option[(state.length > 6? "remove": "set") + "Attribute"]("selected", "selected");
|
1394
|
+
return this.self.callback.call(this.self, item, state, _force);
|
1395
|
+
},
|
1396
|
+
enable: function(key, group){
|
1397
|
+
return this.handle("enable", key, group, false);
|
1398
|
+
},
|
1399
|
+
disable: function(key, group){
|
1400
|
+
return this.handle("disable", key, group, false);
|
1401
|
+
},
|
1402
|
+
select: function(key, group){
|
1403
|
+
return this.handle("select", key, group, false);
|
1404
|
+
},
|
1405
|
+
unselect: function(key, group, _force){
|
1406
|
+
return this.handle("unselect", key, group, _force);
|
1407
|
+
},
|
1408
|
+
toggle: function(item, group){
|
1409
|
+
if(!(item = this.get(item, group))){ return false; }
|
1410
|
+
return this.handle((item.selected? "unselect": "select"), item, group, false);
|
1411
|
+
},
|
1412
|
+
|
1413
|
+
/*
|
1414
|
+
| INVERT CURRENT <STATE>
|
1415
|
+
| @since 0.5.15 [0.3.0]
|
1416
|
+
*/
|
1417
|
+
invert: function(state){
|
1418
|
+
state = this._r(state);
|
1419
|
+
if(["enable", "disable"].indexOf(state) >= 0){
|
1420
|
+
var invert = this.disabled, action = (state == "enable")? "disable": "enable";
|
1421
|
+
} else if(["select", "unselect"].indexOf(state) >= 0){
|
1422
|
+
var invert = this.selected, action = (state == "select")? "unselect": "select";
|
1423
|
+
}
|
1424
|
+
var convert = Array.prototype.filter.call(this, function(element){
|
1425
|
+
return !(element in invert);
|
1426
|
+
}), self = this;
|
1427
|
+
|
1428
|
+
// Loop
|
1429
|
+
[].concat(invert).forEach(function(item){
|
1430
|
+
self.handle.call(self, action, item);
|
1431
|
+
});
|
1432
|
+
[].concat(convert).forEach(function(item){
|
1433
|
+
self.handle.call(self, state, item);
|
1434
|
+
});
|
1435
|
+
return true;
|
1436
|
+
},
|
1437
|
+
|
1438
|
+
/*
|
1439
|
+
| SET <STATE> ON ALL OPTIONs
|
1440
|
+
| @since 0.5.0 [0.5.0]
|
1441
|
+
*/
|
1442
|
+
all: function(state, group){
|
1443
|
+
var self = this, list = this;
|
1444
|
+
if(group in this.items){
|
1445
|
+
list = Object.keys(this.items[group]);
|
1446
|
+
} else if(["unselect", "enable"].indexOf(state) >= 0){
|
1447
|
+
list = [].concat((state == "unselect")? this.selected: this.disabled);
|
1448
|
+
}
|
1449
|
+
Array.prototype.forEach.call(list, function(item){
|
1450
|
+
self.handle.call(self, state, item, group, false);
|
1451
|
+
});
|
1452
|
+
return true;
|
1453
|
+
},
|
1454
|
+
|
1455
|
+
/*
|
1456
|
+
| SET <STATE> FOR A BUNCH OF OPTIONs
|
1457
|
+
| @since 0.5.4 [0.5.3]
|
1458
|
+
*/
|
1459
|
+
walk: function(state, items, args){
|
1460
|
+
if(items instanceof Array || items.length){
|
1461
|
+
for(var l = items.length, i = 0; i < l; i++){
|
1462
|
+
this.handle.apply(this, [state, items[i], null].concat(args));
|
1463
|
+
}
|
1464
|
+
} else if(items instanceof Object){
|
1465
|
+
var self = this;
|
1466
|
+
if(items.forEach){
|
1467
|
+
items.forEach(function(value){
|
1468
|
+
self.handle.apply(self, [state, value, null].concat(args));
|
1469
|
+
});
|
528
1470
|
} else {
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
if (opts.multiTags) {
|
536
|
-
if (originalSelect.multiple) {
|
537
|
-
// Update the selected options list
|
538
|
-
updateSelectedOptionsList(
|
539
|
-
selectedOptionsList,
|
540
|
-
selectedOptions
|
541
|
-
);
|
1471
|
+
for(var key in items){
|
1472
|
+
if(typeof items[key] !== "string" && typeof items[key] !== "number" && !(items[key] instanceof Element)){
|
1473
|
+
continue;
|
1474
|
+
}
|
1475
|
+
this.handle.apply(this, [state, items[key], (key in this.items? key: null)]).concat(args);
|
542
1476
|
}
|
543
1477
|
}
|
544
1478
|
}
|
1479
|
+
return this;
|
1480
|
+
},
|
1481
|
+
|
1482
|
+
/*
|
1483
|
+
| APPLY LINGUSTIC RULES
|
1484
|
+
| @since 0.5.13 [0.5.13]
|
1485
|
+
*/
|
1486
|
+
applyLinguisticRules: function(search, casesensitive){
|
1487
|
+
var rules = this.self.con.linguisticRules, values = [];
|
1488
|
+
|
1489
|
+
// Prepare Rules
|
1490
|
+
Object.keys(rules).forEach(function(key){
|
1491
|
+
values.push("(" + key + "|[" + rules[key] + "])");
|
1492
|
+
});
|
1493
|
+
if(casesensitive){
|
1494
|
+
values = values.concat(values.map(function(s){ return s.toUpperCase(); }));
|
1495
|
+
}
|
545
1496
|
|
1497
|
+
return search.replace(new RegExp(values.join("|"), (casesensitive)? "g": "ig"), function(m){
|
1498
|
+
return values[[].indexOf.call(arguments, m, 1) - 1];
|
1499
|
+
});
|
1500
|
+
},
|
546
1501
|
|
547
|
-
function updateCounter(originalSelect) {
|
548
|
-
// Get the custom ID for the current original select
|
549
|
-
let customId = originalSelect.id;
|
550
|
-
|
551
|
-
if (customId) {
|
552
|
-
// Get the counter element
|
553
|
-
let counterElement = document
|
554
|
-
.querySelector(`.${customId}`)
|
555
|
-
.querySelector(".tail--counter");
|
556
1502
|
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
1503
|
+
/*
|
1504
|
+
| FIND SOME OPTIONs - ARRAY EDITION
|
1505
|
+
| @since 0.5.15 [0.3.0]
|
1506
|
+
*/
|
1507
|
+
find: function(search, config){
|
1508
|
+
var self = this, matches, has = {};
|
562
1509
|
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
}
|
1510
|
+
// Get Config
|
1511
|
+
if(!config){
|
1512
|
+
config = this.self.con.searchConfig;
|
567
1513
|
}
|
568
1514
|
|
569
|
-
|
570
|
-
|
571
|
-
|
1515
|
+
// Config Callback
|
1516
|
+
if(typeof config === "function"){
|
1517
|
+
matches = config.bind(this, search);
|
572
1518
|
}
|
573
1519
|
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
1520
|
+
// Config Handler
|
1521
|
+
else {
|
1522
|
+
config = (config instanceof Array)? config: [config];
|
1523
|
+
config.forEach(function(c){
|
1524
|
+
if(typeof c === "string"){ has[c] = true; }
|
1525
|
+
});
|
1526
|
+
has.any = (!has.any)? has.attributes && has.value: has.any;
|
578
1527
|
|
579
|
-
|
580
|
-
if
|
581
|
-
|
1528
|
+
// Cleanup & Prepare
|
1529
|
+
if(!has.regex || has.text){
|
1530
|
+
search = search.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
1531
|
+
}
|
1532
|
+
if(!has.exactglyphes){
|
1533
|
+
search = this.self.options.applyLinguisticRules(search, has.case);
|
1534
|
+
}
|
1535
|
+
if(has.word){
|
1536
|
+
search = '\\b' + search + '\\b';
|
582
1537
|
}
|
583
|
-
}
|
584
1538
|
|
585
|
-
|
586
|
-
|
587
|
-
|
1539
|
+
// Search
|
1540
|
+
var regex = new RegExp(search, (!has.case)? "mi": "m"),
|
1541
|
+
sfunc = function(opt){ return regex.test(opt.text || opt.value); };
|
1542
|
+
|
1543
|
+
// Handle
|
1544
|
+
if(has.any){
|
1545
|
+
matches = function(opt){ return sfunc(opt) || [].some.call(opt.attributes, sfunc); };
|
1546
|
+
} else if(has.attributes){
|
1547
|
+
matches = function(opt){ return [].some.call(opt.attributes, sfunc); };
|
1548
|
+
} else {
|
1549
|
+
matches = sfunc;
|
1550
|
+
}
|
1551
|
+
|
1552
|
+
if(!this.self.con.searchDisabled){
|
1553
|
+
var temp = matches;
|
1554
|
+
matches = function(opt){ return !opt.disabled && temp(opt); };
|
588
1555
|
}
|
589
1556
|
}
|
590
1557
|
|
591
|
-
//
|
592
|
-
|
1558
|
+
// Hammer Time
|
1559
|
+
return [].filter.call(this.self.e.options, matches).map(function(opt){
|
1560
|
+
return opt.hidden? false: self.get(opt)
|
1561
|
+
});
|
1562
|
+
},
|
1563
|
+
|
1564
|
+
/*
|
1565
|
+
| FIND SOME OPTIONs - WALKER EDITION
|
1566
|
+
| @since 0.5.5 [0.3.0]
|
1567
|
+
*/
|
1568
|
+
finder: function(search, config){
|
1569
|
+
if(this._finderLoop === undefined){
|
1570
|
+
this._finderLoop = this.find(search, config);
|
1571
|
+
}
|
1572
|
+
var item;
|
1573
|
+
while((item = this._finderLoop.shift()) !== undefined){
|
1574
|
+
return item;
|
1575
|
+
}
|
1576
|
+
delete this._finderLoop;
|
1577
|
+
return false;
|
1578
|
+
},
|
1579
|
+
|
1580
|
+
/*
|
1581
|
+
| NEW OPTIONS WALKER
|
1582
|
+
| @since 0.5.15 [0.4.0]
|
1583
|
+
*/
|
1584
|
+
walker: function(orderi, orderg){
|
1585
|
+
if(typeof this._inLoop !== "undefined" && this._inLoop){
|
1586
|
+
if(this._inItems.length > 0){
|
1587
|
+
do {
|
1588
|
+
var temp = this.items[this._inGroup][this._inItems.shift()];
|
1589
|
+
} while(temp.hidden === true);
|
1590
|
+
return temp;
|
1591
|
+
}
|
593
1592
|
|
594
|
-
|
595
|
-
|
1593
|
+
// Sort Items
|
1594
|
+
if(this._inGroups.length > 0){
|
1595
|
+
while(this._inGroups.length > 0){
|
1596
|
+
var group = this._inGroups.shift();
|
1597
|
+
if(!(group in this.items)){
|
1598
|
+
return false;
|
1599
|
+
}
|
596
1600
|
|
597
|
-
|
598
|
-
|
1601
|
+
var keys = Object.keys(this.items[group]);
|
1602
|
+
if(keys.length > 0){
|
1603
|
+
break;
|
1604
|
+
}
|
1605
|
+
}
|
1606
|
+
if(orderi == "ASC"){
|
1607
|
+
keys.sort();
|
1608
|
+
} else if(orderi == "DESC"){
|
1609
|
+
keys.sort().reverse();
|
1610
|
+
} else if(typeof orderi === "function"){
|
1611
|
+
keys = orderi.call(this, keys);
|
1612
|
+
}
|
1613
|
+
this._inItems = keys;
|
1614
|
+
this._inGroup = group;
|
1615
|
+
return this.walker(null, null);
|
1616
|
+
}
|
599
1617
|
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
1618
|
+
// Delete and Exit
|
1619
|
+
delete this._inLoop;
|
1620
|
+
delete this._inItems;
|
1621
|
+
delete this._inGroup;
|
1622
|
+
delete this._inGroups;
|
1623
|
+
return false;
|
1624
|
+
}
|
1625
|
+
|
1626
|
+
// Sort Groups
|
1627
|
+
var groups = Object.keys(this.groups) || [];
|
1628
|
+
if(orderg == "ASC"){
|
1629
|
+
groups.sort();
|
1630
|
+
} else if(orderg == "DESC"){
|
1631
|
+
groups.sort().reverse();
|
1632
|
+
} else if(typeof orderg === "function"){
|
1633
|
+
groups = orderg.call(this, groups);
|
1634
|
+
}
|
1635
|
+
groups.unshift("#");
|
1636
|
+
|
1637
|
+
// Init Loop
|
1638
|
+
this._inLoop = true;
|
1639
|
+
this._inItems = [];
|
1640
|
+
this._inGroups = groups;
|
1641
|
+
return this.walker(orderi, null);
|
1642
|
+
}
|
1643
|
+
};
|
1644
|
+
|
1645
|
+
// Return
|
1646
|
+
return select;
|
1647
|
+
}));
|