@keenthemes/ktui 1.0.20 → 1.0.22
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 +423 -148
- package/dist/ktui.min.js +1 -1
- package/dist/ktui.min.js.map +1 -1
- package/dist/styles.css +161 -31
- package/examples/datatable/sorting-test.html +398 -0
- package/examples/image-input/file-upload-example.html +189 -0
- package/examples/select/modal.html +3 -1
- package/examples/select/{remote-data_.html → 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 +13 -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 +5 -6
- 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 +13 -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 +5 -6
- 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 +95 -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 +21 -14
- 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);
|
|
@@ -8043,6 +8126,10 @@ var KTDataTable = /** @class */ (function (_super) {
|
|
|
8043
8126
|
this._element.classList.add('datatable-initialized');
|
|
8044
8127
|
// Initialize checkbox logic
|
|
8045
8128
|
this._checkbox.init();
|
|
8129
|
+
// Re-initialize sort handler to restore click listeners after table redraw
|
|
8130
|
+
if (this._sortHandler) {
|
|
8131
|
+
this._sortHandler.initSort();
|
|
8132
|
+
}
|
|
8046
8133
|
this._attachSearchEvent();
|
|
8047
8134
|
if (typeof index_1.default !== 'undefined') {
|
|
8048
8135
|
index_1.default.init();
|
|
@@ -8065,7 +8152,11 @@ var KTDataTable = /** @class */ (function (_super) {
|
|
|
8065
8152
|
// Set search value
|
|
8066
8153
|
if (searchElement) {
|
|
8067
8154
|
searchElement.value =
|
|
8068
|
-
search === undefined || search === null
|
|
8155
|
+
search === undefined || search === null
|
|
8156
|
+
? ''
|
|
8157
|
+
: typeof search === 'string'
|
|
8158
|
+
? search
|
|
8159
|
+
: String(search);
|
|
8069
8160
|
}
|
|
8070
8161
|
if (searchElement) {
|
|
8071
8162
|
// Check if a debounced search function already exists
|
|
@@ -8472,7 +8563,8 @@ var KTDataTable = /** @class */ (function (_super) {
|
|
|
8472
8563
|
}
|
|
8473
8564
|
if (typeof columnDef.render === 'function') {
|
|
8474
8565
|
var result = columnDef.render.call(_this, item[key], item, _this);
|
|
8475
|
-
if (result instanceof HTMLElement ||
|
|
8566
|
+
if (result instanceof HTMLElement ||
|
|
8567
|
+
result instanceof DocumentFragment) {
|
|
8476
8568
|
td.appendChild(result);
|
|
8477
8569
|
}
|
|
8478
8570
|
else if (typeof result === 'string') {
|
|
@@ -8818,7 +8910,8 @@ var KTDataTable = /** @class */ (function (_super) {
|
|
|
8818
8910
|
}
|
|
8819
8911
|
// --- 4. Dispose of handler objects (checkbox, sort) ---
|
|
8820
8912
|
// KTDataTableCheckboxAPI does not have a dispose method, but we can remove header checkbox listener
|
|
8821
|
-
if (this._checkbox &&
|
|
8913
|
+
if (this._checkbox &&
|
|
8914
|
+
typeof this._checkbox.dispose === 'function') {
|
|
8822
8915
|
this._checkbox.dispose();
|
|
8823
8916
|
}
|
|
8824
8917
|
else {
|
|
@@ -9654,13 +9747,15 @@ var KTSelectDropdown = /** @class */ (function (_super) {
|
|
|
9654
9747
|
var currentDropdownZIndexStr = dom_1.default.getCssProp(this._dropdownElement, 'z-index');
|
|
9655
9748
|
if (currentDropdownZIndexStr && currentDropdownZIndexStr !== 'auto') {
|
|
9656
9749
|
var currentDropdownZIndex = parseInt(currentDropdownZIndexStr);
|
|
9657
|
-
if (!isNaN(currentDropdownZIndex) &&
|
|
9750
|
+
if (!isNaN(currentDropdownZIndex) &&
|
|
9751
|
+
currentDropdownZIndex > (zIndexToApply || 0)) {
|
|
9658
9752
|
zIndexToApply = currentDropdownZIndex;
|
|
9659
9753
|
}
|
|
9660
9754
|
}
|
|
9661
9755
|
// Ensure dropdown is above elements within its original toggle's parent context
|
|
9662
9756
|
var toggleParentContextZindex = dom_1.default.getHighestZindex(this._element); // _element is the select wrapper
|
|
9663
|
-
if (toggleParentContextZindex !== null &&
|
|
9757
|
+
if (toggleParentContextZindex !== null &&
|
|
9758
|
+
toggleParentContextZindex >= (zIndexToApply || 0)) {
|
|
9664
9759
|
zIndexToApply = toggleParentContextZindex + 1;
|
|
9665
9760
|
}
|
|
9666
9761
|
if (zIndexToApply !== null) {
|
|
@@ -9758,16 +9853,13 @@ var KTSelectDropdown = /** @class */ (function (_super) {
|
|
|
9758
9853
|
};
|
|
9759
9854
|
KTSelectDropdown.prototype._resolveDropdownContainer = function () {
|
|
9760
9855
|
var containerSelector = this._config.dropdownContainer;
|
|
9761
|
-
if (containerSelector
|
|
9856
|
+
if (containerSelector) {
|
|
9762
9857
|
var containerElement = document.querySelector(containerSelector);
|
|
9763
9858
|
if (!containerElement && this._config.debug) {
|
|
9764
9859
|
console.warn("KTSelectDropdown: dropdownContainer selector \"".concat(containerSelector, "\" not found. Dropdown will remain in its default position."));
|
|
9765
9860
|
}
|
|
9766
9861
|
return containerElement;
|
|
9767
9862
|
}
|
|
9768
|
-
else if (containerSelector === 'body') {
|
|
9769
|
-
return document.body;
|
|
9770
|
-
}
|
|
9771
9863
|
return null;
|
|
9772
9864
|
};
|
|
9773
9865
|
return KTSelectDropdown;
|
|
@@ -10138,7 +10230,9 @@ var KTSelectSearch = /** @class */ (function () {
|
|
|
10138
10230
|
});
|
|
10139
10231
|
}
|
|
10140
10232
|
// Listen for dropdown close to reset options - ATTACH TO WRAPPER
|
|
10141
|
-
this._select
|
|
10233
|
+
this._select
|
|
10234
|
+
.getWrapperElement()
|
|
10235
|
+
.addEventListener('dropdown.close', function () {
|
|
10142
10236
|
_this._focusManager.resetFocus();
|
|
10143
10237
|
// If clearSearchOnClose is false and there's a value, the search term and filtered state should persist.
|
|
10144
10238
|
// KTSelect's closeDropdown method already calls this._searchModule.clearSearch() (which clears highlights)
|
|
@@ -10160,7 +10254,9 @@ var KTSelectSearch = /** @class */ (function () {
|
|
|
10160
10254
|
}
|
|
10161
10255
|
});
|
|
10162
10256
|
// Consolidated 'dropdown.show' event listener - ATTACH TO WRAPPER
|
|
10163
|
-
this._select
|
|
10257
|
+
this._select
|
|
10258
|
+
.getWrapperElement()
|
|
10259
|
+
.addEventListener('dropdown.show', function () {
|
|
10164
10260
|
var _a;
|
|
10165
10261
|
_this._focusManager.resetFocus(); // Always clear previous focus state
|
|
10166
10262
|
if ((_a = _this._searchInput) === null || _a === void 0 ? void 0 : _a.value) {
|
|
@@ -10321,9 +10417,7 @@ var KTSelectSearch = /** @class */ (function () {
|
|
|
10321
10417
|
}
|
|
10322
10418
|
// Restore original content before filtering, so highlighting is applied fresh.
|
|
10323
10419
|
this._restoreOptionContentsBeforeFilter();
|
|
10324
|
-
var visibleCount = (0, utils_1.filterOptions)(options, query, config, dropdownElement, function (count) {
|
|
10325
|
-
return _this._handleNoResults(count);
|
|
10326
|
-
});
|
|
10420
|
+
var visibleCount = (0, utils_1.filterOptions)(options, query, config, dropdownElement, function (count) { return _this._handleNoResults(count); });
|
|
10327
10421
|
this._select.updateSelectAllButtonState();
|
|
10328
10422
|
};
|
|
10329
10423
|
/**
|
|
@@ -11556,6 +11650,8 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
11556
11650
|
// Core properties
|
|
11557
11651
|
_this._name = 'select';
|
|
11558
11652
|
_this._dataOptionPrefix = 'kt-'; // Use 'kt-' prefix to support data-kt-select-option attributes
|
|
11653
|
+
// Cached DOM references for performance
|
|
11654
|
+
_this._optionsContainer = null;
|
|
11559
11655
|
// State
|
|
11560
11656
|
_this._dropdownIsOpen = false;
|
|
11561
11657
|
_this._comboboxModule = null;
|
|
@@ -11609,6 +11705,10 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
11609
11705
|
return;
|
|
11610
11706
|
if (this._config.debug)
|
|
11611
11707
|
console.log('Initializing remote data with URL:', this._config.dataUrl);
|
|
11708
|
+
// For remote data, we need to create the HTML structure first
|
|
11709
|
+
// so that the component can be properly initialized
|
|
11710
|
+
this._createHtmlStructure();
|
|
11711
|
+
this._setupElementReferences();
|
|
11612
11712
|
// Show loading state
|
|
11613
11713
|
this._renderLoadingState();
|
|
11614
11714
|
// Fetch remote data
|
|
@@ -11627,7 +11727,10 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
11627
11727
|
_this._generateOptionsHtml(_this._element);
|
|
11628
11728
|
if (_this._config.debug)
|
|
11629
11729
|
console.log('Generating options HTML from remote data');
|
|
11630
|
-
|
|
11730
|
+
// Update the dropdown to show the new options
|
|
11731
|
+
_this._updateDropdownWithNewOptions();
|
|
11732
|
+
// Complete the component setup with the fetched data
|
|
11733
|
+
_this._completeRemoteSetup();
|
|
11631
11734
|
// Add pagination "Load More" button if needed
|
|
11632
11735
|
if (_this._config.pagination && _this._remoteModule.hasMorePages()) {
|
|
11633
11736
|
_this._addLoadMoreButton();
|
|
@@ -11651,6 +11754,108 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
11651
11754
|
var options = Array.from(this._element.querySelectorAll('option:not([value=""])'));
|
|
11652
11755
|
options.forEach(function (option) { return option.remove(); });
|
|
11653
11756
|
};
|
|
11757
|
+
/**
|
|
11758
|
+
* Unified method to render options in dropdown - eliminates code duplication
|
|
11759
|
+
*/
|
|
11760
|
+
KTSelect.prototype._renderOptionsInDropdown = function (optionsData, clearContainer) {
|
|
11761
|
+
var _this = this;
|
|
11762
|
+
if (clearContainer === void 0) { clearContainer = true; }
|
|
11763
|
+
if (!this._dropdownContentElement)
|
|
11764
|
+
return;
|
|
11765
|
+
// Use cached options container for better performance
|
|
11766
|
+
var optionsContainer = this._optionsContainer ||
|
|
11767
|
+
this._dropdownContentElement.querySelector('[data-kt-select-options]');
|
|
11768
|
+
if (!optionsContainer)
|
|
11769
|
+
return;
|
|
11770
|
+
// Clear container if requested
|
|
11771
|
+
if (clearContainer) {
|
|
11772
|
+
optionsContainer.innerHTML = '';
|
|
11773
|
+
}
|
|
11774
|
+
// Use DocumentFragment for efficient DOM manipulation
|
|
11775
|
+
var fragment = document.createDocumentFragment();
|
|
11776
|
+
// Process options data
|
|
11777
|
+
optionsData.forEach(function (optionData) {
|
|
11778
|
+
var optionElement;
|
|
11779
|
+
// Handle different input types
|
|
11780
|
+
if (optionData instanceof HTMLOptionElement) {
|
|
11781
|
+
// Skip empty placeholder options
|
|
11782
|
+
if (optionData.value === '' && optionData.textContent.trim() === '') {
|
|
11783
|
+
return;
|
|
11784
|
+
}
|
|
11785
|
+
optionElement = optionData;
|
|
11786
|
+
}
|
|
11787
|
+
else {
|
|
11788
|
+
// Handle KTSelectOptionData objects - cast to ensure type safety
|
|
11789
|
+
var dataItem = optionData;
|
|
11790
|
+
optionElement = document.createElement('option');
|
|
11791
|
+
optionElement.value = dataItem.id || '';
|
|
11792
|
+
optionElement.textContent = dataItem.title || '';
|
|
11793
|
+
if (dataItem.selected) {
|
|
11794
|
+
optionElement.setAttribute('selected', 'selected');
|
|
11795
|
+
}
|
|
11796
|
+
if (dataItem.disabled) {
|
|
11797
|
+
optionElement.setAttribute('disabled', 'disabled');
|
|
11798
|
+
}
|
|
11799
|
+
}
|
|
11800
|
+
// Create KTSelectOption instance for proper rendering
|
|
11801
|
+
var selectOption = new option_1.KTSelectOption(optionElement, _this._config);
|
|
11802
|
+
var renderedOption = selectOption.render();
|
|
11803
|
+
// Add to fragment for batch DOM operation
|
|
11804
|
+
fragment.appendChild(renderedOption);
|
|
11805
|
+
});
|
|
11806
|
+
// Batch append all options at once
|
|
11807
|
+
optionsContainer.appendChild(fragment);
|
|
11808
|
+
// Update options NodeList
|
|
11809
|
+
this._options = this._wrapperElement.querySelectorAll('[data-kt-select-option]');
|
|
11810
|
+
if (this._config.debug) {
|
|
11811
|
+
console.log("Rendered ".concat(optionsData.length, " options in dropdown"));
|
|
11812
|
+
}
|
|
11813
|
+
};
|
|
11814
|
+
/**
|
|
11815
|
+
* Update dropdown with new options from the original select element
|
|
11816
|
+
*/
|
|
11817
|
+
KTSelect.prototype._updateDropdownWithNewOptions = function () {
|
|
11818
|
+
// Get all options from the original select element
|
|
11819
|
+
var options = Array.from(this._element.querySelectorAll('option'));
|
|
11820
|
+
// Use unified renderer
|
|
11821
|
+
this._renderOptionsInDropdown(options, true);
|
|
11822
|
+
};
|
|
11823
|
+
/**
|
|
11824
|
+
* Complete the setup for remote data after HTML structure is created
|
|
11825
|
+
*/
|
|
11826
|
+
KTSelect.prototype._completeRemoteSetup = function () {
|
|
11827
|
+
// Initialize options
|
|
11828
|
+
this._preSelectOptions(this._element);
|
|
11829
|
+
// Apply disabled state if needed
|
|
11830
|
+
this._applyInitialDisabledState();
|
|
11831
|
+
// Initialize search if enabled
|
|
11832
|
+
if (this._config.enableSearch) {
|
|
11833
|
+
this._initializeSearchModule();
|
|
11834
|
+
}
|
|
11835
|
+
// Initialize combobox if enabled
|
|
11836
|
+
if (this._config.combobox) {
|
|
11837
|
+
this._comboboxModule = new combobox_1.KTSelectCombobox(this);
|
|
11838
|
+
}
|
|
11839
|
+
// Initialize tags if enabled
|
|
11840
|
+
if (this._config.tags) {
|
|
11841
|
+
this._tagsModule = new tags_1.KTSelectTags(this);
|
|
11842
|
+
}
|
|
11843
|
+
// Initialize focus manager after dropdown element is created
|
|
11844
|
+
this._focusManager = new utils_1.FocusManager(this._dropdownContentElement, '[data-kt-select-option]', this._config);
|
|
11845
|
+
// Initialize dropdown module after all elements are created
|
|
11846
|
+
this._dropdownModule = new dropdown_1.KTSelectDropdown(this._wrapperElement, this._displayElement, this._dropdownContentElement, this._config, this);
|
|
11847
|
+
// Update display and set ARIA attributes
|
|
11848
|
+
this._updateDisplayAndAriaAttributes();
|
|
11849
|
+
this.updateSelectedOptionDisplay();
|
|
11850
|
+
this._setAriaAttributes();
|
|
11851
|
+
// Update select all button state
|
|
11852
|
+
this.updateSelectAllButtonState();
|
|
11853
|
+
// Focus the first selected option or first option if nothing selected
|
|
11854
|
+
this._focusSelectedOption();
|
|
11855
|
+
// Attach event listeners after all modules are initialized
|
|
11856
|
+
this._attachEventListeners();
|
|
11857
|
+
this._observeNativeSelect();
|
|
11858
|
+
};
|
|
11654
11859
|
/**
|
|
11655
11860
|
* Helper to show a dropdown message (error, loading, noResults)
|
|
11656
11861
|
*/
|
|
@@ -11867,13 +12072,19 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
11867
12072
|
// Move classes from original select to wrapper and display elements
|
|
11868
12073
|
if (this._element.classList.length > 0) {
|
|
11869
12074
|
var originalClasses = Array.from(this._element.classList);
|
|
11870
|
-
var displaySpecificClasses_1 = [
|
|
12075
|
+
var displaySpecificClasses_1 = [
|
|
12076
|
+
'kt-select',
|
|
12077
|
+
'kt-select-sm',
|
|
12078
|
+
'kt-select-lg',
|
|
12079
|
+
];
|
|
11871
12080
|
var classesForWrapper = originalClasses.filter(function (className) { return !displaySpecificClasses_1.includes(className); });
|
|
11872
12081
|
if (classesForWrapper.length > 0) {
|
|
11873
12082
|
(_a = wrapperElement.classList).add.apply(_a, classesForWrapper);
|
|
11874
12083
|
}
|
|
11875
12084
|
// Move display-specific classes to display element
|
|
11876
|
-
var classesForDisplay = originalClasses.filter(function (className) {
|
|
12085
|
+
var classesForDisplay = originalClasses.filter(function (className) {
|
|
12086
|
+
return displaySpecificClasses_1.includes(className);
|
|
12087
|
+
});
|
|
11877
12088
|
if (classesForDisplay.length > 0) {
|
|
11878
12089
|
(_b = displayElement.classList).add.apply(_b, classesForDisplay);
|
|
11879
12090
|
}
|
|
@@ -11893,7 +12104,7 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
11893
12104
|
}
|
|
11894
12105
|
// Create options container using template
|
|
11895
12106
|
var optionsContainer = templates_1.defaultTemplates.options(this._config);
|
|
11896
|
-
// Add each option directly to the container
|
|
12107
|
+
// Add each option directly to the container (only if options exist)
|
|
11897
12108
|
options.forEach(function (optionElement) {
|
|
11898
12109
|
// Skip empty placeholder options (only if BOTH value AND text are empty)
|
|
11899
12110
|
// This allows options with empty value but visible text to display in dropdown
|
|
@@ -11920,13 +12131,18 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
11920
12131
|
*/
|
|
11921
12132
|
KTSelect.prototype._setupElementReferences = function () {
|
|
11922
12133
|
this._wrapperElement = this._element.nextElementSibling;
|
|
12134
|
+
// Safety check - ensure wrapper element exists
|
|
12135
|
+
if (!this._wrapperElement) {
|
|
12136
|
+
console.error('KTSelect: Wrapper element not found. HTML structure may not be created properly.');
|
|
12137
|
+
return;
|
|
12138
|
+
}
|
|
11923
12139
|
// Get display element
|
|
11924
12140
|
this._displayElement = this._wrapperElement.querySelector("[data-kt-select-display]");
|
|
11925
12141
|
// Get dropdown content element - this is critical for dropdown functionality
|
|
11926
12142
|
this._dropdownContentElement = this._wrapperElement.querySelector("[data-kt-select-dropdown]");
|
|
11927
12143
|
if (!this._dropdownContentElement) {
|
|
11928
|
-
console.
|
|
11929
|
-
|
|
12144
|
+
console.error('KTSelect: Dropdown content element not found', this._wrapperElement);
|
|
12145
|
+
return;
|
|
11930
12146
|
}
|
|
11931
12147
|
// Get search input element - this is used for the search functionality
|
|
11932
12148
|
this._searchInputElement = this._dropdownContentElement.querySelector("[data-kt-select-search]");
|
|
@@ -11935,6 +12151,8 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
11935
12151
|
this._searchInputElement = this._displayElement;
|
|
11936
12152
|
}
|
|
11937
12153
|
this._selectAllButton = this._wrapperElement.querySelector('[data-kt-select-select-all]');
|
|
12154
|
+
// Cache the options container for performance
|
|
12155
|
+
this._optionsContainer = this._dropdownContentElement.querySelector('[data-kt-select-options]');
|
|
11938
12156
|
this._options = this._wrapperElement.querySelectorAll("[data-kt-select-option]");
|
|
11939
12157
|
};
|
|
11940
12158
|
/**
|
|
@@ -11946,7 +12164,8 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
11946
12164
|
// Dropdown option click events
|
|
11947
12165
|
this._eventManager.addListener(this._dropdownContentElement, 'click', this._handleDropdownOptionClick.bind(this));
|
|
11948
12166
|
if (this._selectAllButton) {
|
|
11949
|
-
this._selectAllButtonToggle =
|
|
12167
|
+
this._selectAllButtonToggle =
|
|
12168
|
+
this._selectAllButton.querySelector('button');
|
|
11950
12169
|
if (this._selectAllButtonToggle) {
|
|
11951
12170
|
this._eventManager.addListener(this._selectAllButtonToggle, 'click', this._handleSelectAllClick.bind(this));
|
|
11952
12171
|
}
|
|
@@ -12691,6 +12910,8 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12691
12910
|
var query = event.target.value;
|
|
12692
12911
|
// Check if the query is long enough
|
|
12693
12912
|
if (query.length < (this._config.searchMinLength || 0)) {
|
|
12913
|
+
// Restore original options if query is too short
|
|
12914
|
+
this._restoreOriginalOptions();
|
|
12694
12915
|
return;
|
|
12695
12916
|
}
|
|
12696
12917
|
// Debounce the search
|
|
@@ -12745,7 +12966,36 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12745
12966
|
* @param message Error message
|
|
12746
12967
|
*/
|
|
12747
12968
|
KTSelect.prototype._renderSearchErrorState = function (message) {
|
|
12969
|
+
var _this = this;
|
|
12748
12970
|
this._showDropdownMessage('error', message);
|
|
12971
|
+
// Restore original options after error with a delay
|
|
12972
|
+
setTimeout(function () {
|
|
12973
|
+
_this._restoreOriginalOptions();
|
|
12974
|
+
}, 2000);
|
|
12975
|
+
};
|
|
12976
|
+
/**
|
|
12977
|
+
* Restore original options when search is cleared
|
|
12978
|
+
*/
|
|
12979
|
+
KTSelect.prototype._restoreOriginalOptions = function () {
|
|
12980
|
+
if (!this._dropdownContentElement || !this._originalOptionsHtml)
|
|
12981
|
+
return;
|
|
12982
|
+
// Use cached options container for better performance
|
|
12983
|
+
var optionsContainer = this._optionsContainer ||
|
|
12984
|
+
this._dropdownContentElement.querySelector('[data-kt-select-options]');
|
|
12985
|
+
if (!optionsContainer)
|
|
12986
|
+
return;
|
|
12987
|
+
// Restore original options
|
|
12988
|
+
optionsContainer.innerHTML = this._originalOptionsHtml;
|
|
12989
|
+
// Update options NodeList
|
|
12990
|
+
this._options = this._wrapperElement.querySelectorAll('[data-kt-select-option]');
|
|
12991
|
+
// Refresh search module
|
|
12992
|
+
if (this._searchModule) {
|
|
12993
|
+
this._searchModule.refreshAfterSearch();
|
|
12994
|
+
}
|
|
12995
|
+
this.updateSelectAllButtonState();
|
|
12996
|
+
if (this._config.debug) {
|
|
12997
|
+
console.log('Restored original options after search clear');
|
|
12998
|
+
}
|
|
12749
12999
|
};
|
|
12750
13000
|
/**
|
|
12751
13001
|
* Update search results in the dropdown
|
|
@@ -12754,31 +13004,24 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12754
13004
|
KTSelect.prototype._updateSearchResults = function (items) {
|
|
12755
13005
|
if (!this._dropdownContentElement)
|
|
12756
13006
|
return;
|
|
12757
|
-
|
|
13007
|
+
// Use cached options container for better performance
|
|
13008
|
+
var optionsContainer = this._optionsContainer ||
|
|
13009
|
+
this._dropdownContentElement.querySelector('[data-kt-select-options]');
|
|
12758
13010
|
if (!optionsContainer)
|
|
12759
13011
|
return;
|
|
12760
|
-
//
|
|
12761
|
-
optionsContainer.innerHTML = '';
|
|
13012
|
+
// Handle empty results
|
|
12762
13013
|
if (items.length === 0) {
|
|
12763
|
-
|
|
13014
|
+
optionsContainer.innerHTML = '';
|
|
12764
13015
|
var noResultsElement = templates_1.defaultTemplates.searchEmpty(this._config);
|
|
12765
13016
|
optionsContainer.appendChild(noResultsElement);
|
|
12766
13017
|
return;
|
|
12767
13018
|
}
|
|
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
|
-
});
|
|
13019
|
+
// Use unified renderer for search results
|
|
13020
|
+
this._renderOptionsInDropdown(items, true);
|
|
12776
13021
|
// Add pagination "Load More" button if needed
|
|
12777
13022
|
if (this._config.pagination && this._remoteModule.hasMorePages()) {
|
|
12778
13023
|
this._addLoadMoreButton();
|
|
12779
13024
|
}
|
|
12780
|
-
// Update options NodeList
|
|
12781
|
-
this._options = this._wrapperElement.querySelectorAll("[data-kt-select-option]");
|
|
12782
13025
|
};
|
|
12783
13026
|
/**
|
|
12784
13027
|
* Check if dropdown is open
|
|
@@ -12790,10 +13033,12 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12790
13033
|
var _this = this;
|
|
12791
13034
|
var selectedValues = this.getSelectedOptions();
|
|
12792
13035
|
var displaySeparator = this._config.displaySeparator || ', ';
|
|
12793
|
-
var texts = selectedValues
|
|
13036
|
+
var texts = selectedValues
|
|
13037
|
+
.map(function (value) {
|
|
12794
13038
|
var option = Array.from(_this._options).find(function (opt) { return opt.getAttribute('data-value') === value; });
|
|
12795
13039
|
return (option === null || option === void 0 ? void 0 : option.getAttribute('data-text')) || '';
|
|
12796
|
-
})
|
|
13040
|
+
})
|
|
13041
|
+
.filter(Boolean);
|
|
12797
13042
|
return texts.join(displaySeparator);
|
|
12798
13043
|
};
|
|
12799
13044
|
/**
|
|
@@ -12801,7 +13046,9 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12801
13046
|
*/
|
|
12802
13047
|
KTSelect.prototype._isOptionDisabled = function (value) {
|
|
12803
13048
|
var dropdownOption = Array.from(this._options).find(function (opt) { return opt.getAttribute('data-value') === value; });
|
|
12804
|
-
var isDropdownDisabled = dropdownOption &&
|
|
13049
|
+
var isDropdownDisabled = dropdownOption &&
|
|
13050
|
+
(dropdownOption.classList.contains('disabled') ||
|
|
13051
|
+
dropdownOption.getAttribute('aria-disabled') === 'true');
|
|
12805
13052
|
var selectOption = Array.from(this._element.querySelectorAll('option')).find(function (opt) { return opt.value === value; });
|
|
12806
13053
|
var isNativeDisabled = selectOption && selectOption.disabled;
|
|
12807
13054
|
return Boolean(isDropdownDisabled || isNativeDisabled);
|
|
@@ -12823,9 +13070,14 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12823
13070
|
if (event.target === this._searchInputElement) {
|
|
12824
13071
|
// Allow navigation keys like ArrowDown, ArrowUp, Escape, Enter (for search/selection) to be handled by the logic below.
|
|
12825
13072
|
// For other keys (characters, space, backspace, delete), let the input field process them.
|
|
12826
|
-
if (event.key !== 'ArrowDown' &&
|
|
12827
|
-
event.key !== '
|
|
12828
|
-
event.key !== '
|
|
13073
|
+
if (event.key !== 'ArrowDown' &&
|
|
13074
|
+
event.key !== 'ArrowUp' &&
|
|
13075
|
+
event.key !== 'Escape' &&
|
|
13076
|
+
event.key !== 'Enter' &&
|
|
13077
|
+
event.key !== 'Tab' &&
|
|
13078
|
+
event.key !== 'Home' &&
|
|
13079
|
+
event.key !== 'End' &&
|
|
13080
|
+
event.key !== ' ') {
|
|
12829
13081
|
// If it's a character key and we are NOT type-to-searching (because search has focus)
|
|
12830
13082
|
// then let the input field handle it for its own value.
|
|
12831
13083
|
// The search module's 'input' event will handle filtering based on the input's value.
|
|
@@ -12839,7 +13091,10 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12839
13091
|
if (event.altKey || event.ctrlKey || event.metaKey)
|
|
12840
13092
|
return;
|
|
12841
13093
|
// Type-to-search: only for single char keys, when search input does not have focus
|
|
12842
|
-
if (event.key.length === 1 &&
|
|
13094
|
+
if (event.key.length === 1 &&
|
|
13095
|
+
!event.repeat &&
|
|
13096
|
+
!event.key.match(/\s/) &&
|
|
13097
|
+
document.activeElement !== this._searchInputElement) {
|
|
12843
13098
|
buffer.push(event.key);
|
|
12844
13099
|
var str = buffer.getBuffer();
|
|
12845
13100
|
if (isOpen) {
|
|
@@ -12888,7 +13143,9 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12888
13143
|
if (focusedOptionEl) {
|
|
12889
13144
|
var val = focusedOptionEl.dataset.value;
|
|
12890
13145
|
// If single select, and the item is already selected, just close.
|
|
12891
|
-
if (val !== undefined &&
|
|
13146
|
+
if (val !== undefined &&
|
|
13147
|
+
!this._config.multiple &&
|
|
13148
|
+
this._state.isSelected(val)) {
|
|
12892
13149
|
if (this._config.debug)
|
|
12893
13150
|
console.log('Enter on already selected item in single-select mode. Closing.');
|
|
12894
13151
|
this.closeDropdown();
|
|
@@ -12929,7 +13186,8 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12929
13186
|
var _this = this;
|
|
12930
13187
|
var optionsConfig = this._config.optionsConfig || {};
|
|
12931
13188
|
var displaySeparator = this._config.displaySeparator || ', ';
|
|
12932
|
-
var contentArray = Array.from(new Set(selectedValues
|
|
13189
|
+
var contentArray = Array.from(new Set(selectedValues
|
|
13190
|
+
.map(function (value) {
|
|
12933
13191
|
var option = Array.from(_this._options).find(function (opt) { return opt.getAttribute('data-value') === value; });
|
|
12934
13192
|
if (!option)
|
|
12935
13193
|
return '';
|
|
@@ -12938,7 +13196,7 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12938
13196
|
// Replace all {{varname}} in option.innerHTML with values from _config
|
|
12939
13197
|
Object.entries(optionsConfig[value] || {}).forEach(function (_a) {
|
|
12940
13198
|
var key = _a[0], val = _a[1];
|
|
12941
|
-
if ([
|
|
13199
|
+
if (['string', 'number', 'boolean'].includes(typeof val)) {
|
|
12942
13200
|
displayTemplate = displayTemplate.replace(new RegExp("{{".concat(key, "}}"), 'g'), String(val));
|
|
12943
13201
|
}
|
|
12944
13202
|
});
|
|
@@ -12947,7 +13205,8 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12947
13205
|
selectedTexts: _this.getSelectedOptionsText() || '',
|
|
12948
13206
|
text: text,
|
|
12949
13207
|
});
|
|
12950
|
-
})
|
|
13208
|
+
})
|
|
13209
|
+
.filter(Boolean)));
|
|
12951
13210
|
return contentArray.join(displaySeparator);
|
|
12952
13211
|
};
|
|
12953
13212
|
KTSelect.prototype.getDisplayElement = function () {
|
|
@@ -12966,7 +13225,8 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12966
13225
|
// Option(s) added or removed
|
|
12967
13226
|
needsRebuild = true;
|
|
12968
13227
|
}
|
|
12969
|
-
else if (mutation.type === 'attributes' &&
|
|
13228
|
+
else if (mutation.type === 'attributes' &&
|
|
13229
|
+
mutation.target instanceof HTMLOptionElement) {
|
|
12970
13230
|
if (mutation.attributeName === 'selected') {
|
|
12971
13231
|
needsSelectionSync = true;
|
|
12972
13232
|
}
|
|
@@ -14978,7 +15238,9 @@ var KTSelectTags = /** @class */ (function () {
|
|
|
14978
15238
|
}
|
|
14979
15239
|
}
|
|
14980
15240
|
if (!optionElement) {
|
|
14981
|
-
var originalOptions = _this._select
|
|
15241
|
+
var originalOptions = _this._select
|
|
15242
|
+
.getElement()
|
|
15243
|
+
.querySelectorAll('option');
|
|
14982
15244
|
for (var _b = 0, _c = Array.from(originalOptions); _b < _c.length; _b++) {
|
|
14983
15245
|
var opt = _c[_b];
|
|
14984
15246
|
if (opt.value === optionValue) {
|
|
@@ -15938,7 +16200,9 @@ function filterOptions(options, query, config, dropdownElement, onVisibleCount)
|
|
|
15938
16200
|
for (var _a = 0, options_2 = options; _a < options_2.length; _a++) {
|
|
15939
16201
|
var option = options_2[_a];
|
|
15940
16202
|
// Use data-text for matching if available, otherwise fall back to textContent
|
|
15941
|
-
var optionText = (option.dataset.text ||
|
|
16203
|
+
var optionText = (option.dataset.text ||
|
|
16204
|
+
option.textContent ||
|
|
16205
|
+
'').toLowerCase();
|
|
15942
16206
|
var isMatch = optionText.includes(queryLower);
|
|
15943
16207
|
if (isMatch) {
|
|
15944
16208
|
option.classList.remove('hidden');
|
|
@@ -16015,7 +16279,8 @@ var FocusManager = /** @class */ (function () {
|
|
|
16015
16279
|
return null;
|
|
16016
16280
|
for (var i = 0; i < options.length; i++) {
|
|
16017
16281
|
var option = options[i];
|
|
16018
|
-
if (!option.classList.contains('disabled') &&
|
|
16282
|
+
if (!option.classList.contains('disabled') &&
|
|
16283
|
+
option.getAttribute('aria-disabled') !== 'true') {
|
|
16019
16284
|
this.resetFocus();
|
|
16020
16285
|
this._focusedOptionIndex = i;
|
|
16021
16286
|
this.applyFocus(option);
|
|
@@ -16034,7 +16299,8 @@ var FocusManager = /** @class */ (function () {
|
|
|
16034
16299
|
return null;
|
|
16035
16300
|
for (var i = options.length - 1; i >= 0; i--) {
|
|
16036
16301
|
var option = options[i];
|
|
16037
|
-
if (!option.classList.contains('disabled') &&
|
|
16302
|
+
if (!option.classList.contains('disabled') &&
|
|
16303
|
+
option.getAttribute('aria-disabled') !== 'true') {
|
|
16038
16304
|
this.resetFocus();
|
|
16039
16305
|
this._focusedOptionIndex = i;
|
|
16040
16306
|
this.applyFocus(option);
|
|
@@ -16059,7 +16325,8 @@ var FocusManager = /** @class */ (function () {
|
|
|
16059
16325
|
var option = options[idx];
|
|
16060
16326
|
if (!option.classList.contains('disabled') &&
|
|
16061
16327
|
option.getAttribute('aria-disabled') !== 'true' &&
|
|
16062
|
-
(((_b = option.textContent) === null || _b === void 0 ? void 0 : _b.toLowerCase().startsWith(lowerStr)) ||
|
|
16328
|
+
(((_b = option.textContent) === null || _b === void 0 ? void 0 : _b.toLowerCase().startsWith(lowerStr)) ||
|
|
16329
|
+
((_c = option.dataset.value) === null || _c === void 0 ? void 0 : _c.toLowerCase().startsWith(lowerStr)))) {
|
|
16063
16330
|
this.resetFocus();
|
|
16064
16331
|
this._focusedOptionIndex = idx;
|
|
16065
16332
|
this.applyFocus(option);
|
|
@@ -16076,11 +16343,14 @@ var FocusManager = /** @class */ (function () {
|
|
|
16076
16343
|
var options = this.getVisibleOptions();
|
|
16077
16344
|
if (options.length === 0)
|
|
16078
16345
|
return null;
|
|
16079
|
-
var idx = this._focusedOptionIndex === null
|
|
16346
|
+
var idx = this._focusedOptionIndex === null
|
|
16347
|
+
? 0
|
|
16348
|
+
: (this._focusedOptionIndex + 1) % options.length;
|
|
16080
16349
|
var startIdx = idx;
|
|
16081
16350
|
do {
|
|
16082
16351
|
var option = options[idx];
|
|
16083
|
-
if (!option.classList.contains('disabled') &&
|
|
16352
|
+
if (!option.classList.contains('disabled') &&
|
|
16353
|
+
option.getAttribute('aria-disabled') !== 'true') {
|
|
16084
16354
|
this.resetFocus();
|
|
16085
16355
|
this._focusedOptionIndex = idx;
|
|
16086
16356
|
this.applyFocus(option);
|
|
@@ -16098,11 +16368,14 @@ var FocusManager = /** @class */ (function () {
|
|
|
16098
16368
|
var options = this.getVisibleOptions();
|
|
16099
16369
|
if (options.length === 0)
|
|
16100
16370
|
return null;
|
|
16101
|
-
var idx = this._focusedOptionIndex === null
|
|
16371
|
+
var idx = this._focusedOptionIndex === null
|
|
16372
|
+
? options.length - 1
|
|
16373
|
+
: (this._focusedOptionIndex - 1 + options.length) % options.length;
|
|
16102
16374
|
var startIdx = idx;
|
|
16103
16375
|
do {
|
|
16104
16376
|
var option = options[idx];
|
|
16105
|
-
if (!option.classList.contains('disabled') &&
|
|
16377
|
+
if (!option.classList.contains('disabled') &&
|
|
16378
|
+
option.getAttribute('aria-disabled') !== 'true') {
|
|
16106
16379
|
this.resetFocus();
|
|
16107
16380
|
this._focusedOptionIndex = idx;
|
|
16108
16381
|
this.applyFocus(option);
|
|
@@ -16120,7 +16393,8 @@ var FocusManager = /** @class */ (function () {
|
|
|
16120
16393
|
if (!option)
|
|
16121
16394
|
return;
|
|
16122
16395
|
// Ensure it's not disabled
|
|
16123
|
-
if (option.classList.contains('disabled') ||
|
|
16396
|
+
if (option.classList.contains('disabled') ||
|
|
16397
|
+
option.getAttribute('aria-disabled') === 'true') {
|
|
16124
16398
|
return;
|
|
16125
16399
|
}
|
|
16126
16400
|
// DO NOT CALL resetFocus() here. Caller's responsibility.
|
|
@@ -16169,7 +16443,8 @@ var FocusManager = /** @class */ (function () {
|
|
|
16169
16443
|
var index = options.findIndex(function (option) { return option.dataset.value === value; });
|
|
16170
16444
|
if (index >= 0) {
|
|
16171
16445
|
var optionToFocus = options[index];
|
|
16172
|
-
if (!optionToFocus.classList.contains('disabled') &&
|
|
16446
|
+
if (!optionToFocus.classList.contains('disabled') &&
|
|
16447
|
+
optionToFocus.getAttribute('aria-disabled') !== 'true') {
|
|
16173
16448
|
this.resetFocus();
|
|
16174
16449
|
this._focusedOptionIndex = index;
|
|
16175
16450
|
this.applyFocus(optionToFocus);
|