@keenthemes/ktui 1.0.20 → 1.0.21
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/ktui.js +418 -144
- package/dist/ktui.min.js +1 -1
- package/dist/ktui.min.js.map +1 -1
- package/dist/styles.css +139 -31
- package/examples/image-input/file-upload-example.html +189 -0
- package/examples/select/remote-data_.html +5 -0
- package/examples/select/test-optimizations.html +227 -0
- package/examples/select/test-remote-search.html +151 -0
- package/examples/sticky/README.md +158 -0
- package/examples/sticky/debug-sticky.html +144 -0
- package/examples/sticky/test-runner.html +175 -0
- package/examples/sticky/test-sticky-logic.js +369 -0
- package/examples/sticky/test-sticky-positioning.html +386 -0
- package/examples/toast/example.html +52 -0
- package/lib/cjs/components/component.js +5 -3
- package/lib/cjs/components/component.js.map +1 -1
- package/lib/cjs/components/datatable/datatable-sort.js +4 -0
- package/lib/cjs/components/datatable/datatable-sort.js.map +1 -1
- package/lib/cjs/components/datatable/datatable.js +9 -3
- package/lib/cjs/components/datatable/datatable.js.map +1 -1
- package/lib/cjs/components/image-input/image-input.js +10 -2
- package/lib/cjs/components/image-input/image-input.js.map +1 -1
- package/lib/cjs/components/select/combobox.js +50 -20
- package/lib/cjs/components/select/combobox.js.map +1 -1
- package/lib/cjs/components/select/dropdown.js +4 -2
- package/lib/cjs/components/select/dropdown.js.map +1 -1
- package/lib/cjs/components/select/index.js.map +1 -1
- package/lib/cjs/components/select/option.js +2 -1
- package/lib/cjs/components/select/option.js.map +1 -1
- package/lib/cjs/components/select/remote.js +50 -50
- package/lib/cjs/components/select/remote.js.map +1 -1
- package/lib/cjs/components/select/search.js +7 -5
- package/lib/cjs/components/select/search.js.map +1 -1
- package/lib/cjs/components/select/select.js +199 -33
- package/lib/cjs/components/select/select.js.map +1 -1
- package/lib/cjs/components/select/tags.js +3 -1
- package/lib/cjs/components/select/tags.js.map +1 -1
- package/lib/cjs/components/select/templates.js.map +1 -1
- package/lib/cjs/components/select/utils.js +23 -10
- package/lib/cjs/components/select/utils.js.map +1 -1
- package/lib/cjs/components/sticky/sticky.js +52 -14
- package/lib/cjs/components/sticky/sticky.js.map +1 -1
- package/lib/esm/components/component.js +5 -3
- package/lib/esm/components/component.js.map +1 -1
- package/lib/esm/components/datatable/datatable-sort.js +4 -0
- package/lib/esm/components/datatable/datatable-sort.js.map +1 -1
- package/lib/esm/components/datatable/datatable.js +9 -3
- package/lib/esm/components/datatable/datatable.js.map +1 -1
- package/lib/esm/components/image-input/image-input.js +10 -2
- package/lib/esm/components/image-input/image-input.js.map +1 -1
- package/lib/esm/components/select/combobox.js +50 -20
- package/lib/esm/components/select/combobox.js.map +1 -1
- package/lib/esm/components/select/dropdown.js +4 -2
- package/lib/esm/components/select/dropdown.js.map +1 -1
- package/lib/esm/components/select/index.js +1 -1
- package/lib/esm/components/select/index.js.map +1 -1
- package/lib/esm/components/select/option.js +2 -1
- package/lib/esm/components/select/option.js.map +1 -1
- package/lib/esm/components/select/remote.js +50 -50
- package/lib/esm/components/select/remote.js.map +1 -1
- package/lib/esm/components/select/search.js +8 -6
- package/lib/esm/components/select/search.js.map +1 -1
- package/lib/esm/components/select/select.js +199 -33
- package/lib/esm/components/select/select.js.map +1 -1
- package/lib/esm/components/select/tags.js +3 -1
- package/lib/esm/components/select/tags.js.map +1 -1
- package/lib/esm/components/select/templates.js.map +1 -1
- package/lib/esm/components/select/utils.js +23 -10
- package/lib/esm/components/select/utils.js.map +1 -1
- package/lib/esm/components/sticky/sticky.js +52 -14
- package/lib/esm/components/sticky/sticky.js.map +1 -1
- package/package.json +1 -1
- package/src/components/component.ts +12 -11
- package/src/components/datatable/datatable-sort.ts +6 -0
- package/src/components/datatable/datatable.ts +90 -81
- package/src/components/image-input/image-input.ts +11 -2
- package/src/components/image-input/types.ts +1 -0
- package/src/components/input/input-group.css +1 -1
- package/src/components/input/input.css +1 -1
- package/src/components/scrollable/scrollable.css +3 -3
- package/src/components/select/combobox.ts +84 -34
- package/src/components/select/dropdown.ts +20 -11
- package/src/components/select/index.ts +6 -1
- package/src/components/select/option.ts +7 -6
- package/src/components/select/remote.ts +51 -52
- package/src/components/select/search.ts +51 -45
- package/src/components/select/select.css +12 -11
- package/src/components/select/select.ts +371 -102
- package/src/components/select/tags.ts +9 -3
- package/src/components/select/templates.ts +1 -4
- package/src/components/select/utils.ts +55 -20
- package/src/components/select/variants.css +0 -1
- package/src/components/sticky/sticky.ts +47 -16
- package/src/components/sticky/types.ts +3 -0
- package/src/components/table/table.css +1 -1
- package/src/components/textarea/textarea.css +1 -1
- package/src/components/toast/toast.css +84 -47
- package/src/components/toast/types.ts +3 -0
package/dist/ktui.js
CHANGED
|
@@ -2507,12 +2507,14 @@ var KTComponent = /** @class */ (function () {
|
|
|
2507
2507
|
switch (_a.label) {
|
|
2508
2508
|
case 0:
|
|
2509
2509
|
callbacks = this._events.get(eventType);
|
|
2510
|
-
if (
|
|
2510
|
+
if (callbacks instanceof Map == false) {
|
|
2511
2511
|
return [2 /*return*/];
|
|
2512
2512
|
}
|
|
2513
|
-
return [4 /*yield*/, Promise.all(Array.from(callbacks.values())
|
|
2513
|
+
return [4 /*yield*/, Promise.all(Array.from(callbacks.values())
|
|
2514
|
+
.filter(function (callable) {
|
|
2514
2515
|
return typeof callable === 'function';
|
|
2515
|
-
})
|
|
2516
|
+
})
|
|
2517
|
+
.map(function (callable) {
|
|
2516
2518
|
return Promise.resolve(callable(payload));
|
|
2517
2519
|
}))];
|
|
2518
2520
|
case 1:
|
|
@@ -2641,6 +2643,7 @@ var KTImageInput = /** @class */ (function (_super) {
|
|
|
2641
2643
|
hiddenClass: 'hidden',
|
|
2642
2644
|
};
|
|
2643
2645
|
_this._previewUrl = '';
|
|
2646
|
+
_this._selectedFile = null;
|
|
2644
2647
|
if (data_1.default.has(element, _this._name))
|
|
2645
2648
|
return _this;
|
|
2646
2649
|
_this._init(element);
|
|
@@ -2679,6 +2682,7 @@ var KTImageInput = /** @class */ (function (_super) {
|
|
|
2679
2682
|
_this._previewElement.style.backgroundImage = "url(".concat(reader.result, ")");
|
|
2680
2683
|
};
|
|
2681
2684
|
reader.readAsDataURL(this._inputElement.files[0]);
|
|
2685
|
+
this._selectedFile = this._inputElement.files[0];
|
|
2682
2686
|
this._inputElement.value = '';
|
|
2683
2687
|
this._hiddenElement.value = '';
|
|
2684
2688
|
this._lastMode = 'new';
|
|
@@ -2709,6 +2713,7 @@ var KTImageInput = /** @class */ (function (_super) {
|
|
|
2709
2713
|
}
|
|
2710
2714
|
this._inputElement.value = '';
|
|
2711
2715
|
this._hiddenElement.value = '';
|
|
2716
|
+
this._selectedFile = null;
|
|
2712
2717
|
this._lastMode = 'saved';
|
|
2713
2718
|
}
|
|
2714
2719
|
else if (this._lastMode == 'saved') {
|
|
@@ -2718,6 +2723,7 @@ var KTImageInput = /** @class */ (function (_super) {
|
|
|
2718
2723
|
this._element.classList.add('empty');
|
|
2719
2724
|
this._hiddenElement.value = '1';
|
|
2720
2725
|
this._inputElement.value = '';
|
|
2726
|
+
this._selectedFile = null;
|
|
2721
2727
|
this._lastMode = 'placeholder';
|
|
2722
2728
|
}
|
|
2723
2729
|
else if (this._lastMode == 'placeholder') {
|
|
@@ -2731,6 +2737,7 @@ var KTImageInput = /** @class */ (function (_super) {
|
|
|
2731
2737
|
}
|
|
2732
2738
|
this._inputElement.value = '';
|
|
2733
2739
|
this._hiddenElement.value = '';
|
|
2740
|
+
this._selectedFile = null;
|
|
2734
2741
|
this._lastMode = 'saved';
|
|
2735
2742
|
}
|
|
2736
2743
|
this._fireEvent('remove');
|
|
@@ -2755,10 +2762,10 @@ var KTImageInput = /** @class */ (function (_super) {
|
|
|
2755
2762
|
this._previewUrl = url.replace(/(url\(|\)|")/g, '');
|
|
2756
2763
|
};
|
|
2757
2764
|
KTImageInput.prototype.isEmpty = function () {
|
|
2758
|
-
return this.
|
|
2765
|
+
return this._selectedFile === null;
|
|
2759
2766
|
};
|
|
2760
2767
|
KTImageInput.prototype.isChanged = function () {
|
|
2761
|
-
return this.
|
|
2768
|
+
return this._selectedFile !== null;
|
|
2762
2769
|
};
|
|
2763
2770
|
KTImageInput.prototype.remove = function () {
|
|
2764
2771
|
this._remove();
|
|
@@ -2772,6 +2779,9 @@ var KTImageInput = /** @class */ (function (_super) {
|
|
|
2772
2779
|
KTImageInput.prototype.getPreviewUrl = function () {
|
|
2773
2780
|
return this._getPreviewUrl();
|
|
2774
2781
|
};
|
|
2782
|
+
KTImageInput.prototype.getSelectedFile = function () {
|
|
2783
|
+
return this._selectedFile;
|
|
2784
|
+
};
|
|
2775
2785
|
KTImageInput.getInstance = function (element) {
|
|
2776
2786
|
if (!element)
|
|
2777
2787
|
return null;
|
|
@@ -2845,7 +2855,10 @@ var KTSticky = /** @class */ (function (_super) {
|
|
|
2845
2855
|
name: '',
|
|
2846
2856
|
class: '',
|
|
2847
2857
|
top: '',
|
|
2858
|
+
middle: false,
|
|
2859
|
+
bottom: '',
|
|
2848
2860
|
start: '',
|
|
2861
|
+
center: false,
|
|
2849
2862
|
end: '',
|
|
2850
2863
|
width: '',
|
|
2851
2864
|
zindex: '',
|
|
@@ -2988,7 +3001,10 @@ var KTSticky = /** @class */ (function (_super) {
|
|
|
2988
3001
|
return false;
|
|
2989
3002
|
var width = this._getOption('width');
|
|
2990
3003
|
var top = this._getOption('top');
|
|
3004
|
+
var middle = this._getOption('middle');
|
|
3005
|
+
var bottom = this._getOption('bottom');
|
|
2991
3006
|
var start = this._getOption('start');
|
|
3007
|
+
var center = this._getOption('center');
|
|
2992
3008
|
var end = this._getOption('end');
|
|
2993
3009
|
var height = this._calculateHeight();
|
|
2994
3010
|
var zindex = this._getOption('zindex');
|
|
@@ -3006,29 +3022,56 @@ var KTSticky = /** @class */ (function (_super) {
|
|
|
3006
3022
|
}
|
|
3007
3023
|
this._element.style.width = "".concat(Math.round(parseFloat(width)), "px");
|
|
3008
3024
|
}
|
|
3009
|
-
if (
|
|
3010
|
-
this._element.style.
|
|
3025
|
+
if (middle === true) {
|
|
3026
|
+
this._element.style.insetBlockStart = "50%";
|
|
3011
3027
|
}
|
|
3012
|
-
|
|
3013
|
-
if (
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3028
|
+
else {
|
|
3029
|
+
if (top) {
|
|
3030
|
+
if (top === 'auto') {
|
|
3031
|
+
this._element.style.insetBlockStart = "0px";
|
|
3032
|
+
}
|
|
3033
|
+
else {
|
|
3034
|
+
this._element.style.insetBlockStart = "".concat(top, "px");
|
|
3017
3035
|
}
|
|
3018
3036
|
}
|
|
3019
3037
|
else {
|
|
3020
|
-
|
|
3038
|
+
if (bottom) {
|
|
3039
|
+
if (bottom === 'auto') {
|
|
3040
|
+
this._element.style.insetBlockEnd = "0px";
|
|
3041
|
+
}
|
|
3042
|
+
else {
|
|
3043
|
+
this._element.style.insetBlockEnd = "".concat(bottom, "px");
|
|
3044
|
+
}
|
|
3045
|
+
}
|
|
3021
3046
|
}
|
|
3022
3047
|
}
|
|
3023
|
-
if (
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3048
|
+
if (center === true) {
|
|
3049
|
+
this._element.style.insetInlineStart = "50%";
|
|
3050
|
+
}
|
|
3051
|
+
else {
|
|
3052
|
+
if (start) {
|
|
3053
|
+
if (start === 'auto') {
|
|
3054
|
+
var offsetLeft = dom_1.default.offset(this._element).left;
|
|
3055
|
+
if (offsetLeft >= 0) {
|
|
3056
|
+
this._element.style.insetInlineStart = "".concat(offsetLeft, "px");
|
|
3057
|
+
}
|
|
3058
|
+
}
|
|
3059
|
+
else {
|
|
3060
|
+
this._element.style.insetInlineStart = "".concat(start, "px");
|
|
3028
3061
|
}
|
|
3029
3062
|
}
|
|
3030
3063
|
else {
|
|
3031
|
-
|
|
3064
|
+
if (end) {
|
|
3065
|
+
if (end === 'auto') {
|
|
3066
|
+
var offsetRight = dom_1.default.offset(this._element).right;
|
|
3067
|
+
if (offsetRight >= 0) {
|
|
3068
|
+
this._element.style.insetInlineEnd = "".concat(offsetRight, "px");
|
|
3069
|
+
}
|
|
3070
|
+
}
|
|
3071
|
+
else {
|
|
3072
|
+
this._element.style.insetInlineEnd = "".concat(end, "px");
|
|
3073
|
+
}
|
|
3074
|
+
}
|
|
3032
3075
|
}
|
|
3033
3076
|
}
|
|
3034
3077
|
if (zindex) {
|
|
@@ -3049,6 +3092,11 @@ var KTSticky = /** @class */ (function (_super) {
|
|
|
3049
3092
|
if (!this._element)
|
|
3050
3093
|
return;
|
|
3051
3094
|
this._element.style.top = '';
|
|
3095
|
+
this._element.style.bottom = '';
|
|
3096
|
+
this._element.style.insetInlineStart = '';
|
|
3097
|
+
this._element.style.insetInlineEnd = '';
|
|
3098
|
+
this._element.style.insetBlockStart = '';
|
|
3099
|
+
this._element.style.insetBlockEnd = '';
|
|
3052
3100
|
this._element.style.width = '';
|
|
3053
3101
|
this._element.style.left = '';
|
|
3054
3102
|
this._element.style.right = '';
|
|
@@ -3370,11 +3418,9 @@ var KTSelectRemote = /** @class */ (function () {
|
|
|
3370
3418
|
console.log("Mapping fields: value=".concat(valueField, ", label=").concat(labelField));
|
|
3371
3419
|
if (this._config.debug)
|
|
3372
3420
|
console.log('Item data:', JSON.stringify(item).substring(0, 200) + '...'); // Trimmed for readability
|
|
3373
|
-
// Extract values using
|
|
3421
|
+
// Extract values using improved getValue function
|
|
3374
3422
|
var getValue = function (obj, path) {
|
|
3375
|
-
if (!path)
|
|
3376
|
-
return null;
|
|
3377
|
-
if (!obj)
|
|
3423
|
+
if (!path || !obj)
|
|
3378
3424
|
return null;
|
|
3379
3425
|
try {
|
|
3380
3426
|
// Handle dot notation to access nested properties
|
|
@@ -3403,65 +3449,67 @@ var KTSelectRemote = /** @class */ (function () {
|
|
|
3403
3449
|
return null;
|
|
3404
3450
|
}
|
|
3405
3451
|
};
|
|
3406
|
-
//
|
|
3452
|
+
// Get ID and ensure it's a string
|
|
3407
3453
|
var id = getValue(item, valueField);
|
|
3408
|
-
// Ensure id is always a proper string
|
|
3409
3454
|
if (id === null || id === undefined) {
|
|
3410
|
-
//
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
item
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
|
|
3420
|
-
id = String(item.id);
|
|
3421
|
-
if (this._config.debug)
|
|
3422
|
-
console.log("Using direct item.id as fallback: ".concat(id));
|
|
3423
|
-
}
|
|
3424
|
-
else {
|
|
3425
|
-
// If no ID found at all, use the title instead (will be extracted below)
|
|
3426
|
-
if (this._config.debug)
|
|
3427
|
-
console.log("No ID found, will use title as fallback");
|
|
3428
|
-
id = null;
|
|
3455
|
+
// Try common fallback fields for ID
|
|
3456
|
+
var fallbackFields = ['id', 'value', 'key', 'pk'];
|
|
3457
|
+
for (var _i = 0, fallbackFields_1 = fallbackFields; _i < fallbackFields_1.length; _i++) {
|
|
3458
|
+
var field = fallbackFields_1[_i];
|
|
3459
|
+
if (item[field] !== null && item[field] !== undefined) {
|
|
3460
|
+
id = String(item[field]);
|
|
3461
|
+
if (this._config.debug)
|
|
3462
|
+
console.log("Using fallback field '".concat(field, "' for ID: ").concat(id));
|
|
3463
|
+
break;
|
|
3464
|
+
}
|
|
3429
3465
|
}
|
|
3430
3466
|
}
|
|
3431
|
-
else if (typeof id === 'object') {
|
|
3432
|
-
// If ID is an object, log the issue and set to null to use title fallback
|
|
3433
|
-
console.warn("ID for path ".concat(valueField, " is an object, will use title fallback instead"));
|
|
3434
|
-
id = null;
|
|
3435
|
-
}
|
|
3436
3467
|
else {
|
|
3437
|
-
// Otherwise, ensure it's a string
|
|
3438
3468
|
id = String(id);
|
|
3469
|
+
}
|
|
3470
|
+
// If still no ID, generate one
|
|
3471
|
+
if (!id) {
|
|
3472
|
+
id = "option-".concat(Math.random().toString(36).substr(2, 9));
|
|
3439
3473
|
if (this._config.debug)
|
|
3440
|
-
console.log("
|
|
3474
|
+
console.log("Generated fallback ID: ".concat(id));
|
|
3441
3475
|
}
|
|
3442
|
-
//
|
|
3476
|
+
// Get label with proper fallbacks
|
|
3443
3477
|
var title = getValue(item, labelField);
|
|
3444
|
-
title = title !== null ? String(title) : '';
|
|
3445
|
-
if (this._config.debug)
|
|
3446
|
-
console.log("Title/label field [".concat(labelField, "]:"), title);
|
|
3447
|
-
// If title is still empty, try common field names
|
|
3448
3478
|
if (!title) {
|
|
3449
|
-
// Try common
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3479
|
+
// Try common fallback fields for title
|
|
3480
|
+
var fallbackFields = [
|
|
3481
|
+
'name',
|
|
3482
|
+
'title',
|
|
3483
|
+
'label',
|
|
3484
|
+
'text',
|
|
3485
|
+
'displayName',
|
|
3486
|
+
'description',
|
|
3487
|
+
];
|
|
3488
|
+
for (var _a = 0, fallbackFields_2 = fallbackFields; _a < fallbackFields_2.length; _a++) {
|
|
3489
|
+
var field = fallbackFields_2[_a];
|
|
3490
|
+
if (item[field] !== null && item[field] !== undefined) {
|
|
3491
|
+
title = String(item[field]);
|
|
3492
|
+
if (this._config.debug)
|
|
3493
|
+
console.log("Using fallback field '".concat(field, "' for title: ").concat(title));
|
|
3494
|
+
break;
|
|
3495
|
+
}
|
|
3496
|
+
}
|
|
3497
|
+
}
|
|
3498
|
+
else {
|
|
3499
|
+
title = String(title);
|
|
3500
|
+
}
|
|
3501
|
+
// If still no title, use ID as fallback
|
|
3502
|
+
if (!title) {
|
|
3503
|
+
title = "Option ".concat(id);
|
|
3458
3504
|
if (this._config.debug)
|
|
3459
|
-
console.log(
|
|
3505
|
+
console.log("Using ID as fallback title: ".concat(title));
|
|
3460
3506
|
}
|
|
3461
|
-
// Create the option object with
|
|
3507
|
+
// Create the option object with consistent structure
|
|
3462
3508
|
var result = {
|
|
3463
|
-
id: id
|
|
3464
|
-
title: title
|
|
3509
|
+
id: id,
|
|
3510
|
+
title: title,
|
|
3511
|
+
selected: Boolean(item.selected),
|
|
3512
|
+
disabled: Boolean(item.disabled),
|
|
3465
3513
|
};
|
|
3466
3514
|
if (this._config.debug)
|
|
3467
3515
|
console.log('Final mapped item:', JSON.stringify(result));
|
|
@@ -5783,7 +5831,8 @@ var KTSelectOption = /** @class */ (function (_super) {
|
|
|
5783
5831
|
// Ensure optionsConfig is initialized
|
|
5784
5832
|
if (_this._globalConfig) {
|
|
5785
5833
|
_this._globalConfig.optionsConfig = _this._globalConfig.optionsConfig || {};
|
|
5786
|
-
_this._globalConfig.optionsConfig[element.value] =
|
|
5834
|
+
_this._globalConfig.optionsConfig[element.value] =
|
|
5835
|
+
_this._config;
|
|
5787
5836
|
// console.log('[KTSelectOption] Populating _globalConfig.optionsConfig for value', (element as HTMLInputElement).value, 'with:', JSON.parse(JSON.stringify(this._config)));
|
|
5788
5837
|
// console.log('[KTSelectOption] _globalConfig.optionsConfig is now:', JSON.parse(JSON.stringify(this._globalConfig.optionsConfig)));
|
|
5789
5838
|
}
|
|
@@ -6600,6 +6649,10 @@ function createSortHandler(config, theadElement, getState, setState, fireEvent,
|
|
|
6600
6649
|
// If the sort class is not found, it's not a sortable column
|
|
6601
6650
|
if (!header.querySelector(".".concat((_b = (_a = config.sort) === null || _a === void 0 ? void 0 : _a.classes) === null || _b === void 0 ? void 0 : _b.base)))
|
|
6602
6651
|
return;
|
|
6652
|
+
// Check if sorting is disabled for this column
|
|
6653
|
+
var sortDisabled = header.getAttribute('data-kt-datatable-column-sort') === 'false';
|
|
6654
|
+
if (sortDisabled)
|
|
6655
|
+
return;
|
|
6603
6656
|
var sortAttribute = header.getAttribute('data-kt-datatable-column-sort') ||
|
|
6604
6657
|
header.getAttribute('data-kt-datatable-column');
|
|
6605
6658
|
var sortField = sortAttribute
|
|
@@ -6686,7 +6739,8 @@ var KTSelectCombobox = /** @class */ (function () {
|
|
|
6686
6739
|
*/
|
|
6687
6740
|
KTSelectCombobox.prototype._attachEventListeners = function () {
|
|
6688
6741
|
this._removeEventListeners();
|
|
6689
|
-
if (this._searchInputElement) {
|
|
6742
|
+
if (this._searchInputElement) {
|
|
6743
|
+
// Ensure element exists
|
|
6690
6744
|
this._searchInputElement.addEventListener('input', this._boundInputHandler);
|
|
6691
6745
|
}
|
|
6692
6746
|
if (this._clearButtonElement) {
|
|
@@ -6711,7 +6765,8 @@ var KTSelectCombobox = /** @class */ (function () {
|
|
|
6711
6765
|
var inputElement = event.target;
|
|
6712
6766
|
var query = inputElement.value;
|
|
6713
6767
|
this._toggleClearButtonVisibility(query);
|
|
6714
|
-
if (!this._select.isDropdownOpen()) {
|
|
6768
|
+
if (!this._select.isDropdownOpen()) {
|
|
6769
|
+
// Use public getter
|
|
6715
6770
|
this._select.openDropdown();
|
|
6716
6771
|
}
|
|
6717
6772
|
// For single select without displayTemplate, if user types, they are essentially clearing the previous selection text
|
|
@@ -6750,7 +6805,9 @@ var KTSelectCombobox = /** @class */ (function () {
|
|
|
6750
6805
|
if (!this._clearButtonElement)
|
|
6751
6806
|
return;
|
|
6752
6807
|
var hasSelectedItems = this._select.getSelectedOptions().length > 0;
|
|
6753
|
-
if (inputValue.length > 0 ||
|
|
6808
|
+
if (inputValue.length > 0 ||
|
|
6809
|
+
(hasSelectedItems &&
|
|
6810
|
+
(this._config.multiple || this._config.displayTemplate))) {
|
|
6754
6811
|
this._clearButtonElement.classList.remove('hidden');
|
|
6755
6812
|
}
|
|
6756
6813
|
else {
|
|
@@ -6782,41 +6839,67 @@ var KTSelectCombobox = /** @class */ (function () {
|
|
|
6782
6839
|
if (this._valuesContainerElement) {
|
|
6783
6840
|
this._valuesContainerElement.innerHTML = '';
|
|
6784
6841
|
}
|
|
6785
|
-
if (this._config.tags && this._valuesContainerElement) {
|
|
6842
|
+
if (this._config.tags && this._valuesContainerElement) {
|
|
6843
|
+
// Combobox + Tags
|
|
6786
6844
|
selectedOptions.forEach(function (value) {
|
|
6787
6845
|
// Ensure value is properly escaped for querySelector
|
|
6788
|
-
var optionElement = _this._select
|
|
6846
|
+
var optionElement = _this._select
|
|
6847
|
+
.getElement()
|
|
6848
|
+
.querySelector("option[value=\"".concat(CSS.escape(value), "\"]"));
|
|
6789
6849
|
if (optionElement) {
|
|
6790
6850
|
var tagElement = templates_1.defaultTemplates.tag(optionElement, _this._config);
|
|
6791
6851
|
_this._valuesContainerElement.appendChild(tagElement);
|
|
6792
6852
|
}
|
|
6793
6853
|
});
|
|
6794
6854
|
this._searchInputElement.value = ''; // Input field is for typing new searches
|
|
6795
|
-
this._searchInputElement.placeholder =
|
|
6796
|
-
|
|
6797
|
-
|
|
6798
|
-
|
|
6855
|
+
this._searchInputElement.placeholder =
|
|
6856
|
+
selectedOptions.length > 0
|
|
6857
|
+
? ''
|
|
6858
|
+
: this._config.placeholder || 'Select...';
|
|
6859
|
+
}
|
|
6860
|
+
else if (this._config.displayTemplate && this._valuesContainerElement) {
|
|
6861
|
+
// Combobox + DisplayTemplate (no tags)
|
|
6862
|
+
this._valuesContainerElement.innerHTML =
|
|
6863
|
+
this._select.renderDisplayTemplateForSelected(selectedOptions);
|
|
6799
6864
|
this._searchInputElement.value = ''; // Input field is for typing new searches
|
|
6800
|
-
this._searchInputElement.placeholder =
|
|
6865
|
+
this._searchInputElement.placeholder =
|
|
6866
|
+
selectedOptions.length > 0
|
|
6867
|
+
? ''
|
|
6868
|
+
: this._config.placeholder || 'Select...';
|
|
6801
6869
|
}
|
|
6802
|
-
else if (this._config.multiple && this._valuesContainerElement) {
|
|
6870
|
+
else if (this._config.multiple && this._valuesContainerElement) {
|
|
6871
|
+
// Combobox + Multiple (no tags, no display template)
|
|
6803
6872
|
// For simplicity, join text. A proper tag implementation would be more complex here.
|
|
6804
|
-
this._valuesContainerElement.innerHTML = selectedOptions
|
|
6805
|
-
|
|
6873
|
+
this._valuesContainerElement.innerHTML = selectedOptions
|
|
6874
|
+
.map(function (value) {
|
|
6875
|
+
var optionEl = _this._select
|
|
6876
|
+
.getElement()
|
|
6877
|
+
.querySelector("option[value=\"".concat(CSS.escape(value), "\"]"));
|
|
6806
6878
|
return optionEl ? optionEl.textContent : '';
|
|
6807
|
-
})
|
|
6879
|
+
})
|
|
6880
|
+
.join(', '); // Basic comma separation
|
|
6808
6881
|
this._searchInputElement.value = '';
|
|
6809
|
-
this._searchInputElement.placeholder =
|
|
6882
|
+
this._searchInputElement.placeholder =
|
|
6883
|
+
selectedOptions.length > 0
|
|
6884
|
+
? ''
|
|
6885
|
+
: this._config.placeholder || 'Select...';
|
|
6810
6886
|
}
|
|
6811
|
-
else if (!this._config.multiple && selectedOptions.length > 0) {
|
|
6887
|
+
else if (!this._config.multiple && selectedOptions.length > 0) {
|
|
6888
|
+
// Single select combobox: display selected option's text in the input
|
|
6812
6889
|
var selectedValue = selectedOptions[0];
|
|
6813
|
-
var optionElement = this._select
|
|
6814
|
-
|
|
6890
|
+
var optionElement = this._select
|
|
6891
|
+
.getElement()
|
|
6892
|
+
.querySelector("option[value=\"".concat(CSS.escape(selectedValue), "\"]"));
|
|
6893
|
+
this._searchInputElement.value = optionElement
|
|
6894
|
+
? optionElement.textContent || ''
|
|
6895
|
+
: '';
|
|
6815
6896
|
// placeholder is implicitly handled by input value for single select
|
|
6816
6897
|
}
|
|
6817
|
-
else {
|
|
6898
|
+
else {
|
|
6899
|
+
// No selection or not fitting above categories (e.g. single select, no items)
|
|
6818
6900
|
this._searchInputElement.value = '';
|
|
6819
|
-
this._searchInputElement.placeholder =
|
|
6901
|
+
this._searchInputElement.placeholder =
|
|
6902
|
+
this._config.placeholder || 'Select...';
|
|
6820
6903
|
// _valuesContainerElement is already cleared if it exists
|
|
6821
6904
|
}
|
|
6822
6905
|
this._toggleClearButtonVisibility(this._searchInputElement.value);
|
|
@@ -8065,7 +8148,11 @@ var KTDataTable = /** @class */ (function (_super) {
|
|
|
8065
8148
|
// Set search value
|
|
8066
8149
|
if (searchElement) {
|
|
8067
8150
|
searchElement.value =
|
|
8068
|
-
search === undefined || search === null
|
|
8151
|
+
search === undefined || search === null
|
|
8152
|
+
? ''
|
|
8153
|
+
: typeof search === 'string'
|
|
8154
|
+
? search
|
|
8155
|
+
: String(search);
|
|
8069
8156
|
}
|
|
8070
8157
|
if (searchElement) {
|
|
8071
8158
|
// Check if a debounced search function already exists
|
|
@@ -8472,7 +8559,8 @@ var KTDataTable = /** @class */ (function (_super) {
|
|
|
8472
8559
|
}
|
|
8473
8560
|
if (typeof columnDef.render === 'function') {
|
|
8474
8561
|
var result = columnDef.render.call(_this, item[key], item, _this);
|
|
8475
|
-
if (result instanceof HTMLElement ||
|
|
8562
|
+
if (result instanceof HTMLElement ||
|
|
8563
|
+
result instanceof DocumentFragment) {
|
|
8476
8564
|
td.appendChild(result);
|
|
8477
8565
|
}
|
|
8478
8566
|
else if (typeof result === 'string') {
|
|
@@ -8818,7 +8906,8 @@ var KTDataTable = /** @class */ (function (_super) {
|
|
|
8818
8906
|
}
|
|
8819
8907
|
// --- 4. Dispose of handler objects (checkbox, sort) ---
|
|
8820
8908
|
// KTDataTableCheckboxAPI does not have a dispose method, but we can remove header checkbox listener
|
|
8821
|
-
if (this._checkbox &&
|
|
8909
|
+
if (this._checkbox &&
|
|
8910
|
+
typeof this._checkbox.dispose === 'function') {
|
|
8822
8911
|
this._checkbox.dispose();
|
|
8823
8912
|
}
|
|
8824
8913
|
else {
|
|
@@ -9654,13 +9743,15 @@ var KTSelectDropdown = /** @class */ (function (_super) {
|
|
|
9654
9743
|
var currentDropdownZIndexStr = dom_1.default.getCssProp(this._dropdownElement, 'z-index');
|
|
9655
9744
|
if (currentDropdownZIndexStr && currentDropdownZIndexStr !== 'auto') {
|
|
9656
9745
|
var currentDropdownZIndex = parseInt(currentDropdownZIndexStr);
|
|
9657
|
-
if (!isNaN(currentDropdownZIndex) &&
|
|
9746
|
+
if (!isNaN(currentDropdownZIndex) &&
|
|
9747
|
+
currentDropdownZIndex > (zIndexToApply || 0)) {
|
|
9658
9748
|
zIndexToApply = currentDropdownZIndex;
|
|
9659
9749
|
}
|
|
9660
9750
|
}
|
|
9661
9751
|
// Ensure dropdown is above elements within its original toggle's parent context
|
|
9662
9752
|
var toggleParentContextZindex = dom_1.default.getHighestZindex(this._element); // _element is the select wrapper
|
|
9663
|
-
if (toggleParentContextZindex !== null &&
|
|
9753
|
+
if (toggleParentContextZindex !== null &&
|
|
9754
|
+
toggleParentContextZindex >= (zIndexToApply || 0)) {
|
|
9664
9755
|
zIndexToApply = toggleParentContextZindex + 1;
|
|
9665
9756
|
}
|
|
9666
9757
|
if (zIndexToApply !== null) {
|
|
@@ -10138,7 +10229,9 @@ var KTSelectSearch = /** @class */ (function () {
|
|
|
10138
10229
|
});
|
|
10139
10230
|
}
|
|
10140
10231
|
// Listen for dropdown close to reset options - ATTACH TO WRAPPER
|
|
10141
|
-
this._select
|
|
10232
|
+
this._select
|
|
10233
|
+
.getWrapperElement()
|
|
10234
|
+
.addEventListener('dropdown.close', function () {
|
|
10142
10235
|
_this._focusManager.resetFocus();
|
|
10143
10236
|
// If clearSearchOnClose is false and there's a value, the search term and filtered state should persist.
|
|
10144
10237
|
// KTSelect's closeDropdown method already calls this._searchModule.clearSearch() (which clears highlights)
|
|
@@ -10160,7 +10253,9 @@ var KTSelectSearch = /** @class */ (function () {
|
|
|
10160
10253
|
}
|
|
10161
10254
|
});
|
|
10162
10255
|
// Consolidated 'dropdown.show' event listener - ATTACH TO WRAPPER
|
|
10163
|
-
this._select
|
|
10256
|
+
this._select
|
|
10257
|
+
.getWrapperElement()
|
|
10258
|
+
.addEventListener('dropdown.show', function () {
|
|
10164
10259
|
var _a;
|
|
10165
10260
|
_this._focusManager.resetFocus(); // Always clear previous focus state
|
|
10166
10261
|
if ((_a = _this._searchInput) === null || _a === void 0 ? void 0 : _a.value) {
|
|
@@ -10321,9 +10416,7 @@ var KTSelectSearch = /** @class */ (function () {
|
|
|
10321
10416
|
}
|
|
10322
10417
|
// Restore original content before filtering, so highlighting is applied fresh.
|
|
10323
10418
|
this._restoreOptionContentsBeforeFilter();
|
|
10324
|
-
var visibleCount = (0, utils_1.filterOptions)(options, query, config, dropdownElement, function (count) {
|
|
10325
|
-
return _this._handleNoResults(count);
|
|
10326
|
-
});
|
|
10419
|
+
var visibleCount = (0, utils_1.filterOptions)(options, query, config, dropdownElement, function (count) { return _this._handleNoResults(count); });
|
|
10327
10420
|
this._select.updateSelectAllButtonState();
|
|
10328
10421
|
};
|
|
10329
10422
|
/**
|
|
@@ -11556,6 +11649,8 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
11556
11649
|
// Core properties
|
|
11557
11650
|
_this._name = 'select';
|
|
11558
11651
|
_this._dataOptionPrefix = 'kt-'; // Use 'kt-' prefix to support data-kt-select-option attributes
|
|
11652
|
+
// Cached DOM references for performance
|
|
11653
|
+
_this._optionsContainer = null;
|
|
11559
11654
|
// State
|
|
11560
11655
|
_this._dropdownIsOpen = false;
|
|
11561
11656
|
_this._comboboxModule = null;
|
|
@@ -11609,6 +11704,10 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
11609
11704
|
return;
|
|
11610
11705
|
if (this._config.debug)
|
|
11611
11706
|
console.log('Initializing remote data with URL:', this._config.dataUrl);
|
|
11707
|
+
// For remote data, we need to create the HTML structure first
|
|
11708
|
+
// so that the component can be properly initialized
|
|
11709
|
+
this._createHtmlStructure();
|
|
11710
|
+
this._setupElementReferences();
|
|
11612
11711
|
// Show loading state
|
|
11613
11712
|
this._renderLoadingState();
|
|
11614
11713
|
// Fetch remote data
|
|
@@ -11627,7 +11726,10 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
11627
11726
|
_this._generateOptionsHtml(_this._element);
|
|
11628
11727
|
if (_this._config.debug)
|
|
11629
11728
|
console.log('Generating options HTML from remote data');
|
|
11630
|
-
|
|
11729
|
+
// Update the dropdown to show the new options
|
|
11730
|
+
_this._updateDropdownWithNewOptions();
|
|
11731
|
+
// Complete the component setup with the fetched data
|
|
11732
|
+
_this._completeRemoteSetup();
|
|
11631
11733
|
// Add pagination "Load More" button if needed
|
|
11632
11734
|
if (_this._config.pagination && _this._remoteModule.hasMorePages()) {
|
|
11633
11735
|
_this._addLoadMoreButton();
|
|
@@ -11651,6 +11753,108 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
11651
11753
|
var options = Array.from(this._element.querySelectorAll('option:not([value=""])'));
|
|
11652
11754
|
options.forEach(function (option) { return option.remove(); });
|
|
11653
11755
|
};
|
|
11756
|
+
/**
|
|
11757
|
+
* Unified method to render options in dropdown - eliminates code duplication
|
|
11758
|
+
*/
|
|
11759
|
+
KTSelect.prototype._renderOptionsInDropdown = function (optionsData, clearContainer) {
|
|
11760
|
+
var _this = this;
|
|
11761
|
+
if (clearContainer === void 0) { clearContainer = true; }
|
|
11762
|
+
if (!this._dropdownContentElement)
|
|
11763
|
+
return;
|
|
11764
|
+
// Use cached options container for better performance
|
|
11765
|
+
var optionsContainer = this._optionsContainer ||
|
|
11766
|
+
this._dropdownContentElement.querySelector('[data-kt-select-options]');
|
|
11767
|
+
if (!optionsContainer)
|
|
11768
|
+
return;
|
|
11769
|
+
// Clear container if requested
|
|
11770
|
+
if (clearContainer) {
|
|
11771
|
+
optionsContainer.innerHTML = '';
|
|
11772
|
+
}
|
|
11773
|
+
// Use DocumentFragment for efficient DOM manipulation
|
|
11774
|
+
var fragment = document.createDocumentFragment();
|
|
11775
|
+
// Process options data
|
|
11776
|
+
optionsData.forEach(function (optionData) {
|
|
11777
|
+
var optionElement;
|
|
11778
|
+
// Handle different input types
|
|
11779
|
+
if (optionData instanceof HTMLOptionElement) {
|
|
11780
|
+
// Skip empty placeholder options
|
|
11781
|
+
if (optionData.value === '' && optionData.textContent.trim() === '') {
|
|
11782
|
+
return;
|
|
11783
|
+
}
|
|
11784
|
+
optionElement = optionData;
|
|
11785
|
+
}
|
|
11786
|
+
else {
|
|
11787
|
+
// Handle KTSelectOptionData objects - cast to ensure type safety
|
|
11788
|
+
var dataItem = optionData;
|
|
11789
|
+
optionElement = document.createElement('option');
|
|
11790
|
+
optionElement.value = dataItem.id || '';
|
|
11791
|
+
optionElement.textContent = dataItem.title || '';
|
|
11792
|
+
if (dataItem.selected) {
|
|
11793
|
+
optionElement.setAttribute('selected', 'selected');
|
|
11794
|
+
}
|
|
11795
|
+
if (dataItem.disabled) {
|
|
11796
|
+
optionElement.setAttribute('disabled', 'disabled');
|
|
11797
|
+
}
|
|
11798
|
+
}
|
|
11799
|
+
// Create KTSelectOption instance for proper rendering
|
|
11800
|
+
var selectOption = new option_1.KTSelectOption(optionElement, _this._config);
|
|
11801
|
+
var renderedOption = selectOption.render();
|
|
11802
|
+
// Add to fragment for batch DOM operation
|
|
11803
|
+
fragment.appendChild(renderedOption);
|
|
11804
|
+
});
|
|
11805
|
+
// Batch append all options at once
|
|
11806
|
+
optionsContainer.appendChild(fragment);
|
|
11807
|
+
// Update options NodeList
|
|
11808
|
+
this._options = this._wrapperElement.querySelectorAll('[data-kt-select-option]');
|
|
11809
|
+
if (this._config.debug) {
|
|
11810
|
+
console.log("Rendered ".concat(optionsData.length, " options in dropdown"));
|
|
11811
|
+
}
|
|
11812
|
+
};
|
|
11813
|
+
/**
|
|
11814
|
+
* Update dropdown with new options from the original select element
|
|
11815
|
+
*/
|
|
11816
|
+
KTSelect.prototype._updateDropdownWithNewOptions = function () {
|
|
11817
|
+
// Get all options from the original select element
|
|
11818
|
+
var options = Array.from(this._element.querySelectorAll('option'));
|
|
11819
|
+
// Use unified renderer
|
|
11820
|
+
this._renderOptionsInDropdown(options, true);
|
|
11821
|
+
};
|
|
11822
|
+
/**
|
|
11823
|
+
* Complete the setup for remote data after HTML structure is created
|
|
11824
|
+
*/
|
|
11825
|
+
KTSelect.prototype._completeRemoteSetup = function () {
|
|
11826
|
+
// Initialize options
|
|
11827
|
+
this._preSelectOptions(this._element);
|
|
11828
|
+
// Apply disabled state if needed
|
|
11829
|
+
this._applyInitialDisabledState();
|
|
11830
|
+
// Initialize search if enabled
|
|
11831
|
+
if (this._config.enableSearch) {
|
|
11832
|
+
this._initializeSearchModule();
|
|
11833
|
+
}
|
|
11834
|
+
// Initialize combobox if enabled
|
|
11835
|
+
if (this._config.combobox) {
|
|
11836
|
+
this._comboboxModule = new combobox_1.KTSelectCombobox(this);
|
|
11837
|
+
}
|
|
11838
|
+
// Initialize tags if enabled
|
|
11839
|
+
if (this._config.tags) {
|
|
11840
|
+
this._tagsModule = new tags_1.KTSelectTags(this);
|
|
11841
|
+
}
|
|
11842
|
+
// Initialize focus manager after dropdown element is created
|
|
11843
|
+
this._focusManager = new utils_1.FocusManager(this._dropdownContentElement, '[data-kt-select-option]', this._config);
|
|
11844
|
+
// Initialize dropdown module after all elements are created
|
|
11845
|
+
this._dropdownModule = new dropdown_1.KTSelectDropdown(this._wrapperElement, this._displayElement, this._dropdownContentElement, this._config, this);
|
|
11846
|
+
// Update display and set ARIA attributes
|
|
11847
|
+
this._updateDisplayAndAriaAttributes();
|
|
11848
|
+
this.updateSelectedOptionDisplay();
|
|
11849
|
+
this._setAriaAttributes();
|
|
11850
|
+
// Update select all button state
|
|
11851
|
+
this.updateSelectAllButtonState();
|
|
11852
|
+
// Focus the first selected option or first option if nothing selected
|
|
11853
|
+
this._focusSelectedOption();
|
|
11854
|
+
// Attach event listeners after all modules are initialized
|
|
11855
|
+
this._attachEventListeners();
|
|
11856
|
+
this._observeNativeSelect();
|
|
11857
|
+
};
|
|
11654
11858
|
/**
|
|
11655
11859
|
* Helper to show a dropdown message (error, loading, noResults)
|
|
11656
11860
|
*/
|
|
@@ -11867,13 +12071,19 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
11867
12071
|
// Move classes from original select to wrapper and display elements
|
|
11868
12072
|
if (this._element.classList.length > 0) {
|
|
11869
12073
|
var originalClasses = Array.from(this._element.classList);
|
|
11870
|
-
var displaySpecificClasses_1 = [
|
|
12074
|
+
var displaySpecificClasses_1 = [
|
|
12075
|
+
'kt-select',
|
|
12076
|
+
'kt-select-sm',
|
|
12077
|
+
'kt-select-lg',
|
|
12078
|
+
];
|
|
11871
12079
|
var classesForWrapper = originalClasses.filter(function (className) { return !displaySpecificClasses_1.includes(className); });
|
|
11872
12080
|
if (classesForWrapper.length > 0) {
|
|
11873
12081
|
(_a = wrapperElement.classList).add.apply(_a, classesForWrapper);
|
|
11874
12082
|
}
|
|
11875
12083
|
// Move display-specific classes to display element
|
|
11876
|
-
var classesForDisplay = originalClasses.filter(function (className) {
|
|
12084
|
+
var classesForDisplay = originalClasses.filter(function (className) {
|
|
12085
|
+
return displaySpecificClasses_1.includes(className);
|
|
12086
|
+
});
|
|
11877
12087
|
if (classesForDisplay.length > 0) {
|
|
11878
12088
|
(_b = displayElement.classList).add.apply(_b, classesForDisplay);
|
|
11879
12089
|
}
|
|
@@ -11893,7 +12103,7 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
11893
12103
|
}
|
|
11894
12104
|
// Create options container using template
|
|
11895
12105
|
var optionsContainer = templates_1.defaultTemplates.options(this._config);
|
|
11896
|
-
// Add each option directly to the container
|
|
12106
|
+
// Add each option directly to the container (only if options exist)
|
|
11897
12107
|
options.forEach(function (optionElement) {
|
|
11898
12108
|
// Skip empty placeholder options (only if BOTH value AND text are empty)
|
|
11899
12109
|
// This allows options with empty value but visible text to display in dropdown
|
|
@@ -11920,13 +12130,18 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
11920
12130
|
*/
|
|
11921
12131
|
KTSelect.prototype._setupElementReferences = function () {
|
|
11922
12132
|
this._wrapperElement = this._element.nextElementSibling;
|
|
12133
|
+
// Safety check - ensure wrapper element exists
|
|
12134
|
+
if (!this._wrapperElement) {
|
|
12135
|
+
console.error('KTSelect: Wrapper element not found. HTML structure may not be created properly.');
|
|
12136
|
+
return;
|
|
12137
|
+
}
|
|
11923
12138
|
// Get display element
|
|
11924
12139
|
this._displayElement = this._wrapperElement.querySelector("[data-kt-select-display]");
|
|
11925
12140
|
// Get dropdown content element - this is critical for dropdown functionality
|
|
11926
12141
|
this._dropdownContentElement = this._wrapperElement.querySelector("[data-kt-select-dropdown]");
|
|
11927
12142
|
if (!this._dropdownContentElement) {
|
|
11928
|
-
console.
|
|
11929
|
-
|
|
12143
|
+
console.error('KTSelect: Dropdown content element not found', this._wrapperElement);
|
|
12144
|
+
return;
|
|
11930
12145
|
}
|
|
11931
12146
|
// Get search input element - this is used for the search functionality
|
|
11932
12147
|
this._searchInputElement = this._dropdownContentElement.querySelector("[data-kt-select-search]");
|
|
@@ -11935,6 +12150,8 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
11935
12150
|
this._searchInputElement = this._displayElement;
|
|
11936
12151
|
}
|
|
11937
12152
|
this._selectAllButton = this._wrapperElement.querySelector('[data-kt-select-select-all]');
|
|
12153
|
+
// Cache the options container for performance
|
|
12154
|
+
this._optionsContainer = this._dropdownContentElement.querySelector('[data-kt-select-options]');
|
|
11938
12155
|
this._options = this._wrapperElement.querySelectorAll("[data-kt-select-option]");
|
|
11939
12156
|
};
|
|
11940
12157
|
/**
|
|
@@ -11946,7 +12163,8 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
11946
12163
|
// Dropdown option click events
|
|
11947
12164
|
this._eventManager.addListener(this._dropdownContentElement, 'click', this._handleDropdownOptionClick.bind(this));
|
|
11948
12165
|
if (this._selectAllButton) {
|
|
11949
|
-
this._selectAllButtonToggle =
|
|
12166
|
+
this._selectAllButtonToggle =
|
|
12167
|
+
this._selectAllButton.querySelector('button');
|
|
11950
12168
|
if (this._selectAllButtonToggle) {
|
|
11951
12169
|
this._eventManager.addListener(this._selectAllButtonToggle, 'click', this._handleSelectAllClick.bind(this));
|
|
11952
12170
|
}
|
|
@@ -12691,6 +12909,8 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12691
12909
|
var query = event.target.value;
|
|
12692
12910
|
// Check if the query is long enough
|
|
12693
12911
|
if (query.length < (this._config.searchMinLength || 0)) {
|
|
12912
|
+
// Restore original options if query is too short
|
|
12913
|
+
this._restoreOriginalOptions();
|
|
12694
12914
|
return;
|
|
12695
12915
|
}
|
|
12696
12916
|
// Debounce the search
|
|
@@ -12745,7 +12965,36 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12745
12965
|
* @param message Error message
|
|
12746
12966
|
*/
|
|
12747
12967
|
KTSelect.prototype._renderSearchErrorState = function (message) {
|
|
12968
|
+
var _this = this;
|
|
12748
12969
|
this._showDropdownMessage('error', message);
|
|
12970
|
+
// Restore original options after error with a delay
|
|
12971
|
+
setTimeout(function () {
|
|
12972
|
+
_this._restoreOriginalOptions();
|
|
12973
|
+
}, 2000);
|
|
12974
|
+
};
|
|
12975
|
+
/**
|
|
12976
|
+
* Restore original options when search is cleared
|
|
12977
|
+
*/
|
|
12978
|
+
KTSelect.prototype._restoreOriginalOptions = function () {
|
|
12979
|
+
if (!this._dropdownContentElement || !this._originalOptionsHtml)
|
|
12980
|
+
return;
|
|
12981
|
+
// Use cached options container for better performance
|
|
12982
|
+
var optionsContainer = this._optionsContainer ||
|
|
12983
|
+
this._dropdownContentElement.querySelector('[data-kt-select-options]');
|
|
12984
|
+
if (!optionsContainer)
|
|
12985
|
+
return;
|
|
12986
|
+
// Restore original options
|
|
12987
|
+
optionsContainer.innerHTML = this._originalOptionsHtml;
|
|
12988
|
+
// Update options NodeList
|
|
12989
|
+
this._options = this._wrapperElement.querySelectorAll('[data-kt-select-option]');
|
|
12990
|
+
// Refresh search module
|
|
12991
|
+
if (this._searchModule) {
|
|
12992
|
+
this._searchModule.refreshAfterSearch();
|
|
12993
|
+
}
|
|
12994
|
+
this.updateSelectAllButtonState();
|
|
12995
|
+
if (this._config.debug) {
|
|
12996
|
+
console.log('Restored original options after search clear');
|
|
12997
|
+
}
|
|
12749
12998
|
};
|
|
12750
12999
|
/**
|
|
12751
13000
|
* Update search results in the dropdown
|
|
@@ -12754,31 +13003,24 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12754
13003
|
KTSelect.prototype._updateSearchResults = function (items) {
|
|
12755
13004
|
if (!this._dropdownContentElement)
|
|
12756
13005
|
return;
|
|
12757
|
-
|
|
13006
|
+
// Use cached options container for better performance
|
|
13007
|
+
var optionsContainer = this._optionsContainer ||
|
|
13008
|
+
this._dropdownContentElement.querySelector('[data-kt-select-options]');
|
|
12758
13009
|
if (!optionsContainer)
|
|
12759
13010
|
return;
|
|
12760
|
-
//
|
|
12761
|
-
optionsContainer.innerHTML = '';
|
|
13011
|
+
// Handle empty results
|
|
12762
13012
|
if (items.length === 0) {
|
|
12763
|
-
|
|
13013
|
+
optionsContainer.innerHTML = '';
|
|
12764
13014
|
var noResultsElement = templates_1.defaultTemplates.searchEmpty(this._config);
|
|
12765
13015
|
optionsContainer.appendChild(noResultsElement);
|
|
12766
13016
|
return;
|
|
12767
13017
|
}
|
|
12768
|
-
//
|
|
12769
|
-
|
|
12770
|
-
// Create option for the original select
|
|
12771
|
-
var selectOption = document.createElement('option');
|
|
12772
|
-
selectOption.value = item.id;
|
|
12773
|
-
// Add to dropdown container
|
|
12774
|
-
optionsContainer.appendChild(selectOption);
|
|
12775
|
-
});
|
|
13018
|
+
// Use unified renderer for search results
|
|
13019
|
+
this._renderOptionsInDropdown(items, true);
|
|
12776
13020
|
// Add pagination "Load More" button if needed
|
|
12777
13021
|
if (this._config.pagination && this._remoteModule.hasMorePages()) {
|
|
12778
13022
|
this._addLoadMoreButton();
|
|
12779
13023
|
}
|
|
12780
|
-
// Update options NodeList
|
|
12781
|
-
this._options = this._wrapperElement.querySelectorAll("[data-kt-select-option]");
|
|
12782
13024
|
};
|
|
12783
13025
|
/**
|
|
12784
13026
|
* Check if dropdown is open
|
|
@@ -12790,10 +13032,12 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12790
13032
|
var _this = this;
|
|
12791
13033
|
var selectedValues = this.getSelectedOptions();
|
|
12792
13034
|
var displaySeparator = this._config.displaySeparator || ', ';
|
|
12793
|
-
var texts = selectedValues
|
|
13035
|
+
var texts = selectedValues
|
|
13036
|
+
.map(function (value) {
|
|
12794
13037
|
var option = Array.from(_this._options).find(function (opt) { return opt.getAttribute('data-value') === value; });
|
|
12795
13038
|
return (option === null || option === void 0 ? void 0 : option.getAttribute('data-text')) || '';
|
|
12796
|
-
})
|
|
13039
|
+
})
|
|
13040
|
+
.filter(Boolean);
|
|
12797
13041
|
return texts.join(displaySeparator);
|
|
12798
13042
|
};
|
|
12799
13043
|
/**
|
|
@@ -12801,7 +13045,9 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12801
13045
|
*/
|
|
12802
13046
|
KTSelect.prototype._isOptionDisabled = function (value) {
|
|
12803
13047
|
var dropdownOption = Array.from(this._options).find(function (opt) { return opt.getAttribute('data-value') === value; });
|
|
12804
|
-
var isDropdownDisabled = dropdownOption &&
|
|
13048
|
+
var isDropdownDisabled = dropdownOption &&
|
|
13049
|
+
(dropdownOption.classList.contains('disabled') ||
|
|
13050
|
+
dropdownOption.getAttribute('aria-disabled') === 'true');
|
|
12805
13051
|
var selectOption = Array.from(this._element.querySelectorAll('option')).find(function (opt) { return opt.value === value; });
|
|
12806
13052
|
var isNativeDisabled = selectOption && selectOption.disabled;
|
|
12807
13053
|
return Boolean(isDropdownDisabled || isNativeDisabled);
|
|
@@ -12823,9 +13069,14 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12823
13069
|
if (event.target === this._searchInputElement) {
|
|
12824
13070
|
// Allow navigation keys like ArrowDown, ArrowUp, Escape, Enter (for search/selection) to be handled by the logic below.
|
|
12825
13071
|
// For other keys (characters, space, backspace, delete), let the input field process them.
|
|
12826
|
-
if (event.key !== 'ArrowDown' &&
|
|
12827
|
-
event.key !== '
|
|
12828
|
-
event.key !== '
|
|
13072
|
+
if (event.key !== 'ArrowDown' &&
|
|
13073
|
+
event.key !== 'ArrowUp' &&
|
|
13074
|
+
event.key !== 'Escape' &&
|
|
13075
|
+
event.key !== 'Enter' &&
|
|
13076
|
+
event.key !== 'Tab' &&
|
|
13077
|
+
event.key !== 'Home' &&
|
|
13078
|
+
event.key !== 'End' &&
|
|
13079
|
+
event.key !== ' ') {
|
|
12829
13080
|
// If it's a character key and we are NOT type-to-searching (because search has focus)
|
|
12830
13081
|
// then let the input field handle it for its own value.
|
|
12831
13082
|
// The search module's 'input' event will handle filtering based on the input's value.
|
|
@@ -12839,7 +13090,10 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12839
13090
|
if (event.altKey || event.ctrlKey || event.metaKey)
|
|
12840
13091
|
return;
|
|
12841
13092
|
// Type-to-search: only for single char keys, when search input does not have focus
|
|
12842
|
-
if (event.key.length === 1 &&
|
|
13093
|
+
if (event.key.length === 1 &&
|
|
13094
|
+
!event.repeat &&
|
|
13095
|
+
!event.key.match(/\s/) &&
|
|
13096
|
+
document.activeElement !== this._searchInputElement) {
|
|
12843
13097
|
buffer.push(event.key);
|
|
12844
13098
|
var str = buffer.getBuffer();
|
|
12845
13099
|
if (isOpen) {
|
|
@@ -12888,7 +13142,9 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12888
13142
|
if (focusedOptionEl) {
|
|
12889
13143
|
var val = focusedOptionEl.dataset.value;
|
|
12890
13144
|
// If single select, and the item is already selected, just close.
|
|
12891
|
-
if (val !== undefined &&
|
|
13145
|
+
if (val !== undefined &&
|
|
13146
|
+
!this._config.multiple &&
|
|
13147
|
+
this._state.isSelected(val)) {
|
|
12892
13148
|
if (this._config.debug)
|
|
12893
13149
|
console.log('Enter on already selected item in single-select mode. Closing.');
|
|
12894
13150
|
this.closeDropdown();
|
|
@@ -12929,7 +13185,8 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12929
13185
|
var _this = this;
|
|
12930
13186
|
var optionsConfig = this._config.optionsConfig || {};
|
|
12931
13187
|
var displaySeparator = this._config.displaySeparator || ', ';
|
|
12932
|
-
var contentArray = Array.from(new Set(selectedValues
|
|
13188
|
+
var contentArray = Array.from(new Set(selectedValues
|
|
13189
|
+
.map(function (value) {
|
|
12933
13190
|
var option = Array.from(_this._options).find(function (opt) { return opt.getAttribute('data-value') === value; });
|
|
12934
13191
|
if (!option)
|
|
12935
13192
|
return '';
|
|
@@ -12938,7 +13195,7 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12938
13195
|
// Replace all {{varname}} in option.innerHTML with values from _config
|
|
12939
13196
|
Object.entries(optionsConfig[value] || {}).forEach(function (_a) {
|
|
12940
13197
|
var key = _a[0], val = _a[1];
|
|
12941
|
-
if ([
|
|
13198
|
+
if (['string', 'number', 'boolean'].includes(typeof val)) {
|
|
12942
13199
|
displayTemplate = displayTemplate.replace(new RegExp("{{".concat(key, "}}"), 'g'), String(val));
|
|
12943
13200
|
}
|
|
12944
13201
|
});
|
|
@@ -12947,7 +13204,8 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12947
13204
|
selectedTexts: _this.getSelectedOptionsText() || '',
|
|
12948
13205
|
text: text,
|
|
12949
13206
|
});
|
|
12950
|
-
})
|
|
13207
|
+
})
|
|
13208
|
+
.filter(Boolean)));
|
|
12951
13209
|
return contentArray.join(displaySeparator);
|
|
12952
13210
|
};
|
|
12953
13211
|
KTSelect.prototype.getDisplayElement = function () {
|
|
@@ -12966,7 +13224,8 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12966
13224
|
// Option(s) added or removed
|
|
12967
13225
|
needsRebuild = true;
|
|
12968
13226
|
}
|
|
12969
|
-
else if (mutation.type === 'attributes' &&
|
|
13227
|
+
else if (mutation.type === 'attributes' &&
|
|
13228
|
+
mutation.target instanceof HTMLOptionElement) {
|
|
12970
13229
|
if (mutation.attributeName === 'selected') {
|
|
12971
13230
|
needsSelectionSync = true;
|
|
12972
13231
|
}
|
|
@@ -14978,7 +15237,9 @@ var KTSelectTags = /** @class */ (function () {
|
|
|
14978
15237
|
}
|
|
14979
15238
|
}
|
|
14980
15239
|
if (!optionElement) {
|
|
14981
|
-
var originalOptions = _this._select
|
|
15240
|
+
var originalOptions = _this._select
|
|
15241
|
+
.getElement()
|
|
15242
|
+
.querySelectorAll('option');
|
|
14982
15243
|
for (var _b = 0, _c = Array.from(originalOptions); _b < _c.length; _b++) {
|
|
14983
15244
|
var opt = _c[_b];
|
|
14984
15245
|
if (opt.value === optionValue) {
|
|
@@ -15938,7 +16199,9 @@ function filterOptions(options, query, config, dropdownElement, onVisibleCount)
|
|
|
15938
16199
|
for (var _a = 0, options_2 = options; _a < options_2.length; _a++) {
|
|
15939
16200
|
var option = options_2[_a];
|
|
15940
16201
|
// Use data-text for matching if available, otherwise fall back to textContent
|
|
15941
|
-
var optionText = (option.dataset.text ||
|
|
16202
|
+
var optionText = (option.dataset.text ||
|
|
16203
|
+
option.textContent ||
|
|
16204
|
+
'').toLowerCase();
|
|
15942
16205
|
var isMatch = optionText.includes(queryLower);
|
|
15943
16206
|
if (isMatch) {
|
|
15944
16207
|
option.classList.remove('hidden');
|
|
@@ -16015,7 +16278,8 @@ var FocusManager = /** @class */ (function () {
|
|
|
16015
16278
|
return null;
|
|
16016
16279
|
for (var i = 0; i < options.length; i++) {
|
|
16017
16280
|
var option = options[i];
|
|
16018
|
-
if (!option.classList.contains('disabled') &&
|
|
16281
|
+
if (!option.classList.contains('disabled') &&
|
|
16282
|
+
option.getAttribute('aria-disabled') !== 'true') {
|
|
16019
16283
|
this.resetFocus();
|
|
16020
16284
|
this._focusedOptionIndex = i;
|
|
16021
16285
|
this.applyFocus(option);
|
|
@@ -16034,7 +16298,8 @@ var FocusManager = /** @class */ (function () {
|
|
|
16034
16298
|
return null;
|
|
16035
16299
|
for (var i = options.length - 1; i >= 0; i--) {
|
|
16036
16300
|
var option = options[i];
|
|
16037
|
-
if (!option.classList.contains('disabled') &&
|
|
16301
|
+
if (!option.classList.contains('disabled') &&
|
|
16302
|
+
option.getAttribute('aria-disabled') !== 'true') {
|
|
16038
16303
|
this.resetFocus();
|
|
16039
16304
|
this._focusedOptionIndex = i;
|
|
16040
16305
|
this.applyFocus(option);
|
|
@@ -16059,7 +16324,8 @@ var FocusManager = /** @class */ (function () {
|
|
|
16059
16324
|
var option = options[idx];
|
|
16060
16325
|
if (!option.classList.contains('disabled') &&
|
|
16061
16326
|
option.getAttribute('aria-disabled') !== 'true' &&
|
|
16062
|
-
(((_b = option.textContent) === null || _b === void 0 ? void 0 : _b.toLowerCase().startsWith(lowerStr)) ||
|
|
16327
|
+
(((_b = option.textContent) === null || _b === void 0 ? void 0 : _b.toLowerCase().startsWith(lowerStr)) ||
|
|
16328
|
+
((_c = option.dataset.value) === null || _c === void 0 ? void 0 : _c.toLowerCase().startsWith(lowerStr)))) {
|
|
16063
16329
|
this.resetFocus();
|
|
16064
16330
|
this._focusedOptionIndex = idx;
|
|
16065
16331
|
this.applyFocus(option);
|
|
@@ -16076,11 +16342,14 @@ var FocusManager = /** @class */ (function () {
|
|
|
16076
16342
|
var options = this.getVisibleOptions();
|
|
16077
16343
|
if (options.length === 0)
|
|
16078
16344
|
return null;
|
|
16079
|
-
var idx = this._focusedOptionIndex === null
|
|
16345
|
+
var idx = this._focusedOptionIndex === null
|
|
16346
|
+
? 0
|
|
16347
|
+
: (this._focusedOptionIndex + 1) % options.length;
|
|
16080
16348
|
var startIdx = idx;
|
|
16081
16349
|
do {
|
|
16082
16350
|
var option = options[idx];
|
|
16083
|
-
if (!option.classList.contains('disabled') &&
|
|
16351
|
+
if (!option.classList.contains('disabled') &&
|
|
16352
|
+
option.getAttribute('aria-disabled') !== 'true') {
|
|
16084
16353
|
this.resetFocus();
|
|
16085
16354
|
this._focusedOptionIndex = idx;
|
|
16086
16355
|
this.applyFocus(option);
|
|
@@ -16098,11 +16367,14 @@ var FocusManager = /** @class */ (function () {
|
|
|
16098
16367
|
var options = this.getVisibleOptions();
|
|
16099
16368
|
if (options.length === 0)
|
|
16100
16369
|
return null;
|
|
16101
|
-
var idx = this._focusedOptionIndex === null
|
|
16370
|
+
var idx = this._focusedOptionIndex === null
|
|
16371
|
+
? options.length - 1
|
|
16372
|
+
: (this._focusedOptionIndex - 1 + options.length) % options.length;
|
|
16102
16373
|
var startIdx = idx;
|
|
16103
16374
|
do {
|
|
16104
16375
|
var option = options[idx];
|
|
16105
|
-
if (!option.classList.contains('disabled') &&
|
|
16376
|
+
if (!option.classList.contains('disabled') &&
|
|
16377
|
+
option.getAttribute('aria-disabled') !== 'true') {
|
|
16106
16378
|
this.resetFocus();
|
|
16107
16379
|
this._focusedOptionIndex = idx;
|
|
16108
16380
|
this.applyFocus(option);
|
|
@@ -16120,7 +16392,8 @@ var FocusManager = /** @class */ (function () {
|
|
|
16120
16392
|
if (!option)
|
|
16121
16393
|
return;
|
|
16122
16394
|
// Ensure it's not disabled
|
|
16123
|
-
if (option.classList.contains('disabled') ||
|
|
16395
|
+
if (option.classList.contains('disabled') ||
|
|
16396
|
+
option.getAttribute('aria-disabled') === 'true') {
|
|
16124
16397
|
return;
|
|
16125
16398
|
}
|
|
16126
16399
|
// DO NOT CALL resetFocus() here. Caller's responsibility.
|
|
@@ -16169,7 +16442,8 @@ var FocusManager = /** @class */ (function () {
|
|
|
16169
16442
|
var index = options.findIndex(function (option) { return option.dataset.value === value; });
|
|
16170
16443
|
if (index >= 0) {
|
|
16171
16444
|
var optionToFocus = options[index];
|
|
16172
|
-
if (!optionToFocus.classList.contains('disabled') &&
|
|
16445
|
+
if (!optionToFocus.classList.contains('disabled') &&
|
|
16446
|
+
optionToFocus.getAttribute('aria-disabled') !== 'true') {
|
|
16173
16447
|
this.resetFocus();
|
|
16174
16448
|
this._focusedOptionIndex = index;
|
|
16175
16449
|
this.applyFocus(optionToFocus);
|