selective-ui 1.2.6 → 1.3.0
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/README.md +0 -7
- package/dist/selective-ui.esm.js +169 -79
- 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.js +2 -2
- package/dist/selective-ui.min.js.br +0 -0
- package/dist/selective-ui.umd.js +170 -80
- package/dist/selective-ui.umd.js.map +1 -1
- package/package.json +11 -2
- package/src/ts/adapter/mixed-adapter.ts +15 -3
- package/src/ts/components/popup/popup.ts +48 -21
- package/src/ts/components/selectbox.ts +48 -28
- package/src/ts/core/search-controller.ts +2 -1
- package/src/ts/global.ts +2 -2
- package/src/ts/index.ts +2 -2
- package/src/ts/models/group-model.ts +1 -2
- package/src/ts/services/ea-observer.ts +7 -5
- package/src/ts/types/components/searchbox.type.ts +6 -0
- package/src/ts/types/core/base/mixed-adapter.type.ts +9 -5
- package/src/ts/types/core/search-controller.type.ts +69 -35
- package/src/ts/types/services/select-observer.type.ts +9 -5
- package/src/ts/types/utils/istorage.type.ts +1 -0
- package/src/ts/utils/istorage.ts +3 -2
- package/src/ts/utils/libs.ts +17 -10
- package/src/ts/views/group-view.ts +31 -5
- package/src/ts/views/option-view.ts +16 -3
package/dist/selective-ui.umd.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! Selective UI v1.
|
|
1
|
+
/*! Selective UI v1.3.0 | MIT License */
|
|
2
2
|
(function (global, factory) {
|
|
3
3
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|
4
4
|
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
autofocus: true,
|
|
34
34
|
searchable: true,
|
|
35
35
|
loadingfield: true,
|
|
36
|
+
preload: false,
|
|
36
37
|
visible: true,
|
|
37
38
|
skipError: false,
|
|
38
39
|
customDelimiter: ",",
|
|
@@ -42,8 +43,8 @@
|
|
|
42
43
|
textSelectAll: "Select all",
|
|
43
44
|
textDeselectAll: "Deselect all",
|
|
44
45
|
textAccessoryDeselect: "Deselect: ",
|
|
45
|
-
animationtime: 200, //
|
|
46
|
-
delaysearchtime: 200, //
|
|
46
|
+
animationtime: 200, // milliseconds
|
|
47
|
+
delaysearchtime: 200, // milliseconds
|
|
47
48
|
allowHtml: false,
|
|
48
49
|
maxSelected: 0,
|
|
49
50
|
labelHalign: "left",
|
|
@@ -661,8 +662,7 @@
|
|
|
661
662
|
tmp.innerHTML = s;
|
|
662
663
|
tmp.querySelectorAll("script, style, iframe, object, embed, link").forEach((n) => n.remove());
|
|
663
664
|
tmp.querySelectorAll("*").forEach((n) => {
|
|
664
|
-
for (const
|
|
665
|
-
const a = n.attributes[k];
|
|
665
|
+
for (const a of Array.from(n.attributes)) {
|
|
666
666
|
const name = a.name ?? "";
|
|
667
667
|
const value = a.value ?? "";
|
|
668
668
|
if (/^on/i.test(name)) {
|
|
@@ -703,26 +703,34 @@
|
|
|
703
703
|
return s.replace(/đ/g, "d").replace(/Đ/g, "d");
|
|
704
704
|
}
|
|
705
705
|
/**
|
|
706
|
-
*
|
|
707
|
-
*
|
|
708
|
-
*
|
|
706
|
+
* Flattens a `<select>` element into an ordered array that includes optgroups
|
|
707
|
+
* and their child options.
|
|
708
|
+
*
|
|
709
|
+
* Notes:
|
|
710
|
+
* - Keeps original DOM order.
|
|
711
|
+
* - Adds a non-standard `__parentGroup` pointer on options inside optgroups.
|
|
712
|
+
*
|
|
713
|
+
* @param {HTMLSelectElement} selectElement - The source select element.
|
|
714
|
+
* @returns {Array<HTMLOptGroupElement | HTMLOptionElement>} Flattened node list.
|
|
709
715
|
*/
|
|
710
716
|
static parseSelectToArray(selectElement) {
|
|
711
717
|
const result = [];
|
|
712
|
-
const children =
|
|
713
|
-
children.
|
|
718
|
+
const children = selectElement.children;
|
|
719
|
+
for (let childIndex = 0; childIndex < children.length; childIndex++) {
|
|
720
|
+
const child = children[childIndex];
|
|
714
721
|
if (child.tagName === "OPTGROUP") {
|
|
715
722
|
const group = child;
|
|
716
723
|
result.push(group);
|
|
717
|
-
|
|
724
|
+
for (let optionIndex = 0; optionIndex < group.children.length; optionIndex++) {
|
|
725
|
+
const option = group.children[optionIndex];
|
|
718
726
|
option["__parentGroup"] = group;
|
|
719
727
|
result.push(option);
|
|
720
|
-
}
|
|
728
|
+
}
|
|
721
729
|
}
|
|
722
730
|
else if (child.tagName === "OPTION") {
|
|
723
731
|
result.push(child);
|
|
724
732
|
}
|
|
725
|
-
}
|
|
733
|
+
}
|
|
726
734
|
return result;
|
|
727
735
|
}
|
|
728
736
|
/**
|
|
@@ -2404,7 +2412,7 @@
|
|
|
2404
2412
|
}
|
|
2405
2413
|
: {};
|
|
2406
2414
|
// Load ModelManager resources into the list container
|
|
2407
|
-
this.modelManager.load(this.optionsContainer, { isMultiple: options.multiple }, recyclerViewOpt);
|
|
2415
|
+
this.modelManager.load(this.optionsContainer, { isMultiple: options.multiple, options: options }, recyclerViewOpt);
|
|
2408
2416
|
const MMResources = this.modelManager.getResources();
|
|
2409
2417
|
this.optionAdapter = MMResources.adapter;
|
|
2410
2418
|
this.recyclerView = MMResources.recyclerView;
|
|
@@ -2531,36 +2539,60 @@
|
|
|
2531
2539
|
setupEffector(effectorSvc) {
|
|
2532
2540
|
this.effSvc = effectorSvc;
|
|
2533
2541
|
}
|
|
2542
|
+
/**
|
|
2543
|
+
* Loads and initializes the popup (one-time setup):
|
|
2544
|
+
* - Appends the popup node to `document.body`
|
|
2545
|
+
* - Initializes the resize observer service
|
|
2546
|
+
* - Binds the effect service to the popup element
|
|
2547
|
+
* - Blocks mousedown events inside the popup to prevent auto-close
|
|
2548
|
+
*
|
|
2549
|
+
* Safely no-ops when the popup has already been created
|
|
2550
|
+
* or required dependencies are missing.
|
|
2551
|
+
*/
|
|
2552
|
+
load() {
|
|
2553
|
+
if (!this.node || !this.parent || !this.effSvc)
|
|
2554
|
+
return;
|
|
2555
|
+
if (this.isCreated)
|
|
2556
|
+
return;
|
|
2557
|
+
document.body.appendChild(this.node);
|
|
2558
|
+
this.isCreated = true;
|
|
2559
|
+
this.resizeObser = new ResizeObserverService();
|
|
2560
|
+
this.effSvc.setElement(this.node);
|
|
2561
|
+
this.node.addEventListener("mousedown", (e) => {
|
|
2562
|
+
e.stopPropagation();
|
|
2563
|
+
e.preventDefault();
|
|
2564
|
+
});
|
|
2565
|
+
}
|
|
2534
2566
|
/**
|
|
2535
2567
|
* Opens (expands) the popup:
|
|
2536
|
-
* -
|
|
2537
|
-
* - Synchronizes
|
|
2538
|
-
* -
|
|
2539
|
-
* -
|
|
2568
|
+
* - Ensures the popup is loaded and initialized
|
|
2569
|
+
* - Synchronizes option handle visibility
|
|
2570
|
+
* - Optionally evaluates and applies the empty/not-found state
|
|
2571
|
+
* - Computes placement relative to the parent anchor
|
|
2572
|
+
* - Runs the expand animation
|
|
2573
|
+
* - Connects the resize observer after animation completes
|
|
2574
|
+
* - Resumes the recycler view
|
|
2575
|
+
*
|
|
2576
|
+
* Safely no-ops when required dependencies are missing.
|
|
2540
2577
|
*
|
|
2541
2578
|
* @param callback - Optional callback invoked when the opening animation completes.
|
|
2542
|
-
* @param isShowEmptyState - If true,
|
|
2579
|
+
* @param isShowEmptyState - If true, applies the empty/not-found state before animation.
|
|
2543
2580
|
*/
|
|
2544
2581
|
open(callback = null, isShowEmptyState) {
|
|
2545
2582
|
if (!this.node || !this.options || !this.optionHandle || !this.parent || !this.effSvc)
|
|
2546
2583
|
return;
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
this.resizeObser = new ResizeObserverService();
|
|
2551
|
-
this.effSvc.setElement(this.node);
|
|
2552
|
-
// Prevent the popup from closing when clicking inside
|
|
2553
|
-
this.node.addEventListener("mousedown", (e) => {
|
|
2554
|
-
e.stopPropagation();
|
|
2555
|
-
e.preventDefault();
|
|
2556
|
-
});
|
|
2557
|
-
}
|
|
2584
|
+
// Ensure one-time initialization
|
|
2585
|
+
this.load();
|
|
2586
|
+
// Sync option visibility state
|
|
2558
2587
|
this.optionHandle.update();
|
|
2588
|
+
// Apply empty state if requested
|
|
2559
2589
|
if (isShowEmptyState) {
|
|
2560
2590
|
this.updateEmptyState();
|
|
2561
2591
|
}
|
|
2592
|
+
// Compute placement based on parent anchor
|
|
2562
2593
|
const location = this.getParentLocation();
|
|
2563
2594
|
const { position, top, maxHeight, realHeight } = this.calculatePosition(location);
|
|
2595
|
+
// Run expand animation
|
|
2564
2596
|
this.effSvc.expand({
|
|
2565
2597
|
duration: this.options.animationtime,
|
|
2566
2598
|
display: "flex",
|
|
@@ -2573,13 +2605,14 @@
|
|
|
2573
2605
|
onComplete: () => {
|
|
2574
2606
|
if (!this.resizeObser || !this.parent)
|
|
2575
2607
|
return;
|
|
2608
|
+
// Recompute position on parent resize to keep behavior consistent
|
|
2576
2609
|
this.resizeObser.onChanged = (_metrics) => {
|
|
2577
|
-
// Recompute from parent each time to keep behavior identical.
|
|
2578
2610
|
const loc = this.getParentLocation();
|
|
2579
2611
|
this.handleResize(loc);
|
|
2580
2612
|
};
|
|
2581
2613
|
this.resizeObser.connect(this.parent.container.tags.ViewPanel);
|
|
2582
2614
|
callback?.();
|
|
2615
|
+
// Resume recycler view rendering after animation
|
|
2583
2616
|
const rv = this.recyclerView;
|
|
2584
2617
|
rv?.resume?.();
|
|
2585
2618
|
},
|
|
@@ -3788,6 +3821,7 @@
|
|
|
3788
3821
|
*/
|
|
3789
3822
|
this.privOnCollapsedChanged = [];
|
|
3790
3823
|
this.label = this.targetElement.label;
|
|
3824
|
+
this.collapsed = Libs.string2Boolean(this.targetElement.dataset?.collapsed);
|
|
3791
3825
|
}
|
|
3792
3826
|
/**
|
|
3793
3827
|
* Initializes group state from the backing `<optgroup>` (if present) and mounts the model.
|
|
@@ -3804,7 +3838,6 @@
|
|
|
3804
3838
|
* @override
|
|
3805
3839
|
*/
|
|
3806
3840
|
init() {
|
|
3807
|
-
this.collapsed = Libs.string2Boolean(this.targetElement.dataset?.collapsed);
|
|
3808
3841
|
super.init();
|
|
3809
3842
|
this.mount();
|
|
3810
3843
|
}
|
|
@@ -5524,7 +5557,8 @@
|
|
|
5524
5557
|
.join(",");
|
|
5525
5558
|
let payload;
|
|
5526
5559
|
if (typeof cfg.data === "function") {
|
|
5527
|
-
|
|
5560
|
+
const selectiveInstance = this.selectBox?.Selective?.find(this.selectBox?.container?.targetElement);
|
|
5561
|
+
payload = cfg.data.call(selectiveInstance, keyword, page);
|
|
5528
5562
|
if (payload && typeof payload.selectedValue === "undefined")
|
|
5529
5563
|
payload.selectedValue = selectedValues;
|
|
5530
5564
|
}
|
|
@@ -6469,8 +6503,18 @@
|
|
|
6469
6503
|
* @see {@link View}
|
|
6470
6504
|
*/
|
|
6471
6505
|
class GroupView extends View {
|
|
6472
|
-
|
|
6473
|
-
|
|
6506
|
+
/**
|
|
6507
|
+
* Creates a new GroupView bound to the given parent element.
|
|
6508
|
+
*
|
|
6509
|
+
* Initialization flow:
|
|
6510
|
+
* 1. Calls `super(parent)` (View base constructor).
|
|
6511
|
+
*
|
|
6512
|
+
* @public
|
|
6513
|
+
* @param {HTMLElement} parent - Container element that will host this group view.
|
|
6514
|
+
* @param {SelectiveOptions} options - Optional configuration for this group view.
|
|
6515
|
+
*/
|
|
6516
|
+
constructor(parent, options) {
|
|
6517
|
+
super(parent);
|
|
6474
6518
|
/**
|
|
6475
6519
|
* Strongly-typed reference to the mounted group view structure.
|
|
6476
6520
|
*
|
|
@@ -6485,6 +6529,16 @@
|
|
|
6485
6529
|
* @public
|
|
6486
6530
|
*/
|
|
6487
6531
|
this.view = null;
|
|
6532
|
+
/**
|
|
6533
|
+
* Parsed configuration (bound from the `<select>` element via binder map).
|
|
6534
|
+
*
|
|
6535
|
+
* Provides feature flags (multiple/disabled/readonly/visible/virtualScroll/ajax/autoclose…),
|
|
6536
|
+
* a11y ids (e.g. `SEID_LIST`, `SEID_HOLDER`) and user callbacks under `options.on`.
|
|
6537
|
+
*
|
|
6538
|
+
* @internal
|
|
6539
|
+
*/
|
|
6540
|
+
this.options = null;
|
|
6541
|
+
this.options = options;
|
|
6488
6542
|
}
|
|
6489
6543
|
/**
|
|
6490
6544
|
* Mounts the group view into the DOM.
|
|
@@ -6492,8 +6546,8 @@
|
|
|
6492
6546
|
* Creation flow:
|
|
6493
6547
|
* 1. Generates unique group ID (7-character random string).
|
|
6494
6548
|
* 2. Creates DOM structure via {@link Libs.mountNode}:
|
|
6495
|
-
* - Root: `<div role="group" aria-labelledby="seui-{id}-header">`
|
|
6496
|
-
* - Header: `<div role="presentation" id="seui-{id}-header">`
|
|
6549
|
+
* - Root: `<div role="group" aria-labelledby="seui-{this.options?.SEID || default}-{id}-header">`
|
|
6550
|
+
* - Header: `<div role="presentation" id="seui-{this.options?.SEID || default}-{id}-header">`
|
|
6497
6551
|
* - Items: `<div role="group">` (nested group for child items)
|
|
6498
6552
|
* 3. Appends root to {@link parent} container.
|
|
6499
6553
|
* 4. Transitions `INITIALIZED → MOUNTED` via `super.mount()`.
|
|
@@ -6519,8 +6573,8 @@
|
|
|
6519
6573
|
node: "div",
|
|
6520
6574
|
classList: ["seui-group"],
|
|
6521
6575
|
role: "group",
|
|
6522
|
-
ariaLabelledby: `seui-${group_id}-header`,
|
|
6523
|
-
id: `seui-${group_id}-group`,
|
|
6576
|
+
ariaLabelledby: `seui-${this.options?.SEID || "default"}-${group_id}-header`,
|
|
6577
|
+
id: `seui-${this.options?.SEID || "default"}-${group_id}-group`,
|
|
6524
6578
|
},
|
|
6525
6579
|
child: {
|
|
6526
6580
|
GroupHeader: {
|
|
@@ -6528,7 +6582,7 @@
|
|
|
6528
6582
|
node: "div",
|
|
6529
6583
|
classList: ["seui-group-header"],
|
|
6530
6584
|
role: "presentation",
|
|
6531
|
-
id: `seui-${group_id}-header`,
|
|
6585
|
+
id: `seui-${this.options?.SEID || "default"}-${group_id}-header`,
|
|
6532
6586
|
},
|
|
6533
6587
|
},
|
|
6534
6588
|
GroupItems: {
|
|
@@ -6737,8 +6791,9 @@
|
|
|
6737
6791
|
*
|
|
6738
6792
|
* @public
|
|
6739
6793
|
* @param {HTMLElement} parent - Container element that will host this option view.
|
|
6794
|
+
* @param {SelectiveOptions} options - Optional configuration for this option view.
|
|
6740
6795
|
*/
|
|
6741
|
-
constructor(parent) {
|
|
6796
|
+
constructor(parent, options) {
|
|
6742
6797
|
super(parent);
|
|
6743
6798
|
/**
|
|
6744
6799
|
* Strongly-typed reference to the mounted option view structure.
|
|
@@ -6754,6 +6809,15 @@
|
|
|
6754
6809
|
* @public
|
|
6755
6810
|
*/
|
|
6756
6811
|
this.view = null;
|
|
6812
|
+
/**
|
|
6813
|
+
* Parsed configuration (bound from the `<select>` element via binder map).
|
|
6814
|
+
*
|
|
6815
|
+
* Provides feature flags (multiple/disabled/readonly/visible/virtualScroll/ajax/autoclose…),
|
|
6816
|
+
* a11y ids (e.g. `SEID_LIST`, `SEID_HOLDER`) and user callbacks under `options.on`.
|
|
6817
|
+
*
|
|
6818
|
+
* @internal
|
|
6819
|
+
*/
|
|
6820
|
+
this.options = null;
|
|
6757
6821
|
/**
|
|
6758
6822
|
* Internal configuration object (Proxy target).
|
|
6759
6823
|
*
|
|
@@ -6795,6 +6859,7 @@
|
|
|
6795
6859
|
* @private
|
|
6796
6860
|
*/
|
|
6797
6861
|
this.isRendered = false;
|
|
6862
|
+
this.options = options;
|
|
6798
6863
|
this.initialize();
|
|
6799
6864
|
}
|
|
6800
6865
|
/**
|
|
@@ -6999,7 +7064,7 @@
|
|
|
6999
7064
|
mount() {
|
|
7000
7065
|
const viewClass = ["seui-option-view"];
|
|
7001
7066
|
const opt_id = Libs.randomString(7);
|
|
7002
|
-
const inputID = `option_${opt_id}`;
|
|
7067
|
+
const inputID = `option_${this.options?.SEID ?? "default"}_${opt_id}`;
|
|
7003
7068
|
if (this.config.isMultiple)
|
|
7004
7069
|
viewClass.push("multiple");
|
|
7005
7070
|
if (this.config.hasImage) {
|
|
@@ -7045,7 +7110,7 @@
|
|
|
7045
7110
|
OptionView: {
|
|
7046
7111
|
tag: {
|
|
7047
7112
|
node: "div",
|
|
7048
|
-
id: `seui-${opt_id}-option`,
|
|
7113
|
+
id: `seui-${this.options?.SEID ?? "default"}-${opt_id}-option`,
|
|
7049
7114
|
classList: viewClass,
|
|
7050
7115
|
role: "option",
|
|
7051
7116
|
ariaSelected: "false",
|
|
@@ -7259,6 +7324,15 @@
|
|
|
7259
7324
|
super(items);
|
|
7260
7325
|
/** Whether the adapter operates in multi-selection mode. */
|
|
7261
7326
|
this.isMultiple = false;
|
|
7327
|
+
/**
|
|
7328
|
+
* Parsed configuration (bound from the `<select>` element via binder map).
|
|
7329
|
+
*
|
|
7330
|
+
* Provides feature flags (multiple/disabled/readonly/visible/virtualScroll/ajax/autoclose…),
|
|
7331
|
+
* a11y ids (e.g. `SEID_LIST`, `SEID_HOLDER`) and user callbacks under `options.on`.
|
|
7332
|
+
*
|
|
7333
|
+
* @internal
|
|
7334
|
+
*/
|
|
7335
|
+
this.options = null;
|
|
7262
7336
|
/**
|
|
7263
7337
|
* Subscribers for aggregated visibility statistics.
|
|
7264
7338
|
* Fired via a debounced scheduler to avoid repeated recomputation during batch updates.
|
|
@@ -7351,8 +7425,8 @@
|
|
|
7351
7425
|
*/
|
|
7352
7426
|
viewHolder(parent, item) {
|
|
7353
7427
|
if (item instanceof GroupModel)
|
|
7354
|
-
return new GroupView(parent);
|
|
7355
|
-
return new OptionView(parent);
|
|
7428
|
+
return new GroupView(parent, this.options);
|
|
7429
|
+
return new OptionView(parent, this.options);
|
|
7356
7430
|
}
|
|
7357
7431
|
/**
|
|
7358
7432
|
* Binds a model (group or option) to its view and delegates to specialized handlers.
|
|
@@ -7420,7 +7494,7 @@
|
|
|
7420
7494
|
groupModel.items.forEach((optionModel, idx) => {
|
|
7421
7495
|
let optionViewer = optionModel.view;
|
|
7422
7496
|
if (!optionModel.isInit || !optionViewer) {
|
|
7423
|
-
optionViewer = new OptionView(itemsContainer);
|
|
7497
|
+
optionViewer = new OptionView(itemsContainer, this.options);
|
|
7424
7498
|
}
|
|
7425
7499
|
this.handleOptionView(optionModel, optionViewer, idx);
|
|
7426
7500
|
optionModel.isInit = true;
|
|
@@ -9177,16 +9251,17 @@
|
|
|
9177
9251
|
});
|
|
9178
9252
|
this.optionModelManager = optionModelManager;
|
|
9179
9253
|
// Popup
|
|
9180
|
-
|
|
9181
|
-
container.popup
|
|
9182
|
-
|
|
9183
|
-
|
|
9254
|
+
const popup = new Popup(select, options, optionModelManager);
|
|
9255
|
+
container.popup = popup;
|
|
9256
|
+
popup.setupEffector(effector);
|
|
9257
|
+
popup.setupInfiniteScroll(searchController, options);
|
|
9258
|
+
popup.onAdapterPropChanged("selected", () => {
|
|
9184
9259
|
this.getAction()?.change(null, true);
|
|
9185
9260
|
});
|
|
9186
|
-
|
|
9261
|
+
popup.onAdapterPropChanged("selected_internal", () => {
|
|
9187
9262
|
this.getAction()?.change(null, false);
|
|
9188
9263
|
});
|
|
9189
|
-
|
|
9264
|
+
popup.onAdapterPropChanging("select", () => {
|
|
9190
9265
|
this.oldValue = this.getAction()?.value ?? "";
|
|
9191
9266
|
});
|
|
9192
9267
|
accessoryBox.setRoot(container.tags.ViewPanel);
|
|
@@ -9243,7 +9318,11 @@
|
|
|
9243
9318
|
Refresher.resizeBox(select, container.tags.ViewPanel);
|
|
9244
9319
|
select.classList.add("init");
|
|
9245
9320
|
// initial mask
|
|
9246
|
-
this.getAction()
|
|
9321
|
+
const action = this.getAction();
|
|
9322
|
+
action?.change?.(null, false);
|
|
9323
|
+
if (this.options.preload) {
|
|
9324
|
+
action?.load?.();
|
|
9325
|
+
}
|
|
9247
9326
|
// Call parent lifecycle mount
|
|
9248
9327
|
super.mount();
|
|
9249
9328
|
}
|
|
@@ -9683,6 +9762,26 @@
|
|
|
9683
9762
|
}
|
|
9684
9763
|
this.change(false, trigger);
|
|
9685
9764
|
},
|
|
9765
|
+
load() {
|
|
9766
|
+
if ((!superThis.hasLoadedOnce || superThis.isBeforeSearch) && bindedOptions?.ajax) {
|
|
9767
|
+
container.searchController.resetPagination();
|
|
9768
|
+
container.popup.showLoading();
|
|
9769
|
+
superThis.hasLoadedOnce = true;
|
|
9770
|
+
superThis.isBeforeSearch = false;
|
|
9771
|
+
setTimeout(() => {
|
|
9772
|
+
if (!container.popup || !container.searchController)
|
|
9773
|
+
return;
|
|
9774
|
+
container.searchController
|
|
9775
|
+
.search("")
|
|
9776
|
+
.then(() => container.popup?.triggerResize?.())
|
|
9777
|
+
.catch((err) => console.error("Initial ajax load error:", err));
|
|
9778
|
+
}, bindedOptions.animationtime);
|
|
9779
|
+
container.popup.load();
|
|
9780
|
+
}
|
|
9781
|
+
else {
|
|
9782
|
+
container.popup.load();
|
|
9783
|
+
}
|
|
9784
|
+
},
|
|
9686
9785
|
open() {
|
|
9687
9786
|
if (superThis.isOpen)
|
|
9688
9787
|
return;
|
|
@@ -9692,45 +9791,34 @@
|
|
|
9692
9791
|
if (closeToken.isCancel)
|
|
9693
9792
|
return;
|
|
9694
9793
|
}
|
|
9695
|
-
if (this.disabled)
|
|
9794
|
+
if (this.disabled) {
|
|
9696
9795
|
return;
|
|
9796
|
+
}
|
|
9697
9797
|
const beforeShowToken = iEvents.callEvent([getInstance()], ...bindedOptions.on.beforeShow);
|
|
9698
|
-
if (beforeShowToken.isCancel)
|
|
9798
|
+
if (beforeShowToken.isCancel) {
|
|
9699
9799
|
return;
|
|
9800
|
+
}
|
|
9700
9801
|
superThis.isOpen = true;
|
|
9701
9802
|
container.directive.setDropdown(true);
|
|
9702
9803
|
const adapter = container.popup.optionAdapter;
|
|
9703
9804
|
const selectedOption = adapter.getSelectedItem();
|
|
9704
|
-
if (selectedOption)
|
|
9805
|
+
if (selectedOption) {
|
|
9705
9806
|
adapter.setHighlight(selectedOption, false);
|
|
9706
|
-
else
|
|
9707
|
-
adapter.resetHighlight();
|
|
9708
|
-
if ((!superThis.hasLoadedOnce || superThis.isBeforeSearch) && bindedOptions?.ajax) {
|
|
9709
|
-
container.searchController.resetPagination();
|
|
9710
|
-
container.popup.showLoading();
|
|
9711
|
-
superThis.hasLoadedOnce = true;
|
|
9712
|
-
superThis.isBeforeSearch = false;
|
|
9713
|
-
setTimeout(() => {
|
|
9714
|
-
if (!container.popup || !container.searchController)
|
|
9715
|
-
return;
|
|
9716
|
-
container.searchController
|
|
9717
|
-
.search("")
|
|
9718
|
-
.then(() => container.popup?.triggerResize?.())
|
|
9719
|
-
.catch((err) => console.error("Initial ajax load error:", err));
|
|
9720
|
-
}, bindedOptions.animationtime);
|
|
9721
|
-
container.popup.open(null, false);
|
|
9722
9807
|
}
|
|
9723
9808
|
else {
|
|
9724
|
-
|
|
9809
|
+
adapter.resetHighlight();
|
|
9725
9810
|
}
|
|
9811
|
+
this.load();
|
|
9812
|
+
container.popup.open(null, !container.popup.loadingState.isVisible);
|
|
9726
9813
|
container.searchbox.show();
|
|
9727
9814
|
const ViewPanel = container.tags.ViewPanel;
|
|
9728
9815
|
ViewPanel.setAttribute("aria-expanded", "true");
|
|
9729
9816
|
ViewPanel.setAttribute("aria-controls", bindedOptions.SEID_LIST);
|
|
9730
9817
|
ViewPanel.setAttribute("aria-haspopup", "listbox");
|
|
9731
9818
|
ViewPanel.setAttribute("aria-labelledby", bindedOptions.SEID_HOLDER);
|
|
9732
|
-
if (bindedOptions.multiple)
|
|
9819
|
+
if (bindedOptions.multiple) {
|
|
9733
9820
|
ViewPanel.setAttribute("aria-multiselectable", "true");
|
|
9821
|
+
}
|
|
9734
9822
|
iEvents.callEvent([getInstance()], ...bindedOptions.on.show);
|
|
9735
9823
|
if (superThis.pluginContext) {
|
|
9736
9824
|
superThis.runPluginHook("onOpen", (plugin) => plugin.onOpen?.(superThis.pluginContext));
|
|
@@ -10004,7 +10092,7 @@
|
|
|
10004
10092
|
*
|
|
10005
10093
|
* @internal
|
|
10006
10094
|
*/
|
|
10007
|
-
this.actions =
|
|
10095
|
+
this.actions = new Set();
|
|
10008
10096
|
}
|
|
10009
10097
|
/**
|
|
10010
10098
|
* Registers a callback invoked whenever a matching element is detected as added to the DOM.
|
|
@@ -10016,7 +10104,7 @@
|
|
|
10016
10104
|
* @param action - Function executed with the newly detected element.
|
|
10017
10105
|
*/
|
|
10018
10106
|
onDetect(action) {
|
|
10019
|
-
this.actions.
|
|
10107
|
+
this.actions.add(action);
|
|
10020
10108
|
}
|
|
10021
10109
|
/**
|
|
10022
10110
|
* Clears all registered detection callbacks.
|
|
@@ -10025,7 +10113,7 @@
|
|
|
10025
10113
|
* to scan mutations but will not invoke any listeners until new callbacks are registered.
|
|
10026
10114
|
*/
|
|
10027
10115
|
clearDetect() {
|
|
10028
|
-
this.actions
|
|
10116
|
+
this.actions.clear();
|
|
10029
10117
|
}
|
|
10030
10118
|
/**
|
|
10031
10119
|
* Starts observing the document for additions of elements matching the given tag name.
|
|
@@ -10099,7 +10187,9 @@
|
|
|
10099
10187
|
* @internal
|
|
10100
10188
|
*/
|
|
10101
10189
|
handle(element) {
|
|
10102
|
-
this.actions
|
|
10190
|
+
for (const action of this.actions) {
|
|
10191
|
+
action(element);
|
|
10192
|
+
}
|
|
10103
10193
|
}
|
|
10104
10194
|
}
|
|
10105
10195
|
|
|
@@ -10805,7 +10895,7 @@
|
|
|
10805
10895
|
if (typeof globalThis.GLOBAL_SEUI == "undefined") {
|
|
10806
10896
|
const SECLASS = new Selective();
|
|
10807
10897
|
globalThis.GLOBAL_SEUI = {
|
|
10808
|
-
version: "1.
|
|
10898
|
+
version: "1.3.0",
|
|
10809
10899
|
name: "SelectiveUI",
|
|
10810
10900
|
bind: SECLASS.bind.bind(SECLASS),
|
|
10811
10901
|
find: SECLASS.find.bind(SECLASS),
|
|
@@ -10838,7 +10928,7 @@
|
|
|
10838
10928
|
init();
|
|
10839
10929
|
}
|
|
10840
10930
|
}
|
|
10841
|
-
console.log(`[${"SelectiveUI"}] v${"1.
|
|
10931
|
+
console.log(`[${"SelectiveUI"}] v${"1.3.0"} loaded successfully`);
|
|
10842
10932
|
}
|
|
10843
10933
|
else {
|
|
10844
10934
|
console.warn(`[${globalThis.GLOBAL_SEUI.name}] Already loaded (v${globalThis.GLOBAL_SEUI.version}). ` +
|