slim-select 2.8.2 → 2.9.1
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.
- package/.prettierignore +1 -0
- package/.prettierrc +4 -3
- package/README.md +5 -2
- package/dist/classes.d.ts +43 -0
- package/dist/helpers.d.ts +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/render.d.ts +4 -44
- package/dist/select.d.ts +4 -2
- package/dist/settings.d.ts +2 -1
- package/dist/slimselect.cjs.js +248 -120
- package/dist/slimselect.css +1 -1
- package/dist/slimselect.css.map +1 -1
- package/dist/slimselect.es.js +248 -120
- package/dist/slimselect.global.js +248 -120
- package/dist/slimselect.js +248 -120
- package/dist/slimselect.min.js +1 -1
- package/dist/slimselect.umd.js +248 -120
- package/dist/slimselect.umd.min.js +1 -1
- package/dist/store.d.ts +4 -2
- package/index.html +1 -4
- package/jest.config.js +6 -0
- package/package.json +31 -40
- package/src/slim-select/classes.test.ts +72 -0
- package/src/slim-select/classes.ts +109 -0
- package/src/slim-select/helpers.test.ts +160 -0
- package/src/slim-select/helpers.ts +3 -12
- package/src/slim-select/index.test.ts +109 -16
- package/src/slim-select/index.ts +41 -12
- package/src/slim-select/render.test.ts +1169 -18
- package/src/slim-select/render.ts +78 -97
- package/src/slim-select/rollup.config.mjs +28 -28
- package/src/slim-select/select.test.ts +306 -156
- package/src/slim-select/select.ts +70 -21
- package/src/slim-select/settings.test.ts +272 -0
- package/src/slim-select/settings.ts +5 -1
- package/src/slim-select/slimselect.scss +7 -3
- package/src/slim-select/store.test.ts +986 -235
- package/src/slim-select/store.ts +70 -28
- package/src/{vue/slimselect.vue → slim-select/vue.vue} +19 -17
- package/tsconfig.json +2 -3
- package/{vite.config.ts → vite.config.mts} +11 -4
- package/src/react/.eslintignore +0 -2
- package/src/react/.eslintrc.cjs +0 -24
- package/src/react/index.html +0 -14
- package/src/react/jestconfig.json +0 -11
- package/src/react/package.json +0 -32
- package/src/react/src/frameworkpage.tsx +0 -133
- package/src/react/src/index.ts +0 -3
- package/src/react/src/slimselect.tsx +0 -148
- package/src/react/tests/slimselect.test.tsx +0 -52
- package/src/react/tsconfig.json +0 -37
- package/src/react/tsconfig.node.json +0 -10
- package/src/react/vite.config.ts +0 -55
- package/src/vue/README.md +0 -48
- package/src/vue/dist/slim-select/helpers.d.ts +0 -5
- package/src/vue/dist/slim-select/index.d.ts +0 -46
- package/src/vue/dist/slim-select/render.d.ts +0 -120
- package/src/vue/dist/slim-select/select.d.ts +0 -28
- package/src/vue/dist/slim-select/settings.d.ts +0 -34
- package/src/vue/dist/slim-select/store.d.ts +0 -80
- package/src/vue/dist/slimselectvue.es.js +0 -1978
- package/src/vue/dist/slimselectvue.global.js +0 -1981
- package/src/vue/dist/slimselectvue.ssr.js +0 -1980
- package/src/vue/dist/vue/hello.d.ts +0 -2
- package/src/vue/dist/vue/slimselect.vue.d.ts +0 -326
- package/src/vue/hello.ts +0 -5
- package/src/vue/package.json +0 -28
- package/src/vue/rollup.config.mjs +0 -44
- package/src/vue/tsconfig.json +0 -14
package/dist/slimselect.umd.js
CHANGED
|
@@ -4,6 +4,54 @@
|
|
|
4
4
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.SlimSelect = factory());
|
|
5
5
|
})(this, (function () { 'use strict';
|
|
6
6
|
|
|
7
|
+
class CssClasses {
|
|
8
|
+
constructor(classes) {
|
|
9
|
+
if (!classes) {
|
|
10
|
+
classes = {};
|
|
11
|
+
}
|
|
12
|
+
this.main = classes.main || 'ss-main';
|
|
13
|
+
this.placeholder = classes.placeholder || 'ss-placeholder';
|
|
14
|
+
this.values = classes.values || 'ss-values';
|
|
15
|
+
this.single = classes.single || 'ss-single';
|
|
16
|
+
this.max = classes.max || 'ss-max';
|
|
17
|
+
this.value = classes.value || 'ss-value';
|
|
18
|
+
this.valueText = classes.valueText || 'ss-value-text';
|
|
19
|
+
this.valueDelete = classes.valueDelete || 'ss-value-delete';
|
|
20
|
+
this.valueOut = classes.valueOut || 'ss-value-out';
|
|
21
|
+
this.deselect = classes.deselect || 'ss-deselect';
|
|
22
|
+
this.deselectPath = classes.deselectPath || 'M10,10 L90,90 M10,90 L90,10';
|
|
23
|
+
this.arrow = classes.arrow || 'ss-arrow';
|
|
24
|
+
this.arrowClose = classes.arrowClose || 'M10,30 L50,70 L90,30';
|
|
25
|
+
this.arrowOpen = classes.arrowOpen || 'M10,70 L50,30 L90,70';
|
|
26
|
+
this.content = classes.content || 'ss-content';
|
|
27
|
+
this.openAbove = classes.openAbove || 'ss-open-above';
|
|
28
|
+
this.openBelow = classes.openBelow || 'ss-open-below';
|
|
29
|
+
this.search = classes.search || 'ss-search';
|
|
30
|
+
this.searchHighlighter = classes.searchHighlighter || 'ss-search-highlight';
|
|
31
|
+
this.searching = classes.searching || 'ss-searching';
|
|
32
|
+
this.addable = classes.addable || 'ss-addable';
|
|
33
|
+
this.addablePath = classes.addablePath || 'M50,10 L50,90 M10,50 L90,50';
|
|
34
|
+
this.list = classes.list || 'ss-list';
|
|
35
|
+
this.optgroup = classes.optgroup || 'ss-optgroup';
|
|
36
|
+
this.optgroupLabel = classes.optgroupLabel || 'ss-optgroup-label';
|
|
37
|
+
this.optgroupLabelText = classes.optgroupLabelText || 'ss-optgroup-label-text';
|
|
38
|
+
this.optgroupActions = classes.optgroupActions || 'ss-optgroup-actions';
|
|
39
|
+
this.optgroupSelectAll = classes.optgroupSelectAll || 'ss-selectall';
|
|
40
|
+
this.optgroupSelectAllBox = classes.optgroupSelectAllBox || 'M60,10 L10,10 L10,90 L90,90 L90,50';
|
|
41
|
+
this.optgroupSelectAllCheck = classes.optgroupSelectAllCheck || 'M30,45 L50,70 L90,10';
|
|
42
|
+
this.optgroupClosable = classes.optgroupClosable || 'ss-closable';
|
|
43
|
+
this.option = classes.option || 'ss-option';
|
|
44
|
+
this.optionDelete = classes.optionDelete || 'M10,10 L90,90 M10,90 L90,10';
|
|
45
|
+
this.highlighted = classes.highlighted || 'ss-highlighted';
|
|
46
|
+
this.open = classes.open || 'ss-open';
|
|
47
|
+
this.close = classes.close || 'ss-close';
|
|
48
|
+
this.selected = classes.selected || 'ss-selected';
|
|
49
|
+
this.error = classes.error || 'ss-error';
|
|
50
|
+
this.disabled = classes.disabled || 'ss-disabled';
|
|
51
|
+
this.hide = classes.hide || 'ss-hide';
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
7
55
|
function generateID() {
|
|
8
56
|
return Math.random().toString(36).substring(2, 10);
|
|
9
57
|
}
|
|
@@ -91,6 +139,7 @@
|
|
|
91
139
|
constructor(type, data) {
|
|
92
140
|
this.selectType = 'single';
|
|
93
141
|
this.data = [];
|
|
142
|
+
this.selectedOrder = [];
|
|
94
143
|
this.selectType = type;
|
|
95
144
|
this.setData(data);
|
|
96
145
|
}
|
|
@@ -105,12 +154,18 @@
|
|
|
105
154
|
}
|
|
106
155
|
if ('options' in dataObj && dataObj.options) {
|
|
107
156
|
for (let option of dataObj.options) {
|
|
108
|
-
|
|
157
|
+
const validationError = this.validateOption(option);
|
|
158
|
+
if (validationError) {
|
|
159
|
+
return validationError;
|
|
160
|
+
}
|
|
109
161
|
}
|
|
110
162
|
}
|
|
111
163
|
}
|
|
112
164
|
else if (dataObj instanceof Option || 'text' in dataObj) {
|
|
113
|
-
|
|
165
|
+
const validationError = this.validateOption(dataObj);
|
|
166
|
+
if (validationError) {
|
|
167
|
+
return validationError;
|
|
168
|
+
}
|
|
114
169
|
}
|
|
115
170
|
else {
|
|
116
171
|
return new Error('Data object must be a valid optgroup or option');
|
|
@@ -147,7 +202,7 @@
|
|
|
147
202
|
setData(data) {
|
|
148
203
|
this.data = this.partialToFullData(data);
|
|
149
204
|
if (this.selectType === 'single') {
|
|
150
|
-
this.setSelectedBy('
|
|
205
|
+
this.setSelectedBy('id', this.getSelected());
|
|
151
206
|
}
|
|
152
207
|
}
|
|
153
208
|
getData() {
|
|
@@ -156,12 +211,19 @@
|
|
|
156
211
|
getDataOptions() {
|
|
157
212
|
return this.filter(null, false);
|
|
158
213
|
}
|
|
159
|
-
addOption(option) {
|
|
160
|
-
|
|
214
|
+
addOption(option, addToStart = false) {
|
|
215
|
+
if (addToStart) {
|
|
216
|
+
let data = [new Option(option)];
|
|
217
|
+
this.setData(data.concat(this.getData()));
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
this.setData(this.getData().concat(new Option(option)));
|
|
221
|
+
}
|
|
161
222
|
}
|
|
162
223
|
setSelectedBy(selectedType, selectedValues) {
|
|
163
224
|
let firstOption = null;
|
|
164
225
|
let hasSelected = false;
|
|
226
|
+
const selectedObjects = [];
|
|
165
227
|
for (let dataObj of this.data) {
|
|
166
228
|
if (dataObj instanceof Optgroup) {
|
|
167
229
|
for (let option of dataObj.options) {
|
|
@@ -169,8 +231,11 @@
|
|
|
169
231
|
firstOption = option;
|
|
170
232
|
}
|
|
171
233
|
option.selected = hasSelected ? false : selectedValues.includes(option[selectedType]);
|
|
172
|
-
if (option.selected
|
|
173
|
-
|
|
234
|
+
if (option.selected) {
|
|
235
|
+
selectedObjects.push(option);
|
|
236
|
+
if (this.selectType === 'single') {
|
|
237
|
+
hasSelected = true;
|
|
238
|
+
}
|
|
174
239
|
}
|
|
175
240
|
}
|
|
176
241
|
}
|
|
@@ -179,36 +244,35 @@
|
|
|
179
244
|
firstOption = dataObj;
|
|
180
245
|
}
|
|
181
246
|
dataObj.selected = hasSelected ? false : selectedValues.includes(dataObj[selectedType]);
|
|
182
|
-
if (dataObj.selected
|
|
183
|
-
|
|
247
|
+
if (dataObj.selected) {
|
|
248
|
+
selectedObjects.push(dataObj);
|
|
249
|
+
if (this.selectType === 'single') {
|
|
250
|
+
hasSelected = true;
|
|
251
|
+
}
|
|
184
252
|
}
|
|
185
253
|
}
|
|
186
254
|
}
|
|
187
255
|
if (this.selectType === 'single' && firstOption && !hasSelected) {
|
|
188
256
|
firstOption.selected = true;
|
|
257
|
+
selectedObjects.push(firstOption);
|
|
189
258
|
}
|
|
259
|
+
const selectedIds = selectedValues.map((value) => {
|
|
260
|
+
var _a;
|
|
261
|
+
return ((_a = selectedObjects.find((option) => option[selectedType] === value)) === null || _a === void 0 ? void 0 : _a.id) || '';
|
|
262
|
+
});
|
|
263
|
+
this.selectedOrder = selectedIds;
|
|
190
264
|
}
|
|
191
265
|
getSelected() {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
});
|
|
197
|
-
return selectedValues;
|
|
266
|
+
return this.getSelectedOptions().map((option) => option.id);
|
|
267
|
+
}
|
|
268
|
+
getSelectedValues() {
|
|
269
|
+
return this.getSelectedOptions().map((option) => option.value);
|
|
198
270
|
}
|
|
199
271
|
getSelectedOptions() {
|
|
200
272
|
return this.filter((opt) => {
|
|
201
273
|
return opt.selected;
|
|
202
274
|
}, false);
|
|
203
275
|
}
|
|
204
|
-
getSelectedIDs() {
|
|
205
|
-
let selectedOptions = this.getSelectedOptions();
|
|
206
|
-
let selectedIDs = [];
|
|
207
|
-
selectedOptions.forEach((op) => {
|
|
208
|
-
selectedIDs.push(op.id);
|
|
209
|
-
});
|
|
210
|
-
return selectedIDs;
|
|
211
|
-
}
|
|
212
276
|
getOptgroupByID(id) {
|
|
213
277
|
for (let dataObj of this.data) {
|
|
214
278
|
if (dataObj instanceof Optgroup && dataObj.id === id) {
|
|
@@ -279,54 +343,35 @@
|
|
|
279
343
|
});
|
|
280
344
|
return dataSearch;
|
|
281
345
|
}
|
|
346
|
+
selectedOrderOptions(options) {
|
|
347
|
+
const newOrder = [];
|
|
348
|
+
this.selectedOrder.forEach((id) => {
|
|
349
|
+
const option = options.find((opt) => opt.id === id);
|
|
350
|
+
if (option) {
|
|
351
|
+
newOrder.push(option);
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
options.forEach((option) => {
|
|
355
|
+
let isIn = false;
|
|
356
|
+
newOrder.forEach((selectedOption) => {
|
|
357
|
+
if (option.id === selectedOption.id) {
|
|
358
|
+
isIn = true;
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
if (!isIn) {
|
|
363
|
+
newOrder.push(option);
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
return newOrder;
|
|
367
|
+
}
|
|
282
368
|
}
|
|
283
369
|
|
|
284
370
|
class Render {
|
|
285
|
-
constructor(settings, store, callbacks) {
|
|
286
|
-
this.classes = {
|
|
287
|
-
main: 'ss-main',
|
|
288
|
-
placeholder: 'ss-placeholder',
|
|
289
|
-
values: 'ss-values',
|
|
290
|
-
single: 'ss-single',
|
|
291
|
-
max: 'ss-max',
|
|
292
|
-
value: 'ss-value',
|
|
293
|
-
valueText: 'ss-value-text',
|
|
294
|
-
valueDelete: 'ss-value-delete',
|
|
295
|
-
valueOut: 'ss-value-out',
|
|
296
|
-
deselect: 'ss-deselect',
|
|
297
|
-
deselectPath: 'M10,10 L90,90 M10,90 L90,10',
|
|
298
|
-
arrow: 'ss-arrow',
|
|
299
|
-
arrowClose: 'M10,30 L50,70 L90,30',
|
|
300
|
-
arrowOpen: 'M10,70 L50,30 L90,70',
|
|
301
|
-
content: 'ss-content',
|
|
302
|
-
openAbove: 'ss-open-above',
|
|
303
|
-
openBelow: 'ss-open-below',
|
|
304
|
-
search: 'ss-search',
|
|
305
|
-
searchHighlighter: 'ss-search-highlight',
|
|
306
|
-
searching: 'ss-searching',
|
|
307
|
-
addable: 'ss-addable',
|
|
308
|
-
addablePath: 'M50,10 L50,90 M10,50 L90,50',
|
|
309
|
-
list: 'ss-list',
|
|
310
|
-
optgroup: 'ss-optgroup',
|
|
311
|
-
optgroupLabel: 'ss-optgroup-label',
|
|
312
|
-
optgroupLabelText: 'ss-optgroup-label-text',
|
|
313
|
-
optgroupActions: 'ss-optgroup-actions',
|
|
314
|
-
optgroupSelectAll: 'ss-selectall',
|
|
315
|
-
optgroupSelectAllBox: 'M60,10 L10,10 L10,90 L90,90 L90,50',
|
|
316
|
-
optgroupSelectAllCheck: 'M30,45 L50,70 L90,10',
|
|
317
|
-
optgroupClosable: 'ss-closable',
|
|
318
|
-
option: 'ss-option',
|
|
319
|
-
optionDelete: 'M10,10 L90,90 M10,90 L90,10',
|
|
320
|
-
highlighted: 'ss-highlighted',
|
|
321
|
-
open: 'ss-open',
|
|
322
|
-
close: 'ss-close',
|
|
323
|
-
selected: 'ss-selected',
|
|
324
|
-
error: 'ss-error',
|
|
325
|
-
disabled: 'ss-disabled',
|
|
326
|
-
hide: 'ss-hide',
|
|
327
|
-
};
|
|
371
|
+
constructor(settings, classes, store, callbacks) {
|
|
328
372
|
this.store = store;
|
|
329
373
|
this.settings = settings;
|
|
374
|
+
this.classes = classes;
|
|
330
375
|
this.callbacks = callbacks;
|
|
331
376
|
this.main = this.mainDiv();
|
|
332
377
|
this.content = this.contentDiv();
|
|
@@ -422,7 +467,7 @@
|
|
|
422
467
|
this.callbacks.close();
|
|
423
468
|
return false;
|
|
424
469
|
}
|
|
425
|
-
return
|
|
470
|
+
return true;
|
|
426
471
|
};
|
|
427
472
|
main.onclick = (e) => {
|
|
428
473
|
if (this.settings.disabled) {
|
|
@@ -460,8 +505,8 @@
|
|
|
460
505
|
}
|
|
461
506
|
else {
|
|
462
507
|
const firstOption = this.store.getFirstOption();
|
|
463
|
-
const
|
|
464
|
-
this.callbacks.setSelected(
|
|
508
|
+
const id = firstOption ? firstOption.id : '';
|
|
509
|
+
this.callbacks.setSelected(id, false);
|
|
465
510
|
}
|
|
466
511
|
if (this.settings.closeOnSelect) {
|
|
467
512
|
this.callbacks.close();
|
|
@@ -494,12 +539,12 @@
|
|
|
494
539
|
deselect: {
|
|
495
540
|
main: deselect,
|
|
496
541
|
svg: deselectSvg,
|
|
497
|
-
path: deselectPath
|
|
542
|
+
path: deselectPath
|
|
498
543
|
},
|
|
499
544
|
arrow: {
|
|
500
545
|
main: arrow,
|
|
501
|
-
path: arrowPath
|
|
502
|
-
}
|
|
546
|
+
path: arrowPath
|
|
547
|
+
}
|
|
503
548
|
};
|
|
504
549
|
}
|
|
505
550
|
mainFocus(eventType) {
|
|
@@ -585,6 +630,9 @@
|
|
|
585
630
|
maxValuesMessage.remove();
|
|
586
631
|
}
|
|
587
632
|
}
|
|
633
|
+
if (this.settings.keepOrder) {
|
|
634
|
+
selectedOptions = this.store.selectedOrderOptions(selectedOptions);
|
|
635
|
+
}
|
|
588
636
|
let removeNodes = [];
|
|
589
637
|
for (let i = 0; i < currentNodes.length; i++) {
|
|
590
638
|
const node = currentNodes[i];
|
|
@@ -638,7 +686,7 @@
|
|
|
638
686
|
value.dataset.id = option.id;
|
|
639
687
|
const text = document.createElement('div');
|
|
640
688
|
text.classList.add(this.classes.valueText);
|
|
641
|
-
text.
|
|
689
|
+
text.textContent = option.text;
|
|
642
690
|
value.appendChild(text);
|
|
643
691
|
if (!option.mandatory) {
|
|
644
692
|
const deleteDiv = document.createElement('div');
|
|
@@ -661,18 +709,18 @@
|
|
|
661
709
|
shouldDelete = this.callbacks.beforeChange(after, before) === true;
|
|
662
710
|
}
|
|
663
711
|
if (shouldDelete) {
|
|
664
|
-
let
|
|
712
|
+
let selectedIds = [];
|
|
665
713
|
for (const o of after) {
|
|
666
714
|
if (o instanceof Optgroup) {
|
|
667
715
|
for (const c of o.options) {
|
|
668
|
-
|
|
716
|
+
selectedIds.push(c.id);
|
|
669
717
|
}
|
|
670
718
|
}
|
|
671
719
|
if (o instanceof Option) {
|
|
672
|
-
|
|
720
|
+
selectedIds.push(o.id);
|
|
673
721
|
}
|
|
674
722
|
}
|
|
675
|
-
this.callbacks.setSelected(
|
|
723
|
+
this.callbacks.setSelected(selectedIds, false);
|
|
676
724
|
if (this.settings.closeOnSelect) {
|
|
677
725
|
this.callbacks.close();
|
|
678
726
|
}
|
|
@@ -702,7 +750,7 @@
|
|
|
702
750
|
return {
|
|
703
751
|
main: main,
|
|
704
752
|
search: search,
|
|
705
|
-
list: list
|
|
753
|
+
list: list
|
|
706
754
|
};
|
|
707
755
|
}
|
|
708
756
|
moveContent() {
|
|
@@ -732,7 +780,7 @@
|
|
|
732
780
|
main.classList.add(this.classes.search);
|
|
733
781
|
const searchReturn = {
|
|
734
782
|
main,
|
|
735
|
-
input
|
|
783
|
+
input
|
|
736
784
|
};
|
|
737
785
|
if (!this.settings.showSearch) {
|
|
738
786
|
main.classList.add(this.classes.hide);
|
|
@@ -760,9 +808,15 @@
|
|
|
760
808
|
case 'Escape':
|
|
761
809
|
this.callbacks.close();
|
|
762
810
|
return false;
|
|
763
|
-
case 'Enter':
|
|
764
811
|
case ' ':
|
|
765
|
-
|
|
812
|
+
const highlighted = this.content.list.querySelector('.' + this.classes.highlighted);
|
|
813
|
+
if (highlighted) {
|
|
814
|
+
highlighted.click();
|
|
815
|
+
return false;
|
|
816
|
+
}
|
|
817
|
+
return true;
|
|
818
|
+
case 'Enter':
|
|
819
|
+
if (this.callbacks.addable) {
|
|
766
820
|
addable.click();
|
|
767
821
|
return false;
|
|
768
822
|
}
|
|
@@ -801,12 +855,12 @@
|
|
|
801
855
|
let newOption = new Option(oo);
|
|
802
856
|
this.callbacks.addOption(newOption);
|
|
803
857
|
if (this.settings.isMultiple) {
|
|
804
|
-
let
|
|
805
|
-
|
|
806
|
-
this.callbacks.setSelected(
|
|
858
|
+
let ids = this.store.getSelected();
|
|
859
|
+
ids.push(newOption.id);
|
|
860
|
+
this.callbacks.setSelected(ids, true);
|
|
807
861
|
}
|
|
808
862
|
else {
|
|
809
|
-
this.callbacks.setSelected([newOption.
|
|
863
|
+
this.callbacks.setSelected([newOption.id], true);
|
|
810
864
|
}
|
|
811
865
|
this.callbacks.search('');
|
|
812
866
|
if (this.settings.closeOnSelect) {
|
|
@@ -824,9 +878,12 @@
|
|
|
824
878
|
if (typeof value === 'string') {
|
|
825
879
|
runFinish({
|
|
826
880
|
text: value,
|
|
827
|
-
value: value
|
|
881
|
+
value: value
|
|
828
882
|
});
|
|
829
883
|
}
|
|
884
|
+
else if (addableValue instanceof Error) {
|
|
885
|
+
this.renderError(addableValue.message);
|
|
886
|
+
}
|
|
830
887
|
else {
|
|
831
888
|
runFinish(value);
|
|
832
889
|
}
|
|
@@ -835,9 +892,12 @@
|
|
|
835
892
|
else if (typeof addableValue === 'string') {
|
|
836
893
|
runFinish({
|
|
837
894
|
text: addableValue,
|
|
838
|
-
value: addableValue
|
|
895
|
+
value: addableValue
|
|
839
896
|
});
|
|
840
897
|
}
|
|
898
|
+
else if (addableValue instanceof Error) {
|
|
899
|
+
this.renderError(addableValue.message);
|
|
900
|
+
}
|
|
841
901
|
else {
|
|
842
902
|
runFinish(addableValue);
|
|
843
903
|
}
|
|
@@ -847,7 +907,7 @@
|
|
|
847
907
|
searchReturn.addable = {
|
|
848
908
|
main: addable,
|
|
849
909
|
svg: plus,
|
|
850
|
-
path: plusPath
|
|
910
|
+
path: plusPath
|
|
851
911
|
};
|
|
852
912
|
}
|
|
853
913
|
return searchReturn;
|
|
@@ -944,10 +1004,26 @@
|
|
|
944
1004
|
if (data.length === 0) {
|
|
945
1005
|
const noResults = document.createElement('div');
|
|
946
1006
|
noResults.classList.add(this.classes.search);
|
|
947
|
-
|
|
1007
|
+
if (this.callbacks.addable) {
|
|
1008
|
+
noResults.innerHTML = this.settings.addableText.replace('{value}', this.content.search.input.value);
|
|
1009
|
+
}
|
|
1010
|
+
else {
|
|
1011
|
+
noResults.innerHTML = this.settings.searchText;
|
|
1012
|
+
}
|
|
948
1013
|
this.content.list.appendChild(noResults);
|
|
949
1014
|
return;
|
|
950
1015
|
}
|
|
1016
|
+
if (this.settings.allowDeselect && !this.settings.isMultiple) {
|
|
1017
|
+
const placeholderOption = this.store.filter((o) => o.placeholder, false);
|
|
1018
|
+
if (!placeholderOption.length) {
|
|
1019
|
+
this.store.addOption(new Option({
|
|
1020
|
+
text: '',
|
|
1021
|
+
value: '',
|
|
1022
|
+
selected: false,
|
|
1023
|
+
placeholder: true
|
|
1024
|
+
}), true);
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
951
1027
|
for (const d of data) {
|
|
952
1028
|
if (d instanceof Optgroup) {
|
|
953
1029
|
const optgroupEl = document.createElement('div');
|
|
@@ -994,7 +1070,7 @@
|
|
|
994
1070
|
if (allSelected) {
|
|
995
1071
|
const newSelected = currentSelected.filter((s) => {
|
|
996
1072
|
for (const o of d.options) {
|
|
997
|
-
if (s === o.
|
|
1073
|
+
if (s === o.id) {
|
|
998
1074
|
return false;
|
|
999
1075
|
}
|
|
1000
1076
|
}
|
|
@@ -1004,7 +1080,7 @@
|
|
|
1004
1080
|
return;
|
|
1005
1081
|
}
|
|
1006
1082
|
else {
|
|
1007
|
-
const newSelected = currentSelected.concat(d.options.map((o) => o.
|
|
1083
|
+
const newSelected = currentSelected.concat(d.options.map((o) => o.id));
|
|
1008
1084
|
for (const o of d.options) {
|
|
1009
1085
|
if (!this.store.getOptionByID(o.id)) {
|
|
1010
1086
|
this.callbacks.addOption(o);
|
|
@@ -1161,7 +1237,7 @@
|
|
|
1161
1237
|
if (!this.store.getOptionByID(elementID)) {
|
|
1162
1238
|
this.callbacks.addOption(option);
|
|
1163
1239
|
}
|
|
1164
|
-
this.callbacks.setSelected(after.map((o) => o.
|
|
1240
|
+
this.callbacks.setSelected(after.map((o) => o.id), false);
|
|
1165
1241
|
if (this.settings.closeOnSelect) {
|
|
1166
1242
|
this.callbacks.close();
|
|
1167
1243
|
}
|
|
@@ -1178,7 +1254,7 @@
|
|
|
1178
1254
|
}
|
|
1179
1255
|
highlightText(str, search, className) {
|
|
1180
1256
|
let completedString = str;
|
|
1181
|
-
const regex = new RegExp('(' + search.trim() + ')(?![^<]*>[^<>]*</)', 'i');
|
|
1257
|
+
const regex = new RegExp('(?![^<]*>)(' + search.trim() + ')(?![^<]*>[^<>]*</)', 'i');
|
|
1182
1258
|
if (!str.match(regex)) {
|
|
1183
1259
|
return str;
|
|
1184
1260
|
}
|
|
@@ -1267,7 +1343,7 @@
|
|
|
1267
1343
|
this.select = select;
|
|
1268
1344
|
this.valueChange = this.valueChange.bind(this);
|
|
1269
1345
|
this.select.addEventListener('change', this.valueChange, {
|
|
1270
|
-
passive: true
|
|
1346
|
+
passive: true
|
|
1271
1347
|
});
|
|
1272
1348
|
this.observer = new MutationObserver(this.observeCall.bind(this));
|
|
1273
1349
|
this.changeListen(true);
|
|
@@ -1295,7 +1371,7 @@
|
|
|
1295
1371
|
this.observer.observe(this.select, {
|
|
1296
1372
|
subtree: true,
|
|
1297
1373
|
childList: true,
|
|
1298
|
-
attributes: true
|
|
1374
|
+
attributes: true
|
|
1299
1375
|
});
|
|
1300
1376
|
}
|
|
1301
1377
|
}
|
|
@@ -1307,7 +1383,7 @@
|
|
|
1307
1383
|
}
|
|
1308
1384
|
valueChange(ev) {
|
|
1309
1385
|
if (this.listen && this.onValueChange) {
|
|
1310
|
-
this.onValueChange(this.
|
|
1386
|
+
this.onValueChange(this.getSelectedOptions());
|
|
1311
1387
|
}
|
|
1312
1388
|
return true;
|
|
1313
1389
|
}
|
|
@@ -1326,6 +1402,15 @@
|
|
|
1326
1402
|
if (m.attributeName === 'class') {
|
|
1327
1403
|
classChanged = true;
|
|
1328
1404
|
}
|
|
1405
|
+
if (m.type === 'childList') {
|
|
1406
|
+
for (const n of m.addedNodes) {
|
|
1407
|
+
if (n.nodeName === 'OPTION' && n.value === this.select.value) {
|
|
1408
|
+
this.select.dispatchEvent(new Event('change'));
|
|
1409
|
+
break;
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
optgroupOptionChanged = true;
|
|
1413
|
+
}
|
|
1329
1414
|
}
|
|
1330
1415
|
if (m.target.nodeName === 'OPTGROUP' || m.target.nodeName === 'OPTION') {
|
|
1331
1416
|
optgroupOptionChanged = true;
|
|
@@ -1365,7 +1450,7 @@
|
|
|
1365
1450
|
selectAll: optgroup.dataset ? optgroup.dataset.selectall === 'true' : false,
|
|
1366
1451
|
selectAllText: optgroup.dataset ? optgroup.dataset.selectalltext : 'Select all',
|
|
1367
1452
|
closable: optgroup.dataset ? optgroup.dataset.closable : 'off',
|
|
1368
|
-
options: []
|
|
1453
|
+
options: []
|
|
1369
1454
|
};
|
|
1370
1455
|
const options = optgroup.childNodes;
|
|
1371
1456
|
for (const o of options) {
|
|
@@ -1382,26 +1467,26 @@
|
|
|
1382
1467
|
text: option.text,
|
|
1383
1468
|
html: option.dataset && option.dataset.html ? option.dataset.html : '',
|
|
1384
1469
|
selected: option.selected,
|
|
1385
|
-
display: option.style.display
|
|
1470
|
+
display: option.style.display !== 'none',
|
|
1386
1471
|
disabled: option.disabled,
|
|
1387
1472
|
mandatory: option.dataset ? option.dataset.mandatory === 'true' : false,
|
|
1388
1473
|
placeholder: option.dataset.placeholder === 'true',
|
|
1389
1474
|
class: option.className,
|
|
1390
1475
|
style: option.style.cssText,
|
|
1391
|
-
data: option.dataset
|
|
1476
|
+
data: option.dataset
|
|
1392
1477
|
};
|
|
1393
1478
|
}
|
|
1394
|
-
|
|
1395
|
-
let
|
|
1396
|
-
const
|
|
1397
|
-
for (const o of
|
|
1479
|
+
getSelectedOptions() {
|
|
1480
|
+
let options = [];
|
|
1481
|
+
const opts = this.select.childNodes;
|
|
1482
|
+
for (const o of opts) {
|
|
1398
1483
|
if (o.nodeName === 'OPTGROUP') {
|
|
1399
1484
|
const optgroupOptions = o.childNodes;
|
|
1400
1485
|
for (const oo of optgroupOptions) {
|
|
1401
1486
|
if (oo.nodeName === 'OPTION') {
|
|
1402
1487
|
const option = oo;
|
|
1403
1488
|
if (option.selected) {
|
|
1404
|
-
|
|
1489
|
+
options.push(this.getDataFromOption(option));
|
|
1405
1490
|
}
|
|
1406
1491
|
}
|
|
1407
1492
|
}
|
|
@@ -1409,13 +1494,16 @@
|
|
|
1409
1494
|
if (o.nodeName === 'OPTION') {
|
|
1410
1495
|
const option = o;
|
|
1411
1496
|
if (option.selected) {
|
|
1412
|
-
|
|
1497
|
+
options.push(this.getDataFromOption(option));
|
|
1413
1498
|
}
|
|
1414
1499
|
}
|
|
1415
1500
|
}
|
|
1416
|
-
return
|
|
1501
|
+
return options;
|
|
1417
1502
|
}
|
|
1418
|
-
|
|
1503
|
+
getSelectedValues() {
|
|
1504
|
+
return this.getSelectedOptions().map((option) => option.value);
|
|
1505
|
+
}
|
|
1506
|
+
setSelected(ids) {
|
|
1419
1507
|
this.changeListen(false);
|
|
1420
1508
|
const options = this.select.childNodes;
|
|
1421
1509
|
for (const o of options) {
|
|
@@ -1425,13 +1513,34 @@
|
|
|
1425
1513
|
for (const oo of optgroupOptions) {
|
|
1426
1514
|
if (oo.nodeName === 'OPTION') {
|
|
1427
1515
|
const option = oo;
|
|
1428
|
-
option.selected =
|
|
1516
|
+
option.selected = ids.includes(option.id);
|
|
1429
1517
|
}
|
|
1430
1518
|
}
|
|
1431
1519
|
}
|
|
1432
1520
|
if (o.nodeName === 'OPTION') {
|
|
1433
1521
|
const option = o;
|
|
1434
|
-
option.selected =
|
|
1522
|
+
option.selected = ids.includes(option.id);
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
this.changeListen(true);
|
|
1526
|
+
}
|
|
1527
|
+
setSelectedByValue(values) {
|
|
1528
|
+
this.changeListen(false);
|
|
1529
|
+
const options = this.select.childNodes;
|
|
1530
|
+
for (const o of options) {
|
|
1531
|
+
if (o.nodeName === 'OPTGROUP') {
|
|
1532
|
+
const optgroup = o;
|
|
1533
|
+
const optgroupOptions = optgroup.childNodes;
|
|
1534
|
+
for (const oo of optgroupOptions) {
|
|
1535
|
+
if (oo.nodeName === 'OPTION') {
|
|
1536
|
+
const option = oo;
|
|
1537
|
+
option.selected = values.includes(option.value);
|
|
1538
|
+
}
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1541
|
+
if (o.nodeName === 'OPTION') {
|
|
1542
|
+
const option = o;
|
|
1543
|
+
option.selected = values.includes(option.value);
|
|
1435
1544
|
}
|
|
1436
1545
|
}
|
|
1437
1546
|
this.changeListen(true);
|
|
@@ -1465,7 +1574,7 @@
|
|
|
1465
1574
|
this.select.appendChild(this.createOption(d));
|
|
1466
1575
|
}
|
|
1467
1576
|
}
|
|
1468
|
-
this.select.dispatchEvent(new Event('change'));
|
|
1577
|
+
this.select.dispatchEvent(new Event('change', { bubbles: true }));
|
|
1469
1578
|
this.changeListen(true);
|
|
1470
1579
|
}
|
|
1471
1580
|
createOptgroup(optgroup) {
|
|
@@ -1499,7 +1608,7 @@
|
|
|
1499
1608
|
if (info.disabled) {
|
|
1500
1609
|
optionEl.disabled = true;
|
|
1501
1610
|
}
|
|
1502
|
-
if (info.display
|
|
1611
|
+
if (!info.display) {
|
|
1503
1612
|
optionEl.style.display = 'none';
|
|
1504
1613
|
}
|
|
1505
1614
|
if (info.placeholder) {
|
|
@@ -1550,6 +1659,7 @@
|
|
|
1550
1659
|
this.disabled = settings.disabled !== undefined ? settings.disabled : false;
|
|
1551
1660
|
this.alwaysOpen = settings.alwaysOpen !== undefined ? settings.alwaysOpen : false;
|
|
1552
1661
|
this.showSearch = settings.showSearch !== undefined ? settings.showSearch : true;
|
|
1662
|
+
this.focusSearch = settings.focusSearch !== undefined ? settings.focusSearch : true;
|
|
1553
1663
|
this.ariaLabel = settings.ariaLabel || 'Combobox';
|
|
1554
1664
|
this.searchPlaceholder = settings.searchPlaceholder || 'Search';
|
|
1555
1665
|
this.searchText = settings.searchText || 'No Results';
|
|
@@ -1569,6 +1679,7 @@
|
|
|
1569
1679
|
this.timeoutDelay = settings.timeoutDelay || 200;
|
|
1570
1680
|
this.maxValuesShown = settings.maxValuesShown || 20;
|
|
1571
1681
|
this.maxValuesMessage = settings.maxValuesMessage || '{number} selected';
|
|
1682
|
+
this.addableText = settings.addableText || 'Press "Enter" to add {value}';
|
|
1572
1683
|
}
|
|
1573
1684
|
}
|
|
1574
1685
|
|
|
@@ -1586,7 +1697,7 @@
|
|
|
1586
1697
|
beforeOpen: undefined,
|
|
1587
1698
|
afterOpen: undefined,
|
|
1588
1699
|
beforeClose: undefined,
|
|
1589
|
-
afterClose: undefined
|
|
1700
|
+
afterClose: undefined
|
|
1590
1701
|
};
|
|
1591
1702
|
this.windowResize = debounce(() => {
|
|
1592
1703
|
if (!this.settings.isOpen && !this.settings.isFullOpen) {
|
|
@@ -1630,6 +1741,7 @@
|
|
|
1630
1741
|
this.destroy();
|
|
1631
1742
|
}
|
|
1632
1743
|
this.settings = new Settings(config.settings);
|
|
1744
|
+
this.cssClasses = new CssClasses(config.cssClasses);
|
|
1633
1745
|
const debounceEvents = ['afterChange', 'beforeOpen', 'afterOpen', 'beforeClose', 'afterClose'];
|
|
1634
1746
|
for (const key in config.events) {
|
|
1635
1747
|
if (!config.events.hasOwnProperty(key)) {
|
|
@@ -1649,8 +1761,8 @@
|
|
|
1649
1761
|
this.select = new Select(this.selectEl);
|
|
1650
1762
|
this.select.updateSelect(this.settings.id, this.settings.style, this.settings.class);
|
|
1651
1763
|
this.select.hideUI();
|
|
1652
|
-
this.select.onValueChange = (
|
|
1653
|
-
this.setSelected(
|
|
1764
|
+
this.select.onValueChange = (options) => {
|
|
1765
|
+
this.setSelected(options.map((option) => option.id));
|
|
1654
1766
|
};
|
|
1655
1767
|
this.select.onClassChange = (classes) => {
|
|
1656
1768
|
this.settings.class = classes;
|
|
@@ -1679,9 +1791,9 @@
|
|
|
1679
1791
|
addOption: this.addOption.bind(this),
|
|
1680
1792
|
search: this.search.bind(this),
|
|
1681
1793
|
beforeChange: this.events.beforeChange,
|
|
1682
|
-
afterChange: this.events.afterChange
|
|
1794
|
+
afterChange: this.events.afterChange
|
|
1683
1795
|
};
|
|
1684
|
-
this.render = new Render(this.settings, this.store, renderCallbacks);
|
|
1796
|
+
this.render = new Render(this.settings, this.cssClasses, this.store, renderCallbacks);
|
|
1685
1797
|
this.render.renderValues();
|
|
1686
1798
|
this.render.renderOptions(this.store.getData());
|
|
1687
1799
|
const selectAriaLabel = this.selectEl.getAttribute('aria-label');
|
|
@@ -1740,11 +1852,27 @@
|
|
|
1740
1852
|
}
|
|
1741
1853
|
}
|
|
1742
1854
|
getSelected() {
|
|
1743
|
-
|
|
1855
|
+
let options = this.store.getSelectedOptions();
|
|
1856
|
+
if (this.settings.keepOrder) {
|
|
1857
|
+
options = this.store.selectedOrderOptions(options);
|
|
1858
|
+
}
|
|
1859
|
+
return options.map((option) => option.value);
|
|
1744
1860
|
}
|
|
1745
|
-
setSelected(
|
|
1861
|
+
setSelected(values, runAfterChange = true) {
|
|
1746
1862
|
const selected = this.store.getSelected();
|
|
1747
|
-
this.store.
|
|
1863
|
+
const options = this.store.getDataOptions();
|
|
1864
|
+
values = Array.isArray(values) ? values : [values];
|
|
1865
|
+
const ids = [];
|
|
1866
|
+
for (const value of values) {
|
|
1867
|
+
if (options.find((option) => option.id == value)) {
|
|
1868
|
+
ids.push(value);
|
|
1869
|
+
continue;
|
|
1870
|
+
}
|
|
1871
|
+
for (const option of options.filter((option) => option.value == value)) {
|
|
1872
|
+
ids.push(option.id);
|
|
1873
|
+
}
|
|
1874
|
+
}
|
|
1875
|
+
this.store.setSelectedBy('id', ids);
|
|
1748
1876
|
const data = this.store.getData();
|
|
1749
1877
|
this.select.updateOptions(data);
|
|
1750
1878
|
this.render.renderValues();
|
|
@@ -1779,7 +1907,7 @@
|
|
|
1779
1907
|
this.events.beforeOpen();
|
|
1780
1908
|
}
|
|
1781
1909
|
this.render.open();
|
|
1782
|
-
if (this.settings.showSearch) {
|
|
1910
|
+
if (this.settings.showSearch && this.settings.focusSearch) {
|
|
1783
1911
|
this.render.searchFocus();
|
|
1784
1912
|
}
|
|
1785
1913
|
this.settings.isOpen = true;
|