@keenthemes/ktui 1.0.12 → 1.0.14
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 +738 -700
- package/dist/ktui.min.js +1 -1
- package/dist/ktui.min.js.map +1 -1
- package/dist/styles.css +5824 -0
- package/examples/select/avatar.html +47 -0
- package/examples/select/basic-usage.html +10 -14
- package/examples/select/{test.html → combobox-icons_.html} +13 -48
- package/examples/select/country.html +43 -0
- package/examples/select/description.html +25 -41
- package/examples/select/disable-option.html +10 -16
- package/examples/select/disable-select.html +7 -6
- package/examples/select/icon-multiple.html +23 -31
- package/examples/select/icon.html +20 -30
- package/examples/select/max-selection.html +8 -9
- package/examples/select/modal.html +16 -17
- package/examples/select/multiple.html +11 -13
- package/examples/select/placeholder.html +9 -12
- package/examples/select/search.html +30 -22
- package/examples/select/sizes.html +94 -0
- package/examples/select/template-customization.html +0 -3
- package/lib/cjs/components/component.js +1 -1
- package/lib/cjs/components/component.js.map +1 -1
- package/lib/cjs/components/datatable/datatable.js +14 -11
- package/lib/cjs/components/datatable/datatable.js.map +1 -1
- package/lib/cjs/components/select/combobox.js +96 -61
- package/lib/cjs/components/select/combobox.js.map +1 -1
- package/lib/cjs/components/select/config.js +13 -8
- package/lib/cjs/components/select/config.js.map +1 -1
- package/lib/cjs/components/select/dropdown.js +32 -96
- package/lib/cjs/components/select/dropdown.js.map +1 -1
- package/lib/cjs/components/select/option.js +53 -20
- package/lib/cjs/components/select/option.js.map +1 -1
- package/lib/cjs/components/select/search.js +146 -97
- package/lib/cjs/components/select/search.js.map +1 -1
- package/lib/cjs/components/select/select.js +219 -118
- package/lib/cjs/components/select/select.js.map +1 -1
- package/lib/cjs/components/select/tags.js +0 -26
- package/lib/cjs/components/select/tags.js.map +1 -1
- package/lib/cjs/components/select/templates.js +130 -105
- package/lib/cjs/components/select/templates.js.map +1 -1
- package/lib/cjs/components/select/utils.js +33 -132
- package/lib/cjs/components/select/utils.js.map +1 -1
- package/lib/cjs/helpers/dom.js +0 -24
- package/lib/cjs/helpers/dom.js.map +1 -1
- package/lib/esm/components/component.js +1 -1
- package/lib/esm/components/component.js.map +1 -1
- package/lib/esm/components/datatable/datatable.js +14 -11
- package/lib/esm/components/datatable/datatable.js.map +1 -1
- package/lib/esm/components/select/combobox.js +96 -61
- package/lib/esm/components/select/combobox.js.map +1 -1
- package/lib/esm/components/select/config.js +13 -8
- package/lib/esm/components/select/config.js.map +1 -1
- package/lib/esm/components/select/dropdown.js +32 -96
- package/lib/esm/components/select/dropdown.js.map +1 -1
- package/lib/esm/components/select/option.js +53 -20
- package/lib/esm/components/select/option.js.map +1 -1
- package/lib/esm/components/select/search.js +146 -97
- package/lib/esm/components/select/search.js.map +1 -1
- package/lib/esm/components/select/select.js +219 -118
- package/lib/esm/components/select/select.js.map +1 -1
- package/lib/esm/components/select/tags.js +0 -26
- package/lib/esm/components/select/tags.js.map +1 -1
- package/lib/esm/components/select/templates.js +130 -105
- package/lib/esm/components/select/templates.js.map +1 -1
- package/lib/esm/components/select/utils.js +32 -130
- package/lib/esm/components/select/utils.js.map +1 -1
- package/lib/esm/helpers/dom.js +0 -24
- package/lib/esm/helpers/dom.js.map +1 -1
- package/package.json +9 -6
- package/src/components/component.ts +0 -4
- package/src/components/datatable/datatable.ts +14 -11
- package/src/components/input/input.css +1 -1
- package/src/components/scrollable/scrollable.css +9 -5
- package/src/components/select/combobox.ts +98 -87
- package/src/components/select/config.ts +16 -13
- package/src/components/select/dropdown.ts +43 -108
- package/src/components/select/option.ts +44 -25
- package/src/components/select/search.ts +158 -117
- package/src/components/select/select.css +99 -27
- package/src/components/select/select.ts +236 -128
- package/src/components/select/tags.ts +1 -27
- package/src/components/select/templates.ts +191 -132
- package/src/components/select/utils.ts +30 -166
- package/src/components/toast/toast.css +1 -1
- package/src/helpers/dom.ts +0 -30
- package/webpack.config.js +6 -1
- package/examples/select/combobox-icons.html +0 -58
- package/examples/select/icon-description.html +0 -56
- /package/examples/select/{combobox.html → combobox_.html} +0 -0
- /package/examples/select/{remote-data.html → remote-data_.html} +0 -0
- /package/examples/select/{tags-icons.html → tags-icons_.html} +0 -0
- /package/examples/select/{tags-selected.html → tags-selected_.html} +0 -0
- /package/examples/select/{tags.html → tags_.html} +0 -0
package/dist/ktui.js
CHANGED
|
@@ -2453,7 +2453,7 @@ var KTComponent = /** @class */ (function () {
|
|
|
2453
2453
|
if (config === void 0) { config = {}; }
|
|
2454
2454
|
if (!this._element)
|
|
2455
2455
|
return;
|
|
2456
|
-
this._config = __assign(__assign(__assign(__assign(
|
|
2456
|
+
this._config = __assign(__assign(__assign(__assign({}, this._defaultConfig), this._getGlobalConfig()), dom_1.default.getDataAttributes(this._element, this._dataOptionPrefix + this._name)), config);
|
|
2457
2457
|
};
|
|
2458
2458
|
KTComponent.prototype.dispose = function () {
|
|
2459
2459
|
if (!this._element)
|
|
@@ -5653,6 +5653,17 @@ var __extends = (this && this.__extends) || (function () {
|
|
|
5653
5653
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
5654
5654
|
};
|
|
5655
5655
|
})();
|
|
5656
|
+
var __assign = (this && this.__assign) || function () {
|
|
5657
|
+
__assign = Object.assign || function(t) {
|
|
5658
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5659
|
+
s = arguments[i];
|
|
5660
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
5661
|
+
t[p] = s[p];
|
|
5662
|
+
}
|
|
5663
|
+
return t;
|
|
5664
|
+
};
|
|
5665
|
+
return __assign.apply(this, arguments);
|
|
5666
|
+
};
|
|
5656
5667
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
5657
5668
|
exports.KTSelectOption = void 0;
|
|
5658
5669
|
var component_1 = __webpack_require__(2658);
|
|
@@ -5665,39 +5676,61 @@ var KTSelectOption = /** @class */ (function (_super) {
|
|
|
5665
5676
|
_this._dataOptionPrefix = 'kt-'; // Use 'kt-' prefix to support data-kt-select-option attributes
|
|
5666
5677
|
// Always initialize a new option instance
|
|
5667
5678
|
_this._init(element);
|
|
5668
|
-
_this._buildConfig();
|
|
5669
5679
|
_this._globalConfig = config;
|
|
5680
|
+
_this._buildConfig();
|
|
5670
5681
|
// Clean the config
|
|
5671
5682
|
_this._config = _this._config[''] || {};
|
|
5672
5683
|
// Add the option config to the global config
|
|
5673
|
-
|
|
5674
|
-
_this._globalConfig
|
|
5684
|
+
// Ensure optionsConfig is initialized
|
|
5685
|
+
if (_this._globalConfig) {
|
|
5686
|
+
_this._globalConfig.optionsConfig = _this._globalConfig.optionsConfig || {};
|
|
5687
|
+
_this._globalConfig.optionsConfig[element.value] = _this._config;
|
|
5688
|
+
}
|
|
5689
|
+
else {
|
|
5690
|
+
// Handle case where _globalConfig might be undefined, though constructor expects it.
|
|
5691
|
+
// This might indicate a need to ensure config is always passed or has a default.
|
|
5692
|
+
console.warn('KTSelectOption: _globalConfig is undefined during constructor.');
|
|
5693
|
+
}
|
|
5675
5694
|
// Don't store in KTData to avoid Singleton pattern issues
|
|
5676
5695
|
// Each option should be a unique instance
|
|
5677
5696
|
element.instance = _this;
|
|
5678
5697
|
return _this;
|
|
5679
5698
|
}
|
|
5699
|
+
Object.defineProperty(KTSelectOption.prototype, "id", {
|
|
5700
|
+
get: function () {
|
|
5701
|
+
return this.getHTMLOptionElement().value;
|
|
5702
|
+
},
|
|
5703
|
+
enumerable: false,
|
|
5704
|
+
configurable: true
|
|
5705
|
+
});
|
|
5706
|
+
Object.defineProperty(KTSelectOption.prototype, "title", {
|
|
5707
|
+
get: function () {
|
|
5708
|
+
return this.getHTMLOptionElement().textContent || '';
|
|
5709
|
+
},
|
|
5710
|
+
enumerable: false,
|
|
5711
|
+
configurable: true
|
|
5712
|
+
});
|
|
5680
5713
|
KTSelectOption.prototype.getHTMLOptionElement = function () {
|
|
5681
5714
|
return this._element;
|
|
5682
5715
|
};
|
|
5716
|
+
/**
|
|
5717
|
+
* Gathers all necessary data for rendering this option,
|
|
5718
|
+
* including standard HTML attributes and custom data-kt-* attributes.
|
|
5719
|
+
*/
|
|
5720
|
+
KTSelectOption.prototype.getOptionDataForTemplate = function () {
|
|
5721
|
+
var el = this.getHTMLOptionElement();
|
|
5722
|
+
var text = el.textContent || '';
|
|
5723
|
+
return __assign(__assign({}, this._config), {
|
|
5724
|
+
// Standard HTMLOptionElement properties
|
|
5725
|
+
value: el.value, text: text, selected: el.selected, disabled: el.disabled,
|
|
5726
|
+
// Provide 'content' for convenience in templates, defaulting to text.
|
|
5727
|
+
// User's optionTemplate can then use {{content}} or specific fields like {{text}}, {{icon}}, etc.
|
|
5728
|
+
content: text });
|
|
5729
|
+
};
|
|
5683
5730
|
KTSelectOption.prototype.render = function () {
|
|
5684
|
-
|
|
5685
|
-
|
|
5686
|
-
|
|
5687
|
-
var originalTemplate = this._globalConfig.optionTemplate;
|
|
5688
|
-
if (this._globalConfig.optionTemplate) {
|
|
5689
|
-
// Replace all {{varname}} in option.innerHTML with values from _config
|
|
5690
|
-
Object.entries(this._config || {}).forEach(function (_a) {
|
|
5691
|
-
var key = _a[0], value = _a[1];
|
|
5692
|
-
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
|
|
5693
|
-
_this._globalConfig.optionTemplate = _this._globalConfig.optionTemplate.replace(new RegExp("{{".concat(key, "}}"), 'g'), String(value));
|
|
5694
|
-
}
|
|
5695
|
-
});
|
|
5696
|
-
}
|
|
5697
|
-
var template = templates_1.defaultTemplates.option(optionElement, this._globalConfig);
|
|
5698
|
-
// Restore the original template
|
|
5699
|
-
this._globalConfig.optionTemplate = originalTemplate;
|
|
5700
|
-
return template;
|
|
5731
|
+
// 'this' is the KTSelectOption instance.
|
|
5732
|
+
// defaultTemplates.option will handle using this instance's data along with _globalConfig.
|
|
5733
|
+
return templates_1.defaultTemplates.option(this, this._globalConfig);
|
|
5701
5734
|
};
|
|
5702
5735
|
return KTSelectOption;
|
|
5703
5736
|
}(component_1.default));
|
|
@@ -6515,52 +6548,35 @@ Object.defineProperty(exports, "KTScrollspy", ({ enumerable: true, get: function
|
|
|
6515
6548
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
6516
6549
|
exports.KTSelectCombobox = void 0;
|
|
6517
6550
|
var utils_1 = __webpack_require__(9011);
|
|
6551
|
+
var templates_1 = __webpack_require__(9069);
|
|
6518
6552
|
/**
|
|
6519
6553
|
* KTSelectCombobox - Handles combobox-specific functionality for KTSelect
|
|
6520
6554
|
*/
|
|
6521
6555
|
var KTSelectCombobox = /** @class */ (function () {
|
|
6522
6556
|
function KTSelectCombobox(select) {
|
|
6523
6557
|
var _this = this;
|
|
6524
|
-
var _a;
|
|
6525
6558
|
this._select = select;
|
|
6526
6559
|
this._config = select.getConfig();
|
|
6527
|
-
|
|
6528
|
-
|
|
6529
|
-
|
|
6530
|
-
this.
|
|
6531
|
-
displayElement.tagName === 'INPUT'
|
|
6532
|
-
? displayElement
|
|
6533
|
-
: displayElement.querySelector('input[data-kt-select-search]');
|
|
6534
|
-
// Find the clear button robustly
|
|
6535
|
-
var clearButtonContainer = null;
|
|
6536
|
-
if (displayElement.tagName === 'DIV') {
|
|
6537
|
-
clearButtonContainer = displayElement;
|
|
6538
|
-
}
|
|
6539
|
-
else if (displayElement.tagName === 'INPUT') {
|
|
6540
|
-
clearButtonContainer = displayElement.parentElement;
|
|
6541
|
-
}
|
|
6542
|
-
this._clearButtonElement = clearButtonContainer
|
|
6543
|
-
? clearButtonContainer.querySelector('[data-kt-select-clear-button]')
|
|
6544
|
-
: null;
|
|
6545
|
-
this._valuesContainerElement = (_a = displayElement === null || displayElement === void 0 ? void 0 : displayElement.closest('[data-kt-select-combobox]')) === null || _a === void 0 ? void 0 : _a.querySelector('[data-kt-select-combobox-values]');
|
|
6546
|
-
// Create bound handler references to allow proper cleanup
|
|
6560
|
+
var displayElement = select.getDisplayElement(); // KTSelect's main display element for combobox
|
|
6561
|
+
this._searchInputElement = displayElement.querySelector('input[data-kt-select-search]');
|
|
6562
|
+
this._clearButtonElement = displayElement.querySelector('[data-kt-select-clear-button]');
|
|
6563
|
+
this._valuesContainerElement = displayElement.querySelector('[data-kt-select-combobox-values]');
|
|
6547
6564
|
this._boundInputHandler = this._handleComboboxInput.bind(this);
|
|
6548
6565
|
this._boundClearHandler = this._handleClearButtonClick.bind(this);
|
|
6549
|
-
// Attach event listeners
|
|
6550
6566
|
this._attachEventListeners();
|
|
6551
|
-
// Reset combobox search state when dropdown closes
|
|
6552
6567
|
this._select.getElement().addEventListener('dropdown.close', function () {
|
|
6553
|
-
|
|
6554
|
-
//
|
|
6555
|
-
_this.
|
|
6568
|
+
// When dropdown closes, if not multi-select and not using displayTemplate,
|
|
6569
|
+
// ensure input shows the selected value or placeholder.
|
|
6570
|
+
if (!_this._config.multiple && !_this._config.displayTemplate) {
|
|
6571
|
+
_this.updateDisplay(_this._select.getSelectedOptions());
|
|
6572
|
+
}
|
|
6573
|
+
else {
|
|
6574
|
+
// For tags or displayTemplate, the input should be clear for typing.
|
|
6575
|
+
_this._searchInputElement.value = '';
|
|
6576
|
+
}
|
|
6577
|
+
_this._toggleClearButtonVisibility(_this._searchInputElement.value);
|
|
6578
|
+
// this._select.showAllOptions(); // showAllOptions might be too broad, filtering is managed by typing.
|
|
6556
6579
|
});
|
|
6557
|
-
// When selection changes, update the input value to the selected option's text
|
|
6558
|
-
// this._select.getElement().addEventListener('change', () => {
|
|
6559
|
-
// // Only update the input value, do not reset the filter or show all options
|
|
6560
|
-
// const selectedValues = this._select.getSelectedOptions();
|
|
6561
|
-
// const content = this._select.renderDisplayTemplateForSelected(selectedValues);
|
|
6562
|
-
// this._valuesContainerElement?.append(stringToElement(content));
|
|
6563
|
-
// });
|
|
6564
6580
|
if (this._config.debug)
|
|
6565
6581
|
console.log('KTSelectCombobox initialized');
|
|
6566
6582
|
}
|
|
@@ -6568,16 +6584,13 @@ var KTSelectCombobox = /** @class */ (function () {
|
|
|
6568
6584
|
* Attach event listeners specific to combobox
|
|
6569
6585
|
*/
|
|
6570
6586
|
KTSelectCombobox.prototype._attachEventListeners = function () {
|
|
6571
|
-
// First remove any existing listeners to prevent duplicates
|
|
6572
6587
|
this._removeEventListeners();
|
|
6573
|
-
|
|
6574
|
-
|
|
6575
|
-
|
|
6588
|
+
if (this._searchInputElement) { // Ensure element exists
|
|
6589
|
+
this._searchInputElement.addEventListener('input', this._boundInputHandler);
|
|
6590
|
+
}
|
|
6576
6591
|
if (this._clearButtonElement) {
|
|
6577
6592
|
this._clearButtonElement.addEventListener('click', this._boundClearHandler);
|
|
6578
6593
|
}
|
|
6579
|
-
if (this._config.debug)
|
|
6580
|
-
console.log('Combobox event listeners attached to:', this._searchInputElement);
|
|
6581
6594
|
};
|
|
6582
6595
|
/**
|
|
6583
6596
|
* Remove event listeners to prevent memory leaks or duplicates
|
|
@@ -6595,16 +6608,21 @@ var KTSelectCombobox = /** @class */ (function () {
|
|
|
6595
6608
|
*/
|
|
6596
6609
|
KTSelectCombobox.prototype._handleComboboxInput = function (event) {
|
|
6597
6610
|
var inputElement = event.target;
|
|
6598
|
-
var query = inputElement.value
|
|
6599
|
-
|
|
6600
|
-
|
|
6601
|
-
// Toggle clear button visibility based on input value
|
|
6602
|
-
// this._toggleClearButtonVisibility(query);
|
|
6603
|
-
// If dropdown isn't open, open it when user starts typing
|
|
6604
|
-
if (!this._select._dropdownIsOpen) {
|
|
6611
|
+
var query = inputElement.value;
|
|
6612
|
+
this._toggleClearButtonVisibility(query);
|
|
6613
|
+
if (!this._select.isDropdownOpen()) { // Use public getter
|
|
6605
6614
|
this._select.openDropdown();
|
|
6606
6615
|
}
|
|
6607
|
-
//
|
|
6616
|
+
// For single select without displayTemplate, if user types, they are essentially clearing the previous selection text
|
|
6617
|
+
// The actual selection state isn't cleared until they pick a new option or clear explicitly.
|
|
6618
|
+
// For multi-select or with displayTemplate, the input is purely for search.
|
|
6619
|
+
if (this._config.multiple || this._config.displayTemplate) {
|
|
6620
|
+
// Values are in _valuesContainerElement, input is for search
|
|
6621
|
+
}
|
|
6622
|
+
else {
|
|
6623
|
+
// Single select, no displayTemplate: If user types, it implies they might be changing selection.
|
|
6624
|
+
// We don't clear the actual _select state here, just the visual in input.
|
|
6625
|
+
}
|
|
6608
6626
|
this._filterOptionsForCombobox(query);
|
|
6609
6627
|
};
|
|
6610
6628
|
/**
|
|
@@ -6613,29 +6631,25 @@ var KTSelectCombobox = /** @class */ (function () {
|
|
|
6613
6631
|
KTSelectCombobox.prototype._handleClearButtonClick = function (event) {
|
|
6614
6632
|
event.preventDefault();
|
|
6615
6633
|
event.stopPropagation();
|
|
6616
|
-
// Clear the input
|
|
6617
6634
|
this._searchInputElement.value = '';
|
|
6618
|
-
|
|
6619
|
-
// this._toggleClearButtonVisibility('');
|
|
6620
|
-
// Show all options and open dropdown
|
|
6621
|
-
this._select.showAllOptions();
|
|
6622
|
-
this._select.openDropdown();
|
|
6623
|
-
// Clear the current selection
|
|
6624
|
-
this._select.clearSelection();
|
|
6625
|
-
// Clear the combobox values container if present (for displayTemplate)
|
|
6635
|
+
this._toggleClearButtonVisibility('');
|
|
6626
6636
|
if (this._valuesContainerElement) {
|
|
6627
6637
|
this._valuesContainerElement.innerHTML = '';
|
|
6628
6638
|
}
|
|
6629
|
-
//
|
|
6639
|
+
this._select.clearSelection(); // This will also trigger updateSelectedOptionDisplay
|
|
6640
|
+
this._select.showAllOptions(); // Show all options after clearing
|
|
6641
|
+
this._select.openDropdown();
|
|
6630
6642
|
this._searchInputElement.focus();
|
|
6631
6643
|
};
|
|
6632
6644
|
/**
|
|
6633
|
-
* Toggle clear button visibility based on input value
|
|
6645
|
+
* Toggle clear button visibility based on input value and selection state.
|
|
6646
|
+
* Clear button should be visible if there's text in input OR if there are selected items (for multi/displayTemplate modes).
|
|
6634
6647
|
*/
|
|
6635
|
-
KTSelectCombobox.prototype._toggleClearButtonVisibility = function (
|
|
6648
|
+
KTSelectCombobox.prototype._toggleClearButtonVisibility = function (inputValue) {
|
|
6636
6649
|
if (!this._clearButtonElement)
|
|
6637
6650
|
return;
|
|
6638
|
-
|
|
6651
|
+
var hasSelectedItems = this._select.getSelectedOptions().length > 0;
|
|
6652
|
+
if (inputValue.length > 0 || (hasSelectedItems && (this._config.multiple || this._config.displayTemplate))) {
|
|
6639
6653
|
this._clearButtonElement.classList.remove('hidden');
|
|
6640
6654
|
}
|
|
6641
6655
|
else {
|
|
@@ -6646,11 +6660,65 @@ var KTSelectCombobox = /** @class */ (function () {
|
|
|
6646
6660
|
* Filter options for combobox based on input query
|
|
6647
6661
|
*/
|
|
6648
6662
|
KTSelectCombobox.prototype._filterOptionsForCombobox = function (query) {
|
|
6649
|
-
// Use the same filter logic as KTSelectSearch
|
|
6650
6663
|
var options = Array.from(this._select.getOptionsElement());
|
|
6651
6664
|
var config = this._select.getConfig();
|
|
6652
6665
|
var dropdownElement = this._select.getDropdownElement();
|
|
6653
6666
|
(0, utils_1.filterOptions)(options, query, config, dropdownElement);
|
|
6667
|
+
// After filtering, focusManager in KTSelectSearch (if search is also enabled there)
|
|
6668
|
+
// or the main FocusManager should adjust focus if needed.
|
|
6669
|
+
// For combobox, this filtering is the primary search mechanism.
|
|
6670
|
+
// We might need to tell select's focus manager to focus first option.
|
|
6671
|
+
this._select._focusManager.focusFirst(); // Consider if this is always right
|
|
6672
|
+
};
|
|
6673
|
+
/**
|
|
6674
|
+
* Updates the combobox display (input field or values container) based on selection.
|
|
6675
|
+
*/
|
|
6676
|
+
KTSelectCombobox.prototype.updateDisplay = function (selectedOptions) {
|
|
6677
|
+
var _this = this;
|
|
6678
|
+
if (!this._searchInputElement)
|
|
6679
|
+
return;
|
|
6680
|
+
// Always clear the values container first if it exists
|
|
6681
|
+
if (this._valuesContainerElement) {
|
|
6682
|
+
this._valuesContainerElement.innerHTML = '';
|
|
6683
|
+
}
|
|
6684
|
+
if (this._config.tags && this._valuesContainerElement) { // Combobox + Tags
|
|
6685
|
+
selectedOptions.forEach(function (value) {
|
|
6686
|
+
// Ensure value is properly escaped for querySelector
|
|
6687
|
+
var optionElement = _this._select.getElement().querySelector("option[value=\"".concat(CSS.escape(value), "\"]"));
|
|
6688
|
+
if (optionElement) {
|
|
6689
|
+
var tagElement = templates_1.defaultTemplates.tag(optionElement, _this._config);
|
|
6690
|
+
_this._valuesContainerElement.appendChild(tagElement);
|
|
6691
|
+
}
|
|
6692
|
+
});
|
|
6693
|
+
this._searchInputElement.value = ''; // Input field is for typing new searches
|
|
6694
|
+
this._searchInputElement.placeholder = selectedOptions.length > 0 ? '' : (this._config.placeholder || 'Select...');
|
|
6695
|
+
}
|
|
6696
|
+
else if (this._config.displayTemplate && this._valuesContainerElement) { // Combobox + DisplayTemplate (no tags)
|
|
6697
|
+
this._valuesContainerElement.innerHTML = this._select.renderDisplayTemplateForSelected(selectedOptions);
|
|
6698
|
+
this._searchInputElement.value = ''; // Input field is for typing new searches
|
|
6699
|
+
this._searchInputElement.placeholder = selectedOptions.length > 0 ? '' : (this._config.placeholder || 'Select...');
|
|
6700
|
+
}
|
|
6701
|
+
else if (this._config.multiple && this._valuesContainerElement) { // Combobox + Multiple (no tags, no display template)
|
|
6702
|
+
// For simplicity, join text. A proper tag implementation would be more complex here.
|
|
6703
|
+
this._valuesContainerElement.innerHTML = selectedOptions.map(function (value) {
|
|
6704
|
+
var optionEl = _this._select.getElement().querySelector("option[value=\"".concat(CSS.escape(value), "\"]"));
|
|
6705
|
+
return optionEl ? optionEl.textContent : '';
|
|
6706
|
+
}).join(', '); // Basic comma separation
|
|
6707
|
+
this._searchInputElement.value = '';
|
|
6708
|
+
this._searchInputElement.placeholder = selectedOptions.length > 0 ? '' : (this._config.placeholder || 'Select...');
|
|
6709
|
+
}
|
|
6710
|
+
else if (!this._config.multiple && selectedOptions.length > 0) { // Single select combobox: display selected option's text in the input
|
|
6711
|
+
var selectedValue = selectedOptions[0];
|
|
6712
|
+
var optionElement = this._select.getElement().querySelector("option[value=\"".concat(CSS.escape(selectedValue), "\"]"));
|
|
6713
|
+
this._searchInputElement.value = optionElement ? optionElement.textContent || '' : '';
|
|
6714
|
+
// placeholder is implicitly handled by input value for single select
|
|
6715
|
+
}
|
|
6716
|
+
else { // No selection or not fitting above categories (e.g. single select, no items)
|
|
6717
|
+
this._searchInputElement.value = '';
|
|
6718
|
+
this._searchInputElement.placeholder = this._config.placeholder || 'Select...';
|
|
6719
|
+
// _valuesContainerElement is already cleared if it exists
|
|
6720
|
+
}
|
|
6721
|
+
this._toggleClearButtonVisibility(this._searchInputElement.value);
|
|
6654
6722
|
};
|
|
6655
6723
|
/**
|
|
6656
6724
|
* Destroy the combobox component and clean up event listeners
|
|
@@ -7895,7 +7963,7 @@ var KTDataTable = /** @class */ (function (_super) {
|
|
|
7895
7963
|
// Set search value
|
|
7896
7964
|
if (searchElement) {
|
|
7897
7965
|
searchElement.value =
|
|
7898
|
-
typeof search === 'string' ? search : String(search);
|
|
7966
|
+
search === undefined || search === null ? '' : typeof search === 'string' ? search : String(search);
|
|
7899
7967
|
}
|
|
7900
7968
|
if (searchElement) {
|
|
7901
7969
|
// Check if a debounced search function already exists
|
|
@@ -8368,16 +8436,19 @@ var KTDataTable = /** @class */ (function (_super) {
|
|
|
8368
8436
|
if (!_sizeElement) {
|
|
8369
8437
|
return _sizeElement;
|
|
8370
8438
|
}
|
|
8371
|
-
//
|
|
8372
|
-
|
|
8373
|
-
|
|
8374
|
-
|
|
8375
|
-
|
|
8376
|
-
|
|
8377
|
-
|
|
8378
|
-
|
|
8379
|
-
|
|
8380
|
-
|
|
8439
|
+
// Wait for the element to be attached to the DOM
|
|
8440
|
+
setTimeout(function () {
|
|
8441
|
+
// Create <option> elements for each page size option
|
|
8442
|
+
var options = _this._config.pageSizes.map(function (size) {
|
|
8443
|
+
var option = document.createElement('option');
|
|
8444
|
+
option.value = String(size);
|
|
8445
|
+
option.text = String(size);
|
|
8446
|
+
option.selected = _this.getState().pageSize === size;
|
|
8447
|
+
return option;
|
|
8448
|
+
});
|
|
8449
|
+
// Add the <option> elements to the provided element
|
|
8450
|
+
_sizeElement.append.apply(_sizeElement, options);
|
|
8451
|
+
}, 100);
|
|
8381
8452
|
// Create an event listener for the "change" event on the element
|
|
8382
8453
|
var _pageSizeControlsEvent = function (event) {
|
|
8383
8454
|
// When the element changes, reload the page with the new page size and page number 1
|
|
@@ -9217,7 +9288,7 @@ var utils_1 = __webpack_require__(9011);
|
|
|
9217
9288
|
*
|
|
9218
9289
|
* A specialized dropdown implementation for the KTSelect component.
|
|
9219
9290
|
* This module handles the dropdown functionality for the select component,
|
|
9220
|
-
* including positioning
|
|
9291
|
+
* including positioning and showing/hiding.
|
|
9221
9292
|
*/
|
|
9222
9293
|
var KTSelectDropdown = /** @class */ (function (_super) {
|
|
9223
9294
|
__extends(KTSelectDropdown, _super);
|
|
@@ -9228,7 +9299,7 @@ var KTSelectDropdown = /** @class */ (function (_super) {
|
|
|
9228
9299
|
* @param dropdownElement The dropdown content element
|
|
9229
9300
|
* @param config The configuration options
|
|
9230
9301
|
*/
|
|
9231
|
-
function KTSelectDropdown(element, toggleElement, dropdownElement, config) {
|
|
9302
|
+
function KTSelectDropdown(element, toggleElement, dropdownElement, config, ktSelectInstance) {
|
|
9232
9303
|
var _this = _super.call(this) || this;
|
|
9233
9304
|
_this._name = 'select-dropdown';
|
|
9234
9305
|
// State
|
|
@@ -9239,6 +9310,7 @@ var KTSelectDropdown = /** @class */ (function (_super) {
|
|
|
9239
9310
|
_this._toggleElement = toggleElement;
|
|
9240
9311
|
_this._dropdownElement = dropdownElement;
|
|
9241
9312
|
_this._config = config;
|
|
9313
|
+
_this._ktSelectInstance = ktSelectInstance; // Assign instance
|
|
9242
9314
|
_this._eventManager = new utils_1.EventManager();
|
|
9243
9315
|
_this._focusManager = new utils_1.FocusManager(dropdownElement, '[data-kt-select-option]', config);
|
|
9244
9316
|
_this._setupEventListeners();
|
|
@@ -9259,7 +9331,18 @@ var KTSelectDropdown = /** @class */ (function (_super) {
|
|
|
9259
9331
|
KTSelectDropdown.prototype._handleToggleClick = function (event) {
|
|
9260
9332
|
event.preventDefault();
|
|
9261
9333
|
event.stopPropagation();
|
|
9262
|
-
this.
|
|
9334
|
+
if (this._config.disabled) {
|
|
9335
|
+
if (this._config.debug)
|
|
9336
|
+
console.log('KTSelectDropdown._handleToggleClick: select is disabled');
|
|
9337
|
+
return;
|
|
9338
|
+
}
|
|
9339
|
+
// Call KTSelect's methods
|
|
9340
|
+
if (this._ktSelectInstance.isDropdownOpen()) {
|
|
9341
|
+
this._ktSelectInstance.closeDropdown();
|
|
9342
|
+
}
|
|
9343
|
+
else {
|
|
9344
|
+
this._ktSelectInstance.openDropdown();
|
|
9345
|
+
}
|
|
9263
9346
|
};
|
|
9264
9347
|
/**
|
|
9265
9348
|
* Handle clicks outside the dropdown
|
|
@@ -9270,7 +9353,8 @@ var KTSelectDropdown = /** @class */ (function (_super) {
|
|
|
9270
9353
|
var target = event.target;
|
|
9271
9354
|
if (!this._element.contains(target) &&
|
|
9272
9355
|
!this._dropdownElement.contains(target)) {
|
|
9273
|
-
|
|
9356
|
+
// Call KTSelect's closeDropdown method
|
|
9357
|
+
this._ktSelectInstance.closeDropdown();
|
|
9274
9358
|
}
|
|
9275
9359
|
};
|
|
9276
9360
|
/**
|
|
@@ -9372,29 +9456,6 @@ var KTSelectDropdown = /** @class */ (function (_super) {
|
|
|
9372
9456
|
this._popperInstance.update();
|
|
9373
9457
|
}
|
|
9374
9458
|
};
|
|
9375
|
-
/**
|
|
9376
|
-
* Toggle the dropdown
|
|
9377
|
-
*/
|
|
9378
|
-
KTSelectDropdown.prototype.toggle = function () {
|
|
9379
|
-
if (this._config.disabled) {
|
|
9380
|
-
if (this._config.debug)
|
|
9381
|
-
console.log('KTSelectDropdown.toggle: select is disabled, not toggling');
|
|
9382
|
-
return;
|
|
9383
|
-
}
|
|
9384
|
-
if (this._config.debug)
|
|
9385
|
-
console.log('KTSelectDropdown.toggle called - isOpen:', this._isOpen);
|
|
9386
|
-
if (this._isTransitioning) {
|
|
9387
|
-
if (this._config.debug)
|
|
9388
|
-
console.log('KTSelectDropdown.toggle - ignoring during transition');
|
|
9389
|
-
return;
|
|
9390
|
-
}
|
|
9391
|
-
if (this._isOpen) {
|
|
9392
|
-
this.close();
|
|
9393
|
-
}
|
|
9394
|
-
else {
|
|
9395
|
-
this.open();
|
|
9396
|
-
}
|
|
9397
|
-
};
|
|
9398
9459
|
/**
|
|
9399
9460
|
* Open the dropdown
|
|
9400
9461
|
*/
|
|
@@ -9407,71 +9468,41 @@ var KTSelectDropdown = /** @class */ (function (_super) {
|
|
|
9407
9468
|
}
|
|
9408
9469
|
if (this._isOpen || this._isTransitioning)
|
|
9409
9470
|
return;
|
|
9410
|
-
// Fire before show event
|
|
9411
|
-
var beforeShowEvent = new CustomEvent('kt.select.dropdown.show', {
|
|
9412
|
-
bubbles: true,
|
|
9413
|
-
cancelable: true,
|
|
9414
|
-
});
|
|
9415
|
-
this._element.dispatchEvent(beforeShowEvent);
|
|
9416
|
-
if (beforeShowEvent.defaultPrevented)
|
|
9417
|
-
return;
|
|
9418
9471
|
// Begin opening transition
|
|
9419
9472
|
this._isTransitioning = true;
|
|
9420
|
-
// Set initial styles
|
|
9473
|
+
// Set initial styles
|
|
9421
9474
|
this._dropdownElement.classList.remove('hidden');
|
|
9422
9475
|
this._dropdownElement.style.opacity = '0';
|
|
9423
9476
|
// Set dropdown width
|
|
9424
9477
|
this._setDropdownWidth();
|
|
9425
|
-
//
|
|
9478
|
+
// Reflow
|
|
9426
9479
|
dom_1.default.reflow(this._dropdownElement);
|
|
9427
|
-
// Apply z-index
|
|
9480
|
+
// Apply z-index
|
|
9428
9481
|
if (this._config.dropdownZindex) {
|
|
9429
9482
|
this._dropdownElement.style.zIndex =
|
|
9430
9483
|
this._config.dropdownZindex.toString();
|
|
9431
9484
|
}
|
|
9432
9485
|
else {
|
|
9433
|
-
// Auto-calculate z-index
|
|
9434
9486
|
var parentZindex = dom_1.default.getHighestZindex(this._element);
|
|
9435
9487
|
if (parentZindex) {
|
|
9436
9488
|
this._dropdownElement.style.zIndex = (parentZindex + 1).toString();
|
|
9437
9489
|
}
|
|
9438
9490
|
}
|
|
9439
|
-
// Initialize popper
|
|
9491
|
+
// Initialize popper
|
|
9440
9492
|
this._initPopper();
|
|
9441
|
-
// Add active classes
|
|
9493
|
+
// Add active classes for visual state
|
|
9442
9494
|
this._dropdownElement.classList.add('open');
|
|
9443
9495
|
this._toggleElement.classList.add('active');
|
|
9444
|
-
|
|
9496
|
+
// ARIA attributes will be handled by KTSelect
|
|
9445
9497
|
// Start transition
|
|
9446
9498
|
this._dropdownElement.style.opacity = '1';
|
|
9447
9499
|
// Handle transition end
|
|
9448
9500
|
dom_1.default.transitionEnd(this._dropdownElement, function () {
|
|
9449
9501
|
_this._isTransitioning = false;
|
|
9450
9502
|
_this._isOpen = true;
|
|
9451
|
-
// Focus
|
|
9452
|
-
if (_this._config.enableSearch) {
|
|
9453
|
-
var searchInput = _this._dropdownElement.querySelector('input[type="search"]');
|
|
9454
|
-
if (searchInput) {
|
|
9455
|
-
searchInput.focus();
|
|
9456
|
-
}
|
|
9457
|
-
}
|
|
9458
|
-
// Fire after show event
|
|
9459
|
-
var afterShowEvent = new CustomEvent('kt.select.dropdown.shown', {
|
|
9460
|
-
bubbles: true,
|
|
9461
|
-
});
|
|
9462
|
-
_this._element.dispatchEvent(afterShowEvent);
|
|
9503
|
+
// Focus and events will be handled by KTSelect
|
|
9463
9504
|
});
|
|
9464
9505
|
};
|
|
9465
|
-
/**
|
|
9466
|
-
* Focus the first option in the dropdown
|
|
9467
|
-
*/
|
|
9468
|
-
KTSelectDropdown.prototype._focusFirstOption = function () {
|
|
9469
|
-
var firstOption = this._focusManager.getVisibleOptions()[0];
|
|
9470
|
-
if (firstOption) {
|
|
9471
|
-
this._focusManager.applyFocus(firstOption);
|
|
9472
|
-
this._focusManager.scrollIntoView(firstOption);
|
|
9473
|
-
}
|
|
9474
|
-
};
|
|
9475
9506
|
/**
|
|
9476
9507
|
* Close the dropdown
|
|
9477
9508
|
*/
|
|
@@ -9484,34 +9515,19 @@ var KTSelectDropdown = /** @class */ (function (_super) {
|
|
|
9484
9515
|
console.log('KTSelectDropdown.close - early return: dropdown not open or is transitioning');
|
|
9485
9516
|
return;
|
|
9486
9517
|
}
|
|
9487
|
-
//
|
|
9488
|
-
var beforeHideEvent = new CustomEvent('kt.select.dropdown.hide', {
|
|
9489
|
-
bubbles: true,
|
|
9490
|
-
cancelable: true,
|
|
9491
|
-
});
|
|
9492
|
-
this._element.dispatchEvent(beforeHideEvent);
|
|
9493
|
-
if (beforeHideEvent.defaultPrevented) {
|
|
9494
|
-
if (this._config.debug)
|
|
9495
|
-
console.log('KTSelectDropdown.close - canceling due to defaultPrevented on beforeHideEvent');
|
|
9496
|
-
return;
|
|
9497
|
-
}
|
|
9518
|
+
// Events and ARIA will be handled by KTSelect
|
|
9498
9519
|
if (this._config.debug)
|
|
9499
9520
|
console.log('KTSelectDropdown.close - starting transition');
|
|
9500
|
-
// Begin closing transition
|
|
9501
9521
|
this._isTransitioning = true;
|
|
9502
|
-
// Start transition
|
|
9503
9522
|
this._dropdownElement.style.opacity = '0';
|
|
9504
|
-
// Use a combination of transition end and a fallback timer
|
|
9505
9523
|
var transitionComplete = false;
|
|
9506
|
-
// Set a fixed-duration fallback in case the transition event doesn't fire
|
|
9507
9524
|
var fallbackTimer = setTimeout(function () {
|
|
9508
9525
|
if (!transitionComplete) {
|
|
9509
9526
|
if (_this._config.debug)
|
|
9510
9527
|
console.log('KTSelectDropdown.close - fallback timer triggered');
|
|
9511
9528
|
completeTransition();
|
|
9512
9529
|
}
|
|
9513
|
-
}, 300);
|
|
9514
|
-
// Setup the transition end function
|
|
9530
|
+
}, 300);
|
|
9515
9531
|
var completeTransition = function () {
|
|
9516
9532
|
if (transitionComplete)
|
|
9517
9533
|
return;
|
|
@@ -9519,30 +9535,21 @@ var KTSelectDropdown = /** @class */ (function (_super) {
|
|
|
9519
9535
|
clearTimeout(fallbackTimer);
|
|
9520
9536
|
if (_this._config.debug)
|
|
9521
9537
|
console.log('KTSelectDropdown.close - transition ended');
|
|
9522
|
-
// Remove active classes
|
|
9523
9538
|
_this._dropdownElement.classList.add('hidden');
|
|
9524
9539
|
_this._dropdownElement.classList.remove('open');
|
|
9525
9540
|
_this._toggleElement.classList.remove('active');
|
|
9526
|
-
|
|
9527
|
-
// Reset styles - replace display: none with adding hidden class
|
|
9528
|
-
_this._dropdownElement.classList.add('hidden');
|
|
9529
|
-
_this._dropdownElement.style.opacity = '';
|
|
9530
|
-
_this._dropdownElement.style.zIndex = '';
|
|
9531
|
-
// Destroy popper
|
|
9541
|
+
// ARIA attributes will be handled by KTSelect
|
|
9532
9542
|
_this._destroyPopper();
|
|
9533
|
-
// Update state
|
|
9534
9543
|
_this._isTransitioning = false;
|
|
9535
9544
|
_this._isOpen = false;
|
|
9536
|
-
//
|
|
9537
|
-
var afterHideEvent = new CustomEvent('kt.select.dropdown.hidden', {
|
|
9538
|
-
bubbles: true,
|
|
9539
|
-
});
|
|
9540
|
-
_this._element.dispatchEvent(afterHideEvent);
|
|
9545
|
+
// Events will be handled by KTSelect
|
|
9541
9546
|
if (_this._config.debug)
|
|
9542
|
-
console.log('KTSelectDropdown.close -
|
|
9547
|
+
console.log('KTSelectDropdown.close - visual part complete');
|
|
9543
9548
|
};
|
|
9544
|
-
// Handle transition end via the utility but also have the fallback
|
|
9545
9549
|
dom_1.default.transitionEnd(this._dropdownElement, completeTransition);
|
|
9550
|
+
if (dom_1.default.getCssProp(this._dropdownElement, 'transition-duration') === '0s') {
|
|
9551
|
+
completeTransition();
|
|
9552
|
+
}
|
|
9546
9553
|
};
|
|
9547
9554
|
/**
|
|
9548
9555
|
* Check if dropdown is open
|
|
@@ -9910,15 +9917,17 @@ var KTSelectSearch = /** @class */ (function () {
|
|
|
9910
9917
|
console.log('Initializing search module with input:', this._searchInput);
|
|
9911
9918
|
// First remove any existing listeners to prevent duplicates
|
|
9912
9919
|
this._removeEventListeners();
|
|
9913
|
-
// Add the event listener
|
|
9920
|
+
// Add the input event listener for filtering
|
|
9914
9921
|
this._eventManager.addListener(this._searchInput, 'input', this.handleSearchInput);
|
|
9922
|
+
// Add keydown event listener for navigation, selection, and escape
|
|
9923
|
+
this._eventManager.addListener(this._searchInput, 'keydown', this._handleSearchKeyDown.bind(this));
|
|
9915
9924
|
// Add blur event listener to ensure highlights are cleared when focus is lost
|
|
9916
9925
|
this._eventManager.addListener(this._searchInput, 'blur', function () {
|
|
9917
9926
|
// Small delay to prevent race conditions with selection
|
|
9918
9927
|
setTimeout(function () {
|
|
9919
9928
|
if (!_this._searchInput.value) {
|
|
9920
9929
|
_this._resetAllOptions();
|
|
9921
|
-
_this.
|
|
9930
|
+
_this.clearSearch();
|
|
9922
9931
|
}
|
|
9923
9932
|
}, 100);
|
|
9924
9933
|
});
|
|
@@ -9936,39 +9945,48 @@ var KTSelectSearch = /** @class */ (function () {
|
|
|
9936
9945
|
_this.refreshOptionCache();
|
|
9937
9946
|
});
|
|
9938
9947
|
}
|
|
9939
|
-
// Listen for dropdown close to reset options
|
|
9940
|
-
this._select.
|
|
9948
|
+
// Listen for dropdown close to reset options - ATTACH TO WRAPPER
|
|
9949
|
+
this._select.getWrapperElement().addEventListener('dropdown.close', function () {
|
|
9941
9950
|
_this._focusManager.resetFocus();
|
|
9942
|
-
|
|
9943
|
-
|
|
9944
|
-
|
|
9945
|
-
|
|
9951
|
+
// If clearSearchOnClose is false and there's a value, the search term and filtered state should persist.
|
|
9952
|
+
// KTSelect's closeDropdown method already calls this._searchModule.clearSearch() (which clears highlights)
|
|
9953
|
+
// and conditionally clears the input value based on KTSelect's config.clearSearchOnClose.
|
|
9954
|
+
// This listener in search.ts seems to unconditionally clear everything.
|
|
9955
|
+
// For now, keeping its original behavior:
|
|
9956
|
+
_this.clearSearch(); // Clears highlights from current options
|
|
9957
|
+
_this._searchInput.value = ''; // Clears the search input field
|
|
9958
|
+
_this._resetAllOptions(); // Shows all options, restores original text, removes highlights
|
|
9959
|
+
_this._clearNoResultsMessage(); // Clears any "no results" message
|
|
9946
9960
|
});
|
|
9947
|
-
// Clear highlights when an option is selected
|
|
9961
|
+
// Clear highlights when an option is selected - ATTACH TO ORIGINAL SELECT (standard 'change' event)
|
|
9948
9962
|
this._select.getElement().addEventListener('change', function () {
|
|
9949
|
-
_this.
|
|
9963
|
+
_this.clearSearch();
|
|
9950
9964
|
// Close dropdown if configured to do so
|
|
9951
|
-
|
|
9952
|
-
!_this._select.getConfig().multiple) {
|
|
9953
|
-
_this._select.closeDropdown();
|
|
9954
|
-
}
|
|
9965
|
+
_this._select.closeDropdown();
|
|
9955
9966
|
});
|
|
9956
|
-
//
|
|
9957
|
-
|
|
9958
|
-
|
|
9967
|
+
// Consolidated 'dropdown.show' event listener - ATTACH TO WRAPPER
|
|
9968
|
+
this._select.getWrapperElement().addEventListener('dropdown.show', function () {
|
|
9969
|
+
var _a;
|
|
9970
|
+
_this._focusManager.resetFocus(); // Always clear previous focus state
|
|
9971
|
+
if ((_a = _this._searchInput) === null || _a === void 0 ? void 0 : _a.value) {
|
|
9972
|
+
// If there's an existing search term:
|
|
9973
|
+
// 1. Re-filter options. This ensures the display (hidden/visible) is correct
|
|
9974
|
+
// and "no results" message is handled if query yields nothing.
|
|
9975
|
+
_this._filterOptions(_this._searchInput.value);
|
|
9976
|
+
}
|
|
9977
|
+
else {
|
|
9978
|
+
// If search input is empty:
|
|
9979
|
+
// 1. Reset all options to their full, unfiltered, original state.
|
|
9980
|
+
_this._resetAllOptions(); // Shows all, clears highlights from options, restores original text
|
|
9981
|
+
// 2. Clear any "no results" message.
|
|
9982
|
+
_this._clearNoResultsMessage();
|
|
9983
|
+
}
|
|
9984
|
+
// Handle autofocus for the search input (this was one of the original separate listeners)
|
|
9985
|
+
if (_this._select.getConfig().searchAutofocus) {
|
|
9959
9986
|
setTimeout(function () {
|
|
9960
9987
|
var _a;
|
|
9961
|
-
|
|
9962
|
-
|
|
9963
|
-
}, 50);
|
|
9964
|
-
});
|
|
9965
|
-
}
|
|
9966
|
-
// Listen for explicit dropdown open event to clear highlights if needed
|
|
9967
|
-
this._select.getElement().addEventListener('dropdown.show', function () {
|
|
9968
|
-
var _a;
|
|
9969
|
-
// If search input is empty, ensure highlights are cleared on open
|
|
9970
|
-
if (!((_a = _this._searchInput) === null || _a === void 0 ? void 0 : _a.value)) {
|
|
9971
|
-
_this.clearSearchHighlights();
|
|
9988
|
+
(_a = _this._searchInput) === null || _a === void 0 ? void 0 : _a.focus(); // Focus search input
|
|
9989
|
+
}, 50); // Delay to ensure dropdown is visible
|
|
9972
9990
|
}
|
|
9973
9991
|
});
|
|
9974
9992
|
}
|
|
@@ -9983,18 +10001,42 @@ var KTSelectSearch = /** @class */ (function () {
|
|
|
9983
10001
|
}
|
|
9984
10002
|
};
|
|
9985
10003
|
/**
|
|
9986
|
-
*
|
|
10004
|
+
* Handles keydown events on the search input for navigation and actions.
|
|
9987
10005
|
*/
|
|
9988
|
-
KTSelectSearch.prototype.
|
|
9989
|
-
var
|
|
9990
|
-
|
|
9991
|
-
|
|
9992
|
-
|
|
9993
|
-
|
|
9994
|
-
|
|
9995
|
-
|
|
9996
|
-
|
|
9997
|
-
|
|
10006
|
+
KTSelectSearch.prototype._handleSearchKeyDown = function (event) {
|
|
10007
|
+
var key = event.key;
|
|
10008
|
+
switch (key) {
|
|
10009
|
+
case 'ArrowDown':
|
|
10010
|
+
event.preventDefault();
|
|
10011
|
+
this._focusManager.focusNext();
|
|
10012
|
+
break;
|
|
10013
|
+
case 'ArrowUp':
|
|
10014
|
+
event.preventDefault();
|
|
10015
|
+
this._focusManager.focusPrevious();
|
|
10016
|
+
break;
|
|
10017
|
+
case 'Enter':
|
|
10018
|
+
event.preventDefault();
|
|
10019
|
+
// Always attempt to select the first available option in the list.
|
|
10020
|
+
// focusFirst() finds, focuses, and returns the first visible, non-disabled option.
|
|
10021
|
+
var firstAvailableOption = this._focusManager.focusFirst();
|
|
10022
|
+
if (firstAvailableOption) {
|
|
10023
|
+
var optionValue = firstAvailableOption.getAttribute('data-value');
|
|
10024
|
+
if (optionValue) {
|
|
10025
|
+
this._select.toggleSelection(optionValue);
|
|
10026
|
+
// KTSelect.toggleSelection handles closing the dropdown based on config.closeOnSelect and config.multiple
|
|
10027
|
+
}
|
|
10028
|
+
}
|
|
10029
|
+
break;
|
|
10030
|
+
case 'Escape':
|
|
10031
|
+
event.preventDefault();
|
|
10032
|
+
this._searchInput.value = '';
|
|
10033
|
+
this.clearSearch();
|
|
10034
|
+
this._resetAllOptions();
|
|
10035
|
+
this._clearNoResultsMessage();
|
|
10036
|
+
this._focusManager.focusFirst();
|
|
10037
|
+
break;
|
|
10038
|
+
default:
|
|
10039
|
+
break;
|
|
9998
10040
|
}
|
|
9999
10041
|
};
|
|
10000
10042
|
/**
|
|
@@ -10005,42 +10047,66 @@ var KTSelectSearch = /** @class */ (function () {
|
|
|
10005
10047
|
var _this = this;
|
|
10006
10048
|
// Wait for options to be initialized
|
|
10007
10049
|
setTimeout(function () {
|
|
10050
|
+
_this._originalOptionContents.clear(); // Clear before re-caching
|
|
10008
10051
|
var options = Array.from(_this._select.getOptionsElement());
|
|
10009
10052
|
options.forEach(function (option) {
|
|
10010
10053
|
var value = option.getAttribute('data-value');
|
|
10011
10054
|
if (value) {
|
|
10055
|
+
// Store the full innerHTML as the original content
|
|
10012
10056
|
_this._originalOptionContents.set(value, option.innerHTML);
|
|
10013
10057
|
}
|
|
10014
10058
|
});
|
|
10015
10059
|
}, 0);
|
|
10016
10060
|
};
|
|
10061
|
+
/**
|
|
10062
|
+
* Restores the innerHTML of all options from the cache if they have been modified.
|
|
10063
|
+
* This is typically called before applying new filters/highlights.
|
|
10064
|
+
*/
|
|
10065
|
+
KTSelectSearch.prototype._restoreOptionContentsBeforeFilter = function () {
|
|
10066
|
+
var _this = this;
|
|
10067
|
+
var options = Array.from(this._select.getOptionsElement());
|
|
10068
|
+
options.forEach(function (option) {
|
|
10069
|
+
var value = option.getAttribute('data-value');
|
|
10070
|
+
if (value && _this._originalOptionContents.has(value)) {
|
|
10071
|
+
var originalContent = _this._originalOptionContents.get(value);
|
|
10072
|
+
// Only restore if current content is different, to avoid unnecessary DOM manipulation
|
|
10073
|
+
if (option.innerHTML !== originalContent) {
|
|
10074
|
+
option.innerHTML = originalContent;
|
|
10075
|
+
}
|
|
10076
|
+
}
|
|
10077
|
+
});
|
|
10078
|
+
};
|
|
10017
10079
|
KTSelectSearch.prototype._handleSearchInput = function (event) {
|
|
10018
|
-
var query = event.target.value
|
|
10080
|
+
var query = event.target.value;
|
|
10019
10081
|
var config = this._select.getConfig();
|
|
10020
10082
|
// Reset focused option when search changes
|
|
10021
10083
|
this._focusManager.resetFocus();
|
|
10022
|
-
//
|
|
10084
|
+
// Restore original content for all options before filtering/highlighting again
|
|
10085
|
+
this._restoreOptionContentsBeforeFilter();
|
|
10023
10086
|
if (query.trim() === '') {
|
|
10024
|
-
this.
|
|
10087
|
+
this._resetAllOptions();
|
|
10088
|
+
this._focusManager.focusFirst(); // Focus first option when search is cleared
|
|
10089
|
+
return;
|
|
10025
10090
|
}
|
|
10026
|
-
// For remote search,
|
|
10027
|
-
//
|
|
10091
|
+
// For remote search, KTSelect component handles it.
|
|
10092
|
+
// KTSelect will call refreshAfterSearch on this module when remote data is updated.
|
|
10028
10093
|
if (config.remote && config.searchParam) {
|
|
10029
|
-
// If query is too short, reset all options to visible state
|
|
10030
10094
|
if (query.length < config.searchMinLength) {
|
|
10031
10095
|
this._resetAllOptions();
|
|
10032
10096
|
this._clearNoResultsMessage();
|
|
10097
|
+
this._focusManager.focusFirst(); // Focus first if query too short
|
|
10033
10098
|
}
|
|
10034
|
-
// Otherwise, let KTSelect handle remote search
|
|
10035
10099
|
return;
|
|
10036
10100
|
}
|
|
10037
10101
|
// For local search
|
|
10038
10102
|
if (query.length >= config.searchMinLength) {
|
|
10039
10103
|
this._filterOptions(query);
|
|
10104
|
+
this._focusManager.focusFirst(); // Focus first visible option after local filtering
|
|
10040
10105
|
}
|
|
10041
10106
|
else {
|
|
10042
10107
|
this._resetAllOptions();
|
|
10043
10108
|
this._clearNoResultsMessage();
|
|
10109
|
+
this._focusManager.focusFirst(); // Focus first if query too short and not remote
|
|
10044
10110
|
}
|
|
10045
10111
|
};
|
|
10046
10112
|
KTSelectSearch.prototype._filterOptions = function (query) {
|
|
@@ -10052,20 +10118,11 @@ var KTSelectSearch = /** @class */ (function () {
|
|
|
10052
10118
|
if (this._originalOptionContents.size === 0) {
|
|
10053
10119
|
this._cacheOriginalOptionContents();
|
|
10054
10120
|
}
|
|
10055
|
-
//
|
|
10056
|
-
|
|
10057
|
-
|
|
10121
|
+
// Restore original content before filtering, so highlighting is applied fresh.
|
|
10122
|
+
this._restoreOptionContentsBeforeFilter();
|
|
10123
|
+
var visibleCount = (0, utils_1.filterOptions)(options, query, config, dropdownElement, function (count) {
|
|
10124
|
+
return _this._handleNoResults(count);
|
|
10058
10125
|
});
|
|
10059
|
-
// Apply specialized text highlighting if needed
|
|
10060
|
-
if (config.searchHighlight && query.trim() !== '') {
|
|
10061
|
-
this._applyHighlightToDisplay(query);
|
|
10062
|
-
}
|
|
10063
|
-
};
|
|
10064
|
-
/**
|
|
10065
|
-
* Apply highlighting to the display element for multi-select
|
|
10066
|
-
*/
|
|
10067
|
-
KTSelectSearch.prototype._applyHighlightToDisplay = function (query) {
|
|
10068
|
-
// Implementation for display highlighting
|
|
10069
10126
|
};
|
|
10070
10127
|
/**
|
|
10071
10128
|
* Reset all options to their original state
|
|
@@ -10074,34 +10131,29 @@ var KTSelectSearch = /** @class */ (function () {
|
|
|
10074
10131
|
var _this = this;
|
|
10075
10132
|
// Show all options
|
|
10076
10133
|
var options = Array.from(this._select.getOptionsElement());
|
|
10077
|
-
//
|
|
10134
|
+
// Ensure the cache is populated if it's somehow empty here
|
|
10078
10135
|
if (this._originalOptionContents.size === 0) {
|
|
10079
10136
|
this._cacheOriginalOptionContents();
|
|
10080
10137
|
}
|
|
10081
10138
|
options.forEach(function (option) {
|
|
10082
|
-
// Remove the hidden class
|
|
10083
10139
|
option.classList.remove('hidden');
|
|
10140
|
+
if (option.style.display === 'none')
|
|
10141
|
+
option.style.display = ''; // Ensure visible
|
|
10084
10142
|
// Restore original HTML content (remove highlights)
|
|
10085
10143
|
var value = option.getAttribute('data-value');
|
|
10086
10144
|
if (value && _this._originalOptionContents.has(value)) {
|
|
10087
|
-
|
|
10088
|
-
|
|
10089
|
-
|
|
10090
|
-
|
|
10091
|
-
option.getAttribute('style').includes('display:')) {
|
|
10092
|
-
var styleAttr = option.getAttribute('style');
|
|
10093
|
-
if (styleAttr.trim() === 'display: none;' ||
|
|
10094
|
-
styleAttr.trim() === 'display: block;') {
|
|
10095
|
-
option.removeAttribute('style');
|
|
10096
|
-
}
|
|
10097
|
-
else {
|
|
10098
|
-
option.setAttribute('style', styleAttr.replace(/display:\s*[^;]+;?/gi, '').trim());
|
|
10145
|
+
var originalContent = _this._originalOptionContents.get(value);
|
|
10146
|
+
// Only update if different, to minimize DOM changes
|
|
10147
|
+
if (option.innerHTML !== originalContent) {
|
|
10148
|
+
option.innerHTML = originalContent;
|
|
10099
10149
|
}
|
|
10100
10150
|
}
|
|
10101
10151
|
});
|
|
10152
|
+
this._clearNoResultsMessage(); // Ensure no results message is cleared when resetting
|
|
10102
10153
|
};
|
|
10103
10154
|
KTSelectSearch.prototype._handleNoResults = function (visibleOptionsCount) {
|
|
10104
|
-
|
|
10155
|
+
var _a, _b;
|
|
10156
|
+
if (visibleOptionsCount === 0 && ((_b = (_a = this._searchInput) === null || _a === void 0 ? void 0 : _a.value) === null || _b === void 0 ? void 0 : _b.trim()) !== '') {
|
|
10105
10157
|
this._showNoResultsMessage();
|
|
10106
10158
|
}
|
|
10107
10159
|
else {
|
|
@@ -10131,28 +10183,22 @@ var KTSelectSearch = /** @class */ (function () {
|
|
|
10131
10183
|
* Public method to explicitly clear all search highlights
|
|
10132
10184
|
* This is called when search is reset or selection changes
|
|
10133
10185
|
*/
|
|
10134
|
-
KTSelectSearch.prototype.
|
|
10186
|
+
KTSelectSearch.prototype.clearSearch = function () {
|
|
10135
10187
|
var _this = this;
|
|
10136
10188
|
// Restore original option content (removes highlighting)
|
|
10137
|
-
var
|
|
10138
|
-
|
|
10189
|
+
var optionsToClear = Array.from(this._select.getOptionsElement());
|
|
10190
|
+
// Ensure cache is available
|
|
10191
|
+
if (this._originalOptionContents.size === 0 && optionsToClear.length > 0) {
|
|
10192
|
+
this._cacheOriginalOptionContents();
|
|
10193
|
+
}
|
|
10194
|
+
optionsToClear.forEach(function (option) {
|
|
10139
10195
|
var value = option.getAttribute('data-value');
|
|
10140
10196
|
if (value && _this._originalOptionContents.has(value)) {
|
|
10141
|
-
|
|
10142
|
-
|
|
10143
|
-
|
|
10144
|
-
|
|
10145
|
-
|
|
10146
|
-
};
|
|
10147
|
-
/**
|
|
10148
|
-
* Clear any highlights from the display element (selected values)
|
|
10149
|
-
*/
|
|
10150
|
-
KTSelectSearch.prototype._clearDisplayHighlights = function () {
|
|
10151
|
-
// Implementation for clearing display highlights
|
|
10152
|
-
var options = Array.from(this._select.getOptionsElement());
|
|
10153
|
-
options.forEach(function (option) {
|
|
10154
|
-
if (option.dataset && !option.dataset.originalText) {
|
|
10155
|
-
option.dataset.originalText = option.innerHTML;
|
|
10197
|
+
var originalContent = _this._originalOptionContents.get(value);
|
|
10198
|
+
// Only restore if different
|
|
10199
|
+
if (option.innerHTML !== originalContent) {
|
|
10200
|
+
option.innerHTML = originalContent;
|
|
10201
|
+
}
|
|
10156
10202
|
}
|
|
10157
10203
|
});
|
|
10158
10204
|
};
|
|
@@ -10163,14 +10209,23 @@ var KTSelectSearch = /** @class */ (function () {
|
|
|
10163
10209
|
var _this = this;
|
|
10164
10210
|
// Re-cache all option contents
|
|
10165
10211
|
this._originalOptionContents.clear();
|
|
10166
|
-
var
|
|
10167
|
-
|
|
10212
|
+
var currentOptions = Array.from(this._select.getOptionsElement());
|
|
10213
|
+
currentOptions.forEach(function (option) {
|
|
10168
10214
|
var value = option.getAttribute('data-value');
|
|
10169
10215
|
if (value) {
|
|
10170
10216
|
_this._originalOptionContents.set(value, option.innerHTML);
|
|
10171
10217
|
}
|
|
10172
10218
|
});
|
|
10173
10219
|
};
|
|
10220
|
+
/**
|
|
10221
|
+
* Called after search (local or remote via KTSelect) to reset focus.
|
|
10222
|
+
*/
|
|
10223
|
+
KTSelectSearch.prototype.refreshAfterSearch = function () {
|
|
10224
|
+
this._focusManager.resetFocus();
|
|
10225
|
+
this._focusManager.focusFirst();
|
|
10226
|
+
// Re-cache original contents as options might have changed (especially after remote search)
|
|
10227
|
+
this.refreshOptionCache();
|
|
10228
|
+
};
|
|
10174
10229
|
/**
|
|
10175
10230
|
* Clean up all resources used by the search module
|
|
10176
10231
|
*/
|
|
@@ -10178,12 +10233,13 @@ var KTSelectSearch = /** @class */ (function () {
|
|
|
10178
10233
|
// Remove all event listeners
|
|
10179
10234
|
this._removeEventListeners();
|
|
10180
10235
|
// Clear all references
|
|
10181
|
-
this._focusManager
|
|
10182
|
-
|
|
10236
|
+
if (this._focusManager) {
|
|
10237
|
+
this._focusManager.dispose();
|
|
10238
|
+
}
|
|
10183
10239
|
// Clear cached content
|
|
10184
10240
|
this._originalOptionContents.clear();
|
|
10185
10241
|
// Clear highlight elements
|
|
10186
|
-
this.
|
|
10242
|
+
this.clearSearch();
|
|
10187
10243
|
};
|
|
10188
10244
|
return KTSelectSearch;
|
|
10189
10245
|
}());
|
|
@@ -11305,6 +11361,7 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
11305
11361
|
_this._dropdownModule = null;
|
|
11306
11362
|
_this._loadMoreIndicator = null;
|
|
11307
11363
|
_this._typeToSearchBuffer = new utils_1.TypeToSearchBuffer();
|
|
11364
|
+
_this._mutationObserver = null;
|
|
11308
11365
|
// Search debounce timeout
|
|
11309
11366
|
_this._searchDebounceTimeout = null;
|
|
11310
11367
|
// Store original options HTML for restoring after search
|
|
@@ -11399,15 +11456,16 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
11399
11456
|
var optionsContainer = this._dropdownContentElement.querySelector('[data-kt-select-options]');
|
|
11400
11457
|
if (!optionsContainer)
|
|
11401
11458
|
return;
|
|
11459
|
+
// Clear previous messages
|
|
11460
|
+
optionsContainer.innerHTML = '';
|
|
11402
11461
|
switch (type) {
|
|
11403
11462
|
case 'error':
|
|
11404
|
-
optionsContainer.
|
|
11463
|
+
optionsContainer.appendChild(templates_1.defaultTemplates.error(__assign(__assign({}, this._config), { errorMessage: message })));
|
|
11405
11464
|
break;
|
|
11406
11465
|
case 'loading':
|
|
11407
|
-
optionsContainer.
|
|
11466
|
+
optionsContainer.appendChild(templates_1.defaultTemplates.loading(this._config, message || 'Loading...'));
|
|
11408
11467
|
break;
|
|
11409
11468
|
case 'empty':
|
|
11410
|
-
optionsContainer.innerHTML = '';
|
|
11411
11469
|
optionsContainer.appendChild(templates_1.defaultTemplates.empty(this._config));
|
|
11412
11470
|
break;
|
|
11413
11471
|
}
|
|
@@ -11579,20 +11637,15 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
11579
11637
|
// Initialize focus manager after dropdown element is created
|
|
11580
11638
|
this._focusManager = new utils_1.FocusManager(this._dropdownContentElement, '[data-kt-select-option]', this._config);
|
|
11581
11639
|
// Initialize dropdown module after all elements are created
|
|
11582
|
-
this._dropdownModule = new dropdown_1.KTSelectDropdown(this._wrapperElement, this._displayElement, this._dropdownContentElement, this._config);
|
|
11640
|
+
this._dropdownModule = new dropdown_1.KTSelectDropdown(this._wrapperElement, this._displayElement, this._dropdownContentElement, this._config, this);
|
|
11583
11641
|
// Update display and set ARIA attributes
|
|
11584
11642
|
this._updateDisplayAndAriaAttributes();
|
|
11585
11643
|
this.updateSelectedOptionDisplay();
|
|
11586
11644
|
this._setAriaAttributes();
|
|
11587
11645
|
// Attach event listeners after all modules are initialized
|
|
11588
11646
|
this._attachEventListeners();
|
|
11647
|
+
this._observeNativeSelect();
|
|
11589
11648
|
};
|
|
11590
|
-
/**
|
|
11591
|
-
* Initialize options HTML from data
|
|
11592
|
-
*/
|
|
11593
|
-
// private _initializeOptionsHtml() {
|
|
11594
|
-
// this._generateOptionsHtml(this._element);
|
|
11595
|
-
// }
|
|
11596
11649
|
/**
|
|
11597
11650
|
* Creates the HTML structure for the select component
|
|
11598
11651
|
*/
|
|
@@ -11607,7 +11660,13 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
11607
11660
|
wrapperElement.appendChild(displayElement);
|
|
11608
11661
|
// Move classes from original select to display element
|
|
11609
11662
|
if (this._element.classList.length > 0) {
|
|
11610
|
-
|
|
11663
|
+
// Exclude kt-select class from being added to the wrapper element
|
|
11664
|
+
var classes = Array.from(this._element.classList).filter(function (className) { return className !== 'kt-select'; });
|
|
11665
|
+
(_a = wrapperElement.classList).add.apply(_a, classes);
|
|
11666
|
+
// If element has class kt-select, move it to display element
|
|
11667
|
+
if (this._element.classList.contains('kt-select')) {
|
|
11668
|
+
displayElement.classList.add('kt-select');
|
|
11669
|
+
}
|
|
11611
11670
|
this._element.className = '';
|
|
11612
11671
|
}
|
|
11613
11672
|
// Create an empty dropdown first (without options) using template
|
|
@@ -11641,7 +11700,7 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
11641
11700
|
wrapperElement.appendChild(dropdownElement);
|
|
11642
11701
|
// Insert after the original element
|
|
11643
11702
|
this._element.after(wrapperElement);
|
|
11644
|
-
this._element.
|
|
11703
|
+
this._element.classList.add('hidden');
|
|
11645
11704
|
};
|
|
11646
11705
|
/**
|
|
11647
11706
|
* Setup all element references after DOM is created
|
|
@@ -11662,7 +11721,6 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
11662
11721
|
if (!this._searchInputElement) {
|
|
11663
11722
|
this._searchInputElement = this._displayElement;
|
|
11664
11723
|
}
|
|
11665
|
-
this._valueDisplayElement = this._wrapperElement.querySelector("[data-kt-select-value]");
|
|
11666
11724
|
this._options = this._wrapperElement.querySelectorAll("[data-kt-select-option]");
|
|
11667
11725
|
};
|
|
11668
11726
|
/**
|
|
@@ -11673,16 +11731,10 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
11673
11731
|
document.addEventListener('click', this._handleDocumentClick.bind(this));
|
|
11674
11732
|
// Dropdown option click events
|
|
11675
11733
|
this._eventManager.addListener(this._dropdownContentElement, 'click', this._handleDropdownOptionClick.bind(this));
|
|
11676
|
-
//
|
|
11677
|
-
//
|
|
11678
|
-
|
|
11679
|
-
|
|
11680
|
-
// this._handleDropdownClick.bind(this),
|
|
11681
|
-
// );
|
|
11682
|
-
// Attach centralized keyboard handler
|
|
11683
|
-
var keyboardTarget = this._searchInputElement || this._wrapperElement;
|
|
11684
|
-
if (keyboardTarget) {
|
|
11685
|
-
keyboardTarget.addEventListener('keydown', this._handleKeyboardEvent.bind(this));
|
|
11734
|
+
// Attach centralized keyboard handler to the wrapper element.
|
|
11735
|
+
// Events from focusable children like _displayElement or _searchInputElement (if present) will bubble up.
|
|
11736
|
+
if (this._wrapperElement) {
|
|
11737
|
+
this._wrapperElement.addEventListener('keydown', this._handleKeyboardEvent.bind(this));
|
|
11686
11738
|
}
|
|
11687
11739
|
};
|
|
11688
11740
|
/**
|
|
@@ -11825,37 +11877,10 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
11825
11877
|
* DROPDOWN MANAGEMENT
|
|
11826
11878
|
* ========================================================================
|
|
11827
11879
|
*/
|
|
11828
|
-
/**
|
|
11829
|
-
* Toggle dropdown visibility
|
|
11830
|
-
* @deprecated
|
|
11831
|
-
*/
|
|
11832
|
-
KTSelect.prototype.toggleDropdown = function () {
|
|
11833
|
-
if (this._config.disabled) {
|
|
11834
|
-
if (this._config.debug)
|
|
11835
|
-
console.log('toggleDropdown: select is disabled, not opening');
|
|
11836
|
-
return;
|
|
11837
|
-
}
|
|
11838
|
-
if (this._config.debug)
|
|
11839
|
-
console.log('toggleDropdown called');
|
|
11840
|
-
if (this._dropdownModule) {
|
|
11841
|
-
// Always use the dropdown module's state to determine whether to open or close
|
|
11842
|
-
if (this._dropdownModule.isOpen()) {
|
|
11843
|
-
if (this._config.debug)
|
|
11844
|
-
console.log('Dropdown is open, closing...');
|
|
11845
|
-
this.closeDropdown();
|
|
11846
|
-
}
|
|
11847
|
-
else {
|
|
11848
|
-
if (this._config.debug)
|
|
11849
|
-
console.log('Dropdown is closed, opening...');
|
|
11850
|
-
this.openDropdown();
|
|
11851
|
-
}
|
|
11852
|
-
}
|
|
11853
|
-
};
|
|
11854
11880
|
/**
|
|
11855
11881
|
* Open the dropdown
|
|
11856
11882
|
*/
|
|
11857
11883
|
KTSelect.prototype.openDropdown = function () {
|
|
11858
|
-
var _this = this;
|
|
11859
11884
|
if (this._config.disabled) {
|
|
11860
11885
|
if (this._config.debug)
|
|
11861
11886
|
console.log('openDropdown: select is disabled, not opening');
|
|
@@ -11883,14 +11908,6 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
11883
11908
|
// Dispatch custom event
|
|
11884
11909
|
this._dispatchEvent('show');
|
|
11885
11910
|
this._fireEvent('show');
|
|
11886
|
-
// Focus search input if configured and exists
|
|
11887
|
-
if (this._config.enableSearch &&
|
|
11888
|
-
this._config.searchAutofocus &&
|
|
11889
|
-
this._searchInputElement) {
|
|
11890
|
-
setTimeout(function () {
|
|
11891
|
-
_this._searchInputElement.focus();
|
|
11892
|
-
}, 50);
|
|
11893
|
-
}
|
|
11894
11911
|
// Update ARIA states
|
|
11895
11912
|
this._setAriaAttributes();
|
|
11896
11913
|
// Focus the first selected option or first option if nothing selected
|
|
@@ -11911,14 +11928,14 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
11911
11928
|
// Always close by delegating to the dropdown module, which is the source of truth
|
|
11912
11929
|
if (this._config.debug)
|
|
11913
11930
|
console.log('Closing dropdown via dropdownModule...');
|
|
11914
|
-
// Clear search input
|
|
11931
|
+
// Clear search input if the dropdown is closing
|
|
11915
11932
|
if (this._searchModule && this._searchInputElement) {
|
|
11916
11933
|
// Clear search input if configured to do so
|
|
11917
11934
|
if (this._config.clearSearchOnClose) {
|
|
11918
11935
|
this._searchInputElement.value = '';
|
|
11919
11936
|
}
|
|
11920
|
-
//
|
|
11921
|
-
this._searchModule.
|
|
11937
|
+
// Clear search input when dropdown closes
|
|
11938
|
+
this._searchModule.clearSearch();
|
|
11922
11939
|
}
|
|
11923
11940
|
// Set our internal flag to match what we're doing
|
|
11924
11941
|
this._dropdownIsOpen = false;
|
|
@@ -11952,10 +11969,13 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
11952
11969
|
var selectedOptions = this.getSelectedOptions();
|
|
11953
11970
|
if (selectedOptions.length === 0)
|
|
11954
11971
|
return;
|
|
11955
|
-
//
|
|
11956
|
-
var
|
|
11957
|
-
|
|
11958
|
-
|
|
11972
|
+
// Iterate through selected options and focus the first one that is visible
|
|
11973
|
+
for (var _i = 0, selectedOptions_1 = selectedOptions; _i < selectedOptions_1.length; _i++) {
|
|
11974
|
+
var value = selectedOptions_1[_i];
|
|
11975
|
+
if (this._focusManager && this._focusManager.focusOptionByValue(value)) {
|
|
11976
|
+
break; // Stop after focusing the first found selected and visible option
|
|
11977
|
+
}
|
|
11978
|
+
}
|
|
11959
11979
|
};
|
|
11960
11980
|
/**
|
|
11961
11981
|
* ========================================================================
|
|
@@ -12018,38 +12038,62 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12018
12038
|
*/
|
|
12019
12039
|
KTSelect.prototype.updateSelectedOptionDisplay = function () {
|
|
12020
12040
|
var selectedOptions = this.getSelectedOptions();
|
|
12021
|
-
|
|
12022
|
-
|
|
12041
|
+
var tagsEnabled = this._config.tags && this._tagsModule;
|
|
12042
|
+
var valueDisplayEl = this.getValueDisplayElement();
|
|
12043
|
+
if (tagsEnabled) {
|
|
12044
|
+
// Tags module will render tags if selectedOptions > 0, or clear them if selectedOptions === 0.
|
|
12023
12045
|
this._tagsModule.updateTagsDisplay(selectedOptions);
|
|
12024
|
-
|
|
12046
|
+
}
|
|
12047
|
+
// Guard against valueDisplayEl being null due to template modifications
|
|
12048
|
+
if (!valueDisplayEl) {
|
|
12049
|
+
if (this._config.debug) {
|
|
12050
|
+
console.warn('KTSelect: Value display element is null. Cannot update display or placeholder. Check template for [data-kt-select-value].');
|
|
12051
|
+
}
|
|
12052
|
+
return; // Nothing to display on if the element is missing
|
|
12025
12053
|
}
|
|
12026
12054
|
if (typeof this._config.renderSelected === 'function') {
|
|
12027
|
-
|
|
12028
|
-
this._valueDisplayElement.innerHTML = this._config.renderSelected(selectedOptions);
|
|
12055
|
+
valueDisplayEl.innerHTML = this._config.renderSelected(selectedOptions);
|
|
12029
12056
|
}
|
|
12030
12057
|
else {
|
|
12031
12058
|
if (selectedOptions.length === 0) {
|
|
12032
|
-
|
|
12033
|
-
|
|
12059
|
+
// No options selected: display placeholder.
|
|
12060
|
+
// This runs if tags are off, OR if tags are on but no items are selected (tags module would have cleared tags).
|
|
12061
|
+
var placeholderEl = templates_1.defaultTemplates.placeholder(this._config);
|
|
12062
|
+
valueDisplayEl.replaceChildren(placeholderEl);
|
|
12034
12063
|
}
|
|
12035
12064
|
else {
|
|
12036
|
-
|
|
12037
|
-
if (
|
|
12038
|
-
|
|
12039
|
-
|
|
12065
|
+
// Options are selected.
|
|
12066
|
+
if (tagsEnabled) {
|
|
12067
|
+
// Tags are enabled AND options are selected: tags module has rendered them.
|
|
12068
|
+
// Clear valueDisplayEl as tags are the primary display.
|
|
12069
|
+
valueDisplayEl.innerHTML = '';
|
|
12040
12070
|
}
|
|
12041
12071
|
else {
|
|
12042
|
-
//
|
|
12043
|
-
content =
|
|
12072
|
+
// Tags are not enabled AND options are selected: render normal text display.
|
|
12073
|
+
var content = '';
|
|
12074
|
+
if (this._config.displayTemplate) {
|
|
12075
|
+
content = this.renderDisplayTemplateForSelected(this.getSelectedOptions());
|
|
12076
|
+
}
|
|
12077
|
+
else {
|
|
12078
|
+
content = this.getSelectedOptionsText();
|
|
12079
|
+
}
|
|
12080
|
+
valueDisplayEl.innerHTML = content;
|
|
12044
12081
|
}
|
|
12045
|
-
this._valueDisplayElement.innerHTML = content;
|
|
12046
12082
|
}
|
|
12047
12083
|
}
|
|
12048
12084
|
};
|
|
12085
|
+
/**
|
|
12086
|
+
* Check if an option was originally disabled in the HTML
|
|
12087
|
+
*/
|
|
12088
|
+
KTSelect.prototype._isOptionOriginallyDisabled = function (value) {
|
|
12089
|
+
var originalOption = Array.from(this._element.querySelectorAll('option')).find(function (opt) { return opt.value === value; });
|
|
12090
|
+
return originalOption ? originalOption.disabled : false;
|
|
12091
|
+
};
|
|
12049
12092
|
/**
|
|
12050
12093
|
* Update CSS classes for selected options
|
|
12051
12094
|
*/
|
|
12052
12095
|
KTSelect.prototype._updateSelectedOptionClass = function () {
|
|
12096
|
+
var _this = this;
|
|
12053
12097
|
var allOptions = this._wrapperElement.querySelectorAll("[data-kt-select-option]");
|
|
12054
12098
|
var selectedValues = this._state.getSelectedOptions();
|
|
12055
12099
|
var maxReached = typeof this._config.maxSelections === 'number' &&
|
|
@@ -12061,9 +12105,11 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12061
12105
|
if (!optionValue)
|
|
12062
12106
|
return;
|
|
12063
12107
|
var isSelected = selectedValues.includes(optionValue);
|
|
12108
|
+
var isOriginallyDisabled = _this._isOptionOriginallyDisabled(optionValue);
|
|
12064
12109
|
if (isSelected) {
|
|
12065
12110
|
option.classList.add('selected');
|
|
12066
12111
|
option.setAttribute('aria-selected', 'true');
|
|
12112
|
+
// Selected options should not be visually hidden or disabled by maxSelections logic
|
|
12067
12113
|
option.classList.remove('hidden');
|
|
12068
12114
|
option.classList.remove('disabled');
|
|
12069
12115
|
option.removeAttribute('aria-disabled');
|
|
@@ -12071,7 +12117,8 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12071
12117
|
else {
|
|
12072
12118
|
option.classList.remove('selected');
|
|
12073
12119
|
option.setAttribute('aria-selected', 'false');
|
|
12074
|
-
if
|
|
12120
|
+
// An option should be disabled if it was originally disabled OR if maxSelections is reached
|
|
12121
|
+
if (isOriginallyDisabled || maxReached) {
|
|
12075
12122
|
option.classList.add('disabled');
|
|
12076
12123
|
option.setAttribute('aria-disabled', 'true');
|
|
12077
12124
|
}
|
|
@@ -12131,17 +12178,6 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12131
12178
|
* EVENT HANDLERS
|
|
12132
12179
|
* ========================================================================
|
|
12133
12180
|
*/
|
|
12134
|
-
/**
|
|
12135
|
-
* Handle display element click
|
|
12136
|
-
* @deprecated
|
|
12137
|
-
*/
|
|
12138
|
-
KTSelect.prototype._handleDropdownClick = function (event) {
|
|
12139
|
-
if (this._config.debug)
|
|
12140
|
-
console.log('Display element clicked', event.target);
|
|
12141
|
-
event.preventDefault();
|
|
12142
|
-
event.stopPropagation(); // Prevent event bubbling
|
|
12143
|
-
this.toggleDropdown();
|
|
12144
|
-
};
|
|
12145
12181
|
/**
|
|
12146
12182
|
* Handle click within the dropdown
|
|
12147
12183
|
*/
|
|
@@ -12182,6 +12218,13 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12182
12218
|
}
|
|
12183
12219
|
if (this._config.debug)
|
|
12184
12220
|
console.log('Option clicked:', optionValue);
|
|
12221
|
+
// If in single-select mode and the clicked option is already selected, just close the dropdown.
|
|
12222
|
+
if (!this._config.multiple && this._state.isSelected(optionValue)) {
|
|
12223
|
+
if (this._config.debug)
|
|
12224
|
+
console.log('Single select mode: clicked already selected option. Closing dropdown.');
|
|
12225
|
+
this.closeDropdown();
|
|
12226
|
+
return;
|
|
12227
|
+
}
|
|
12185
12228
|
// Use toggleSelection instead of _selectOption to prevent re-rendering
|
|
12186
12229
|
this.toggleSelection(optionValue);
|
|
12187
12230
|
};
|
|
@@ -12245,7 +12288,13 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12245
12288
|
* Get value display element
|
|
12246
12289
|
*/
|
|
12247
12290
|
KTSelect.prototype.getValueDisplayElement = function () {
|
|
12248
|
-
return this.
|
|
12291
|
+
return this._displayElement;
|
|
12292
|
+
};
|
|
12293
|
+
/**
|
|
12294
|
+
* Get wrapper element
|
|
12295
|
+
*/
|
|
12296
|
+
KTSelect.prototype.getWrapperElement = function () {
|
|
12297
|
+
return this._wrapperElement;
|
|
12249
12298
|
};
|
|
12250
12299
|
/**
|
|
12251
12300
|
* Show all options in the dropdown
|
|
@@ -12255,6 +12304,7 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12255
12304
|
var options = Array.from(this._wrapperElement.querySelectorAll("[data-kt-select-option]"));
|
|
12256
12305
|
// Show all options by removing the hidden class and any inline styles
|
|
12257
12306
|
options.forEach(function (option) {
|
|
12307
|
+
var _a;
|
|
12258
12308
|
// Remove hidden class
|
|
12259
12309
|
option.classList.remove('hidden');
|
|
12260
12310
|
// Clean up any existing inline styles for backward compatibility
|
|
@@ -12268,7 +12318,7 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12268
12318
|
}
|
|
12269
12319
|
else {
|
|
12270
12320
|
// Otherwise, remove just the display property
|
|
12271
|
-
option.setAttribute('style', styleAttr.replace(/display:\s*[^;]+;?/gi, '').trim());
|
|
12321
|
+
option.setAttribute('style', (_a = styleAttr === null || styleAttr === void 0 ? void 0 : styleAttr.replace(/display:\s*[^;]+;?/gi, '')) === null || _a === void 0 ? void 0 : _a.trim());
|
|
12272
12322
|
}
|
|
12273
12323
|
}
|
|
12274
12324
|
}
|
|
@@ -12278,7 +12328,7 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12278
12328
|
this._searchInputElement.value = '';
|
|
12279
12329
|
// If we have a search module, clear any search filtering
|
|
12280
12330
|
if (this._searchModule) {
|
|
12281
|
-
this._searchModule.
|
|
12331
|
+
this._searchModule.clearSearch();
|
|
12282
12332
|
}
|
|
12283
12333
|
}
|
|
12284
12334
|
};
|
|
@@ -12307,7 +12357,7 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12307
12357
|
// Get current selection state
|
|
12308
12358
|
var isSelected = this._state.isSelected(value);
|
|
12309
12359
|
if (this._config.debug)
|
|
12310
|
-
console.log("toggleSelection called for value: ".concat(value, ", isSelected: ").concat(isSelected, ", multiple: ").concat(this._config.multiple
|
|
12360
|
+
console.log("toggleSelection called for value: ".concat(value, ", isSelected: ").concat(isSelected, ", multiple: ").concat(this._config.multiple));
|
|
12311
12361
|
// If already selected in single select mode, do nothing (can't deselect in single select)
|
|
12312
12362
|
if (isSelected && !this._config.multiple) {
|
|
12313
12363
|
if (this._config.debug)
|
|
@@ -12316,9 +12366,9 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12316
12366
|
}
|
|
12317
12367
|
if (this._config.debug)
|
|
12318
12368
|
console.log("Toggling selection for option: ".concat(value, ", currently selected: ").concat(isSelected));
|
|
12319
|
-
// Ensure any search
|
|
12369
|
+
// Ensure any search input is cleared when selection changes
|
|
12320
12370
|
if (this._searchModule) {
|
|
12321
|
-
this._searchModule.
|
|
12371
|
+
this._searchModule.clearSearch();
|
|
12322
12372
|
}
|
|
12323
12373
|
// Toggle the selection in the state
|
|
12324
12374
|
this._state.toggleSelectedOptions(value);
|
|
@@ -12341,15 +12391,14 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12341
12391
|
// Update option classes without re-rendering the dropdown content
|
|
12342
12392
|
this._updateSelectedOptionClass();
|
|
12343
12393
|
// For single select mode, always close the dropdown after selection
|
|
12344
|
-
// For multiple select mode, only close if closeOnSelect is true
|
|
12345
12394
|
if (!this._config.multiple) {
|
|
12346
12395
|
if (this._config.debug)
|
|
12347
12396
|
console.log('About to call closeDropdown() for single select mode - always close after selection');
|
|
12348
12397
|
this.closeDropdown();
|
|
12349
12398
|
}
|
|
12350
|
-
else
|
|
12399
|
+
else {
|
|
12351
12400
|
if (this._config.debug)
|
|
12352
|
-
console.log('About to call closeDropdown() for multiple select
|
|
12401
|
+
console.log('About to call closeDropdown() for multiple select');
|
|
12353
12402
|
this.closeDropdown();
|
|
12354
12403
|
}
|
|
12355
12404
|
// Dispatch custom change event with additional data
|
|
@@ -12449,9 +12498,9 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12449
12498
|
.then(function () {
|
|
12450
12499
|
// Update options in the dropdown
|
|
12451
12500
|
_this._updateSearchResults(items);
|
|
12452
|
-
// Refresh the search module
|
|
12453
|
-
if (_this._searchModule
|
|
12454
|
-
_this._searchModule.
|
|
12501
|
+
// Refresh the search module to update focus and cache
|
|
12502
|
+
if (_this._searchModule) {
|
|
12503
|
+
_this._searchModule.refreshAfterSearch();
|
|
12455
12504
|
}
|
|
12456
12505
|
})
|
|
12457
12506
|
.catch(function (error) {
|
|
@@ -12548,19 +12597,47 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12548
12597
|
* Centralized keyboard event handler for all select modes
|
|
12549
12598
|
*/
|
|
12550
12599
|
KTSelect.prototype._handleKeyboardEvent = function (event) {
|
|
12600
|
+
// If the event target is the search input and the event was already handled (defaultPrevented),
|
|
12601
|
+
// then return early to avoid duplicate processing by this broader handler.
|
|
12602
|
+
if (event.target === this._searchInputElement && event.defaultPrevented) {
|
|
12603
|
+
return;
|
|
12604
|
+
}
|
|
12551
12605
|
var isOpen = this._dropdownIsOpen;
|
|
12552
12606
|
var config = this._config;
|
|
12553
12607
|
var focusManager = this._focusManager;
|
|
12554
12608
|
var buffer = this._typeToSearchBuffer;
|
|
12555
|
-
//
|
|
12609
|
+
// If the event target is the search input, let it handle most typing keys naturally.
|
|
12610
|
+
if (event.target === this._searchInputElement) {
|
|
12611
|
+
// Allow navigation keys like ArrowDown, ArrowUp, Escape, Enter (for search/selection) to be handled by the logic below.
|
|
12612
|
+
// For other keys (characters, space, backspace, delete), let the input field process them.
|
|
12613
|
+
if (event.key !== 'ArrowDown' && event.key !== 'ArrowUp' &&
|
|
12614
|
+
event.key !== 'Escape' && event.key !== 'Enter' && event.key !== 'Tab' &&
|
|
12615
|
+
event.key !== 'Home' && event.key !== 'End') {
|
|
12616
|
+
// If it's a character key and we are NOT type-to-searching (because search has focus)
|
|
12617
|
+
// then let the input field handle it for its own value.
|
|
12618
|
+
// The search module's 'input' event will handle filtering based on the input's value.
|
|
12619
|
+
buffer.clear(); // Clear type-to-search buffer when typing in search field
|
|
12620
|
+
return;
|
|
12621
|
+
}
|
|
12622
|
+
// For Enter specifically in search input, we might want to select the focused option or submit search.
|
|
12623
|
+
// This is handled later in the switch.
|
|
12624
|
+
}
|
|
12625
|
+
// Ignore modifier keys (except for specific combinations if added later)
|
|
12556
12626
|
if (event.altKey || event.ctrlKey || event.metaKey)
|
|
12557
12627
|
return;
|
|
12558
|
-
// Type-to-search: only for single char keys
|
|
12559
|
-
if (event.key.length === 1 && !event.repeat && !event.key.match(/\s/)) {
|
|
12628
|
+
// Type-to-search: only for single char keys, when search input does not have focus
|
|
12629
|
+
if (event.key.length === 1 && !event.repeat && !event.key.match(/\s/) && document.activeElement !== this._searchInputElement) {
|
|
12560
12630
|
buffer.push(event.key);
|
|
12561
12631
|
var str = buffer.getBuffer();
|
|
12562
|
-
|
|
12563
|
-
|
|
12632
|
+
if (isOpen) {
|
|
12633
|
+
focusManager.focusByString(str);
|
|
12634
|
+
}
|
|
12635
|
+
else {
|
|
12636
|
+
// If closed, type-to-search could potentially open and select.
|
|
12637
|
+
// For now, let's assume it only works when open or opens it first.
|
|
12638
|
+
// Or, we could find the matching option and set it directly without opening.
|
|
12639
|
+
}
|
|
12640
|
+
return; // Type-to-search handles the event
|
|
12564
12641
|
}
|
|
12565
12642
|
switch (event.key) {
|
|
12566
12643
|
case 'ArrowDown':
|
|
@@ -12594,18 +12671,28 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12594
12671
|
case 'Enter':
|
|
12595
12672
|
case ' ': // Space
|
|
12596
12673
|
if (isOpen) {
|
|
12597
|
-
var
|
|
12598
|
-
if (
|
|
12599
|
-
var
|
|
12600
|
-
|
|
12601
|
-
|
|
12602
|
-
if (
|
|
12603
|
-
|
|
12604
|
-
|
|
12674
|
+
var focusedOptionEl = this._focusManager.getFocusedOption();
|
|
12675
|
+
if (focusedOptionEl) {
|
|
12676
|
+
var val = focusedOptionEl.dataset.value;
|
|
12677
|
+
// If single select, and the item is already selected, just close.
|
|
12678
|
+
if (val !== undefined && !this._config.multiple && this._state.isSelected(val)) {
|
|
12679
|
+
if (this._config.debug)
|
|
12680
|
+
console.log('Enter on already selected item in single-select mode. Closing.');
|
|
12681
|
+
this.closeDropdown();
|
|
12682
|
+
event.preventDefault();
|
|
12683
|
+
break;
|
|
12605
12684
|
}
|
|
12606
12685
|
}
|
|
12607
|
-
//
|
|
12608
|
-
|
|
12686
|
+
// Proceed with selection if not handled above
|
|
12687
|
+
this.selectFocusedOption();
|
|
12688
|
+
// Close dropdown if configured to do so (for new selections)
|
|
12689
|
+
if (!this._config.multiple) {
|
|
12690
|
+
// This will also be true for the case handled above, but closeDropdown is idempotent.
|
|
12691
|
+
// However, the break above prevents this from being reached for that specific case.
|
|
12692
|
+
this.closeDropdown();
|
|
12693
|
+
}
|
|
12694
|
+
event.preventDefault(); // Prevent form submission or other default actions
|
|
12695
|
+
break;
|
|
12609
12696
|
}
|
|
12610
12697
|
else {
|
|
12611
12698
|
this.openDropdown();
|
|
@@ -12649,6 +12736,76 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
12649
12736
|
}).filter(Boolean)));
|
|
12650
12737
|
return contentArray.join(displaySeparator);
|
|
12651
12738
|
};
|
|
12739
|
+
KTSelect.prototype.getDisplayElement = function () {
|
|
12740
|
+
return this._displayElement;
|
|
12741
|
+
};
|
|
12742
|
+
KTSelect.prototype._observeNativeSelect = function () {
|
|
12743
|
+
var _this = this;
|
|
12744
|
+
if (this._mutationObserver)
|
|
12745
|
+
return; // Prevent double observers
|
|
12746
|
+
this._mutationObserver = new MutationObserver(function (mutations) {
|
|
12747
|
+
var needsRebuild = false;
|
|
12748
|
+
var needsSelectionSync = false;
|
|
12749
|
+
for (var _i = 0, mutations_1 = mutations; _i < mutations_1.length; _i++) {
|
|
12750
|
+
var mutation = mutations_1[_i];
|
|
12751
|
+
if (mutation.type === 'childList') {
|
|
12752
|
+
// Option(s) added or removed
|
|
12753
|
+
needsRebuild = true;
|
|
12754
|
+
}
|
|
12755
|
+
else if (mutation.type === 'attributes' && mutation.target instanceof HTMLOptionElement) {
|
|
12756
|
+
if (mutation.attributeName === 'selected') {
|
|
12757
|
+
needsSelectionSync = true;
|
|
12758
|
+
}
|
|
12759
|
+
}
|
|
12760
|
+
}
|
|
12761
|
+
if (needsRebuild) {
|
|
12762
|
+
// Rebuild the custom dropdown options
|
|
12763
|
+
_this._rebuildOptionsFromNative();
|
|
12764
|
+
}
|
|
12765
|
+
if (needsSelectionSync) {
|
|
12766
|
+
_this._syncSelectionFromNative();
|
|
12767
|
+
}
|
|
12768
|
+
});
|
|
12769
|
+
this._mutationObserver.observe(this._element, {
|
|
12770
|
+
childList: true,
|
|
12771
|
+
attributes: true,
|
|
12772
|
+
subtree: true,
|
|
12773
|
+
attributeFilter: ['selected'],
|
|
12774
|
+
});
|
|
12775
|
+
};
|
|
12776
|
+
KTSelect.prototype._rebuildOptionsFromNative = function () {
|
|
12777
|
+
var _this = this;
|
|
12778
|
+
// Remove and rebuild the custom dropdown options from the native select
|
|
12779
|
+
if (this._dropdownContentElement) {
|
|
12780
|
+
var optionsContainer_1 = this._dropdownContentElement.querySelector('[data-kt-select-options]');
|
|
12781
|
+
if (optionsContainer_1) {
|
|
12782
|
+
optionsContainer_1.innerHTML = '';
|
|
12783
|
+
var options = Array.from(this._element.querySelectorAll('option'));
|
|
12784
|
+
options.forEach(function (optionElement) {
|
|
12785
|
+
if (optionElement.value === '' &&
|
|
12786
|
+
optionElement.textContent.trim() === '') {
|
|
12787
|
+
return;
|
|
12788
|
+
}
|
|
12789
|
+
var selectOption = new option_1.KTSelectOption(optionElement, _this._config);
|
|
12790
|
+
var renderedOption = selectOption.render();
|
|
12791
|
+
optionsContainer_1.appendChild(renderedOption);
|
|
12792
|
+
});
|
|
12793
|
+
// Update internal references
|
|
12794
|
+
this._options = this._wrapperElement.querySelectorAll('[data-kt-select-option]');
|
|
12795
|
+
}
|
|
12796
|
+
}
|
|
12797
|
+
// Sync selection after rebuilding
|
|
12798
|
+
this._syncSelectionFromNative();
|
|
12799
|
+
this.updateSelectedOptionDisplay();
|
|
12800
|
+
this._updateSelectedOptionClass();
|
|
12801
|
+
};
|
|
12802
|
+
KTSelect.prototype._syncSelectionFromNative = function () {
|
|
12803
|
+
// Sync internal state from the native select's selected options
|
|
12804
|
+
var selected = Array.from(this._element.querySelectorAll('option:checked')).map(function (opt) { return opt.value; });
|
|
12805
|
+
this._state.setSelectedOptions(this._config.multiple ? selected : selected[0] || '');
|
|
12806
|
+
this.updateSelectedOptionDisplay();
|
|
12807
|
+
this._updateSelectedOptionClass();
|
|
12808
|
+
};
|
|
12652
12809
|
/**
|
|
12653
12810
|
* ========================================================================
|
|
12654
12811
|
* STATIC METHODS
|
|
@@ -14564,32 +14721,6 @@ var KTSelectTags = /** @class */ (function () {
|
|
|
14564
14721
|
wrapper.insertBefore(tag, _this._valueDisplayElement);
|
|
14565
14722
|
});
|
|
14566
14723
|
};
|
|
14567
|
-
/**
|
|
14568
|
-
* Get the label/text for an option by its value
|
|
14569
|
-
*/
|
|
14570
|
-
KTSelectTags.prototype._getOptionLabel = function (optionValue) {
|
|
14571
|
-
var _a, _b;
|
|
14572
|
-
// First look for an option element in the dropdown with matching value
|
|
14573
|
-
var optionElements = this._select.getOptionsElement();
|
|
14574
|
-
for (var _i = 0, _c = Array.from(optionElements); _i < _c.length; _i++) {
|
|
14575
|
-
var option = _c[_i];
|
|
14576
|
-
if (option.dataset.value === optionValue) {
|
|
14577
|
-
return ((_a = option.textContent) === null || _a === void 0 ? void 0 : _a.trim()) || optionValue;
|
|
14578
|
-
}
|
|
14579
|
-
}
|
|
14580
|
-
// If not found in dropdown, look in original select element
|
|
14581
|
-
var originalOptions = this._select
|
|
14582
|
-
.getElement()
|
|
14583
|
-
.querySelectorAll('option');
|
|
14584
|
-
for (var _d = 0, _e = Array.from(originalOptions); _d < _e.length; _d++) {
|
|
14585
|
-
var option = _e[_d];
|
|
14586
|
-
if (option.value === optionValue) {
|
|
14587
|
-
return ((_b = option.textContent) === null || _b === void 0 ? void 0 : _b.trim()) || optionValue;
|
|
14588
|
-
}
|
|
14589
|
-
}
|
|
14590
|
-
// If still not found, return the value itself
|
|
14591
|
-
return optionValue;
|
|
14592
|
-
};
|
|
14593
14724
|
/**
|
|
14594
14725
|
* Remove a tag and its selection
|
|
14595
14726
|
*/
|
|
@@ -15451,30 +15582,6 @@ var KTDom = {
|
|
|
15451
15582
|
}
|
|
15452
15583
|
return attributes;
|
|
15453
15584
|
},
|
|
15454
|
-
getDataAttributesByJson: function (element, prefix) {
|
|
15455
|
-
if (!element) {
|
|
15456
|
-
return {};
|
|
15457
|
-
}
|
|
15458
|
-
var rawValue = element.dataset[prefix];
|
|
15459
|
-
if (!rawValue) {
|
|
15460
|
-
return {};
|
|
15461
|
-
}
|
|
15462
|
-
var parsedValue = utils_1.default.parseDataAttribute(rawValue);
|
|
15463
|
-
if (typeof parsedValue === 'string') {
|
|
15464
|
-
try {
|
|
15465
|
-
return JSON.parse(parsedValue);
|
|
15466
|
-
}
|
|
15467
|
-
catch (e) {
|
|
15468
|
-
console.error("Invalid JSON format for '".concat(prefix, "': ").concat(e instanceof Error ? e.message : e, " ").concat(rawValue));
|
|
15469
|
-
}
|
|
15470
|
-
}
|
|
15471
|
-
// If it's already an object, return as is
|
|
15472
|
-
if (typeof parsedValue === 'object' && parsedValue !== null) {
|
|
15473
|
-
return parsedValue;
|
|
15474
|
-
}
|
|
15475
|
-
// For other types (number, boolean, null), return an empty object
|
|
15476
|
-
return {};
|
|
15477
|
-
},
|
|
15478
15585
|
ready: function (callback) {
|
|
15479
15586
|
if (document.readyState === 'loading') {
|
|
15480
15587
|
document.addEventListener('DOMContentLoaded', function () {
|
|
@@ -15492,7 +15599,7 @@ exports["default"] = KTDom;
|
|
|
15492
15599
|
/***/ }),
|
|
15493
15600
|
|
|
15494
15601
|
/***/ 9011:
|
|
15495
|
-
/***/ (function(__unused_webpack_module, exports
|
|
15602
|
+
/***/ (function(__unused_webpack_module, exports) {
|
|
15496
15603
|
|
|
15497
15604
|
|
|
15498
15605
|
/**
|
|
@@ -15500,15 +15607,12 @@ exports["default"] = KTDom;
|
|
|
15500
15607
|
* Copyright 2025 by Keenthemes Inc
|
|
15501
15608
|
*/
|
|
15502
15609
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
15503
|
-
exports.TypeToSearchBuffer = exports.EventManager = exports.FocusManager =
|
|
15610
|
+
exports.TypeToSearchBuffer = exports.EventManager = exports.FocusManager = void 0;
|
|
15504
15611
|
exports.formatCurrency = formatCurrency;
|
|
15505
15612
|
exports.filterOptions = filterOptions;
|
|
15506
|
-
exports.highlightTextInElement = highlightTextInElement;
|
|
15507
15613
|
exports.debounce = debounce;
|
|
15508
15614
|
exports.renderTemplateString = renderTemplateString;
|
|
15509
15615
|
exports.stringToElement = stringToElement;
|
|
15510
|
-
// utils.ts
|
|
15511
|
-
var templates_1 = __webpack_require__(9069);
|
|
15512
15616
|
/**
|
|
15513
15617
|
* Format a number as a currency string
|
|
15514
15618
|
*/
|
|
@@ -15522,148 +15626,50 @@ function formatCurrency(value) {
|
|
|
15522
15626
|
* Filter options based on a search query
|
|
15523
15627
|
*/
|
|
15524
15628
|
function filterOptions(options, query, config, dropdownElement, onVisibleCount) {
|
|
15525
|
-
var _a;
|
|
15526
15629
|
var visibleOptionsCount = 0;
|
|
15527
|
-
//
|
|
15528
|
-
|
|
15529
|
-
if (noResultsElement) {
|
|
15530
|
-
noResultsElement.remove();
|
|
15531
|
-
}
|
|
15532
|
-
// For empty query, ensure highlights are cleared from all options
|
|
15630
|
+
// For empty query, make all options visible
|
|
15631
|
+
// The KTSelectSearch class is now responsible for restoring original content before calling this.
|
|
15533
15632
|
if (!query || query.trim() === '') {
|
|
15534
|
-
// Just make all options visible without highlighting
|
|
15535
15633
|
for (var _i = 0, options_1 = options; _i < options_1.length; _i++) {
|
|
15536
15634
|
var option = options_1[_i];
|
|
15537
|
-
// Make option visible by removing hidden classes and inline styles
|
|
15538
15635
|
option.classList.remove('hidden');
|
|
15539
|
-
//
|
|
15540
|
-
if (option.
|
|
15541
|
-
option.
|
|
15542
|
-
var styleAttr = option.getAttribute('style');
|
|
15543
|
-
if (styleAttr.trim() === 'display: none;' ||
|
|
15544
|
-
styleAttr.trim() === 'display: block;') {
|
|
15545
|
-
option.removeAttribute('style');
|
|
15546
|
-
}
|
|
15547
|
-
else {
|
|
15548
|
-
option.setAttribute('style', styleAttr.replace(/display:\s*[^;]+;?/gi, '').trim());
|
|
15549
|
-
}
|
|
15550
|
-
}
|
|
15551
|
-
// Clear highlights by restoring original text content
|
|
15552
|
-
if (option.dataset && option.dataset.originalText) {
|
|
15553
|
-
option.innerHTML = option.dataset.originalText;
|
|
15554
|
-
}
|
|
15555
|
-
else {
|
|
15556
|
-
option.innerHTML = option.textContent || '';
|
|
15557
|
-
}
|
|
15558
|
-
// Remove the cache if present
|
|
15559
|
-
if (option.dataset && option.dataset.originalText) {
|
|
15560
|
-
delete option.dataset.originalText;
|
|
15636
|
+
// Remove inline display style if it was used to hide
|
|
15637
|
+
if (option.style.display === 'none') {
|
|
15638
|
+
option.style.display = '';
|
|
15561
15639
|
}
|
|
15640
|
+
// At this point, option.innerHTML should be its original.
|
|
15562
15641
|
visibleOptionsCount++;
|
|
15563
15642
|
}
|
|
15564
|
-
// Call the callback with the visible count if provided
|
|
15565
15643
|
if (onVisibleCount) {
|
|
15566
15644
|
onVisibleCount(visibleOptionsCount);
|
|
15567
15645
|
}
|
|
15568
15646
|
return visibleOptionsCount;
|
|
15569
15647
|
}
|
|
15570
|
-
|
|
15571
|
-
for (var
|
|
15572
|
-
var option = options_2[
|
|
15573
|
-
|
|
15574
|
-
var
|
|
15575
|
-
|
|
15576
|
-
|
|
15577
|
-
if (isMatch || query.trim() === '') {
|
|
15578
|
-
// Show option by removing the hidden class and any display inline styles
|
|
15648
|
+
var queryLower = query.toLowerCase();
|
|
15649
|
+
for (var _a = 0, options_2 = options; _a < options_2.length; _a++) {
|
|
15650
|
+
var option = options_2[_a];
|
|
15651
|
+
// Use data-text for matching if available, otherwise fall back to textContent
|
|
15652
|
+
var optionText = (option.dataset.text || option.textContent || '').toLowerCase();
|
|
15653
|
+
var isMatch = optionText.includes(queryLower);
|
|
15654
|
+
if (isMatch) {
|
|
15579
15655
|
option.classList.remove('hidden');
|
|
15580
|
-
|
|
15581
|
-
|
|
15582
|
-
option.getAttribute('style').includes('display:')) {
|
|
15583
|
-
var styleAttr = option.getAttribute('style');
|
|
15584
|
-
if (styleAttr.trim() === 'display: none;' ||
|
|
15585
|
-
styleAttr.trim() === 'display: block;') {
|
|
15586
|
-
option.removeAttribute('style');
|
|
15587
|
-
}
|
|
15588
|
-
else {
|
|
15589
|
-
option.setAttribute('style', styleAttr.replace(/display:\s*[^;]+;?/gi, '').trim());
|
|
15590
|
-
}
|
|
15591
|
-
}
|
|
15656
|
+
if (option.style.display === 'none')
|
|
15657
|
+
option.style.display = ''; // Ensure visible
|
|
15592
15658
|
visibleOptionsCount++;
|
|
15593
|
-
if (config.searchHighlight && query.trim() !== '') {
|
|
15594
|
-
if (option.dataset && !option.dataset.originalText) {
|
|
15595
|
-
option.dataset.originalText = option.innerHTML;
|
|
15596
|
-
}
|
|
15597
|
-
(0, exports.highlightTextInElementDebounced)(option, query, config);
|
|
15598
|
-
}
|
|
15599
15659
|
}
|
|
15600
15660
|
else {
|
|
15601
|
-
// Hide option using hidden class
|
|
15602
15661
|
option.classList.add('hidden');
|
|
15603
|
-
// Remove any inline display styles
|
|
15604
|
-
if (option.hasAttribute('style') &&
|
|
15605
|
-
option.getAttribute('style').includes('display:')) {
|
|
15606
|
-
var styleAttr = option.getAttribute('style');
|
|
15607
|
-
if (styleAttr.trim() === 'display: none;' ||
|
|
15608
|
-
styleAttr.trim() === 'display: block;') {
|
|
15609
|
-
option.removeAttribute('style');
|
|
15610
|
-
}
|
|
15611
|
-
else {
|
|
15612
|
-
option.setAttribute('style', styleAttr.replace(/display:\s*[^;]+;?/gi, '').trim());
|
|
15613
|
-
}
|
|
15614
|
-
}
|
|
15615
|
-
}
|
|
15616
|
-
// Early exit if maxItems limit is reached
|
|
15617
|
-
if (config.searchMaxItems && visibleOptionsCount >= config.searchMaxItems) {
|
|
15618
|
-
break;
|
|
15619
15662
|
}
|
|
15663
|
+
// Early exit if maxItems limit is reached (optional)
|
|
15664
|
+
// if (config.searchMaxItems && visibleOptionsCount >= config.searchMaxItems) {
|
|
15665
|
+
// break;
|
|
15666
|
+
// }
|
|
15620
15667
|
}
|
|
15621
|
-
// Call the callback with the visible count if provided
|
|
15622
15668
|
if (onVisibleCount) {
|
|
15623
15669
|
onVisibleCount(visibleOptionsCount);
|
|
15624
15670
|
}
|
|
15625
15671
|
return visibleOptionsCount;
|
|
15626
15672
|
}
|
|
15627
|
-
/**
|
|
15628
|
-
* Highlight text only within a specific element, preserving other elements
|
|
15629
|
-
*/
|
|
15630
|
-
function highlightTextInElement(element, query, config) {
|
|
15631
|
-
if (!element || !query || query.trim() === '')
|
|
15632
|
-
return;
|
|
15633
|
-
var queryLower = query.toLowerCase();
|
|
15634
|
-
var text = element.textContent || '';
|
|
15635
|
-
if (!text)
|
|
15636
|
-
return;
|
|
15637
|
-
// Escape regex special characters in query
|
|
15638
|
-
var escapedQuery = query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
15639
|
-
var regex = new RegExp(escapedQuery, 'gi');
|
|
15640
|
-
// Replace all matches with the highlight template
|
|
15641
|
-
var lastIndex = 0;
|
|
15642
|
-
var result = '';
|
|
15643
|
-
var match;
|
|
15644
|
-
var matches = [];
|
|
15645
|
-
while ((match = regex.exec(text)) !== null) {
|
|
15646
|
-
matches.push({ start: match.index, end: regex.lastIndex });
|
|
15647
|
-
}
|
|
15648
|
-
if (matches.length === 0) {
|
|
15649
|
-
element.innerHTML = text;
|
|
15650
|
-
return;
|
|
15651
|
-
}
|
|
15652
|
-
for (var i = 0; i < matches.length; i++) {
|
|
15653
|
-
var _a = matches[i], start = _a.start, end = _a.end;
|
|
15654
|
-
// Add text before match
|
|
15655
|
-
result += text.slice(lastIndex, start);
|
|
15656
|
-
// Add highlighted match using template
|
|
15657
|
-
var highlighted = templates_1.defaultTemplates.highlight(config, text.slice(start, end)).outerHTML;
|
|
15658
|
-
result += highlighted;
|
|
15659
|
-
lastIndex = end;
|
|
15660
|
-
}
|
|
15661
|
-
// Add remaining text
|
|
15662
|
-
result += text.slice(lastIndex);
|
|
15663
|
-
element.innerHTML = result;
|
|
15664
|
-
}
|
|
15665
|
-
// Debounced version for performance
|
|
15666
|
-
exports.highlightTextInElementDebounced = debounce(highlightTextInElement, 100);
|
|
15667
15673
|
/**
|
|
15668
15674
|
* Focus manager for keyboard navigation
|
|
15669
15675
|
* Consolidates redundant focus management logic into shared functions
|
|
@@ -15765,6 +15771,7 @@ var FocusManager = /** @class */ (function () {
|
|
|
15765
15771
|
if (!option.classList.contains('disabled') &&
|
|
15766
15772
|
option.getAttribute('aria-disabled') !== 'true' &&
|
|
15767
15773
|
(((_b = option.textContent) === null || _b === void 0 ? void 0 : _b.toLowerCase().startsWith(lowerStr)) || ((_c = option.dataset.value) === null || _c === void 0 ? void 0 : _c.toLowerCase().startsWith(lowerStr)))) {
|
|
15774
|
+
this.resetFocus();
|
|
15768
15775
|
this._focusedOptionIndex = idx;
|
|
15769
15776
|
this.applyFocus(option);
|
|
15770
15777
|
this.scrollIntoView(option);
|
|
@@ -15823,12 +15830,14 @@ var FocusManager = /** @class */ (function () {
|
|
|
15823
15830
|
FocusManager.prototype.applyFocus = function (option) {
|
|
15824
15831
|
if (!option)
|
|
15825
15832
|
return;
|
|
15833
|
+
// Ensure it's not disabled
|
|
15826
15834
|
if (option.classList.contains('disabled') || option.getAttribute('aria-disabled') === 'true') {
|
|
15827
15835
|
return;
|
|
15828
15836
|
}
|
|
15829
|
-
|
|
15837
|
+
// DO NOT CALL resetFocus() here. Caller's responsibility.
|
|
15830
15838
|
option.classList.add(this._focusClass);
|
|
15831
15839
|
option.classList.add(this._hoverClass);
|
|
15840
|
+
// _triggerFocusChange needs _focusedOptionIndex to be set by the caller before this.
|
|
15832
15841
|
this._triggerFocusChange();
|
|
15833
15842
|
};
|
|
15834
15843
|
/**
|
|
@@ -15841,12 +15850,7 @@ var FocusManager = /** @class */ (function () {
|
|
|
15841
15850
|
focusedElements.forEach(function (element) {
|
|
15842
15851
|
element.classList.remove(_this._focusClass, _this._hoverClass);
|
|
15843
15852
|
});
|
|
15844
|
-
|
|
15845
|
-
var visibleOptions = this.getVisibleOptions();
|
|
15846
|
-
if (this._focusedOptionIndex !== null &&
|
|
15847
|
-
this._focusedOptionIndex >= visibleOptions.length) {
|
|
15848
|
-
this._focusedOptionIndex = null;
|
|
15849
|
-
}
|
|
15853
|
+
this._focusedOptionIndex = null; // Always reset the index
|
|
15850
15854
|
};
|
|
15851
15855
|
/**
|
|
15852
15856
|
* Ensure the focused option is visible in the scrollable container
|
|
@@ -15875,10 +15879,14 @@ var FocusManager = /** @class */ (function () {
|
|
|
15875
15879
|
var options = this.getVisibleOptions();
|
|
15876
15880
|
var index = options.findIndex(function (option) { return option.dataset.value === value; });
|
|
15877
15881
|
if (index >= 0) {
|
|
15878
|
-
|
|
15879
|
-
|
|
15880
|
-
|
|
15881
|
-
|
|
15882
|
+
var optionToFocus = options[index];
|
|
15883
|
+
if (!optionToFocus.classList.contains('disabled') && optionToFocus.getAttribute('aria-disabled') !== 'true') {
|
|
15884
|
+
this.resetFocus();
|
|
15885
|
+
this._focusedOptionIndex = index;
|
|
15886
|
+
this.applyFocus(optionToFocus);
|
|
15887
|
+
this.scrollIntoView(optionToFocus);
|
|
15888
|
+
return true;
|
|
15889
|
+
}
|
|
15882
15890
|
}
|
|
15883
15891
|
return false;
|
|
15884
15892
|
};
|
|
@@ -16095,20 +16103,19 @@ var utils_1 = __webpack_require__(9011);
|
|
|
16095
16103
|
* Users can override any template by providing a matching key in the config.templates object.
|
|
16096
16104
|
*/
|
|
16097
16105
|
exports.coreTemplateStrings = {
|
|
16098
|
-
dropdown: "<div data-kt-select-dropdown class=\"kt-select-dropdown hidden {{class}}\" style=\"z-index: {{zindex}};\"
|
|
16099
|
-
options: "<ul role=\"listbox\" aria-label=\"{{label}}\" class=\"kt-select-options {{class}}\" data-kt-select-options=\"true\"
|
|
16100
|
-
error: "<li class=\"kt-select-error\" role=\"alert\"
|
|
16101
|
-
highlight: "<span data-kt-select-highlight class=\"kt-select-highlight highlighted {{class}}\">{{text}}</span>",
|
|
16106
|
+
dropdown: "<div data-kt-select-dropdown class=\"kt-select-dropdown hidden {{class}}\" style=\"z-index: {{zindex}};\"></div>",
|
|
16107
|
+
options: "<ul role=\"listbox\" aria-label=\"{{label}}\" class=\"kt-select-options {{class}}\" data-kt-select-options=\"true\"></ul>",
|
|
16108
|
+
error: "<li class=\"kt-select-error\" role=\"alert\"></li>",
|
|
16102
16109
|
wrapper: "<div data-kt-select-wrapper class=\"kt-select-wrapper {{class}}\"></div>",
|
|
16103
|
-
combobox: "\n\t\t<div data-kt-select-combobox data-kt-select-display class=\"kt-select-combobox {{class}}\">\n\t\t\t<
|
|
16104
|
-
|
|
16105
|
-
|
|
16106
|
-
option: "<li data-kt-select-option data-value=\"{{value}}\" data-text=\"{{text}}\" class=\"kt-select-option {{class}}\" role=\"option\" {{selected}} {{disabled}}>{{
|
|
16107
|
-
search: "<div data-kt-select-search class=\"kt-select-search {{class}}\"><input type=\"text\" data-kt-select-search=\"true\" placeholder=\"{{searchPlaceholder}}\" class=\"kt-input kt-
|
|
16108
|
-
empty: "<li data-kt-select-empty class=\"kt-select-no-result {{class}}\" role=\"status\"
|
|
16109
|
-
loading: "<li class=\"kt-select-loading {{class}}\" role=\"status\" aria-live=\"polite\"
|
|
16110
|
-
tag: "<div data-kt-select-tag=\"true\" class=\"kt-select-tag {{class}}\"
|
|
16111
|
-
loadMore: "<li class=\"kt-select-load-more {{class}}\" data-kt-select-load-more=\"true\"
|
|
16110
|
+
combobox: "\n\t\t<div data-kt-select-combobox data-kt-select-display class=\"kt-select-combobox {{class}}\">\n\t\t\t<div data-kt-select-combobox-values=\"true\" class=\"kt-select-combobox-values\"></div>\n\t\t\t<input class=\"kt-input kt-select-combobox-input\" data-kt-select-search=\"true\" type=\"text\" placeholder=\"{{placeholder}}\" role=\"searchbox\" aria-label=\"{{label}}\" {{disabled}} />\n\t\t\t<button type=\"button\" data-kt-select-clear-button=\"true\" class=\"kt-select-combobox-clear-btn\" aria-label=\"Clear selection\">\n\t\t\t\t<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n\t\t\t\t\t<line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n\t\t\t\t\t<line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n\t\t\t\t</svg>\n\t\t\t</button>\n\t\t</div>\n\t",
|
|
16111
|
+
placeholder: "<div data-kt-select-placeholder class=\"kt-select-placeholder {{class}}\"></div>",
|
|
16112
|
+
display: "\n\t\t<div data-kt-select-display class=\"kt-select-display {{class}}\" tabindex=\"{{tabindex}}\" role=\"button\" data-selected=\"0\" aria-haspopup=\"listbox\" aria-expanded=\"false\" aria-label=\"{{label}}\" {{disabled}}>\n\t\t\t<div class=\"kt-select-option-text\" data-kt-text-container=\"true\">{{text}}</div>\n\t\t</div>\n\t",
|
|
16113
|
+
option: "\n\t\t<li data-kt-select-option data-value=\"{{value}}\" data-text=\"{{text}}\" class=\"kt-select-option {{class}}\" role=\"option\" {{selected}} {{disabled}}>\n\t\t\t<div class=\"kt-select-option-text\" data-kt-text-container=\"true\">{{text}}</div><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"size-3.5 ms-auto hidden text-primary kt-select-option-selected:block\"><path d=\"M20 6 9 17l-5-5\"/></svg>\n\t\t</li>\n\t",
|
|
16114
|
+
search: "<div data-kt-select-search class=\"kt-select-search {{class}}\"><input type=\"text\" data-kt-select-search=\"true\" placeholder=\"{{searchPlaceholder}}\" class=\"kt-input kt-input-ghost\" role=\"searchbox\" aria-label=\"{{searchPlaceholder}}\"/></div>",
|
|
16115
|
+
empty: "<li data-kt-select-empty class=\"kt-select-no-result {{class}}\" role=\"status\"></li>",
|
|
16116
|
+
loading: "<li class=\"kt-select-loading {{class}}\" role=\"status\" aria-live=\"polite\"></li>",
|
|
16117
|
+
tag: "<div data-kt-select-tag=\"true\" class=\"kt-select-tag {{class}}\"></div>",
|
|
16118
|
+
loadMore: "<li class=\"kt-select-load-more {{class}}\" data-kt-select-load-more=\"true\"></li>",
|
|
16112
16119
|
tagRemoveButton: "<button type=\"button\" data-kt-select-remove-button class=\"kt-select-tag-remove\" aria-label=\"Remove tag\" tabindex=\"0\"><svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><line x1=\"3\" y1=\"3\" x2=\"9\" y2=\"9\"/><line x1=\"9\" y1=\"3\" x2=\"3\" y2=\"9\"/></svg></button>",
|
|
16113
16120
|
};
|
|
16114
16121
|
/**
|
|
@@ -16147,30 +16154,31 @@ function getTemplateStrings(config) {
|
|
|
16147
16154
|
* Default templates for KTSelect component
|
|
16148
16155
|
*/
|
|
16149
16156
|
exports.defaultTemplates = {
|
|
16150
|
-
/**
|
|
16151
|
-
* Renders a highlighted text
|
|
16152
|
-
*/
|
|
16153
|
-
highlight: function (config, text) {
|
|
16154
|
-
var template = getTemplateStrings(config).highlight;
|
|
16155
|
-
var html = template.replace('{{text}}', text).replace('{{class}}', config.highlightClass || '');
|
|
16156
|
-
return stringToElement(html);
|
|
16157
|
-
},
|
|
16158
16157
|
/**
|
|
16159
16158
|
* Renders the dropdown content
|
|
16160
16159
|
*/
|
|
16161
16160
|
dropdown: function (config) {
|
|
16161
|
+
var _a;
|
|
16162
16162
|
var template = getTemplateStrings(config).dropdown;
|
|
16163
|
-
|
|
16163
|
+
// If a custom dropdownTemplate is provided, it's responsible for its own content.
|
|
16164
|
+
// Otherwise, the base template is used, and content is appended later.
|
|
16164
16165
|
if (config.dropdownTemplate) {
|
|
16165
|
-
|
|
16166
|
+
var renderedCustomTemplate = (0, utils_1.renderTemplateString)(config.dropdownTemplate, {
|
|
16166
16167
|
zindex: config.zindex ? String(config.zindex) : '',
|
|
16167
|
-
content: config.content || '',
|
|
16168
|
+
// content: config.content || '', // No longer pass content to custom template directly here
|
|
16168
16169
|
class: config.dropdownClass || '',
|
|
16169
16170
|
});
|
|
16171
|
+
// The custom template IS the dropdown element
|
|
16172
|
+
var customDropdownEl = stringToElement(renderedCustomTemplate);
|
|
16173
|
+
if (config.zindex)
|
|
16174
|
+
customDropdownEl.style.zIndex = String(config.zindex);
|
|
16175
|
+
if (config.dropdownClass)
|
|
16176
|
+
(_a = customDropdownEl.classList).add.apply(_a, config.dropdownClass.split(' '));
|
|
16177
|
+
return customDropdownEl;
|
|
16170
16178
|
}
|
|
16171
16179
|
var html = template
|
|
16172
16180
|
.replace('{{zindex}}', config.zindex ? String(config.zindex) : '')
|
|
16173
|
-
.replace('{{content}}',
|
|
16181
|
+
// .replace('{{content}}', '') // Content is no longer part of the base template string
|
|
16174
16182
|
.replace('{{class}}', config.dropdownClass || '');
|
|
16175
16183
|
return stringToElement(html);
|
|
16176
16184
|
},
|
|
@@ -16182,7 +16190,7 @@ exports.defaultTemplates = {
|
|
|
16182
16190
|
var html = template
|
|
16183
16191
|
.replace('{{label}}', config.label || 'Options')
|
|
16184
16192
|
.replace('{{height}}', config.height ? String(config.height) : '250')
|
|
16185
|
-
.replace('{{options}}',
|
|
16193
|
+
// .replace('{{options}}', '') // Options are now appended dynamically
|
|
16186
16194
|
.replace('{{class}}', config.optionsClass || '');
|
|
16187
16195
|
return stringToElement(html);
|
|
16188
16196
|
},
|
|
@@ -16190,84 +16198,98 @@ exports.defaultTemplates = {
|
|
|
16190
16198
|
* Renders the load more button for pagination
|
|
16191
16199
|
*/
|
|
16192
16200
|
loadMore: function (config) {
|
|
16193
|
-
var html = getTemplateStrings(config)
|
|
16194
|
-
|
|
16201
|
+
var html = getTemplateStrings(config)
|
|
16202
|
+
.loadMore // .replace('{{loadMoreText}}', config.loadMoreText || 'Load more...') // Content is no longer in template string
|
|
16203
|
+
.replace('{{class}}', config.loadMoreClass || '');
|
|
16204
|
+
var element = stringToElement(html);
|
|
16205
|
+
element.textContent = config.loadMoreText || 'Load more...';
|
|
16206
|
+
return element;
|
|
16195
16207
|
},
|
|
16196
16208
|
/**
|
|
16197
16209
|
* Renders an error message in the dropdown
|
|
16198
16210
|
*/
|
|
16199
16211
|
error: function (config) {
|
|
16212
|
+
// Changed return type to HTMLElement
|
|
16200
16213
|
var template = getTemplateStrings(config).error;
|
|
16201
|
-
|
|
16202
|
-
.replace('{{errorMessage}}', config.errorMessage || 'An error occurred')
|
|
16214
|
+
var html = template
|
|
16215
|
+
// .replace('{{errorMessage}}', config.errorMessage || 'An error occurred') // Content is no longer in template string
|
|
16203
16216
|
.replace('{{class}}', config.errorClass || '');
|
|
16217
|
+
var element = stringToElement(html);
|
|
16218
|
+
element.textContent = config.errorMessage || 'An error occurred';
|
|
16219
|
+
return element;
|
|
16204
16220
|
},
|
|
16205
16221
|
/**
|
|
16206
16222
|
* Renders the main container for the select component
|
|
16207
16223
|
*/
|
|
16208
16224
|
wrapper: function (config) {
|
|
16209
|
-
var html = getTemplateStrings(config).wrapper
|
|
16210
|
-
.replace('{{class}}', config.wrapperClass || '');
|
|
16225
|
+
var html = getTemplateStrings(config).wrapper.replace('{{class}}', config.wrapperClass || '');
|
|
16211
16226
|
var element = stringToElement(html);
|
|
16212
|
-
element.setAttribute('data-kt-select-combobox', config.combobox ? 'true' : 'false');
|
|
16213
|
-
element.setAttribute('data-kt-select-tags', config.tags ? 'true' : 'false');
|
|
16214
16227
|
return element;
|
|
16215
16228
|
},
|
|
16216
16229
|
/**
|
|
16217
16230
|
* Renders the display element (trigger) for the select
|
|
16218
16231
|
*/
|
|
16219
16232
|
display: function (config) {
|
|
16220
|
-
|
|
16221
|
-
|
|
16222
|
-
.combobox.replace(/{{placeholder}}/g, config.placeholder || 'Select...')
|
|
16223
|
-
.replace(/{{label}}/g, config.label || config.placeholder || 'Select...')
|
|
16224
|
-
.replace('{{disabled}}', config.disabled ? 'disabled' : '')
|
|
16225
|
-
.replace('{{class}}', config.displayClass || '');
|
|
16226
|
-
return stringToElement(html_1);
|
|
16227
|
-
}
|
|
16228
|
-
var content = config.label || config.placeholder || 'Select...';
|
|
16229
|
-
var html = getTemplateStrings(config).display
|
|
16230
|
-
.replace('{{tabindex}}', config.disabled ? '-1' : '0')
|
|
16233
|
+
var html = getTemplateStrings(config)
|
|
16234
|
+
.display.replace('{{tabindex}}', config.disabled ? '-1' : '0')
|
|
16231
16235
|
.replace('{{label}}', config.label || config.placeholder || 'Select...')
|
|
16232
16236
|
.replace('{{disabled}}', config.disabled ? 'aria-disabled="true"' : '')
|
|
16233
16237
|
.replace('{{placeholder}}', config.placeholder || 'Select...')
|
|
16234
|
-
.replace('{{class}}', config.displayClass || '')
|
|
16235
|
-
|
|
16236
|
-
|
|
16238
|
+
.replace('{{class}}', config.displayClass || '');
|
|
16239
|
+
var element = stringToElement(html);
|
|
16240
|
+
// Add data-multiple attribute if in multiple select mode
|
|
16241
|
+
if (config.multiple) {
|
|
16242
|
+
element.setAttribute('data-multiple', 'true');
|
|
16243
|
+
}
|
|
16244
|
+
return element;
|
|
16237
16245
|
},
|
|
16238
16246
|
/**
|
|
16239
16247
|
* Renders a single option
|
|
16240
16248
|
*/
|
|
16241
16249
|
option: function (option, config) {
|
|
16250
|
+
var _a, _b;
|
|
16242
16251
|
var isHtmlOption = option instanceof HTMLOptionElement;
|
|
16243
|
-
var
|
|
16244
|
-
|
|
16245
|
-
|
|
16246
|
-
|
|
16247
|
-
|
|
16248
|
-
|
|
16249
|
-
?
|
|
16250
|
-
|
|
16251
|
-
|
|
16252
|
+
var optionData;
|
|
16253
|
+
if (isHtmlOption) {
|
|
16254
|
+
// If it's a plain HTMLOptionElement, construct data similarly to how KTSelectOption would
|
|
16255
|
+
// This branch might be less common if KTSelectOption instances are always used for rendering.
|
|
16256
|
+
var el = option;
|
|
16257
|
+
var textContent = el.textContent || '';
|
|
16258
|
+
optionData = __assign({ value: el.value, text: textContent, selected: el.selected, disabled: el.disabled, content: textContent }, (((_a = config.optionsConfig) === null || _a === void 0 ? void 0 : _a[el.value]) || {}));
|
|
16259
|
+
}
|
|
16260
|
+
else {
|
|
16261
|
+
// If it's a KTSelectOption class instance (from './option')
|
|
16262
|
+
// which should have the getOptionDataForTemplate method.
|
|
16263
|
+
optionData = option.getOptionDataForTemplate();
|
|
16264
|
+
}
|
|
16265
|
+
var content = optionData.text; // Default content to option's text
|
|
16252
16266
|
if (config.optionTemplate) {
|
|
16253
|
-
// Use the user template
|
|
16254
|
-
|
|
16255
|
-
|
|
16256
|
-
text: text,
|
|
16257
|
-
class: config.optionClass || '',
|
|
16258
|
-
selected: selected ? 'aria-selected="true"' : 'aria-selected="false"',
|
|
16259
|
-
disabled: disabled ? 'aria-disabled="true"' : '',
|
|
16260
|
-
content: text,
|
|
16261
|
-
});
|
|
16267
|
+
// Use the user-provided template string, rendering with the full optionData.
|
|
16268
|
+
// renderTemplateString will replace {{key}} with values from optionData.
|
|
16269
|
+
content = (0, utils_1.renderTemplateString)(config.optionTemplate, optionData);
|
|
16262
16270
|
}
|
|
16263
|
-
|
|
16264
|
-
.
|
|
16265
|
-
|
|
16266
|
-
|
|
16267
|
-
|
|
16268
|
-
|
|
16269
|
-
|
|
16270
|
-
|
|
16271
|
+
else {
|
|
16272
|
+
content = optionData.text || optionData.content; // Prefer explicit text, fallback to content
|
|
16273
|
+
}
|
|
16274
|
+
// Use the core option template string as the base structure.
|
|
16275
|
+
var baseTemplate = getTemplateStrings(config).option;
|
|
16276
|
+
var optionClasses = [config.optionClass || ''];
|
|
16277
|
+
if (optionData.disabled) {
|
|
16278
|
+
optionClasses.push('disabled');
|
|
16279
|
+
}
|
|
16280
|
+
// Populate the base template for the <li> attributes.
|
|
16281
|
+
// The actual display content (text or custom HTML) will be set on the inner span later.
|
|
16282
|
+
var html = (0, utils_1.renderTemplateString)(baseTemplate, __assign(__assign({}, optionData), { class: optionClasses.join(' ').trim() || '', selected: optionData.selected
|
|
16283
|
+
? 'aria-selected="true"'
|
|
16284
|
+
: 'aria-selected="false"', disabled: optionData.disabled ? 'aria-disabled="true"' : '', content: content }));
|
|
16285
|
+
var element = stringToElement(html);
|
|
16286
|
+
// If a custom option template is provided, replace the element's innerHTML with the content.
|
|
16287
|
+
if (config.optionTemplate) {
|
|
16288
|
+
element.innerHTML = content;
|
|
16289
|
+
}
|
|
16290
|
+
// Ensure data-text attribute is set to the original, clean text for searching/filtering
|
|
16291
|
+
element.setAttribute('data-text', ((_b = optionData === null || optionData === void 0 ? void 0 : optionData.text) === null || _b === void 0 ? void 0 : _b.trim()) || '');
|
|
16292
|
+
return element;
|
|
16271
16293
|
},
|
|
16272
16294
|
/**
|
|
16273
16295
|
* Renders the search input
|
|
@@ -16282,68 +16304,79 @@ exports.defaultTemplates = {
|
|
|
16282
16304
|
* Renders the no results message
|
|
16283
16305
|
*/
|
|
16284
16306
|
empty: function (config) {
|
|
16285
|
-
var html = getTemplateStrings(config)
|
|
16286
|
-
|
|
16287
|
-
|
|
16288
|
-
return
|
|
16307
|
+
var html = getTemplateStrings(config).empty.replace('{{class}}', config.emptyClass || '');
|
|
16308
|
+
var element = stringToElement(html);
|
|
16309
|
+
element.textContent = config.searchNotFoundText || 'No results found';
|
|
16310
|
+
return element;
|
|
16289
16311
|
},
|
|
16290
16312
|
/**
|
|
16291
16313
|
* Renders the loading state
|
|
16292
16314
|
*/
|
|
16293
16315
|
loading: function (config, loadingMessage) {
|
|
16294
|
-
var html = getTemplateStrings(config)
|
|
16295
|
-
|
|
16296
|
-
|
|
16297
|
-
return
|
|
16316
|
+
var html = getTemplateStrings(config).loading.replace('{{class}}', config.loadingClass || '');
|
|
16317
|
+
var element = stringToElement(html);
|
|
16318
|
+
element.textContent = loadingMessage || 'Loading options...';
|
|
16319
|
+
return element;
|
|
16298
16320
|
},
|
|
16299
16321
|
/**
|
|
16300
16322
|
* Renders a tag for multi-select
|
|
16301
16323
|
*/
|
|
16302
16324
|
tag: function (option, config) {
|
|
16325
|
+
var _a;
|
|
16303
16326
|
var template = getTemplateStrings(config).tag;
|
|
16304
|
-
var
|
|
16327
|
+
var preparedContent = option.title; // Default content is the option's title
|
|
16305
16328
|
if (config.tagTemplate) {
|
|
16306
|
-
var
|
|
16307
|
-
var
|
|
16308
|
-
|
|
16309
|
-
|
|
16310
|
-
|
|
16311
|
-
|
|
16312
|
-
|
|
16313
|
-
|
|
16329
|
+
var tagTemplateString_1 = config.tagTemplate;
|
|
16330
|
+
var optionValue = option.getAttribute('data-value') || option.value;
|
|
16331
|
+
// Replace all {{varname}} in option.innerHTML with values from _config.optionsConfig
|
|
16332
|
+
Object.entries(((_a = config.optionsConfig) === null || _a === void 0 ? void 0 : _a[optionValue]) || {}).forEach(function (_a) {
|
|
16333
|
+
var key = _a[0], val = _a[1];
|
|
16334
|
+
if (typeof val === 'string' ||
|
|
16335
|
+
typeof val === 'number' ||
|
|
16336
|
+
typeof val === 'boolean') {
|
|
16337
|
+
tagTemplateString_1 = tagTemplateString_1.replace(new RegExp("{{".concat(key, "}}"), 'g'), String(val));
|
|
16314
16338
|
}
|
|
16315
16339
|
});
|
|
16316
|
-
|
|
16340
|
+
// Render the custom tag template with option data
|
|
16341
|
+
preparedContent = (0, utils_1.renderTemplateString)(tagTemplateString_1, {
|
|
16317
16342
|
title: option.title,
|
|
16318
16343
|
id: option.id,
|
|
16319
|
-
class: config.tagClass || '',
|
|
16320
|
-
content: option.innerHTML,
|
|
16321
|
-
text: option.innerText,
|
|
16344
|
+
class: config.tagClass || '', // This class is for content, not the main tag div
|
|
16345
|
+
// content: option.innerHTML, // Avoid direct innerHTML from option due to potential XSS
|
|
16346
|
+
text: option.innerText || option.textContent || '',
|
|
16347
|
+
value: optionValue,
|
|
16322
16348
|
});
|
|
16323
16349
|
}
|
|
16324
|
-
|
|
16350
|
+
// Append the remove button HTML string to the prepared content
|
|
16351
|
+
preparedContent += getTemplateStrings(config).tagRemoveButton;
|
|
16325
16352
|
var html = template
|
|
16326
|
-
.replace('{{title}}', option.title)
|
|
16327
|
-
.replace('{{id}}', option.id)
|
|
16328
|
-
.replace('{{
|
|
16329
|
-
|
|
16330
|
-
|
|
16353
|
+
// .replace('{{title}}', option.title) // Title is part of preparedContent if using custom template
|
|
16354
|
+
// .replace('{{id}}', option.id) // ID is part of preparedContent if using custom template
|
|
16355
|
+
.replace('{{class}}', config.tagClass || ''); // Class for the main tag div
|
|
16356
|
+
var element = stringToElement(html);
|
|
16357
|
+
element.innerHTML = preparedContent; // Set the fully prepared content (text/HTML + remove button)
|
|
16358
|
+
return element;
|
|
16331
16359
|
},
|
|
16332
16360
|
/**
|
|
16333
16361
|
* Renders the placeholder for the select
|
|
16334
16362
|
*/
|
|
16335
16363
|
placeholder: function (config) {
|
|
16336
|
-
var html = getTemplateStrings(config)
|
|
16337
|
-
.placeholder.replace('{{class}}', config.placeholderClass || '');
|
|
16364
|
+
var html = getTemplateStrings(config).placeholder.replace('{{class}}', config.placeholderClass || '');
|
|
16338
16365
|
var content = config.placeholder || 'Select...';
|
|
16339
16366
|
if (config.placeholderTemplate) {
|
|
16340
16367
|
content = (0, utils_1.renderTemplateString)(config.placeholderTemplate, {
|
|
16341
16368
|
placeholder: config.placeholder || 'Select...',
|
|
16342
16369
|
class: config.placeholderClass || '',
|
|
16343
16370
|
});
|
|
16371
|
+
var element = stringToElement(html);
|
|
16372
|
+
element.innerHTML = content; // For templates, content can be HTML
|
|
16373
|
+
return element;
|
|
16374
|
+
}
|
|
16375
|
+
else {
|
|
16376
|
+
var element = stringToElement(html);
|
|
16377
|
+
element.textContent = content; // For simple text, use textContent
|
|
16378
|
+
return element;
|
|
16344
16379
|
}
|
|
16345
|
-
html = html.replace('{{content}}', content);
|
|
16346
|
-
return stringToElement(html);
|
|
16347
16380
|
},
|
|
16348
16381
|
};
|
|
16349
16382
|
|
|
@@ -17492,9 +17525,9 @@ exports.DefaultConfig = {
|
|
|
17492
17525
|
paginationLimitParam: 'limit', // Parameter name for items per page
|
|
17493
17526
|
paginationTotalParam: 'total', // Parameter name for total items
|
|
17494
17527
|
// Selection Behavior
|
|
17528
|
+
allowClear: false, // Allow clearing the selection (if true, an empty value can be set)
|
|
17495
17529
|
multiple: false, // Enable/disable multi-select
|
|
17496
17530
|
maxSelections: null, // Maximum number of selections allowed in multi-select mode (null for unlimited)
|
|
17497
|
-
closeOnSelect: false, // Close the dropdown after selecting an option (single-select only)
|
|
17498
17531
|
disabled: false, // Disable the select component
|
|
17499
17532
|
isRequired: false, // Make selection required
|
|
17500
17533
|
// Search Functionality
|
|
@@ -17504,7 +17537,6 @@ exports.DefaultConfig = {
|
|
|
17504
17537
|
searchMinLength: 0, // Minimum characters required to trigger search
|
|
17505
17538
|
searchMaxItems: 50, // Maximum number of search results to display
|
|
17506
17539
|
searchNotFoundText: 'No results found', // Text to display when no search results are found
|
|
17507
|
-
searchHighlight: true, // Highlight matching search terms within the options
|
|
17508
17540
|
clearSearchOnClose: true, // Clear search input when dropdown closes
|
|
17509
17541
|
// Multi-Select Display
|
|
17510
17542
|
selectAllText: 'Select all', // Text for the "Select All" option (if implemented)
|
|
@@ -17529,7 +17561,7 @@ var KTSelectState = /** @class */ (function () {
|
|
|
17529
17561
|
this._config = this._initDefaultConfig(config);
|
|
17530
17562
|
}
|
|
17531
17563
|
KTSelectState.prototype._initDefaultConfig = function (config) {
|
|
17532
|
-
return __assign(__assign({}, exports.DefaultConfig), config);
|
|
17564
|
+
return __assign(__assign(__assign({}, exports.DefaultConfig), config), config.config);
|
|
17533
17565
|
};
|
|
17534
17566
|
KTSelectState.prototype.setItems = function (items, query) {
|
|
17535
17567
|
var _this = this;
|
|
@@ -17598,11 +17630,17 @@ var KTSelectState = /** @class */ (function () {
|
|
|
17598
17630
|
return this._config.items || [];
|
|
17599
17631
|
};
|
|
17600
17632
|
KTSelectState.prototype.setItemsFromOptions = function (options) {
|
|
17601
|
-
this._config.items = options.map(function (option) {
|
|
17602
|
-
|
|
17603
|
-
|
|
17604
|
-
|
|
17605
|
-
|
|
17633
|
+
this._config.items = options.map(function (option) {
|
|
17634
|
+
var item = {
|
|
17635
|
+
id: option.value,
|
|
17636
|
+
title: option.textContent || option.value, // Use value as fallback for title
|
|
17637
|
+
// 'selected' property will be definitively set by _preSelectOptions
|
|
17638
|
+
disabled: option.disabled,
|
|
17639
|
+
};
|
|
17640
|
+
return item;
|
|
17641
|
+
});
|
|
17642
|
+
// The 'selected' status of these items and the overall component selection state
|
|
17643
|
+
// are now fully managed by _preSelectOptions in KTSelect during initialization.
|
|
17606
17644
|
};
|
|
17607
17645
|
KTSelectState.prototype.getConfig = function () {
|
|
17608
17646
|
return this._config;
|