@keenthemes/ktui 1.0.25 → 1.0.26
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 +213 -33
- package/dist/ktui.min.js +1 -1
- package/dist/ktui.min.js.map +1 -1
- package/dist/styles.css +210 -0
- package/examples/datatable/checkbox-events-test.html +400 -0
- package/examples/datatable/credentials-test.html +423 -0
- package/examples/datatable/remote-checkbox-test.html +365 -0
- package/examples/modal/persistent-test.html +205 -0
- package/examples/select/formdata-remote-test.html +161 -0
- package/examples/select/modal-positioning-test.html +336 -0
- package/lib/cjs/components/datatable/datatable-checkbox.js +16 -3
- package/lib/cjs/components/datatable/datatable-checkbox.js.map +1 -1
- package/lib/cjs/components/datatable/datatable.js +3 -5
- package/lib/cjs/components/datatable/datatable.js.map +1 -1
- package/lib/cjs/components/image-input/image-input.js.map +1 -1
- package/lib/cjs/components/modal/modal.js +3 -1
- package/lib/cjs/components/modal/modal.js.map +1 -1
- package/lib/cjs/components/select/config.js +5 -0
- package/lib/cjs/components/select/config.js.map +1 -1
- package/lib/cjs/components/select/dropdown.js +25 -2
- package/lib/cjs/components/select/dropdown.js.map +1 -1
- package/lib/cjs/components/select/select.js +161 -22
- package/lib/cjs/components/select/select.js.map +1 -1
- package/lib/cjs/components/select/templates.js.map +1 -1
- package/lib/esm/components/datatable/datatable-checkbox.js +16 -3
- package/lib/esm/components/datatable/datatable-checkbox.js.map +1 -1
- package/lib/esm/components/datatable/datatable.js +3 -5
- package/lib/esm/components/datatable/datatable.js.map +1 -1
- package/lib/esm/components/image-input/image-input.js.map +1 -1
- package/lib/esm/components/modal/modal.js +3 -1
- package/lib/esm/components/modal/modal.js.map +1 -1
- package/lib/esm/components/select/config.js +5 -0
- package/lib/esm/components/select/config.js.map +1 -1
- package/lib/esm/components/select/dropdown.js +25 -2
- package/lib/esm/components/select/dropdown.js.map +1 -1
- package/lib/esm/components/select/select.js +161 -22
- package/lib/esm/components/select/select.js.map +1 -1
- package/lib/esm/components/select/templates.js.map +1 -1
- package/package.json +1 -1
- package/src/components/datatable/datatable-checkbox.ts +18 -3
- package/src/components/datatable/datatable.ts +3 -0
- package/src/components/datatable/types.ts +1 -0
- package/src/components/image-input/image-input.ts +12 -15
- package/src/components/modal/modal.ts +5 -1
- package/src/components/select/config.ts +6 -0
- package/src/components/select/dropdown.ts +32 -3
- package/src/components/select/select.ts +192 -35
- package/src/components/select/templates.ts +2 -1
|
@@ -28,10 +28,7 @@ export class KTImageInput extends KTComponent implements KTImageInputInterface {
|
|
|
28
28
|
protected _lastMode: string;
|
|
29
29
|
protected _selectedFile: File | null = null;
|
|
30
30
|
|
|
31
|
-
constructor(
|
|
32
|
-
element: HTMLElement,
|
|
33
|
-
config?: KTImageInputConfigInterface,
|
|
34
|
-
) {
|
|
31
|
+
constructor(element: HTMLElement, config?: KTImageInputConfigInterface) {
|
|
35
32
|
super();
|
|
36
33
|
|
|
37
34
|
if (KTData.has(element as HTMLElement, this._name)) return;
|
|
@@ -39,14 +36,14 @@ export class KTImageInput extends KTComponent implements KTImageInputInterface {
|
|
|
39
36
|
this._init(element);
|
|
40
37
|
this._buildConfig(config);
|
|
41
38
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
39
|
+
this._inputElement = this._element.querySelector('input[type="file"]')!;
|
|
40
|
+
this._hiddenElement = this._element.querySelector('input[type="hidden"]')!;
|
|
41
|
+
this._removeElement = this._element.querySelector(
|
|
42
|
+
'[data-kt-image-input-remove]',
|
|
43
|
+
)!;
|
|
44
|
+
this._previewElement = this._element.querySelector(
|
|
45
|
+
'[data-kt-image-input-preview]',
|
|
46
|
+
)!;
|
|
50
47
|
|
|
51
48
|
this._update();
|
|
52
49
|
this._handlers();
|
|
@@ -87,9 +84,9 @@ export class KTImageInput extends KTComponent implements KTImageInputInterface {
|
|
|
87
84
|
this._previewElement.style.backgroundImage = `url(${reader.result})`;
|
|
88
85
|
};
|
|
89
86
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
87
|
+
reader.readAsDataURL(this._inputElement.files[0]);
|
|
88
|
+
this._selectedFile = this._inputElement.files[0];
|
|
89
|
+
this._lastMode = 'new';
|
|
93
90
|
|
|
94
91
|
this._element.classList.add('changed');
|
|
95
92
|
this._removeElement.classList.remove('hidden');
|
|
@@ -50,7 +50,11 @@ export class KTModal extends KTComponent implements KTModalInterface {
|
|
|
50
50
|
this._element.addEventListener('click', (event: Event) => {
|
|
51
51
|
if (this._element !== event.target) return;
|
|
52
52
|
|
|
53
|
-
if
|
|
53
|
+
// Only hide if both backdropStatic is false AND persistent is false
|
|
54
|
+
if (
|
|
55
|
+
this._getOption('backdropStatic') === false &&
|
|
56
|
+
KTUtils.stringToBoolean(this._getOption('persistent')) === false
|
|
57
|
+
) {
|
|
54
58
|
this._hide();
|
|
55
59
|
}
|
|
56
60
|
});
|
|
@@ -291,6 +291,12 @@ export class KTSelectState {
|
|
|
291
291
|
}
|
|
292
292
|
|
|
293
293
|
public setSelectedOptions(value: string | string[]): void {
|
|
294
|
+
// Handle empty array case first to prevent undefined elements
|
|
295
|
+
if (Array.isArray(value) && value.length === 0) {
|
|
296
|
+
this._selectedOptions = [];
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
|
|
294
300
|
if (
|
|
295
301
|
this._config.multiple &&
|
|
296
302
|
typeof value === 'string' &&
|
|
@@ -152,6 +152,31 @@ export class KTSelectDropdown extends KTComponent {
|
|
|
152
152
|
}
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
+
/**
|
|
156
|
+
* Detect if the select is inside a modal container
|
|
157
|
+
* @returns The modal element if found, null otherwise
|
|
158
|
+
*/
|
|
159
|
+
private _getModalContainer(): HTMLElement | null {
|
|
160
|
+
return this._element.closest(
|
|
161
|
+
'[data-kt-modal], .kt-modal, .kt-modal-center',
|
|
162
|
+
) as HTMLElement | null;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Get the appropriate positioning strategy based on context
|
|
167
|
+
* @returns 'fixed' if inside modal, 'absolute' otherwise
|
|
168
|
+
*/
|
|
169
|
+
private _getPositioningStrategy(): 'fixed' | 'absolute' {
|
|
170
|
+
// Check if config explicitly sets strategy
|
|
171
|
+
if (this._config.dropdownStrategy) {
|
|
172
|
+
return this._config.dropdownStrategy as 'fixed' | 'absolute';
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Use fixed positioning if inside a modal (to handle transform-based centering)
|
|
176
|
+
const modalParent = this._getModalContainer();
|
|
177
|
+
return modalParent ? 'fixed' : 'absolute';
|
|
178
|
+
}
|
|
179
|
+
|
|
155
180
|
/**
|
|
156
181
|
* Initialize the Popper instance for dropdown positioning
|
|
157
182
|
*/
|
|
@@ -164,17 +189,21 @@ export class KTSelectDropdown extends KTComponent {
|
|
|
164
189
|
|
|
165
190
|
// Get configuration options
|
|
166
191
|
const placement = this._config.dropdownPlacement || 'bottom-start';
|
|
167
|
-
const strategy = this.
|
|
192
|
+
const strategy = this._getPositioningStrategy();
|
|
168
193
|
const preventOverflow = this._config.dropdownPreventOverflow !== false;
|
|
169
194
|
const flip = this._config.dropdownFlip !== false;
|
|
170
195
|
|
|
196
|
+
// Detect modal container for boundary
|
|
197
|
+
const modalParent = this._getModalContainer();
|
|
198
|
+
const boundary = modalParent || 'clippingParents';
|
|
199
|
+
|
|
171
200
|
// Create new popper instance
|
|
172
201
|
this._popperInstance = createPopper(
|
|
173
202
|
this._toggleElement,
|
|
174
203
|
this._dropdownElement,
|
|
175
204
|
{
|
|
176
205
|
placement: placement as Placement,
|
|
177
|
-
strategy: strategy
|
|
206
|
+
strategy: strategy,
|
|
178
207
|
modifiers: [
|
|
179
208
|
{
|
|
180
209
|
name: 'offset',
|
|
@@ -185,7 +214,7 @@ export class KTSelectDropdown extends KTComponent {
|
|
|
185
214
|
{
|
|
186
215
|
name: 'preventOverflow',
|
|
187
216
|
options: {
|
|
188
|
-
boundary:
|
|
217
|
+
boundary: boundary,
|
|
189
218
|
altAxis: preventOverflow,
|
|
190
219
|
},
|
|
191
220
|
},
|
|
@@ -1223,6 +1223,24 @@ export class KTSelect extends KTComponent {
|
|
|
1223
1223
|
});
|
|
1224
1224
|
}
|
|
1225
1225
|
|
|
1226
|
+
/**
|
|
1227
|
+
* Sync native select value attribute for FormData support
|
|
1228
|
+
*/
|
|
1229
|
+
private _syncNativeSelectValue(): void {
|
|
1230
|
+
const selectedOptions = this.getSelectedOptions();
|
|
1231
|
+
|
|
1232
|
+
if (this._config.multiple) {
|
|
1233
|
+
// For multiple select, the selected options are marked via option.selected
|
|
1234
|
+
// The native select's value property will return the first selected option's value
|
|
1235
|
+
// FormData will include all selected values automatically
|
|
1236
|
+
} else {
|
|
1237
|
+
// For single select, set the value attribute explicitly
|
|
1238
|
+
const selectedValue =
|
|
1239
|
+
selectedOptions.length > 0 ? selectedOptions[0] : '';
|
|
1240
|
+
(this._element as HTMLSelectElement).value = selectedValue;
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1226
1244
|
/**
|
|
1227
1245
|
* Update selected option display value
|
|
1228
1246
|
*/
|
|
@@ -1231,6 +1249,9 @@ export class KTSelect extends KTComponent {
|
|
|
1231
1249
|
const tagsEnabled = this._config.tags && this._tagsModule;
|
|
1232
1250
|
const valueDisplayEl = this.getValueDisplayElement();
|
|
1233
1251
|
|
|
1252
|
+
// Sync native select value for FormData support
|
|
1253
|
+
this._syncNativeSelectValue();
|
|
1254
|
+
|
|
1234
1255
|
if (tagsEnabled) {
|
|
1235
1256
|
// Tags module will render tags if selectedOptions > 0, or clear them if selectedOptions === 0.
|
|
1236
1257
|
this._tagsModule.updateTagsDisplay(selectedOptions);
|
|
@@ -1349,6 +1370,9 @@ export class KTSelect extends KTComponent {
|
|
|
1349
1370
|
(opt as HTMLOptionElement).selected = false;
|
|
1350
1371
|
});
|
|
1351
1372
|
|
|
1373
|
+
// Clear native select value
|
|
1374
|
+
(this._element as HTMLSelectElement).value = '';
|
|
1375
|
+
|
|
1352
1376
|
this.updateSelectedOptionDisplay();
|
|
1353
1377
|
this._updateSelectedOptionClass();
|
|
1354
1378
|
|
|
@@ -1805,46 +1829,178 @@ export class KTSelect extends KTComponent {
|
|
|
1805
1829
|
|
|
1806
1830
|
/**
|
|
1807
1831
|
* Update the dropdown to sync with native select element changes
|
|
1808
|
-
*
|
|
1832
|
+
* For remote selects, refetches data from the server
|
|
1833
|
+
* Optionally accepts new options to replace existing ones (static selects only)
|
|
1809
1834
|
* @param newOptions Optional array of new options [{value, text}, ...]
|
|
1810
1835
|
* @public
|
|
1811
1836
|
*/
|
|
1812
1837
|
public update(newOptions?: Array<{ value: string; text: string }>): void {
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
this.
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1838
|
+
// For remote selects, refetch data
|
|
1839
|
+
if (this._config.remote && this._remoteModule) {
|
|
1840
|
+
this._remoteModule
|
|
1841
|
+
.fetchData()
|
|
1842
|
+
.then((items) => {
|
|
1843
|
+
// Clear existing options
|
|
1844
|
+
this._clearExistingOptions();
|
|
1845
|
+
|
|
1846
|
+
// Add new options from remote data
|
|
1847
|
+
items.forEach((item) => {
|
|
1848
|
+
const option = document.createElement('option');
|
|
1849
|
+
option.value = item.id;
|
|
1850
|
+
option.textContent = item.title;
|
|
1851
|
+
if (item.disabled) option.disabled = true;
|
|
1852
|
+
this._element.appendChild(option);
|
|
1853
|
+
});
|
|
1854
|
+
|
|
1855
|
+
// Rebuild dropdown
|
|
1856
|
+
this._rebuildOptionsFromNative();
|
|
1857
|
+
|
|
1858
|
+
// Dispatch updated event
|
|
1859
|
+
this._dispatchEvent('updated');
|
|
1860
|
+
this._fireEvent('updated');
|
|
1861
|
+
})
|
|
1862
|
+
.catch((error) => {
|
|
1863
|
+
console.error('Error updating remote data:', error);
|
|
1864
|
+
this._dispatchEvent('updateError');
|
|
1865
|
+
this._fireEvent('updateError');
|
|
1866
|
+
});
|
|
1867
|
+
} else {
|
|
1868
|
+
// For static selects, handle new options
|
|
1869
|
+
if (newOptions) {
|
|
1870
|
+
// Clear existing options except placeholder
|
|
1871
|
+
this._clearExistingOptions();
|
|
1872
|
+
|
|
1873
|
+
// Add new options to native select
|
|
1874
|
+
newOptions.forEach((opt) => {
|
|
1875
|
+
const option = document.createElement('option');
|
|
1876
|
+
option.value = opt.value;
|
|
1877
|
+
option.textContent = opt.text;
|
|
1878
|
+
this._element.appendChild(option);
|
|
1879
|
+
});
|
|
1880
|
+
}
|
|
1881
|
+
|
|
1882
|
+
// Rebuild dropdown from native select
|
|
1883
|
+
this._rebuildOptionsFromNative();
|
|
1884
|
+
|
|
1885
|
+
// Dispatch updated event
|
|
1886
|
+
this._dispatchEvent('updated');
|
|
1887
|
+
this._fireEvent('updated');
|
|
1824
1888
|
}
|
|
1889
|
+
}
|
|
1890
|
+
|
|
1891
|
+
/**
|
|
1892
|
+
* Reload remote data and rebuild the dropdown
|
|
1893
|
+
* Only works with remote data enabled
|
|
1894
|
+
* @returns Promise that resolves when reload completes
|
|
1895
|
+
* @public
|
|
1896
|
+
*/
|
|
1897
|
+
public reload(): Promise<void> {
|
|
1898
|
+
// Guard clause: only works with remote data
|
|
1899
|
+
if (!this._config.remote || !this._remoteModule) {
|
|
1900
|
+
console.warn('reload() only works with remote data enabled');
|
|
1901
|
+
return Promise.resolve();
|
|
1902
|
+
}
|
|
1903
|
+
|
|
1904
|
+
// Dispatch reload start event
|
|
1905
|
+
this._dispatchEvent('reloadStart');
|
|
1906
|
+
this._fireEvent('reloadStart');
|
|
1907
|
+
|
|
1908
|
+
// Fetch fresh remote data
|
|
1909
|
+
return this._remoteModule
|
|
1910
|
+
.fetchData()
|
|
1911
|
+
.then((items) => {
|
|
1912
|
+
// Clear existing options
|
|
1913
|
+
this._clearExistingOptions();
|
|
1914
|
+
|
|
1915
|
+
// Update state with new items
|
|
1916
|
+
return this._state.setItems(items).then(() => {
|
|
1917
|
+
// Generate new options HTML
|
|
1918
|
+
this._generateOptionsHtml(this._element);
|
|
1919
|
+
|
|
1920
|
+
// Update the dropdown
|
|
1921
|
+
this._updateDropdownWithNewOptions();
|
|
1922
|
+
|
|
1923
|
+
// Sync selection state from native select
|
|
1924
|
+
this._syncSelectionFromNative();
|
|
1925
|
+
|
|
1926
|
+
// Update visual display
|
|
1927
|
+
this.updateSelectedOptionDisplay();
|
|
1928
|
+
this._updateSelectedOptionClass();
|
|
1929
|
+
|
|
1930
|
+
// Update select all button state if applicable
|
|
1931
|
+
if (this._config.multiple && this._config.enableSelectAll) {
|
|
1932
|
+
this.updateSelectAllButtonState();
|
|
1933
|
+
}
|
|
1825
1934
|
|
|
1826
|
-
|
|
1827
|
-
|
|
1935
|
+
// Dispatch reload complete event
|
|
1936
|
+
this._dispatchEvent('reloadComplete');
|
|
1937
|
+
this._fireEvent('reloadComplete');
|
|
1938
|
+
});
|
|
1939
|
+
})
|
|
1940
|
+
.catch((error) => {
|
|
1941
|
+
console.error('Error reloading remote data:', error);
|
|
1828
1942
|
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1943
|
+
// Dispatch reload error event with error details
|
|
1944
|
+
this._dispatchEvent('reloadError', { error });
|
|
1945
|
+
this._fireEvent('reloadError', { error });
|
|
1946
|
+
|
|
1947
|
+
// Re-throw error so caller can handle it
|
|
1948
|
+
throw error;
|
|
1949
|
+
});
|
|
1832
1950
|
}
|
|
1833
1951
|
|
|
1834
1952
|
/**
|
|
1835
1953
|
* Refresh the visual display and state without rebuilding options
|
|
1954
|
+
* For remote selects, refetches data from the server
|
|
1836
1955
|
* @public
|
|
1837
1956
|
*/
|
|
1838
1957
|
public refresh(): void {
|
|
1839
|
-
//
|
|
1840
|
-
this.
|
|
1958
|
+
// For remote selects, refetch data
|
|
1959
|
+
if (this._config.remote && this._remoteModule) {
|
|
1960
|
+
this._remoteModule
|
|
1961
|
+
.fetchData()
|
|
1962
|
+
.then((items) => {
|
|
1963
|
+
// Clear existing options
|
|
1964
|
+
this._clearExistingOptions();
|
|
1965
|
+
|
|
1966
|
+
// Add new options
|
|
1967
|
+
items.forEach((item) => {
|
|
1968
|
+
const option = document.createElement('option');
|
|
1969
|
+
option.value = item.id;
|
|
1970
|
+
option.textContent = item.title;
|
|
1971
|
+
if (item.disabled) option.disabled = true;
|
|
1972
|
+
this._element.appendChild(option);
|
|
1973
|
+
});
|
|
1841
1974
|
|
|
1842
|
-
|
|
1843
|
-
|
|
1975
|
+
// Rebuild dropdown
|
|
1976
|
+
this._rebuildOptionsFromNative();
|
|
1977
|
+
|
|
1978
|
+
// Sync selection state
|
|
1979
|
+
this._syncSelectionFromNative();
|
|
1980
|
+
|
|
1981
|
+
// Reapply ARIA attributes
|
|
1982
|
+
this._setAriaAttributes();
|
|
1983
|
+
|
|
1984
|
+
// Dispatch refreshed event
|
|
1985
|
+
this._dispatchEvent('refreshed');
|
|
1986
|
+
this._fireEvent('refreshed');
|
|
1987
|
+
})
|
|
1988
|
+
.catch((error) => {
|
|
1989
|
+
console.error('Error refreshing remote data:', error);
|
|
1990
|
+
this._dispatchEvent('refreshError');
|
|
1991
|
+
this._fireEvent('refreshError');
|
|
1992
|
+
});
|
|
1993
|
+
} else {
|
|
1994
|
+
// For static selects, just sync visual state
|
|
1995
|
+
this._syncSelectionFromNative();
|
|
1996
|
+
|
|
1997
|
+
// Reapply ARIA attributes
|
|
1998
|
+
this._setAriaAttributes();
|
|
1844
1999
|
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
2000
|
+
// Dispatch refreshed event
|
|
2001
|
+
this._dispatchEvent('refreshed');
|
|
2002
|
+
this._fireEvent('refreshed');
|
|
2003
|
+
}
|
|
1848
2004
|
}
|
|
1849
2005
|
|
|
1850
2006
|
/**
|
|
@@ -1853,7 +2009,6 @@ export class KTSelect extends KTComponent {
|
|
|
1853
2009
|
* ========================================================================
|
|
1854
2010
|
*/
|
|
1855
2011
|
|
|
1856
|
-
|
|
1857
2012
|
/**
|
|
1858
2013
|
* Create instances of KTSelect for all matching elements
|
|
1859
2014
|
*/
|
|
@@ -2091,7 +2246,9 @@ export class KTSelect extends KTComponent {
|
|
|
2091
2246
|
});
|
|
2092
2247
|
|
|
2093
2248
|
if (this._config.debug) {
|
|
2094
|
-
console.log(
|
|
2249
|
+
console.log(
|
|
2250
|
+
`Updated original select with ${items.length} search results`,
|
|
2251
|
+
);
|
|
2095
2252
|
}
|
|
2096
2253
|
}
|
|
2097
2254
|
|
|
@@ -2367,16 +2524,16 @@ export class KTSelect extends KTComponent {
|
|
|
2367
2524
|
return;
|
|
2368
2525
|
}
|
|
2369
2526
|
const selectOption = new KTSelectOption(optionElement, this._config);
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2527
|
+
const renderedOption = selectOption.render();
|
|
2528
|
+
optionsContainer.appendChild(renderedOption);
|
|
2529
|
+
});
|
|
2530
|
+
// Update internal references
|
|
2531
|
+
this._options = this._dropdownContentElement.querySelectorAll(
|
|
2532
|
+
'[data-kt-select-option]',
|
|
2533
|
+
) as NodeListOf<HTMLElement>;
|
|
2534
|
+
}
|
|
2377
2535
|
}
|
|
2378
|
-
|
|
2379
|
-
// Sync selection after rebuilding
|
|
2536
|
+
// Sync selection after rebuilding
|
|
2380
2537
|
this._syncSelectionFromNative();
|
|
2381
2538
|
this.updateSelectedOptionDisplay();
|
|
2382
2539
|
this._updateSelectedOptionClass();
|
|
@@ -393,7 +393,8 @@ export const defaultTemplates: KTSelectTemplateInterface = {
|
|
|
393
393
|
config: KTSelectConfigInterface,
|
|
394
394
|
): HTMLElement => {
|
|
395
395
|
let template = getTemplateStrings(config).tag;
|
|
396
|
-
let preparedContent =
|
|
396
|
+
let preparedContent =
|
|
397
|
+
option.textContent || option.innerText || option.value || ''; // Default content is the option's text
|
|
397
398
|
|
|
398
399
|
if (config.tagTemplate) {
|
|
399
400
|
let tagTemplateString = config.tagTemplate;
|