@keenthemes/ktui 1.0.10 → 1.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/ktui.js +1283 -1100
- package/dist/ktui.min.js +1 -1
- package/dist/ktui.min.js.map +1 -1
- package/examples/select/basic-usage.html +43 -0
- package/examples/select/combobox-icons.html +58 -0
- package/examples/select/combobox.html +46 -0
- package/examples/select/description.html +69 -0
- package/examples/select/disable-option.html +43 -0
- package/examples/select/disable-select.html +34 -0
- package/examples/select/icon-description.html +56 -0
- package/examples/select/icon-multiple.html +58 -0
- package/examples/select/icon.html +58 -0
- package/examples/select/max-selection.html +39 -0
- package/examples/select/modal.html +70 -0
- package/examples/select/multiple.html +42 -0
- package/examples/select/placeholder.html +43 -0
- package/examples/select/remote-data.html +32 -0
- package/examples/select/search.html +49 -0
- package/examples/select/tags-icons.html +58 -0
- package/examples/select/tags-selected.html +59 -0
- package/examples/select/tags.html +58 -0
- package/examples/select/template-customization.html +65 -0
- package/examples/select/test.html +94 -0
- package/examples/toast/example.html +427 -0
- package/lib/cjs/components/component.js +1 -1
- package/lib/cjs/components/component.js.map +1 -1
- package/lib/cjs/components/datatable/datatable.js +22 -6
- package/lib/cjs/components/datatable/datatable.js.map +1 -1
- package/lib/cjs/components/modal/modal.js +0 -4
- package/lib/cjs/components/modal/modal.js.map +1 -1
- package/lib/cjs/components/select/combobox.js +38 -120
- package/lib/cjs/components/select/combobox.js.map +1 -1
- package/lib/cjs/components/select/config.js +4 -16
- package/lib/cjs/components/select/config.js.map +1 -1
- package/lib/cjs/components/select/dropdown.js +10 -49
- package/lib/cjs/components/select/dropdown.js.map +1 -1
- package/lib/cjs/components/select/index.js +2 -1
- package/lib/cjs/components/select/index.js.map +1 -1
- package/lib/cjs/components/select/option.js +21 -4
- package/lib/cjs/components/select/option.js.map +1 -1
- package/lib/cjs/components/select/remote.js +1 -37
- package/lib/cjs/components/select/remote.js.map +1 -1
- package/lib/cjs/components/select/search.js +11 -41
- package/lib/cjs/components/select/search.js.map +1 -1
- package/lib/cjs/components/select/select.js +213 -326
- package/lib/cjs/components/select/select.js.map +1 -1
- package/lib/cjs/components/select/tags.js +39 -31
- package/lib/cjs/components/select/tags.js.map +1 -1
- package/lib/cjs/components/select/templates.js +120 -179
- package/lib/cjs/components/select/templates.js.map +1 -1
- package/lib/cjs/components/select/types.js +0 -12
- package/lib/cjs/components/select/types.js.map +1 -1
- package/lib/cjs/components/select/utils.js +204 -257
- package/lib/cjs/components/select/utils.js.map +1 -1
- package/lib/cjs/components/toast/index.js +10 -0
- package/lib/cjs/components/toast/index.js.map +1 -0
- package/lib/cjs/components/toast/toast.js +543 -0
- package/lib/cjs/components/toast/toast.js.map +1 -0
- package/lib/cjs/components/toast/types.js +7 -0
- package/lib/cjs/components/toast/types.js.map +1 -0
- package/lib/cjs/helpers/dom.js +24 -0
- package/lib/cjs/helpers/dom.js.map +1 -1
- package/lib/cjs/index.js +5 -1
- package/lib/cjs/index.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 +22 -6
- package/lib/esm/components/datatable/datatable.js.map +1 -1
- package/lib/esm/components/modal/modal.js +0 -4
- package/lib/esm/components/modal/modal.js.map +1 -1
- package/lib/esm/components/select/combobox.js +39 -121
- package/lib/esm/components/select/combobox.js.map +1 -1
- package/lib/esm/components/select/config.js +3 -15
- package/lib/esm/components/select/config.js.map +1 -1
- package/lib/esm/components/select/dropdown.js +10 -49
- package/lib/esm/components/select/dropdown.js.map +1 -1
- package/lib/esm/components/select/index.js +1 -1
- package/lib/esm/components/select/index.js.map +1 -1
- package/lib/esm/components/select/option.js +21 -4
- package/lib/esm/components/select/option.js.map +1 -1
- package/lib/esm/components/select/remote.js +1 -37
- package/lib/esm/components/select/remote.js.map +1 -1
- package/lib/esm/components/select/search.js +12 -42
- package/lib/esm/components/select/search.js.map +1 -1
- package/lib/esm/components/select/select.js +214 -327
- package/lib/esm/components/select/select.js.map +1 -1
- package/lib/esm/components/select/tags.js +39 -31
- package/lib/esm/components/select/tags.js.map +1 -1
- package/lib/esm/components/select/templates.js +119 -178
- package/lib/esm/components/select/templates.js.map +1 -1
- package/lib/esm/components/select/types.js +1 -11
- package/lib/esm/components/select/types.js.map +1 -1
- package/lib/esm/components/select/utils.js +201 -255
- package/lib/esm/components/select/utils.js.map +1 -1
- package/lib/esm/components/toast/index.js +6 -0
- package/lib/esm/components/toast/index.js.map +1 -0
- package/lib/esm/components/toast/toast.js +540 -0
- package/lib/esm/components/toast/toast.js.map +1 -0
- package/lib/esm/components/toast/types.js +6 -0
- package/lib/esm/components/toast/types.js.map +1 -0
- package/lib/esm/helpers/dom.js +24 -0
- package/lib/esm/helpers/dom.js.map +1 -1
- package/lib/esm/index.js +3 -0
- package/lib/esm/index.js.map +1 -1
- package/package.json +8 -6
- package/src/components/alert/alert.css +20 -2
- package/src/components/badge/badge.css +5 -0
- package/src/components/component.ts +4 -0
- package/src/components/datatable/datatable.ts +24 -16
- package/src/components/drawer/drawer.css +1 -1
- package/src/components/input/input.css +3 -1
- package/src/components/link/link.css +2 -2
- package/src/components/modal/modal.css +18 -2
- package/src/components/modal/modal.ts +0 -5
- package/src/components/select/combobox.ts +42 -149
- package/src/components/select/config.ts +38 -33
- package/src/components/select/dropdown.ts +8 -55
- package/src/components/select/index.ts +1 -1
- package/src/components/select/option.ts +28 -7
- package/src/components/select/remote.ts +2 -42
- package/src/components/select/search.ts +14 -54
- package/src/components/select/select.css +49 -0
- package/src/components/select/select.ts +231 -437
- package/src/components/select/tags.ts +40 -37
- package/src/components/select/templates.ts +166 -303
- package/src/components/select/types.ts +0 -10
- package/src/components/select/utils.ts +214 -304
- package/src/components/table/table.css +1 -1
- package/src/components/textarea/textarea.css +2 -1
- package/src/components/toast/index.ts +7 -0
- package/src/components/toast/toast.css +60 -0
- package/src/components/toast/toast.ts +605 -0
- package/src/components/toast/types.ts +169 -0
- package/src/helpers/dom.ts +30 -0
- package/src/index.ts +4 -0
- package/styles/main.css +3 -0
- package/styles/vars.css +138 -0
- package/styles.css +1 -0
|
@@ -47,9 +47,8 @@ import { KTSelectSearch } from './search';
|
|
|
47
47
|
import { defaultTemplates } from './templates';
|
|
48
48
|
import { KTSelectCombobox } from './combobox';
|
|
49
49
|
import { KTSelectDropdown } from './dropdown';
|
|
50
|
-
import {
|
|
50
|
+
import { FocusManager, EventManager, renderTemplateString, TypeToSearchBuffer, } from './utils';
|
|
51
51
|
import { KTSelectTags } from './tags';
|
|
52
|
-
import { SelectMode } from './types';
|
|
53
52
|
var KTSelect = /** @class */ (function (_super) {
|
|
54
53
|
__extends(KTSelect, _super);
|
|
55
54
|
/**
|
|
@@ -66,6 +65,7 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
66
65
|
_this._tagsModule = null;
|
|
67
66
|
_this._dropdownModule = null;
|
|
68
67
|
_this._loadMoreIndicator = null;
|
|
68
|
+
_this._typeToSearchBuffer = new TypeToSearchBuffer();
|
|
69
69
|
// Search debounce timeout
|
|
70
70
|
_this._searchDebounceTimeout = null;
|
|
71
71
|
// Store original options HTML for restoring after search
|
|
@@ -150,11 +150,6 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
150
150
|
// Keep only the empty/placeholder option and remove the rest
|
|
151
151
|
var options = Array.from(this._element.querySelectorAll('option:not([value=""])'));
|
|
152
152
|
options.forEach(function (option) { return option.remove(); });
|
|
153
|
-
// Ensure we have at least an empty option
|
|
154
|
-
if (this._element.querySelectorAll('option').length === 0) {
|
|
155
|
-
var emptyOption = defaultTemplates.emptyOption(__assign(__assign({}, this._config), { placeholder: this._config.placeholder }));
|
|
156
|
-
this._element.appendChild(emptyOption);
|
|
157
|
-
}
|
|
158
153
|
};
|
|
159
154
|
/**
|
|
160
155
|
* Helper to show a dropdown message (error, loading, noResults)
|
|
@@ -162,7 +157,7 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
162
157
|
KTSelect.prototype._showDropdownMessage = function (type, message) {
|
|
163
158
|
if (!this._dropdownContentElement)
|
|
164
159
|
return;
|
|
165
|
-
var optionsContainer = this._dropdownContentElement.querySelector('[data-kt-select-options
|
|
160
|
+
var optionsContainer = this._dropdownContentElement.querySelector('[data-kt-select-options]');
|
|
166
161
|
if (!optionsContainer)
|
|
167
162
|
return;
|
|
168
163
|
switch (type) {
|
|
@@ -172,9 +167,9 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
172
167
|
case 'loading':
|
|
173
168
|
optionsContainer.innerHTML = defaultTemplates.loading(this._config, message || 'Loading...').outerHTML;
|
|
174
169
|
break;
|
|
175
|
-
case '
|
|
170
|
+
case 'empty':
|
|
176
171
|
optionsContainer.innerHTML = '';
|
|
177
|
-
optionsContainer.appendChild(defaultTemplates.
|
|
172
|
+
optionsContainer.appendChild(defaultTemplates.empty(this._config));
|
|
178
173
|
break;
|
|
179
174
|
}
|
|
180
175
|
};
|
|
@@ -193,14 +188,6 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
193
188
|
* @param message Error message
|
|
194
189
|
*/
|
|
195
190
|
KTSelect.prototype._renderErrorState = function (message) {
|
|
196
|
-
// Create error option if the select is empty
|
|
197
|
-
if (this._element.querySelectorAll('option').length <= 1) {
|
|
198
|
-
var loadingOptions = this._element.querySelectorAll('option[disabled]:not([value])');
|
|
199
|
-
loadingOptions.forEach(function (option) { return option.remove(); });
|
|
200
|
-
// Use template function for error option instead of hardcoded element
|
|
201
|
-
var errorOption = defaultTemplates.errorOption(__assign(__assign({}, this._config), { errorMessage: message }));
|
|
202
|
-
this._element.appendChild(errorOption);
|
|
203
|
-
}
|
|
204
191
|
// If dropdown is already created, show error message there
|
|
205
192
|
this._showDropdownMessage('error', message);
|
|
206
193
|
if (!this._wrapperElement) {
|
|
@@ -223,7 +210,7 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
223
210
|
// Create load more button using template
|
|
224
211
|
this._loadMoreIndicator = defaultTemplates.loadMore(this._config);
|
|
225
212
|
// Add to dropdown
|
|
226
|
-
var optionsContainer = this._dropdownContentElement.querySelector('[data-kt-select-options
|
|
213
|
+
var optionsContainer = this._dropdownContentElement.querySelector('[data-kt-select-options]');
|
|
227
214
|
if (optionsContainer) {
|
|
228
215
|
optionsContainer.appendChild(this._loadMoreIndicator);
|
|
229
216
|
}
|
|
@@ -293,42 +280,26 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
293
280
|
* @param newItems New items to add to the dropdown
|
|
294
281
|
*/
|
|
295
282
|
KTSelect.prototype._updateOptionsInDropdown = function (newItems) {
|
|
296
|
-
var _this = this;
|
|
297
283
|
if (!this._dropdownContentElement || !newItems.length)
|
|
298
284
|
return;
|
|
299
|
-
var optionsContainer = this._dropdownContentElement.querySelector(
|
|
285
|
+
var optionsContainer = this._dropdownContentElement.querySelector("[data-kt-select-options]");
|
|
300
286
|
if (!optionsContainer)
|
|
301
287
|
return;
|
|
302
288
|
// Get the load more button
|
|
303
|
-
var loadMoreButton = optionsContainer.querySelector(
|
|
289
|
+
var loadMoreButton = optionsContainer.querySelector("[data-kt-select-load-more]");
|
|
304
290
|
// Process each new item
|
|
305
291
|
newItems.forEach(function (item) {
|
|
306
292
|
// Create option for the original select
|
|
307
|
-
var selectOption =
|
|
293
|
+
var selectOption = document.createElement('option');
|
|
308
294
|
selectOption.value = item.id || '';
|
|
309
|
-
// Add description and icon attributes if available and valid
|
|
310
|
-
if (item.description &&
|
|
311
|
-
item.description !== 'null' &&
|
|
312
|
-
item.description !== 'undefined') {
|
|
313
|
-
selectOption.setAttribute('data-kt-select-option-description', item.description);
|
|
314
|
-
}
|
|
315
|
-
if (item.icon && item.icon !== 'null' && item.icon !== 'undefined') {
|
|
316
|
-
selectOption.setAttribute('data-kt-select-option-icon', item.icon);
|
|
317
|
-
}
|
|
318
|
-
// Add the option to the original select element
|
|
319
|
-
_this._element.appendChild(selectOption);
|
|
320
|
-
// Create option element for the dropdown using the KTSelectOption class
|
|
321
|
-
// This ensures consistent option rendering
|
|
322
|
-
var ktOption = new KTSelectOption(selectOption, _this._config);
|
|
323
|
-
var renderedOption = ktOption.render();
|
|
324
295
|
// Add to dropdown container
|
|
325
296
|
if (loadMoreButton) {
|
|
326
297
|
// Insert before the load more button
|
|
327
|
-
optionsContainer.insertBefore(
|
|
298
|
+
optionsContainer.insertBefore(selectOption, loadMoreButton);
|
|
328
299
|
}
|
|
329
300
|
else {
|
|
330
301
|
// Append to the end
|
|
331
|
-
optionsContainer.appendChild(
|
|
302
|
+
optionsContainer.appendChild(selectOption);
|
|
332
303
|
}
|
|
333
304
|
});
|
|
334
305
|
// Update options NodeList to include the new options
|
|
@@ -350,7 +321,7 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
350
321
|
this._setupElementReferences();
|
|
351
322
|
this._initZIndex();
|
|
352
323
|
// Initialize options
|
|
353
|
-
this._initializeOptionsHtml();
|
|
324
|
+
// this._initializeOptionsHtml();
|
|
354
325
|
this._preSelectOptions(this._element);
|
|
355
326
|
// Apply disabled state if needed
|
|
356
327
|
this._applyInitialDisabledState();
|
|
@@ -359,11 +330,11 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
359
330
|
this._initializeSearchModule();
|
|
360
331
|
}
|
|
361
332
|
// Initialize combobox if enabled
|
|
362
|
-
if (this._config.
|
|
333
|
+
if (this._config.combobox) {
|
|
363
334
|
this._comboboxModule = new KTSelectCombobox(this);
|
|
364
335
|
}
|
|
365
336
|
// Initialize tags if enabled
|
|
366
|
-
if (this._config.
|
|
337
|
+
if (this._config.tags) {
|
|
367
338
|
this._tagsModule = new KTSelectTags(this);
|
|
368
339
|
}
|
|
369
340
|
// Initialize focus manager after dropdown element is created
|
|
@@ -380,31 +351,37 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
380
351
|
/**
|
|
381
352
|
* Initialize options HTML from data
|
|
382
353
|
*/
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
}
|
|
354
|
+
// private _initializeOptionsHtml() {
|
|
355
|
+
// this._generateOptionsHtml(this._element);
|
|
356
|
+
// }
|
|
386
357
|
/**
|
|
387
358
|
* Creates the HTML structure for the select component
|
|
388
359
|
*/
|
|
389
360
|
KTSelect.prototype._createHtmlStructure = function () {
|
|
361
|
+
var _a;
|
|
390
362
|
var _this = this;
|
|
391
363
|
var options = Array.from(this._element.querySelectorAll('option'));
|
|
392
364
|
// Create wrapper and display elements
|
|
393
|
-
var wrapperElement = defaultTemplates.
|
|
365
|
+
var wrapperElement = defaultTemplates.wrapper(this._config);
|
|
394
366
|
var displayElement = defaultTemplates.display(this._config);
|
|
395
367
|
// Add the display element to the wrapper
|
|
396
368
|
wrapperElement.appendChild(displayElement);
|
|
369
|
+
// Move classes from original select to display element
|
|
370
|
+
if (this._element.classList.length > 0) {
|
|
371
|
+
(_a = displayElement.classList).add.apply(_a, Array.from(this._element.classList));
|
|
372
|
+
this._element.className = '';
|
|
373
|
+
}
|
|
397
374
|
// Create an empty dropdown first (without options) using template
|
|
398
|
-
var dropdownElement = defaultTemplates.
|
|
375
|
+
var dropdownElement = defaultTemplates.dropdown(__assign(__assign({}, this._config), { zindex: this._config.dropdownZindex }));
|
|
399
376
|
// Add search input if needed
|
|
400
|
-
|
|
401
|
-
var hasSearch = this._config.enableSearch && !isCombobox;
|
|
402
|
-
if (hasSearch) {
|
|
377
|
+
if (this._config.enableSearch) {
|
|
403
378
|
var searchElement = defaultTemplates.search(this._config);
|
|
404
379
|
dropdownElement.appendChild(searchElement);
|
|
405
380
|
}
|
|
406
381
|
// Create options container using template
|
|
407
|
-
var optionsContainer = defaultTemplates.
|
|
382
|
+
var optionsContainer = defaultTemplates.options(this._config);
|
|
383
|
+
// Clear the options container
|
|
384
|
+
optionsContainer.innerHTML = '';
|
|
408
385
|
// Add each option directly to the container
|
|
409
386
|
options.forEach(function (optionElement) {
|
|
410
387
|
// Skip empty placeholder options (only if BOTH value AND text are empty)
|
|
@@ -435,20 +412,17 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
435
412
|
// Get display element
|
|
436
413
|
this._displayElement = this._wrapperElement.querySelector("[data-kt-select-display]");
|
|
437
414
|
// Get dropdown content element - this is critical for dropdown functionality
|
|
438
|
-
this._dropdownContentElement = this._wrapperElement.querySelector("[data-kt-select-dropdown
|
|
415
|
+
this._dropdownContentElement = this._wrapperElement.querySelector("[data-kt-select-dropdown]");
|
|
439
416
|
if (!this._dropdownContentElement) {
|
|
417
|
+
console.log(this._element);
|
|
440
418
|
console.error('Dropdown content element not found', this._wrapperElement);
|
|
441
419
|
}
|
|
442
420
|
// Get search input element - this is used for the search functionality
|
|
443
|
-
// First check if it's in dropdown, then check if it's in display (for combobox)
|
|
444
421
|
this._searchInputElement = this._dropdownContentElement.querySelector("[data-kt-select-search]");
|
|
445
|
-
// If not found in dropdown, check if it's the display element itself
|
|
446
|
-
if (!this._searchInputElement
|
|
447
|
-
this._config.mode === SelectMode.COMBOBOX) {
|
|
422
|
+
// If not found in dropdown, check if it's the display element itself
|
|
423
|
+
if (!this._searchInputElement) {
|
|
448
424
|
this._searchInputElement = this._displayElement;
|
|
449
425
|
}
|
|
450
|
-
if (this._config.debug)
|
|
451
|
-
console.log('Search input found:', this._searchInputElement ? 'Yes' : 'No', 'Mode:', this._config.mode, 'EnableSearch:', this._config.enableSearch);
|
|
452
426
|
this._valueDisplayElement = this._wrapperElement.querySelector("[data-kt-select-value]");
|
|
453
427
|
this._options = this._wrapperElement.querySelectorAll("[data-kt-select-option]");
|
|
454
428
|
};
|
|
@@ -458,17 +432,18 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
458
432
|
KTSelect.prototype._attachEventListeners = function () {
|
|
459
433
|
// Document level event listeners
|
|
460
434
|
document.addEventListener('click', this._handleDocumentClick.bind(this));
|
|
461
|
-
document.addEventListener('keydown', this._handleEscKey.bind(this));
|
|
462
435
|
// Dropdown option click events
|
|
463
436
|
this._eventManager.addListener(this._dropdownContentElement, 'click', this._handleDropdownOptionClick.bind(this));
|
|
464
437
|
// Only attach click handler to display element
|
|
465
|
-
this._eventManager.addListener(
|
|
466
|
-
//
|
|
467
|
-
//
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
438
|
+
// this._eventManager.addListener(
|
|
439
|
+
// this._wrapperElement,
|
|
440
|
+
// 'click',
|
|
441
|
+
// this._handleDropdownClick.bind(this),
|
|
442
|
+
// );
|
|
443
|
+
// Attach centralized keyboard handler
|
|
444
|
+
var keyboardTarget = this._searchInputElement || this._wrapperElement;
|
|
445
|
+
if (keyboardTarget) {
|
|
446
|
+
keyboardTarget.addEventListener('keydown', this._handleKeyboardEvent.bind(this));
|
|
472
447
|
}
|
|
473
448
|
};
|
|
474
449
|
/**
|
|
@@ -538,52 +513,12 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
538
513
|
label =
|
|
539
514
|
extractedLabel !== null ? String(extractedLabel) : 'Unnamed option';
|
|
540
515
|
}
|
|
541
|
-
// Get description - skip if null, undefined, or "null" string
|
|
542
|
-
var description = null;
|
|
543
|
-
if (item.description !== undefined &&
|
|
544
|
-
item.description !== null &&
|
|
545
|
-
String(item.description) !== 'null' &&
|
|
546
|
-
String(item.description) !== 'undefined') {
|
|
547
|
-
description = String(item.description);
|
|
548
|
-
}
|
|
549
|
-
else if (_this._config.dataFieldDescription) {
|
|
550
|
-
var extractedDesc = _this._getValueByKey(item, _this._config.dataFieldDescription);
|
|
551
|
-
if (extractedDesc !== null &&
|
|
552
|
-
extractedDesc !== undefined &&
|
|
553
|
-
String(extractedDesc) !== 'null' &&
|
|
554
|
-
String(extractedDesc) !== 'undefined') {
|
|
555
|
-
description = String(extractedDesc);
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
// Get icon - skip if null, undefined, or "null" string
|
|
559
|
-
var icon = null;
|
|
560
|
-
if (item.icon !== undefined &&
|
|
561
|
-
item.icon !== null &&
|
|
562
|
-
String(item.icon) !== 'null' &&
|
|
563
|
-
String(item.icon) !== 'undefined') {
|
|
564
|
-
icon = String(item.icon);
|
|
565
|
-
}
|
|
566
|
-
else if (_this._config.dataFieldIcon) {
|
|
567
|
-
var extractedIcon = _this._getValueByKey(item, _this._config.dataFieldIcon);
|
|
568
|
-
if (extractedIcon !== null &&
|
|
569
|
-
extractedIcon !== undefined &&
|
|
570
|
-
String(extractedIcon) !== 'null' &&
|
|
571
|
-
String(extractedIcon) !== 'undefined') {
|
|
572
|
-
icon = String(extractedIcon);
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
516
|
// Log the extracted values for debugging
|
|
576
517
|
if (_this._config.debug)
|
|
577
|
-
console.log("Option: value=".concat(value, ", label=").concat(label
|
|
518
|
+
console.log("Option: value=".concat(value, ", label=").concat(label));
|
|
578
519
|
// Set option attributes
|
|
579
520
|
optionElement.value = value;
|
|
580
521
|
optionElement.textContent = label || 'Unnamed option';
|
|
581
|
-
if (description) {
|
|
582
|
-
optionElement.setAttribute('data-kt-select-option-description', description);
|
|
583
|
-
}
|
|
584
|
-
if (icon) {
|
|
585
|
-
optionElement.setAttribute('data-kt-select-option-icon', icon);
|
|
586
|
-
}
|
|
587
522
|
if (item.selected) {
|
|
588
523
|
optionElement.setAttribute('selected', 'selected');
|
|
589
524
|
}
|
|
@@ -653,8 +588,14 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
653
588
|
*/
|
|
654
589
|
/**
|
|
655
590
|
* Toggle dropdown visibility
|
|
591
|
+
* @deprecated
|
|
656
592
|
*/
|
|
657
593
|
KTSelect.prototype.toggleDropdown = function () {
|
|
594
|
+
if (this._config.disabled) {
|
|
595
|
+
if (this._config.debug)
|
|
596
|
+
console.log('toggleDropdown: select is disabled, not opening');
|
|
597
|
+
return;
|
|
598
|
+
}
|
|
658
599
|
if (this._config.debug)
|
|
659
600
|
console.log('toggleDropdown called');
|
|
660
601
|
if (this._dropdownModule) {
|
|
@@ -676,6 +617,11 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
676
617
|
*/
|
|
677
618
|
KTSelect.prototype.openDropdown = function () {
|
|
678
619
|
var _this = this;
|
|
620
|
+
if (this._config.disabled) {
|
|
621
|
+
if (this._config.debug)
|
|
622
|
+
console.log('openDropdown: select is disabled, not opening');
|
|
623
|
+
return;
|
|
624
|
+
}
|
|
679
625
|
if (this._config.debug)
|
|
680
626
|
console.log('openDropdown called, dropdownModule exists:', !!this._dropdownModule);
|
|
681
627
|
if (!this._dropdownModule) {
|
|
@@ -781,6 +727,12 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
781
727
|
* Select an option by value
|
|
782
728
|
*/
|
|
783
729
|
KTSelect.prototype._selectOption = function (value) {
|
|
730
|
+
// Prevent selection if the option is disabled (in dropdown or original select)
|
|
731
|
+
if (this._isOptionDisabled(value)) {
|
|
732
|
+
if (this._config.debug)
|
|
733
|
+
console.log('_selectOption: Option is disabled, ignoring selection');
|
|
734
|
+
return;
|
|
735
|
+
}
|
|
784
736
|
// Get current selection state
|
|
785
737
|
var isSelected = this._state.isSelected(value);
|
|
786
738
|
// Toggle selection in state
|
|
@@ -826,104 +778,34 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
826
778
|
* Update selected option display value
|
|
827
779
|
*/
|
|
828
780
|
KTSelect.prototype.updateSelectedOptionDisplay = function () {
|
|
829
|
-
var _this = this;
|
|
830
781
|
var selectedOptions = this.getSelectedOptions();
|
|
831
|
-
if
|
|
782
|
+
// Tag mode: render tags if enabled
|
|
783
|
+
if (this._config.tags && this._tagsModule) {
|
|
784
|
+
this._tagsModule.updateTagsDisplay(selectedOptions);
|
|
785
|
+
return;
|
|
786
|
+
}
|
|
787
|
+
if (typeof this._config.renderSelected === 'function') {
|
|
832
788
|
// Use the custom renderSelected function if provided
|
|
833
|
-
this.
|
|
789
|
+
this._valueDisplayElement.innerHTML = this._config.renderSelected(selectedOptions);
|
|
834
790
|
}
|
|
835
791
|
else {
|
|
836
792
|
if (selectedOptions.length === 0) {
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
else if (this._config.multiple) {
|
|
842
|
-
if (this._config.mode === SelectMode.TAGS) {
|
|
843
|
-
// Use the tags module to render selected options as tags
|
|
844
|
-
if (this._tagsModule) {
|
|
845
|
-
this._tagsModule.updateTagsDisplay(selectedOptions);
|
|
846
|
-
}
|
|
847
|
-
else {
|
|
848
|
-
// Fallback if tags module not initialized for some reason
|
|
849
|
-
this._updateValueDisplay(selectedOptions.join(', '));
|
|
850
|
-
}
|
|
851
|
-
}
|
|
852
|
-
else {
|
|
853
|
-
// Render as comma-separated values
|
|
854
|
-
var displayText = selectedOptions
|
|
855
|
-
.map(function (option) { return _this._getOptionInnerHtml(option) || ''; })
|
|
856
|
-
.join(', ');
|
|
857
|
-
this._updateValueDisplay(displayText);
|
|
858
|
-
}
|
|
793
|
+
var placeholder = defaultTemplates.placeholder(this._config);
|
|
794
|
+
this._valueDisplayElement.replaceChildren(placeholder);
|
|
859
795
|
}
|
|
860
796
|
else {
|
|
861
|
-
var
|
|
862
|
-
if (
|
|
863
|
-
var
|
|
864
|
-
this.
|
|
865
|
-
// Update combobox input value if in combobox mode
|
|
866
|
-
if (this._config.mode === SelectMode.COMBOBOX &&
|
|
867
|
-
this._comboboxModule) {
|
|
868
|
-
this._comboboxModule.updateSelectedValue(selectedText);
|
|
869
|
-
}
|
|
797
|
+
var content = '';
|
|
798
|
+
if (this._config.displayTemplate) {
|
|
799
|
+
var selectedValues = this.getSelectedOptions();
|
|
800
|
+
content = this.renderDisplayTemplateForSelected(selectedValues);
|
|
870
801
|
}
|
|
871
802
|
else {
|
|
872
|
-
|
|
803
|
+
// If no displayTemplate is provided, use the default comma-separated list of selected options
|
|
804
|
+
content = this.getSelectedOptionsText();
|
|
873
805
|
}
|
|
806
|
+
this._valueDisplayElement.innerHTML = content;
|
|
874
807
|
}
|
|
875
808
|
}
|
|
876
|
-
// Update any debug display boxes if they exist
|
|
877
|
-
this._updateDebugDisplays();
|
|
878
|
-
};
|
|
879
|
-
/**
|
|
880
|
-
* Update the value display element
|
|
881
|
-
*/
|
|
882
|
-
KTSelect.prototype._updateValueDisplay = function (value) {
|
|
883
|
-
if (this._config.mode === SelectMode.COMBOBOX) {
|
|
884
|
-
// For combobox, we only update the hidden value element, not the input
|
|
885
|
-
// The combobox module will handle updating the input value
|
|
886
|
-
if (!this._comboboxModule) {
|
|
887
|
-
this._valueDisplayElement.value = value;
|
|
888
|
-
}
|
|
889
|
-
}
|
|
890
|
-
else {
|
|
891
|
-
this._valueDisplayElement.innerHTML = value;
|
|
892
|
-
}
|
|
893
|
-
};
|
|
894
|
-
/**
|
|
895
|
-
* Update debug displays if present
|
|
896
|
-
*/
|
|
897
|
-
KTSelect.prototype._updateDebugDisplays = function () {
|
|
898
|
-
// Check if we're in a test environment with debug boxes
|
|
899
|
-
var selectId = this.getElement().id;
|
|
900
|
-
if (selectId) {
|
|
901
|
-
var debugElement = document.getElementById("".concat(selectId, "-value"));
|
|
902
|
-
if (debugElement) {
|
|
903
|
-
var selectedOptions = this.getSelectedOptions();
|
|
904
|
-
// Format display based on selection mode
|
|
905
|
-
if (this._config.multiple) {
|
|
906
|
-
// For multiple selection, show comma-separated list
|
|
907
|
-
debugElement.textContent =
|
|
908
|
-
selectedOptions.length > 0 ? selectedOptions.join(', ') : 'None';
|
|
909
|
-
}
|
|
910
|
-
else {
|
|
911
|
-
// For single selection, show just the one value
|
|
912
|
-
debugElement.textContent =
|
|
913
|
-
selectedOptions.length > 0 ? selectedOptions[0] : 'None';
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
|
-
}
|
|
917
|
-
};
|
|
918
|
-
/**
|
|
919
|
-
* Get option inner HTML content by option value
|
|
920
|
-
*/
|
|
921
|
-
KTSelect.prototype._getOptionInnerHtml = function (optionValue) {
|
|
922
|
-
var option = Array.from(this._options).find(function (opt) { return opt.dataset.value === optionValue; });
|
|
923
|
-
if (this._config.mode == SelectMode.COMBOBOX) {
|
|
924
|
-
return option.textContent;
|
|
925
|
-
}
|
|
926
|
-
return option.innerHTML; // Get the entire HTML content of the option
|
|
927
809
|
};
|
|
928
810
|
/**
|
|
929
811
|
* Update CSS classes for selected options
|
|
@@ -969,17 +851,6 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
969
851
|
this._state.setSelectedOptions([]);
|
|
970
852
|
this.updateSelectedOptionDisplay();
|
|
971
853
|
this._updateSelectedOptionClass();
|
|
972
|
-
// For combobox, also clear the input value
|
|
973
|
-
if (this._config.mode === SelectMode.COMBOBOX) {
|
|
974
|
-
if (this._searchInputElement) {
|
|
975
|
-
this._searchInputElement.value = '';
|
|
976
|
-
}
|
|
977
|
-
// If combobox has a clear button, hide it
|
|
978
|
-
if (this._comboboxModule) {
|
|
979
|
-
// The combobox module will handle hiding the clear button
|
|
980
|
-
this._comboboxModule.resetInputValueToSelection();
|
|
981
|
-
}
|
|
982
|
-
}
|
|
983
854
|
// Dispatch change event
|
|
984
855
|
this._dispatchEvent('change');
|
|
985
856
|
this._fireEvent('change');
|
|
@@ -991,49 +862,6 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
991
862
|
var values = Array.from(options).map(function (option) { return option.value; });
|
|
992
863
|
this._state.setSelectedOptions(values);
|
|
993
864
|
};
|
|
994
|
-
/**
|
|
995
|
-
* ========================================================================
|
|
996
|
-
* KEYBOARD NAVIGATION
|
|
997
|
-
* ========================================================================
|
|
998
|
-
*/
|
|
999
|
-
/**
|
|
1000
|
-
* Handle dropdown key down events for keyboard navigation
|
|
1001
|
-
* Only used for standard (non-combobox) dropdowns
|
|
1002
|
-
*/
|
|
1003
|
-
KTSelect.prototype._handleDropdownKeyDown = function (event) {
|
|
1004
|
-
// Log event for debugging
|
|
1005
|
-
if (this._config.debug)
|
|
1006
|
-
console.log('Standard dropdown keydown:', event.key);
|
|
1007
|
-
// Use the shared handler
|
|
1008
|
-
handleDropdownKeyNavigation(event, this, {
|
|
1009
|
-
multiple: this._config.multiple,
|
|
1010
|
-
closeOnSelect: this._config.closeOnSelect,
|
|
1011
|
-
});
|
|
1012
|
-
};
|
|
1013
|
-
/**
|
|
1014
|
-
* Focus next option in dropdown
|
|
1015
|
-
*/
|
|
1016
|
-
KTSelect.prototype._focusNextOption = function () {
|
|
1017
|
-
return this._focusManager.focusNext();
|
|
1018
|
-
};
|
|
1019
|
-
/**
|
|
1020
|
-
* Focus previous option in dropdown
|
|
1021
|
-
*/
|
|
1022
|
-
KTSelect.prototype._focusPreviousOption = function () {
|
|
1023
|
-
return this._focusManager.focusPrevious();
|
|
1024
|
-
};
|
|
1025
|
-
/**
|
|
1026
|
-
* Apply hover/focus state to focused option
|
|
1027
|
-
*/
|
|
1028
|
-
KTSelect.prototype._hoverFocusedOption = function (option) {
|
|
1029
|
-
this._focusManager.applyFocus(option);
|
|
1030
|
-
};
|
|
1031
|
-
/**
|
|
1032
|
-
* Scroll option into view when navigating
|
|
1033
|
-
*/
|
|
1034
|
-
KTSelect.prototype._scrollOptionIntoView = function (option) {
|
|
1035
|
-
this._focusManager.scrollIntoView(option);
|
|
1036
|
-
};
|
|
1037
865
|
/**
|
|
1038
866
|
* Select the currently focused option
|
|
1039
867
|
*/
|
|
@@ -1057,44 +885,7 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
1057
885
|
if (selectedValue) {
|
|
1058
886
|
this._selectOption(selectedValue);
|
|
1059
887
|
}
|
|
1060
|
-
// For combobox mode, update input value AFTER selection to ensure consistency
|
|
1061
|
-
if (this._config.mode === SelectMode.COMBOBOX && this._comboboxModule) {
|
|
1062
|
-
this._comboboxModule.updateSelectedValue(selectedText);
|
|
1063
|
-
// Also directly update the input value for immediate visual feedback
|
|
1064
|
-
if (this._searchInputElement) {
|
|
1065
|
-
this._searchInputElement.value = selectedText;
|
|
1066
|
-
}
|
|
1067
|
-
}
|
|
1068
|
-
}
|
|
1069
|
-
};
|
|
1070
|
-
/**
|
|
1071
|
-
* ========================================================================
|
|
1072
|
-
* COMBOBOX SPECIFIC METHODS
|
|
1073
|
-
* ========================================================================
|
|
1074
|
-
*/
|
|
1075
|
-
/**
|
|
1076
|
-
* Handle combobox input events
|
|
1077
|
-
*/
|
|
1078
|
-
KTSelect.prototype._handleComboboxInput = function (event) {
|
|
1079
|
-
if (this._comboboxModule) {
|
|
1080
|
-
return;
|
|
1081
|
-
}
|
|
1082
|
-
var inputElement = event.target;
|
|
1083
|
-
var query = inputElement.value.toLowerCase();
|
|
1084
|
-
// If dropdown isn't open, open it when user starts typing
|
|
1085
|
-
if (!this._dropdownIsOpen) {
|
|
1086
|
-
this.openDropdown();
|
|
1087
888
|
}
|
|
1088
|
-
// Filter options based on input
|
|
1089
|
-
this._filterOptionsForCombobox(query);
|
|
1090
|
-
};
|
|
1091
|
-
/**
|
|
1092
|
-
* Filter options for combobox based on input query
|
|
1093
|
-
* Uses the shared filterOptions function
|
|
1094
|
-
*/
|
|
1095
|
-
KTSelect.prototype._filterOptionsForCombobox = function (query) {
|
|
1096
|
-
var options = Array.from(this._dropdownContentElement.querySelectorAll('[data-kt-select-option]'));
|
|
1097
|
-
filterOptions(options, query, this._config, this._dropdownContentElement);
|
|
1098
889
|
};
|
|
1099
890
|
/**
|
|
1100
891
|
* ========================================================================
|
|
@@ -1103,6 +894,7 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
1103
894
|
*/
|
|
1104
895
|
/**
|
|
1105
896
|
* Handle display element click
|
|
897
|
+
* @deprecated
|
|
1106
898
|
*/
|
|
1107
899
|
KTSelect.prototype._handleDropdownClick = function (event) {
|
|
1108
900
|
if (this._config.debug)
|
|
@@ -1164,14 +956,6 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
1164
956
|
this.closeDropdown();
|
|
1165
957
|
}
|
|
1166
958
|
};
|
|
1167
|
-
/**
|
|
1168
|
-
* Handle escape key press
|
|
1169
|
-
*/
|
|
1170
|
-
KTSelect.prototype._handleEscKey = function (event) {
|
|
1171
|
-
if (event.key === 'Escape' && this._dropdownIsOpen) {
|
|
1172
|
-
this.closeDropdown();
|
|
1173
|
-
}
|
|
1174
|
-
};
|
|
1175
959
|
/**
|
|
1176
960
|
* ========================================================================
|
|
1177
961
|
* ACCESSIBILITY METHODS
|
|
@@ -1183,18 +967,6 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
1183
967
|
KTSelect.prototype._setAriaAttributes = function () {
|
|
1184
968
|
this._displayElement.setAttribute('aria-expanded', this._dropdownIsOpen.toString());
|
|
1185
969
|
};
|
|
1186
|
-
/**
|
|
1187
|
-
* Handle focus events
|
|
1188
|
-
*/
|
|
1189
|
-
KTSelect.prototype._handleFocus = function () {
|
|
1190
|
-
// Implementation pending
|
|
1191
|
-
};
|
|
1192
|
-
/**
|
|
1193
|
-
* Handle blur events
|
|
1194
|
-
*/
|
|
1195
|
-
KTSelect.prototype._handleBlur = function () {
|
|
1196
|
-
// Implementation pending
|
|
1197
|
-
};
|
|
1198
970
|
/**
|
|
1199
971
|
* ========================================================================
|
|
1200
972
|
* PUBLIC API
|
|
@@ -1263,7 +1035,7 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
1263
1035
|
}
|
|
1264
1036
|
});
|
|
1265
1037
|
// If search input exists, clear it
|
|
1266
|
-
if (this._searchInputElement
|
|
1038
|
+
if (this._searchInputElement) {
|
|
1267
1039
|
this._searchInputElement.value = '';
|
|
1268
1040
|
// If we have a search module, clear any search filtering
|
|
1269
1041
|
if (this._searchModule) {
|
|
@@ -1287,6 +1059,12 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
1287
1059
|
* Toggle the selection of an option
|
|
1288
1060
|
*/
|
|
1289
1061
|
KTSelect.prototype.toggleSelection = function (value) {
|
|
1062
|
+
// Prevent selection if the option is disabled (in dropdown or original select)
|
|
1063
|
+
if (this._isOptionDisabled(value)) {
|
|
1064
|
+
if (this._config.debug)
|
|
1065
|
+
console.log('toggleSelection: Option is disabled, ignoring selection');
|
|
1066
|
+
return;
|
|
1067
|
+
}
|
|
1290
1068
|
// Get current selection state
|
|
1291
1069
|
var isSelected = this._state.isSelected(value);
|
|
1292
1070
|
if (this._config.debug)
|
|
@@ -1454,7 +1232,7 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
1454
1232
|
*/
|
|
1455
1233
|
KTSelect.prototype._renderSearchLoadingState = function () {
|
|
1456
1234
|
if (!this._originalOptionsHtml && this._dropdownContentElement) {
|
|
1457
|
-
var optionsContainer = this._dropdownContentElement.querySelector('[data-kt-select-options
|
|
1235
|
+
var optionsContainer = this._dropdownContentElement.querySelector('[data-kt-select-options]');
|
|
1458
1236
|
if (optionsContainer) {
|
|
1459
1237
|
this._originalOptionsHtml = optionsContainer.innerHTML;
|
|
1460
1238
|
}
|
|
@@ -1473,36 +1251,26 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
1473
1251
|
* @param items Search result items
|
|
1474
1252
|
*/
|
|
1475
1253
|
KTSelect.prototype._updateSearchResults = function (items) {
|
|
1476
|
-
var _this = this;
|
|
1477
1254
|
if (!this._dropdownContentElement)
|
|
1478
1255
|
return;
|
|
1479
|
-
var optionsContainer = this._dropdownContentElement.querySelector('[data-kt-select-options
|
|
1256
|
+
var optionsContainer = this._dropdownContentElement.querySelector('[data-kt-select-options]');
|
|
1480
1257
|
if (!optionsContainer)
|
|
1481
1258
|
return;
|
|
1482
1259
|
// Clear current options
|
|
1483
1260
|
optionsContainer.innerHTML = '';
|
|
1484
1261
|
if (items.length === 0) {
|
|
1485
1262
|
// Show no results message using template for consistency and customization
|
|
1486
|
-
var noResultsElement = defaultTemplates.
|
|
1263
|
+
var noResultsElement = defaultTemplates.empty(this._config);
|
|
1487
1264
|
optionsContainer.appendChild(noResultsElement);
|
|
1488
1265
|
return;
|
|
1489
1266
|
}
|
|
1490
1267
|
// Process each item individually to create options
|
|
1491
1268
|
items.forEach(function (item) {
|
|
1492
1269
|
// Create option for the original select
|
|
1493
|
-
var selectOption =
|
|
1270
|
+
var selectOption = document.createElement('option');
|
|
1494
1271
|
selectOption.value = item.id;
|
|
1495
|
-
if (item.description) {
|
|
1496
|
-
selectOption.setAttribute('data-kt-select-option-description', item.description);
|
|
1497
|
-
}
|
|
1498
|
-
if (item.icon) {
|
|
1499
|
-
selectOption.setAttribute('data-kt-select-option-icon', item.icon);
|
|
1500
|
-
}
|
|
1501
|
-
// Create option element for the dropdown
|
|
1502
|
-
var ktOption = new KTSelectOption(selectOption, _this._config);
|
|
1503
|
-
var renderedOption = ktOption.render();
|
|
1504
1272
|
// Add to dropdown container
|
|
1505
|
-
optionsContainer.appendChild(
|
|
1273
|
+
optionsContainer.appendChild(selectOption);
|
|
1506
1274
|
});
|
|
1507
1275
|
// Add pagination "Load More" button if needed
|
|
1508
1276
|
if (this._config.pagination && this._remoteModule.hasMorePages()) {
|
|
@@ -1511,18 +1279,137 @@ var KTSelect = /** @class */ (function (_super) {
|
|
|
1511
1279
|
// Update options NodeList
|
|
1512
1280
|
this._options = this._wrapperElement.querySelectorAll("[data-kt-select-option]");
|
|
1513
1281
|
};
|
|
1514
|
-
/**
|
|
1515
|
-
* Filter options by query
|
|
1516
|
-
*/
|
|
1517
|
-
KTSelect.prototype.filterOptions = function (query) {
|
|
1518
|
-
this._filterOptionsForCombobox(query);
|
|
1519
|
-
};
|
|
1520
1282
|
/**
|
|
1521
1283
|
* Check if dropdown is open
|
|
1522
1284
|
*/
|
|
1523
1285
|
KTSelect.prototype.isDropdownOpen = function () {
|
|
1524
1286
|
return this._dropdownIsOpen;
|
|
1525
1287
|
};
|
|
1288
|
+
KTSelect.prototype.getSelectedOptionsText = function () {
|
|
1289
|
+
var _this = this;
|
|
1290
|
+
var selectedValues = this.getSelectedOptions();
|
|
1291
|
+
var displaySeparator = this._config.displaySeparator || ', ';
|
|
1292
|
+
var texts = selectedValues.map(function (value) {
|
|
1293
|
+
var option = Array.from(_this._options).find(function (opt) { return opt.getAttribute('data-value') === value; });
|
|
1294
|
+
return (option === null || option === void 0 ? void 0 : option.getAttribute('data-text')) || '';
|
|
1295
|
+
}).filter(Boolean);
|
|
1296
|
+
return texts.join(displaySeparator);
|
|
1297
|
+
};
|
|
1298
|
+
/**
|
|
1299
|
+
* Check if an option is disabled (either in dropdown or original select)
|
|
1300
|
+
*/
|
|
1301
|
+
KTSelect.prototype._isOptionDisabled = function (value) {
|
|
1302
|
+
var dropdownOption = Array.from(this._options).find(function (opt) { return opt.getAttribute('data-value') === value; });
|
|
1303
|
+
var isDropdownDisabled = dropdownOption && (dropdownOption.classList.contains('disabled') || dropdownOption.getAttribute('aria-disabled') === 'true');
|
|
1304
|
+
var selectOption = Array.from(this._element.querySelectorAll('option')).find(function (opt) { return opt.value === value; });
|
|
1305
|
+
var isNativeDisabled = selectOption && selectOption.disabled;
|
|
1306
|
+
return Boolean(isDropdownDisabled || isNativeDisabled);
|
|
1307
|
+
};
|
|
1308
|
+
/**
|
|
1309
|
+
* Centralized keyboard event handler for all select modes
|
|
1310
|
+
*/
|
|
1311
|
+
KTSelect.prototype._handleKeyboardEvent = function (event) {
|
|
1312
|
+
var isOpen = this._dropdownIsOpen;
|
|
1313
|
+
var config = this._config;
|
|
1314
|
+
var focusManager = this._focusManager;
|
|
1315
|
+
var buffer = this._typeToSearchBuffer;
|
|
1316
|
+
// Ignore modifier keys
|
|
1317
|
+
if (event.altKey || event.ctrlKey || event.metaKey)
|
|
1318
|
+
return;
|
|
1319
|
+
// Type-to-search: only for single char keys
|
|
1320
|
+
if (event.key.length === 1 && !event.repeat && !event.key.match(/\s/)) {
|
|
1321
|
+
buffer.push(event.key);
|
|
1322
|
+
var str = buffer.getBuffer();
|
|
1323
|
+
focusManager.focusByString(str);
|
|
1324
|
+
return;
|
|
1325
|
+
}
|
|
1326
|
+
switch (event.key) {
|
|
1327
|
+
case 'ArrowDown':
|
|
1328
|
+
event.preventDefault();
|
|
1329
|
+
if (!isOpen) {
|
|
1330
|
+
this.openDropdown();
|
|
1331
|
+
}
|
|
1332
|
+
else {
|
|
1333
|
+
focusManager.focusNext();
|
|
1334
|
+
}
|
|
1335
|
+
break;
|
|
1336
|
+
case 'ArrowUp':
|
|
1337
|
+
event.preventDefault();
|
|
1338
|
+
if (!isOpen) {
|
|
1339
|
+
this.openDropdown();
|
|
1340
|
+
}
|
|
1341
|
+
else {
|
|
1342
|
+
focusManager.focusPrevious();
|
|
1343
|
+
}
|
|
1344
|
+
break;
|
|
1345
|
+
case 'Home':
|
|
1346
|
+
event.preventDefault();
|
|
1347
|
+
if (isOpen)
|
|
1348
|
+
focusManager.focusFirst();
|
|
1349
|
+
break;
|
|
1350
|
+
case 'End':
|
|
1351
|
+
event.preventDefault();
|
|
1352
|
+
if (isOpen)
|
|
1353
|
+
focusManager.focusLast();
|
|
1354
|
+
break;
|
|
1355
|
+
case 'Enter':
|
|
1356
|
+
case ' ': // Space
|
|
1357
|
+
if (isOpen) {
|
|
1358
|
+
var focused = focusManager.getFocusedOption();
|
|
1359
|
+
if (focused) {
|
|
1360
|
+
var value = focused.dataset.value;
|
|
1361
|
+
if (value) {
|
|
1362
|
+
this.toggleSelection(value);
|
|
1363
|
+
if (!config.multiple && config.closeOnSelect) {
|
|
1364
|
+
this.closeDropdown();
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
1368
|
+
// Prevent form submit
|
|
1369
|
+
event.preventDefault();
|
|
1370
|
+
}
|
|
1371
|
+
else {
|
|
1372
|
+
this.openDropdown();
|
|
1373
|
+
}
|
|
1374
|
+
break;
|
|
1375
|
+
case 'Escape':
|
|
1376
|
+
if (isOpen) {
|
|
1377
|
+
this.closeDropdown();
|
|
1378
|
+
event.target.blur();
|
|
1379
|
+
}
|
|
1380
|
+
break;
|
|
1381
|
+
case 'Tab':
|
|
1382
|
+
// Let Tab propagate for normal focus movement
|
|
1383
|
+
break;
|
|
1384
|
+
default:
|
|
1385
|
+
break;
|
|
1386
|
+
}
|
|
1387
|
+
};
|
|
1388
|
+
KTSelect.prototype.renderDisplayTemplateForSelected = function (selectedValues) {
|
|
1389
|
+
var _this = this;
|
|
1390
|
+
var optionsConfig = this._config.optionsConfig || {};
|
|
1391
|
+
var displaySeparator = this._config.displaySeparator || ', ';
|
|
1392
|
+
var contentArray = Array.from(new Set(selectedValues.map(function (value) {
|
|
1393
|
+
var option = Array.from(_this._options).find(function (opt) { return opt.getAttribute('data-value') === value; });
|
|
1394
|
+
if (!option)
|
|
1395
|
+
return '';
|
|
1396
|
+
var displayTemplate = _this._config.displayTemplate;
|
|
1397
|
+
var text = option.getAttribute('data-text') || '';
|
|
1398
|
+
// Replace all {{varname}} in option.innerHTML with values from _config
|
|
1399
|
+
Object.entries(optionsConfig[value] || {}).forEach(function (_a) {
|
|
1400
|
+
var key = _a[0], val = _a[1];
|
|
1401
|
+
if (["string", "number", "boolean"].includes(typeof val)) {
|
|
1402
|
+
displayTemplate = displayTemplate.replace(new RegExp("{{".concat(key, "}}"), 'g'), String(val));
|
|
1403
|
+
}
|
|
1404
|
+
});
|
|
1405
|
+
return renderTemplateString(displayTemplate, {
|
|
1406
|
+
selectedCount: selectedValues.length || 0,
|
|
1407
|
+
selectedTexts: _this.getSelectedOptionsText() || '',
|
|
1408
|
+
text: text,
|
|
1409
|
+
});
|
|
1410
|
+
}).filter(Boolean)));
|
|
1411
|
+
return contentArray.join(displaySeparator);
|
|
1412
|
+
};
|
|
1526
1413
|
/**
|
|
1527
1414
|
* ========================================================================
|
|
1528
1415
|
* STATIC METHODS
|