selective-ui 1.4.0 → 1.4.2
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/dist/selective-ui.css +2 -2
- package/dist/selective-ui.css.map +1 -1
- package/dist/selective-ui.esm.js +407 -573
- package/dist/selective-ui.esm.js.map +1 -1
- package/dist/selective-ui.esm.min.js +2 -2
- package/dist/selective-ui.esm.min.js.br +0 -0
- package/dist/selective-ui.min.css +1 -1
- package/dist/selective-ui.min.css.br +0 -0
- package/dist/selective-ui.min.js +2 -2
- package/dist/selective-ui.min.js.br +0 -0
- package/dist/selective-ui.umd.js +409 -575
- package/dist/selective-ui.umd.js.map +1 -1
- package/package.json +12 -12
- package/src/css/views/option-view.css +2 -2
- package/src/ts/adapter/mixed-adapter.ts +149 -71
- package/src/ts/components/accessorybox.ts +14 -11
- package/src/ts/components/directive.ts +1 -1
- package/src/ts/components/option-handle.ts +12 -9
- package/src/ts/components/placeholder.ts +5 -5
- package/src/ts/components/popup/empty-state.ts +5 -5
- package/src/ts/components/popup/loading-state.ts +5 -5
- package/src/ts/components/popup/popup.ts +138 -76
- package/src/ts/components/searchbox.ts +17 -13
- package/src/ts/components/selectbox.ts +260 -84
- package/src/ts/core/base/adapter.ts +61 -14
- package/src/ts/core/base/fenwick.ts +3 -2
- package/src/ts/core/base/lifecycle.ts +14 -4
- package/src/ts/core/base/model.ts +17 -15
- package/src/ts/core/base/recyclerview.ts +7 -5
- package/src/ts/core/base/view.ts +10 -5
- package/src/ts/core/base/virtual-recyclerview.ts +178 -45
- package/src/ts/core/model-manager.ts +48 -21
- package/src/ts/core/search-controller.ts +174 -56
- package/src/ts/global.ts +5 -8
- package/src/ts/index.ts +2 -2
- package/src/ts/models/group-model.ts +33 -8
- package/src/ts/models/option-model.ts +88 -20
- package/src/ts/services/dataset-observer.ts +6 -3
- package/src/ts/services/ea-observer.ts +1 -1
- package/src/ts/services/effector.ts +22 -12
- package/src/ts/services/refresher.ts +14 -4
- package/src/ts/services/resize-observer.ts +24 -11
- package/src/ts/services/select-observer.ts +2 -2
- package/src/ts/types/components/popup.type.ts +18 -1
- package/src/ts/types/components/searchbox.type.ts +43 -30
- package/src/ts/types/components/state.box.type.ts +1 -1
- package/src/ts/types/core/base/adapter.type.ts +13 -5
- package/src/ts/types/core/base/lifecycle.type.ts +1 -2
- package/src/ts/types/core/base/model.type.ts +3 -3
- package/src/ts/types/core/base/recyclerview.type.ts +7 -5
- package/src/ts/types/core/base/view.type.ts +6 -6
- package/src/ts/types/core/base/virtual-recyclerview.type.ts +45 -46
- package/src/ts/types/core/search-controller.type.ts +18 -2
- package/src/ts/types/css.d.ts +1 -0
- package/src/ts/types/plugins/plugin.type.ts +2 -2
- package/src/ts/types/services/effector.type.ts +25 -25
- package/src/ts/types/services/resize-observer.type.ts +23 -12
- package/src/ts/types/utils/callback-scheduler.type.ts +2 -2
- package/src/ts/types/utils/ievents.type.ts +1 -1
- package/src/ts/types/utils/istorage.type.ts +62 -60
- package/src/ts/types/utils/libs.type.ts +19 -17
- package/src/ts/types/utils/selective.type.ts +6 -3
- package/src/ts/types/views/view.group.type.ts +9 -5
- package/src/ts/types/views/view.option.type.ts +39 -17
- package/src/ts/utils/callback-scheduler.ts +12 -7
- package/src/ts/utils/ievents.ts +12 -5
- package/src/ts/utils/istorage.ts +5 -3
- package/src/ts/utils/libs.ts +122 -43
- package/src/ts/utils/selective.ts +15 -8
- package/src/ts/views/group-view.ts +11 -9
- package/src/ts/views/option-view.ts +37 -18
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
import { Libs } from "../utils/libs";
|
|
3
2
|
import { Refresher } from "../services/refresher";
|
|
4
3
|
import { PlaceHolder } from "./placeholder";
|
|
@@ -23,11 +22,18 @@ import type { SelectiveOptions } from "../types/utils/selective.type";
|
|
|
23
22
|
import { IEventToken, IEventCallback } from "../types/utils/ievents.type";
|
|
24
23
|
import { MixedItem } from "../types/core/base/mixed-adapter.type";
|
|
25
24
|
import { BinderMap } from "../types/utils/istorage.type";
|
|
26
|
-
import {
|
|
25
|
+
import {
|
|
26
|
+
ContainerRuntime,
|
|
27
|
+
SelectBoxAction,
|
|
28
|
+
SelectBoxTags,
|
|
29
|
+
} from "../types/components/searchbox.type";
|
|
27
30
|
import { AjaxConfig } from "../types/core/search-controller.type";
|
|
28
31
|
import { Selective } from "../utils/selective";
|
|
29
32
|
import { VirtualRecyclerView } from "../core/base/virtual-recyclerview";
|
|
30
|
-
import type {
|
|
33
|
+
import type {
|
|
34
|
+
PluginContext,
|
|
35
|
+
SelectivePlugin,
|
|
36
|
+
} from "../types/plugins/plugin.type";
|
|
31
37
|
|
|
32
38
|
/**
|
|
33
39
|
* SelectBox
|
|
@@ -97,7 +103,7 @@ export class SelectBox extends Lifecycle {
|
|
|
97
103
|
* Created during {@link init} via {@link Libs.mountNode}, inserted into the DOM during {@link mount},
|
|
98
104
|
* and removed during {@link destroy}.
|
|
99
105
|
*/
|
|
100
|
-
private node
|
|
106
|
+
private node?: HTMLDivElement;
|
|
101
107
|
|
|
102
108
|
/**
|
|
103
109
|
* Parsed configuration (bound from the `<select>` element via binder map).
|
|
@@ -107,7 +113,7 @@ export class SelectBox extends Lifecycle {
|
|
|
107
113
|
*
|
|
108
114
|
* @internal
|
|
109
115
|
*/
|
|
110
|
-
private options
|
|
116
|
+
private options?: SelectiveOptions;
|
|
111
117
|
|
|
112
118
|
/**
|
|
113
119
|
* Manager that owns model resources and bridges the Adapter ↔ RecyclerView pipeline.
|
|
@@ -117,7 +123,7 @@ export class SelectBox extends Lifecycle {
|
|
|
117
123
|
*
|
|
118
124
|
* @internal
|
|
119
125
|
*/
|
|
120
|
-
private optionModelManager
|
|
126
|
+
private optionModelManager?: ModelManager<MixedItem, MixedAdapter>;
|
|
121
127
|
|
|
122
128
|
/**
|
|
123
129
|
* Whether the popup/list UI is currently open.
|
|
@@ -159,7 +165,7 @@ export class SelectBox extends Lifecycle {
|
|
|
159
165
|
*
|
|
160
166
|
* Used to locate the instance wrapper via `Selective.find(...)` and to close other open instances.
|
|
161
167
|
*/
|
|
162
|
-
public Selective
|
|
168
|
+
public Selective?: Selective;
|
|
163
169
|
|
|
164
170
|
/**
|
|
165
171
|
* Registered plugins for this SelectBox instance.
|
|
@@ -169,7 +175,7 @@ export class SelectBox extends Lifecycle {
|
|
|
169
175
|
/**
|
|
170
176
|
* Cached plugin context for this SelectBox instance.
|
|
171
177
|
*/
|
|
172
|
-
private pluginContext
|
|
178
|
+
private pluginContext?: PluginContext<SelectBoxTags>;
|
|
173
179
|
|
|
174
180
|
/**
|
|
175
181
|
* Creates a {@link SelectBox} bound to a native `<select>` element.
|
|
@@ -201,7 +207,10 @@ export class SelectBox extends Lifecycle {
|
|
|
201
207
|
this.options.disabled = value;
|
|
202
208
|
this.node.classList.toggle("disabled", value);
|
|
203
209
|
this.node.setAttribute("aria-disabled", String(value));
|
|
204
|
-
this.container.tags?.ViewPanel?.setAttribute(
|
|
210
|
+
this.container.tags?.ViewPanel?.setAttribute(
|
|
211
|
+
"aria-disabled",
|
|
212
|
+
String(value),
|
|
213
|
+
);
|
|
205
214
|
}
|
|
206
215
|
|
|
207
216
|
/**
|
|
@@ -250,7 +259,7 @@ export class SelectBox extends Lifecycle {
|
|
|
250
259
|
const bindedMap = Libs.getBinderMap<BinderMap>(select);
|
|
251
260
|
this.options = bindedMap.options;
|
|
252
261
|
this.Selective = Selective;
|
|
253
|
-
|
|
262
|
+
|
|
254
263
|
this.init(select);
|
|
255
264
|
}
|
|
256
265
|
|
|
@@ -290,15 +299,22 @@ export class SelectBox extends Lifecycle {
|
|
|
290
299
|
const directive = new Directive();
|
|
291
300
|
const searchbox = new SearchBox(options);
|
|
292
301
|
const effector = Effector();
|
|
293
|
-
const optionModelManager = new ModelManager<MixedItem, MixedAdapter>(
|
|
302
|
+
const optionModelManager = new ModelManager<MixedItem, MixedAdapter>(
|
|
303
|
+
options,
|
|
304
|
+
);
|
|
294
305
|
const accessoryBox = new AccessoryBox(options);
|
|
295
|
-
const searchController = new SearchController(
|
|
306
|
+
const searchController = new SearchController(
|
|
307
|
+
select,
|
|
308
|
+
optionModelManager,
|
|
309
|
+
this,
|
|
310
|
+
);
|
|
296
311
|
|
|
297
312
|
const selectObserver = new SelectObserver(select);
|
|
298
313
|
const datasetObserver = new DatasetObserver(select);
|
|
299
314
|
|
|
300
315
|
// ensure placeholder has id for aria-labelledby usage
|
|
301
|
-
if (placeholder.node)
|
|
316
|
+
if (placeholder.node)
|
|
317
|
+
placeholder.node.id = String(options.SEID_HOLDER ?? "");
|
|
302
318
|
|
|
303
319
|
const container = Libs.mountNode<ContainerRuntime>(
|
|
304
320
|
{
|
|
@@ -311,7 +327,11 @@ export class SelectBox extends Lifecycle {
|
|
|
311
327
|
classList: "seui-view",
|
|
312
328
|
tabIndex: 0,
|
|
313
329
|
onkeydown: (e: KeyboardEvent) => {
|
|
314
|
-
if (
|
|
330
|
+
if (
|
|
331
|
+
e.key === "Enter" ||
|
|
332
|
+
e.key === " " ||
|
|
333
|
+
e.key === "ArrowDown"
|
|
334
|
+
) {
|
|
315
335
|
e.preventDefault();
|
|
316
336
|
this.getAction()?.open();
|
|
317
337
|
}
|
|
@@ -326,7 +346,7 @@ export class SelectBox extends Lifecycle {
|
|
|
326
346
|
},
|
|
327
347
|
},
|
|
328
348
|
},
|
|
329
|
-
null
|
|
349
|
+
null,
|
|
330
350
|
);
|
|
331
351
|
|
|
332
352
|
this.container = container;
|
|
@@ -350,7 +370,9 @@ export class SelectBox extends Lifecycle {
|
|
|
350
370
|
} else {
|
|
351
371
|
optionModelManager.setupRecyclerView(RecyclerView);
|
|
352
372
|
}
|
|
353
|
-
optionModelManager.createModelResources(
|
|
373
|
+
optionModelManager.createModelResources(
|
|
374
|
+
Libs.parseSelectToArray(select),
|
|
375
|
+
);
|
|
354
376
|
|
|
355
377
|
optionModelManager.on("onUpdate", () => {
|
|
356
378
|
container.popup?.triggerResize?.();
|
|
@@ -360,7 +382,7 @@ export class SelectBox extends Lifecycle {
|
|
|
360
382
|
|
|
361
383
|
// Popup
|
|
362
384
|
const popup = new Popup(select, options, optionModelManager);
|
|
363
|
-
container.popup = popup
|
|
385
|
+
container.popup = popup;
|
|
364
386
|
popup!.setupEffector(effector);
|
|
365
387
|
popup!.setupInfiniteScroll(searchController, options);
|
|
366
388
|
|
|
@@ -377,8 +399,19 @@ export class SelectBox extends Lifecycle {
|
|
|
377
399
|
accessoryBox.setRoot(container.tags.ViewPanel);
|
|
378
400
|
accessoryBox.setModelManager(optionModelManager);
|
|
379
401
|
|
|
380
|
-
this.setupEventHandlers(
|
|
381
|
-
|
|
402
|
+
this.setupEventHandlers(
|
|
403
|
+
select,
|
|
404
|
+
container,
|
|
405
|
+
options,
|
|
406
|
+
searchController,
|
|
407
|
+
searchbox,
|
|
408
|
+
);
|
|
409
|
+
this.setupObservers(
|
|
410
|
+
selectObserver,
|
|
411
|
+
datasetObserver,
|
|
412
|
+
select,
|
|
413
|
+
optionModelManager,
|
|
414
|
+
);
|
|
382
415
|
|
|
383
416
|
this.plugins = this.Selective?.getPlugins?.() ?? [];
|
|
384
417
|
if (this.plugins.length) {
|
|
@@ -392,7 +425,9 @@ export class SelectBox extends Lifecycle {
|
|
|
392
425
|
actions: this.getAction(),
|
|
393
426
|
};
|
|
394
427
|
this.pluginContext = pluginContext;
|
|
395
|
-
this.runPluginHook("init", (plugin) =>
|
|
428
|
+
this.runPluginHook("init", (plugin) =>
|
|
429
|
+
plugin.init?.(pluginContext),
|
|
430
|
+
);
|
|
396
431
|
}
|
|
397
432
|
|
|
398
433
|
// Initial states
|
|
@@ -427,12 +462,16 @@ export class SelectBox extends Lifecycle {
|
|
|
427
462
|
select.parentNode?.insertBefore(this.node, select);
|
|
428
463
|
this.node.insertBefore(select, container.tags.ViewPanel);
|
|
429
464
|
|
|
430
|
-
container.tags.ViewPanel.addEventListener(
|
|
431
|
-
|
|
432
|
-
e
|
|
433
|
-
|
|
465
|
+
container.tags.ViewPanel.addEventListener(
|
|
466
|
+
"mousedown",
|
|
467
|
+
(e: MouseEvent) => {
|
|
468
|
+
e.stopPropagation();
|
|
469
|
+
e.preventDefault();
|
|
470
|
+
},
|
|
471
|
+
);
|
|
434
472
|
|
|
435
473
|
Refresher.resizeBox(select, container.tags.ViewPanel);
|
|
474
|
+
Refresher.resizeBox(select, this.node, true);
|
|
436
475
|
select.classList.add("init");
|
|
437
476
|
|
|
438
477
|
// initial mask
|
|
@@ -495,10 +534,10 @@ export class SelectBox extends Lifecycle {
|
|
|
495
534
|
container: ContainerRuntime,
|
|
496
535
|
options: SelectiveOptions,
|
|
497
536
|
searchController: SearchController,
|
|
498
|
-
searchbox: SearchBox
|
|
537
|
+
searchbox: SearchBox,
|
|
499
538
|
): void {
|
|
500
539
|
const optionAdapter = container.popup!.optionAdapter;
|
|
501
|
-
let hightlightTimer:
|
|
540
|
+
let hightlightTimer: NodeJS.Timeout | null = null;
|
|
502
541
|
|
|
503
542
|
const searchHandle = (keyword: string, isTrigger: boolean) => {
|
|
504
543
|
if (!isTrigger && keyword === "") {
|
|
@@ -510,7 +549,9 @@ export class SelectBox extends Lifecycle {
|
|
|
510
549
|
.search(keyword)
|
|
511
550
|
.then((result: any) => {
|
|
512
551
|
clearTimeout(hightlightTimer!);
|
|
513
|
-
Libs.callbackScheduler.clear(
|
|
552
|
+
Libs.callbackScheduler.clear(
|
|
553
|
+
`sche_vis_proxy_${optionAdapter.adapterKey}`,
|
|
554
|
+
);
|
|
514
555
|
Libs.callbackScheduler.on(
|
|
515
556
|
`sche_vis_proxy_${optionAdapter.adapterKey}`,
|
|
516
557
|
() => {
|
|
@@ -523,7 +564,7 @@ export class SelectBox extends Lifecycle {
|
|
|
523
564
|
}, options.animationtime ?? 0);
|
|
524
565
|
}
|
|
525
566
|
},
|
|
526
|
-
{ debounce: 10 }
|
|
567
|
+
{ debounce: 10 },
|
|
527
568
|
);
|
|
528
569
|
})
|
|
529
570
|
.catch((error: unknown) => {
|
|
@@ -532,7 +573,7 @@ export class SelectBox extends Lifecycle {
|
|
|
532
573
|
}
|
|
533
574
|
};
|
|
534
575
|
|
|
535
|
-
let searchHandleTimer:
|
|
576
|
+
let searchHandleTimer: NodeJS.Timeout | null = null;
|
|
536
577
|
|
|
537
578
|
searchbox.onSearch = (keyword: string, isTrigger: boolean) => {
|
|
538
579
|
if (!searchController.compareSearchTrigger(keyword)) return;
|
|
@@ -600,7 +641,7 @@ export class SelectBox extends Lifecycle {
|
|
|
600
641
|
selectObserver: SelectObserver,
|
|
601
642
|
datasetObserver: DatasetObserver,
|
|
602
643
|
select: HTMLSelectElement,
|
|
603
|
-
optionModelManager: ModelManager<MixedItem, MixedAdapter
|
|
644
|
+
optionModelManager: ModelManager<MixedItem, MixedAdapter>,
|
|
604
645
|
): void {
|
|
605
646
|
selectObserver.connect();
|
|
606
647
|
selectObserver.onChanged = (sel) => {
|
|
@@ -727,7 +768,7 @@ export class SelectBox extends Lifecycle {
|
|
|
727
768
|
*
|
|
728
769
|
* @returns An action facade for controlling this instance, or `null` if not bound.
|
|
729
770
|
*/
|
|
730
|
-
public getAction(): SelectBoxAction
|
|
771
|
+
public getAction?(): SelectBoxAction {
|
|
731
772
|
const container = this.container;
|
|
732
773
|
const superThis = this;
|
|
733
774
|
const getInstance = () => {
|
|
@@ -764,7 +805,11 @@ export class SelectBox extends Lifecycle {
|
|
|
764
805
|
get value() {
|
|
765
806
|
const item_list = this.valueArray as string[];
|
|
766
807
|
const valLength = item_list.length;
|
|
767
|
-
return valLength > 1
|
|
808
|
+
return valLength > 1
|
|
809
|
+
? item_list
|
|
810
|
+
: valLength === 0
|
|
811
|
+
? ""
|
|
812
|
+
: item_list[0];
|
|
768
813
|
},
|
|
769
814
|
|
|
770
815
|
get valueArray() {
|
|
@@ -792,7 +837,7 @@ export class SelectBox extends Lifecycle {
|
|
|
792
837
|
get mask() {
|
|
793
838
|
const item_list: string[] = [];
|
|
794
839
|
superThis.getModelOption(true).forEach((m) => {
|
|
795
|
-
item_list.push(m.
|
|
840
|
+
item_list.push(m.mask);
|
|
796
841
|
});
|
|
797
842
|
return item_list;
|
|
798
843
|
},
|
|
@@ -803,7 +848,11 @@ export class SelectBox extends Lifecycle {
|
|
|
803
848
|
item_list.push(m.text);
|
|
804
849
|
});
|
|
805
850
|
const valLength = item_list.length;
|
|
806
|
-
return valLength > 1
|
|
851
|
+
return valLength > 1
|
|
852
|
+
? item_list
|
|
853
|
+
: valLength === 0
|
|
854
|
+
? ""
|
|
855
|
+
: item_list[0];
|
|
807
856
|
},
|
|
808
857
|
|
|
809
858
|
get isOpen() {
|
|
@@ -814,10 +863,16 @@ export class SelectBox extends Lifecycle {
|
|
|
814
863
|
return container.view.parentElement;
|
|
815
864
|
},
|
|
816
865
|
|
|
817
|
-
valueDataset(
|
|
866
|
+
valueDataset(
|
|
867
|
+
_evtToken?: IEventCallback,
|
|
868
|
+
strDataset: string = null,
|
|
869
|
+
isArray: boolean = false,
|
|
870
|
+
) {
|
|
818
871
|
var item_list = [];
|
|
819
872
|
superThis.getModelOption(true).forEach((m) => {
|
|
820
|
-
item_list.push(
|
|
873
|
+
item_list.push(
|
|
874
|
+
strDataset ? m.dataset[strDataset] : m.dataset,
|
|
875
|
+
);
|
|
821
876
|
});
|
|
822
877
|
|
|
823
878
|
if (!isArray) {
|
|
@@ -833,13 +888,21 @@ export class SelectBox extends Lifecycle {
|
|
|
833
888
|
|
|
834
889
|
selectAll(_evtToken?: IEventCallback, trigger: boolean = true) {
|
|
835
890
|
if (bindedOptions.multiple && bindedOptions.maxSelected > 0) {
|
|
836
|
-
if (
|
|
891
|
+
if (
|
|
892
|
+
superThis.getModelOption().length >
|
|
893
|
+
bindedOptions.maxSelected
|
|
894
|
+
)
|
|
895
|
+
return;
|
|
837
896
|
}
|
|
838
897
|
|
|
839
|
-
if (this.disabled || this.readonly || !bindedOptions.multiple)
|
|
898
|
+
if (this.disabled || this.readonly || !bindedOptions.multiple)
|
|
899
|
+
return;
|
|
840
900
|
|
|
841
901
|
if (trigger) {
|
|
842
|
-
const beforeChangeToken = iEvents.callEvent(
|
|
902
|
+
const beforeChangeToken = iEvents.callEvent(
|
|
903
|
+
[getInstance()],
|
|
904
|
+
...bindedOptions.on.beforeChange,
|
|
905
|
+
);
|
|
843
906
|
if (beforeChangeToken.isCancel) return;
|
|
844
907
|
superThis.oldValue = this.value;
|
|
845
908
|
}
|
|
@@ -852,10 +915,14 @@ export class SelectBox extends Lifecycle {
|
|
|
852
915
|
},
|
|
853
916
|
|
|
854
917
|
deSelectAll(_evtToken?: IEventCallback, trigger: boolean = true) {
|
|
855
|
-
if (this.disabled || this.readonly || !bindedOptions.multiple)
|
|
918
|
+
if (this.disabled || this.readonly || !bindedOptions.multiple)
|
|
919
|
+
return;
|
|
856
920
|
|
|
857
921
|
if (trigger) {
|
|
858
|
-
const beforeChangeToken = iEvents.callEvent(
|
|
922
|
+
const beforeChangeToken = iEvents.callEvent(
|
|
923
|
+
[getInstance()],
|
|
924
|
+
...bindedOptions.on.beforeChange,
|
|
925
|
+
);
|
|
859
926
|
if (beforeChangeToken.isCancel) return;
|
|
860
927
|
superThis.oldValue = this.value;
|
|
861
928
|
}
|
|
@@ -867,14 +934,22 @@ export class SelectBox extends Lifecycle {
|
|
|
867
934
|
this.change(false, trigger);
|
|
868
935
|
},
|
|
869
936
|
|
|
870
|
-
deSelectByDataset(
|
|
937
|
+
deSelectByDataset(
|
|
938
|
+
_evtToken?: IEventCallback,
|
|
939
|
+
dataset?: any,
|
|
940
|
+
trigger: boolean = true,
|
|
941
|
+
) {
|
|
871
942
|
if (dataset) {
|
|
872
|
-
superThis.getModelOption().forEach(optionModel => {
|
|
943
|
+
superThis.getModelOption().forEach((optionModel) => {
|
|
873
944
|
if (optionModel.dataset) {
|
|
874
945
|
for (let searchKey in dataset) {
|
|
875
946
|
let value = dataset[searchKey];
|
|
876
947
|
!Array.isArray(value) && (value = [value]);
|
|
877
|
-
if (
|
|
948
|
+
if (
|
|
949
|
+
value.includes(
|
|
950
|
+
optionModel.dataset[searchKey],
|
|
951
|
+
)
|
|
952
|
+
) {
|
|
878
953
|
optionModel.selectedNonTrigger = false;
|
|
879
954
|
}
|
|
880
955
|
}
|
|
@@ -884,19 +959,28 @@ export class SelectBox extends Lifecycle {
|
|
|
884
959
|
}
|
|
885
960
|
},
|
|
886
961
|
|
|
887
|
-
setValue(
|
|
962
|
+
setValue(
|
|
963
|
+
_evtToken?: IEventCallback,
|
|
964
|
+
value?: any,
|
|
965
|
+
trigger: boolean = true,
|
|
966
|
+
force: boolean = false,
|
|
967
|
+
) {
|
|
888
968
|
if (!Array.isArray(value)) value = [value];
|
|
889
969
|
value = value.filter((v: any) => v !== "" && v != null);
|
|
890
970
|
|
|
891
971
|
if (value.length === 0) {
|
|
892
|
-
superThis
|
|
972
|
+
superThis
|
|
973
|
+
.getModelOption()
|
|
974
|
+
.forEach((m) => (m.selectedNonTrigger = false));
|
|
893
975
|
this.change(false, trigger);
|
|
894
976
|
return;
|
|
895
977
|
}
|
|
896
978
|
|
|
897
979
|
if (bindedOptions.multiple && bindedOptions.maxSelected > 0) {
|
|
898
980
|
if (value.length > bindedOptions.maxSelected) {
|
|
899
|
-
console.warn(
|
|
981
|
+
console.warn(
|
|
982
|
+
`Cannot select more than ${bindedOptions.maxSelected} items`,
|
|
983
|
+
);
|
|
900
984
|
return;
|
|
901
985
|
}
|
|
902
986
|
}
|
|
@@ -905,33 +989,59 @@ export class SelectBox extends Lifecycle {
|
|
|
905
989
|
|
|
906
990
|
// AJAX: load missing values
|
|
907
991
|
if (container.searchController?.isAjax?.()) {
|
|
908
|
-
|
|
992
|
+
container.searchController.resetPagination();
|
|
993
|
+
superThis.hasLoadedOnce = false;
|
|
994
|
+
|
|
995
|
+
const { missing } =
|
|
996
|
+
container.searchController.checkMissingValues(value);
|
|
909
997
|
|
|
910
998
|
if (missing.length > 0) {
|
|
911
999
|
(async () => {
|
|
912
|
-
if (bindedOptions.loadingfield)
|
|
1000
|
+
if (bindedOptions.loadingfield)
|
|
1001
|
+
container.popup?.showLoading?.();
|
|
913
1002
|
|
|
914
1003
|
try {
|
|
915
|
-
|
|
916
|
-
|
|
1004
|
+
const result =
|
|
1005
|
+
await container.searchController.loadByValues(
|
|
1006
|
+
missing,
|
|
1007
|
+
);
|
|
917
1008
|
if (result.success && result.items.length > 0) {
|
|
918
1009
|
result.items.forEach((it: any) => {
|
|
919
|
-
if (
|
|
1010
|
+
if (
|
|
1011
|
+
missing.includes(it.value) ||
|
|
1012
|
+
missing.includes(it.text)
|
|
1013
|
+
)
|
|
1014
|
+
it.selected = true;
|
|
920
1015
|
});
|
|
921
1016
|
|
|
922
|
-
container.searchController.applyAjaxResult?.(
|
|
923
|
-
|
|
1017
|
+
container.searchController.applyAjaxResult?.(
|
|
1018
|
+
result.items,
|
|
1019
|
+
false,
|
|
1020
|
+
false,
|
|
1021
|
+
);
|
|
1022
|
+
|
|
924
1023
|
setTimeout(() => {
|
|
925
1024
|
container.searchController.resetPagination();
|
|
926
1025
|
this.change(false, trigger);
|
|
927
1026
|
}, 200);
|
|
928
1027
|
} else if (missing.length > 0) {
|
|
929
|
-
console.warn(
|
|
1028
|
+
console.warn(
|
|
1029
|
+
`Could not load ${missing.length} values:`,
|
|
1030
|
+
missing,
|
|
1031
|
+
);
|
|
1032
|
+
setTimeout(() => {
|
|
1033
|
+
container.searchController.resetPagination();
|
|
1034
|
+
this.change(false, trigger);
|
|
1035
|
+
}, 200);
|
|
930
1036
|
}
|
|
931
1037
|
} catch (error) {
|
|
932
|
-
console.error(
|
|
1038
|
+
console.error(
|
|
1039
|
+
"Error loading missing values:",
|
|
1040
|
+
error,
|
|
1041
|
+
);
|
|
933
1042
|
} finally {
|
|
934
|
-
if (bindedOptions.loadingfield)
|
|
1043
|
+
if (bindedOptions.loadingfield)
|
|
1044
|
+
container.popup?.hideLoading?.();
|
|
935
1045
|
}
|
|
936
1046
|
})();
|
|
937
1047
|
return;
|
|
@@ -939,7 +1049,10 @@ export class SelectBox extends Lifecycle {
|
|
|
939
1049
|
}
|
|
940
1050
|
|
|
941
1051
|
if (trigger) {
|
|
942
|
-
const beforeChangeToken = iEvents.callEvent(
|
|
1052
|
+
const beforeChangeToken = iEvents.callEvent(
|
|
1053
|
+
[getInstance()],
|
|
1054
|
+
...bindedOptions.on.beforeChange,
|
|
1055
|
+
);
|
|
943
1056
|
if (beforeChangeToken.isCancel) return;
|
|
944
1057
|
superThis.oldValue = this.value;
|
|
945
1058
|
}
|
|
@@ -956,18 +1069,24 @@ export class SelectBox extends Lifecycle {
|
|
|
956
1069
|
},
|
|
957
1070
|
|
|
958
1071
|
load() {
|
|
959
|
-
if (
|
|
1072
|
+
if (
|
|
1073
|
+
(!superThis.hasLoadedOnce || superThis.isBeforeSearch) &&
|
|
1074
|
+
bindedOptions?.ajax
|
|
1075
|
+
) {
|
|
960
1076
|
container.searchController.resetPagination();
|
|
961
1077
|
container.popup.showLoading();
|
|
962
1078
|
superThis.hasLoadedOnce = true;
|
|
963
1079
|
superThis.isBeforeSearch = false;
|
|
964
1080
|
|
|
965
1081
|
setTimeout(() => {
|
|
966
|
-
if (!container.popup || !container.searchController)
|
|
1082
|
+
if (!container.popup || !container.searchController)
|
|
1083
|
+
return;
|
|
967
1084
|
container.searchController
|
|
968
1085
|
.search("")
|
|
969
1086
|
.then(() => container.popup?.triggerResize?.())
|
|
970
|
-
.catch((err: unknown) =>
|
|
1087
|
+
.catch((err: unknown) =>
|
|
1088
|
+
console.error("Initial ajax load error:", err),
|
|
1089
|
+
);
|
|
971
1090
|
}, bindedOptions.animationtime);
|
|
972
1091
|
container.popup.load();
|
|
973
1092
|
} else {
|
|
@@ -988,7 +1107,10 @@ export class SelectBox extends Lifecycle {
|
|
|
988
1107
|
return;
|
|
989
1108
|
}
|
|
990
1109
|
|
|
991
|
-
const beforeShowToken = iEvents.callEvent(
|
|
1110
|
+
const beforeShowToken = iEvents.callEvent(
|
|
1111
|
+
[getInstance()],
|
|
1112
|
+
...bindedOptions.on.beforeShow,
|
|
1113
|
+
);
|
|
992
1114
|
if (beforeShowToken.isCancel) {
|
|
993
1115
|
return;
|
|
994
1116
|
}
|
|
@@ -1005,15 +1127,30 @@ export class SelectBox extends Lifecycle {
|
|
|
1005
1127
|
}
|
|
1006
1128
|
|
|
1007
1129
|
this.load();
|
|
1008
|
-
container.popup.open(
|
|
1130
|
+
container.popup.open(
|
|
1131
|
+
() => {
|
|
1132
|
+
setTimeout(() => {
|
|
1133
|
+
if (selectedOption) {
|
|
1134
|
+
adapter.setHighlight(selectedOption, bindedOptions.autoscroll);
|
|
1135
|
+
}
|
|
1136
|
+
}, 100);
|
|
1137
|
+
},
|
|
1138
|
+
!container.popup.loadingState.isVisible,
|
|
1139
|
+
);
|
|
1009
1140
|
|
|
1010
1141
|
container.searchbox.show();
|
|
1011
1142
|
|
|
1012
1143
|
const ViewPanel: HTMLElement = container.tags.ViewPanel;
|
|
1013
1144
|
ViewPanel.setAttribute("aria-expanded", "true");
|
|
1014
|
-
ViewPanel.setAttribute(
|
|
1145
|
+
ViewPanel.setAttribute(
|
|
1146
|
+
"aria-controls",
|
|
1147
|
+
bindedOptions.SEID_LIST,
|
|
1148
|
+
);
|
|
1015
1149
|
ViewPanel.setAttribute("aria-haspopup", "listbox");
|
|
1016
|
-
ViewPanel.setAttribute(
|
|
1150
|
+
ViewPanel.setAttribute(
|
|
1151
|
+
"aria-labelledby",
|
|
1152
|
+
bindedOptions.SEID_HOLDER,
|
|
1153
|
+
);
|
|
1017
1154
|
|
|
1018
1155
|
if (bindedOptions.multiple) {
|
|
1019
1156
|
ViewPanel.setAttribute("aria-multiselectable", "true");
|
|
@@ -1021,7 +1158,9 @@ export class SelectBox extends Lifecycle {
|
|
|
1021
1158
|
|
|
1022
1159
|
iEvents.callEvent([getInstance()], ...bindedOptions.on.show);
|
|
1023
1160
|
if (superThis.pluginContext) {
|
|
1024
|
-
superThis.runPluginHook("onOpen", (plugin) =>
|
|
1161
|
+
superThis.runPluginHook("onOpen", (plugin) =>
|
|
1162
|
+
plugin.onOpen?.(superThis.pluginContext),
|
|
1163
|
+
);
|
|
1025
1164
|
}
|
|
1026
1165
|
return;
|
|
1027
1166
|
},
|
|
@@ -1029,7 +1168,10 @@ export class SelectBox extends Lifecycle {
|
|
|
1029
1168
|
close() {
|
|
1030
1169
|
if (!superThis.isOpen) return;
|
|
1031
1170
|
|
|
1032
|
-
const beforeCloseToken = iEvents.callEvent(
|
|
1171
|
+
const beforeCloseToken = iEvents.callEvent(
|
|
1172
|
+
[getInstance()],
|
|
1173
|
+
...bindedOptions.on.beforeClose,
|
|
1174
|
+
);
|
|
1033
1175
|
if (beforeCloseToken.isCancel) return;
|
|
1034
1176
|
|
|
1035
1177
|
superThis.isOpen = false;
|
|
@@ -1044,7 +1186,9 @@ export class SelectBox extends Lifecycle {
|
|
|
1044
1186
|
|
|
1045
1187
|
iEvents.callEvent([getInstance()], ...bindedOptions.on.close);
|
|
1046
1188
|
if (superThis.pluginContext) {
|
|
1047
|
-
superThis.runPluginHook("onClose", (plugin) =>
|
|
1189
|
+
superThis.runPluginHook("onClose", (plugin) =>
|
|
1190
|
+
plugin.onClose?.(superThis.pluginContext),
|
|
1191
|
+
);
|
|
1048
1192
|
}
|
|
1049
1193
|
return;
|
|
1050
1194
|
},
|
|
@@ -1054,10 +1198,15 @@ export class SelectBox extends Lifecycle {
|
|
|
1054
1198
|
else this.open();
|
|
1055
1199
|
},
|
|
1056
1200
|
|
|
1057
|
-
change(_evtToken
|
|
1201
|
+
change(_evtToken?: IEventCallback, canTrigger: boolean = true) {
|
|
1058
1202
|
if (canTrigger) {
|
|
1059
|
-
if (
|
|
1060
|
-
|
|
1203
|
+
if (
|
|
1204
|
+
bindedOptions.multiple &&
|
|
1205
|
+
bindedOptions.maxSelected > 0
|
|
1206
|
+
) {
|
|
1207
|
+
if (
|
|
1208
|
+
this.valueArray.length > bindedOptions.maxSelected
|
|
1209
|
+
) {
|
|
1061
1210
|
this.setValue(null, this.oldValue, false, true);
|
|
1062
1211
|
}
|
|
1063
1212
|
}
|
|
@@ -1067,7 +1216,10 @@ export class SelectBox extends Lifecycle {
|
|
|
1067
1216
|
return;
|
|
1068
1217
|
}
|
|
1069
1218
|
|
|
1070
|
-
const beforeChangeToken = iEvents.callEvent(
|
|
1219
|
+
const beforeChangeToken = iEvents.callEvent(
|
|
1220
|
+
[getInstance(), this.value],
|
|
1221
|
+
...bindedOptions.on.beforeChange,
|
|
1222
|
+
);
|
|
1071
1223
|
if (beforeChangeToken.isCancel) {
|
|
1072
1224
|
this.setValue(null, this.oldValue, false);
|
|
1073
1225
|
return;
|
|
@@ -1078,8 +1230,12 @@ export class SelectBox extends Lifecycle {
|
|
|
1078
1230
|
container.accessorybox.setModelData(this.valueOptions);
|
|
1079
1231
|
|
|
1080
1232
|
if (canTrigger) {
|
|
1081
|
-
if (container.targetElement)
|
|
1082
|
-
|
|
1233
|
+
if (container.targetElement)
|
|
1234
|
+
iEvents.trigger(container.targetElement, "change");
|
|
1235
|
+
iEvents.callEvent(
|
|
1236
|
+
[getInstance(), this.value],
|
|
1237
|
+
...bindedOptions.on.change,
|
|
1238
|
+
);
|
|
1083
1239
|
|
|
1084
1240
|
if (superThis.options?.autoclose) this.close();
|
|
1085
1241
|
}
|
|
@@ -1090,9 +1246,15 @@ export class SelectBox extends Lifecycle {
|
|
|
1090
1246
|
}
|
|
1091
1247
|
|
|
1092
1248
|
if (superThis.pluginContext && superThis.optionModelManager) {
|
|
1093
|
-
const resources =
|
|
1249
|
+
const resources =
|
|
1250
|
+
superThis.optionModelManager.getResources();
|
|
1094
1251
|
superThis.runPluginHook("onChange", (plugin) =>
|
|
1095
|
-
plugin.onChange?.(
|
|
1252
|
+
plugin.onChange?.(
|
|
1253
|
+
this.value,
|
|
1254
|
+
resources.modelList,
|
|
1255
|
+
resources.adapter,
|
|
1256
|
+
superThis.pluginContext,
|
|
1257
|
+
),
|
|
1096
1258
|
);
|
|
1097
1259
|
}
|
|
1098
1260
|
},
|
|
@@ -1100,7 +1262,10 @@ export class SelectBox extends Lifecycle {
|
|
|
1100
1262
|
refreshMask() {
|
|
1101
1263
|
let mask = bindedOptions.placeholder;
|
|
1102
1264
|
|
|
1103
|
-
if (
|
|
1265
|
+
if (
|
|
1266
|
+
!bindedOptions.multiple &&
|
|
1267
|
+
superThis.getModelOption().length > 0
|
|
1268
|
+
) {
|
|
1104
1269
|
mask = this.mask[0];
|
|
1105
1270
|
}
|
|
1106
1271
|
|
|
@@ -1110,7 +1275,11 @@ export class SelectBox extends Lifecycle {
|
|
|
1110
1275
|
container.searchbox.setPlaceHolder(mask);
|
|
1111
1276
|
},
|
|
1112
1277
|
|
|
1113
|
-
on(
|
|
1278
|
+
on(
|
|
1279
|
+
_evtToken: IEventCallback,
|
|
1280
|
+
evtName: string,
|
|
1281
|
+
handle: (...args: any[]) => any,
|
|
1282
|
+
) {
|
|
1114
1283
|
if (!bindedOptions.on[evtName]) bindedOptions.on[evtName] = [];
|
|
1115
1284
|
bindedOptions.on[evtName].push(handle);
|
|
1116
1285
|
},
|
|
@@ -1136,7 +1305,9 @@ export class SelectBox extends Lifecycle {
|
|
|
1136
1305
|
.search("")
|
|
1137
1306
|
.then(() => {
|
|
1138
1307
|
container.popup?.triggerResize?.();
|
|
1139
|
-
|
|
1308
|
+
setTimeout(() => {
|
|
1309
|
+
resove(getInstance());
|
|
1310
|
+
}, 60);
|
|
1140
1311
|
})
|
|
1141
1312
|
.catch((err: unknown) => {
|
|
1142
1313
|
console.error("Initial ajax load error:", err);
|
|
@@ -1183,7 +1354,7 @@ export class SelectBox extends Lifecycle {
|
|
|
1183
1354
|
private createSymProp(
|
|
1184
1355
|
obj: Record<string, any>,
|
|
1185
1356
|
prop: "disabled" | "readonly" | "visible",
|
|
1186
|
-
privateProp: "isDisabled" | "isReadOnly" | "isVisible"
|
|
1357
|
+
privateProp: "isDisabled" | "isReadOnly" | "isVisible",
|
|
1187
1358
|
): void {
|
|
1188
1359
|
const superThis = this;
|
|
1189
1360
|
|
|
@@ -1194,7 +1365,8 @@ export class SelectBox extends Lifecycle {
|
|
|
1194
1365
|
set(value: any) {
|
|
1195
1366
|
superThis[privateProp] = !!value;
|
|
1196
1367
|
if (superThis.container?.targetElement?.dataset) {
|
|
1197
|
-
superThis.container.targetElement.dataset[prop] =
|
|
1368
|
+
superThis.container.targetElement.dataset[prop] =
|
|
1369
|
+
String(!!value);
|
|
1198
1370
|
}
|
|
1199
1371
|
},
|
|
1200
1372
|
enumerable: true,
|
|
@@ -1223,7 +1395,7 @@ export class SelectBox extends Lifecycle {
|
|
|
1223
1395
|
* @returns A flat array of option models (possibly filtered).
|
|
1224
1396
|
* @internal
|
|
1225
1397
|
*/
|
|
1226
|
-
private getModelOption(isSelected
|
|
1398
|
+
private getModelOption(isSelected?: boolean): OptionModel[] {
|
|
1227
1399
|
if (!this.optionModelManager) return [];
|
|
1228
1400
|
|
|
1229
1401
|
const { modelList } = this.optionModelManager.getResources();
|
|
@@ -1233,7 +1405,8 @@ export class SelectBox extends Lifecycle {
|
|
|
1233
1405
|
if (m instanceof OptionModel) {
|
|
1234
1406
|
flatOptions.push(m);
|
|
1235
1407
|
} else if (m instanceof GroupModel) {
|
|
1236
|
-
if (Array.isArray(m.items) && m.items.length)
|
|
1408
|
+
if (Array.isArray(m.items) && m.items.length)
|
|
1409
|
+
flatOptions.push(...m.items);
|
|
1237
1410
|
}
|
|
1238
1411
|
}
|
|
1239
1412
|
|
|
@@ -1253,7 +1426,10 @@ export class SelectBox extends Lifecycle {
|
|
|
1253
1426
|
* @param runner - Hook invocation handler.
|
|
1254
1427
|
* @internal
|
|
1255
1428
|
*/
|
|
1256
|
-
private runPluginHook(
|
|
1429
|
+
private runPluginHook(
|
|
1430
|
+
hook: string,
|
|
1431
|
+
runner: (plugin: SelectivePlugin) => void,
|
|
1432
|
+
): void {
|
|
1257
1433
|
if (!this.plugins.length) return;
|
|
1258
1434
|
|
|
1259
1435
|
this.plugins.forEach((plugin) => {
|