@keenthemes/ktui 1.0.24 → 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 +337 -18
- package/dist/ktui.min.js +1 -1
- package/dist/ktui.min.js.map +1 -1
- package/dist/styles.css +319 -11
- 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/dark-mode-test.html +93 -0
- package/examples/select/dropdowncontainer-test.html +111 -0
- package/examples/select/dynamic-methods.html +273 -0
- package/examples/select/formdata-remote-test.html +161 -0
- package/examples/select/modal-positioning-test.html +336 -0
- package/examples/select/remote-data-preselected.html +283 -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 +285 -7
- 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 +285 -7
- 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.css +4 -4
- package/src/components/select/select.ts +350 -9
- package/src/components/select/templates.ts +2 -1
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>Modal Positioning Test</title>
|
|
7
|
+
<link rel="stylesheet" href="../../dist/styles.css" />
|
|
8
|
+
</head>
|
|
9
|
+
|
|
10
|
+
<body class="bg-gray-50 min-h-screen">
|
|
11
|
+
<div class="bg-white rounded-lg shadow p-8 w-full max-w-2xl mt-10 mx-auto">
|
|
12
|
+
<h1 class="text-xl font-semibold text-gray-900 mb-2">
|
|
13
|
+
Modal Positioning Test
|
|
14
|
+
</h1>
|
|
15
|
+
<p class="text-sm text-gray-600 mb-6">
|
|
16
|
+
Verifies KTSelect dropdowns position correctly inside modals.
|
|
17
|
+
</p>
|
|
18
|
+
|
|
19
|
+
<div class="flex flex-col gap-4">
|
|
20
|
+
<button
|
|
21
|
+
data-kt-modal-toggle="#modal-basic"
|
|
22
|
+
class="px-4 py-2 bg-white border border-gray-300 text-gray-700 text-sm font-medium rounded hover:bg-gray-50 text-left">
|
|
23
|
+
<div class="font-medium">Basic Modal</div>
|
|
24
|
+
<div class="text-xs text-gray-500 mt-0.5">
|
|
25
|
+
Standard modal without centering
|
|
26
|
+
</div>
|
|
27
|
+
</button>
|
|
28
|
+
|
|
29
|
+
<button
|
|
30
|
+
data-kt-modal-toggle="#modal-centered"
|
|
31
|
+
class="px-4 py-2 bg-white border border-gray-300 text-gray-700 text-sm font-medium rounded hover:bg-gray-50 text-left">
|
|
32
|
+
<div class="font-medium">Centered Modal (kt-modal-center)</div>
|
|
33
|
+
<div class="text-xs text-gray-500 mt-0.5">
|
|
34
|
+
Critical test - previously caused bottom-right bug
|
|
35
|
+
</div>
|
|
36
|
+
</button>
|
|
37
|
+
|
|
38
|
+
<button
|
|
39
|
+
data-kt-modal-toggle="#modal-remote"
|
|
40
|
+
class="px-4 py-2 bg-white border border-gray-300 text-gray-700 text-sm font-medium rounded hover:bg-gray-50 text-left">
|
|
41
|
+
<div class="font-medium">Modal with Remote Select</div>
|
|
42
|
+
<div class="text-xs text-gray-500 mt-0.5">
|
|
43
|
+
Tests reload() and clearSelection() methods
|
|
44
|
+
</div>
|
|
45
|
+
</button>
|
|
46
|
+
</div>
|
|
47
|
+
|
|
48
|
+
<div class="mt-6 p-4 bg-gray-50 border border-gray-200 rounded">
|
|
49
|
+
<div class="font-medium text-gray-900 mb-2 text-sm">Control Test</div>
|
|
50
|
+
<select
|
|
51
|
+
data-kt-select="true"
|
|
52
|
+
class="kt-select"
|
|
53
|
+
data-kt-select-placeholder="Select an option...">
|
|
54
|
+
<option value="">Select an option...</option>
|
|
55
|
+
<option value="1">Option 1</option>
|
|
56
|
+
<option value="2">Option 2</option>
|
|
57
|
+
<option value="3">Option 3</option>
|
|
58
|
+
<option value="4">Option 4</option>
|
|
59
|
+
<option value="5">Option 5</option>
|
|
60
|
+
</select>
|
|
61
|
+
<p class="text-xs text-gray-500 mt-2">
|
|
62
|
+
Baseline - should position normally
|
|
63
|
+
</p>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
|
|
67
|
+
<!-- Basic Modal -->
|
|
68
|
+
<div
|
|
69
|
+
id="modal-basic"
|
|
70
|
+
data-kt-modal="true"
|
|
71
|
+
class="hidden fixed inset-0 z-50 overflow-y-auto">
|
|
72
|
+
<div
|
|
73
|
+
class="flex min-h-full items-center justify-center p-4">
|
|
74
|
+
<div
|
|
75
|
+
data-kt-modal-backdrop="true"
|
|
76
|
+
class="fixed inset-0 bg-gray-900 bg-opacity-50"></div>
|
|
77
|
+
|
|
78
|
+
<div
|
|
79
|
+
class="relative bg-white rounded-lg shadow-xl w-full max-w-lg border border-gray-200">
|
|
80
|
+
<div class="border-b border-gray-200 px-6 py-4">
|
|
81
|
+
<h3 class="text-base font-semibold text-gray-900">Basic Modal</h3>
|
|
82
|
+
</div>
|
|
83
|
+
|
|
84
|
+
<div class="px-6 py-5">
|
|
85
|
+
<label class="block mb-2 font-medium text-gray-700">
|
|
86
|
+
Select in Basic Modal
|
|
87
|
+
</label>
|
|
88
|
+
<select
|
|
89
|
+
data-kt-select="true"
|
|
90
|
+
class="kt-select"
|
|
91
|
+
data-kt-select-placeholder="Choose option...">
|
|
92
|
+
<option value="">Choose option...</option>
|
|
93
|
+
<option value="1">Option 1</option>
|
|
94
|
+
<option value="2">Option 2</option>
|
|
95
|
+
<option value="3">Option 3</option>
|
|
96
|
+
<option value="4">Option 4</option>
|
|
97
|
+
<option value="5">Option 5</option>
|
|
98
|
+
<option value="6">Option 6</option>
|
|
99
|
+
<option value="7">Option 7</option>
|
|
100
|
+
<option value="8">Option 8</option>
|
|
101
|
+
</select>
|
|
102
|
+
<p class="text-xs text-gray-500 mt-3">
|
|
103
|
+
Expected: Dropdown appears below/above select
|
|
104
|
+
</p>
|
|
105
|
+
</div>
|
|
106
|
+
|
|
107
|
+
<div class="border-t border-gray-200 px-6 py-4 flex justify-end">
|
|
108
|
+
<button
|
|
109
|
+
type="button"
|
|
110
|
+
data-kt-modal-dismiss="true"
|
|
111
|
+
class="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded hover:bg-gray-50">
|
|
112
|
+
Close
|
|
113
|
+
</button>
|
|
114
|
+
</div>
|
|
115
|
+
</div>
|
|
116
|
+
</div>
|
|
117
|
+
</div>
|
|
118
|
+
|
|
119
|
+
<!-- Centered Modal -->
|
|
120
|
+
<div
|
|
121
|
+
id="modal-centered"
|
|
122
|
+
data-kt-modal="true"
|
|
123
|
+
class="hidden fixed inset-0 z-50 overflow-y-auto">
|
|
124
|
+
<div
|
|
125
|
+
class="flex min-h-full items-center justify-center p-4 kt-modal-center">
|
|
126
|
+
<div
|
|
127
|
+
data-kt-modal-backdrop="true"
|
|
128
|
+
class="fixed inset-0 bg-gray-900 bg-opacity-50"></div>
|
|
129
|
+
|
|
130
|
+
<div
|
|
131
|
+
class="relative bg-white rounded-lg shadow-xl w-full max-w-lg border border-gray-200">
|
|
132
|
+
<div class="border-b border-gray-200 px-6 py-4">
|
|
133
|
+
<h3 class="text-base font-semibold text-gray-900">
|
|
134
|
+
Centered Modal (kt-modal-center)
|
|
135
|
+
</h3>
|
|
136
|
+
</div>
|
|
137
|
+
|
|
138
|
+
<div class="px-6 py-5">
|
|
139
|
+
<label class="block mb-2 font-medium text-gray-700">
|
|
140
|
+
Select in Centered Modal
|
|
141
|
+
</label>
|
|
142
|
+
<select
|
|
143
|
+
data-kt-select="true"
|
|
144
|
+
class="kt-select"
|
|
145
|
+
data-kt-select-placeholder="Choose option..."
|
|
146
|
+
data-kt-select-enable-search="true">
|
|
147
|
+
<option value="">Choose option...</option>
|
|
148
|
+
<option value="1">Option 1</option>
|
|
149
|
+
<option value="2">Option 2</option>
|
|
150
|
+
<option value="3">Option 3</option>
|
|
151
|
+
<option value="4">Option 4</option>
|
|
152
|
+
<option value="5">Option 5</option>
|
|
153
|
+
<option value="6">Option 6</option>
|
|
154
|
+
<option value="7">Option 7</option>
|
|
155
|
+
<option value="8">Option 8</option>
|
|
156
|
+
<option value="9">Option 9</option>
|
|
157
|
+
<option value="10">Option 10</option>
|
|
158
|
+
</select>
|
|
159
|
+
<p class="text-xs text-gray-500 mt-3 p-2 bg-gray-50 border border-gray-200 rounded">
|
|
160
|
+
<strong>Critical:</strong> Dropdown should NOT appear in
|
|
161
|
+
bottom-right corner
|
|
162
|
+
</p>
|
|
163
|
+
</div>
|
|
164
|
+
|
|
165
|
+
<div class="border-t border-gray-200 px-6 py-4 flex justify-end">
|
|
166
|
+
<button
|
|
167
|
+
type="button"
|
|
168
|
+
data-kt-modal-dismiss="true"
|
|
169
|
+
class="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded hover:bg-gray-50">
|
|
170
|
+
Close
|
|
171
|
+
</button>
|
|
172
|
+
</div>
|
|
173
|
+
</div>
|
|
174
|
+
</div>
|
|
175
|
+
</div>
|
|
176
|
+
|
|
177
|
+
<!-- Modal with Remote Select -->
|
|
178
|
+
<div
|
|
179
|
+
id="modal-remote"
|
|
180
|
+
data-kt-modal="true"
|
|
181
|
+
class="hidden fixed inset-0 z-50 overflow-y-auto">
|
|
182
|
+
<div
|
|
183
|
+
class="flex min-h-full items-center justify-center p-4 kt-modal-center">
|
|
184
|
+
<div
|
|
185
|
+
data-kt-modal-backdrop="true"
|
|
186
|
+
class="fixed inset-0 bg-gray-900 bg-opacity-50"></div>
|
|
187
|
+
|
|
188
|
+
<div
|
|
189
|
+
class="relative bg-white rounded-lg shadow-xl w-full max-w-lg border border-gray-200">
|
|
190
|
+
<div class="border-b border-gray-200 px-6 py-4">
|
|
191
|
+
<h3 class="text-base font-semibold text-gray-900">
|
|
192
|
+
Remote Select in Modal
|
|
193
|
+
</h3>
|
|
194
|
+
</div>
|
|
195
|
+
|
|
196
|
+
<div class="px-6 py-5">
|
|
197
|
+
<label class="block mb-2 font-medium text-gray-700">
|
|
198
|
+
Remote Select
|
|
199
|
+
</label>
|
|
200
|
+
<select
|
|
201
|
+
id="remoteSelectInModal"
|
|
202
|
+
data-kt-select="true"
|
|
203
|
+
class="kt-select"
|
|
204
|
+
data-kt-select-remote="true"
|
|
205
|
+
data-kt-select-data-url="https://jsonplaceholder.typicode.com/users"
|
|
206
|
+
data-kt-select-data-value-field="id"
|
|
207
|
+
data-kt-select-data-field-text="name"
|
|
208
|
+
data-kt-select-placeholder="Select a user..."
|
|
209
|
+
data-kt-select-enable-search="true">
|
|
210
|
+
<option value="">Select a user...</option>
|
|
211
|
+
</select>
|
|
212
|
+
|
|
213
|
+
<div class="mt-4 flex gap-2">
|
|
214
|
+
<button
|
|
215
|
+
id="reloadBtn"
|
|
216
|
+
type="button"
|
|
217
|
+
class="px-3 py-1.5 text-xs font-medium text-gray-700 bg-white border border-gray-300 rounded hover:bg-gray-50">
|
|
218
|
+
Test reload()
|
|
219
|
+
</button>
|
|
220
|
+
<button
|
|
221
|
+
id="clearBtn"
|
|
222
|
+
type="button"
|
|
223
|
+
class="px-3 py-1.5 text-xs font-medium text-gray-700 bg-white border border-gray-300 rounded hover:bg-gray-50">
|
|
224
|
+
Test clearSelection()
|
|
225
|
+
</button>
|
|
226
|
+
</div>
|
|
227
|
+
|
|
228
|
+
<div id="modalResults" class="mt-4 text-xs min-h-[3rem]"></div>
|
|
229
|
+
</div>
|
|
230
|
+
|
|
231
|
+
<div class="border-t border-gray-200 px-6 py-4 flex justify-end">
|
|
232
|
+
<button
|
|
233
|
+
type="button"
|
|
234
|
+
data-kt-modal-dismiss="true"
|
|
235
|
+
class="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded hover:bg-gray-50">
|
|
236
|
+
Close
|
|
237
|
+
</button>
|
|
238
|
+
</div>
|
|
239
|
+
</div>
|
|
240
|
+
</div>
|
|
241
|
+
</div>
|
|
242
|
+
|
|
243
|
+
<script>
|
|
244
|
+
document.addEventListener('DOMContentLoaded', function () {
|
|
245
|
+
const form = document.getElementById('testForm');
|
|
246
|
+
const resultsDiv = document.getElementById('results');
|
|
247
|
+
const remoteSelectEl = document.querySelector(
|
|
248
|
+
'select[name="remoteSelect"]',
|
|
249
|
+
);
|
|
250
|
+
|
|
251
|
+
form.addEventListener('submit', function (e) {
|
|
252
|
+
e.preventDefault();
|
|
253
|
+
resultsDiv.innerHTML = '';
|
|
254
|
+
|
|
255
|
+
const formData = new FormData(form);
|
|
256
|
+
const entries = Array.from(formData.entries());
|
|
257
|
+
|
|
258
|
+
const resultDiv = document.createElement('div');
|
|
259
|
+
resultDiv.className = 'p-3 bg-white border border-gray-200 rounded';
|
|
260
|
+
resultDiv.innerHTML = `
|
|
261
|
+
<div class="font-medium text-gray-900 mb-2">FormData Entries (${entries.length})</div>
|
|
262
|
+
<ul class="space-y-1">
|
|
263
|
+
${entries
|
|
264
|
+
.map(
|
|
265
|
+
([key, value]) =>
|
|
266
|
+
`<li class="text-xs font-mono text-gray-700"><span class="font-medium">${key}:</span> "${value}"</li>`,
|
|
267
|
+
)
|
|
268
|
+
.join('')}
|
|
269
|
+
</ul>
|
|
270
|
+
`;
|
|
271
|
+
resultsDiv.appendChild(resultDiv);
|
|
272
|
+
|
|
273
|
+
const remoteSelectValue = formData.get('remoteSelect');
|
|
274
|
+
const verdict = document.createElement('div');
|
|
275
|
+
verdict.className = `p-3 mt-3 rounded border font-medium ${
|
|
276
|
+
remoteSelectValue
|
|
277
|
+
? 'bg-white border-gray-900 text-gray-900'
|
|
278
|
+
: 'bg-gray-100 border-gray-400 text-gray-700'
|
|
279
|
+
}`;
|
|
280
|
+
verdict.textContent = remoteSelectValue
|
|
281
|
+
? 'PASS: Remote select included'
|
|
282
|
+
: 'FAIL: Remote select missing';
|
|
283
|
+
resultsDiv.appendChild(verdict);
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
const modal = document.getElementById('modal-remote');
|
|
287
|
+
const remoteSelectInModal = document.getElementById(
|
|
288
|
+
'remoteSelectInModal',
|
|
289
|
+
);
|
|
290
|
+
const resultsModalDiv = document.getElementById('modalResults');
|
|
291
|
+
const reloadBtn = document.getElementById('reloadBtn');
|
|
292
|
+
const clearBtn = document.getElementById('clearBtn');
|
|
293
|
+
|
|
294
|
+
modal.addEventListener('kt.modal.show', function () {
|
|
295
|
+
const instance = KTSelect.getInstance(remoteSelectInModal);
|
|
296
|
+
|
|
297
|
+
if (instance) {
|
|
298
|
+
reloadBtn.addEventListener('click', async function () {
|
|
299
|
+
resultsModalDiv.innerHTML =
|
|
300
|
+
'<div class="p-2 bg-gray-100 border border-gray-200 rounded">Reloading...</div>';
|
|
301
|
+
|
|
302
|
+
try {
|
|
303
|
+
await instance.reload();
|
|
304
|
+
resultsModalDiv.innerHTML = `
|
|
305
|
+
<div class="p-2 bg-white border border-gray-200 rounded">
|
|
306
|
+
<div class="font-medium text-gray-900">reload() completed</div>
|
|
307
|
+
</div>
|
|
308
|
+
`;
|
|
309
|
+
} catch (error) {
|
|
310
|
+
resultsModalDiv.innerHTML = `
|
|
311
|
+
<div class="p-2 bg-gray-100 border border-gray-300 rounded">
|
|
312
|
+
<div class="font-medium text-gray-900">reload() failed</div>
|
|
313
|
+
<div class="text-gray-600">${error.message}</div>
|
|
314
|
+
</div>
|
|
315
|
+
`;
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
clearBtn.addEventListener('click', function () {
|
|
320
|
+
instance.clearSelection();
|
|
321
|
+
const selectedOptions = instance.getSelectedOptions();
|
|
322
|
+
|
|
323
|
+
resultsModalDiv.innerHTML = `
|
|
324
|
+
<div class="p-2 bg-white border border-gray-200 rounded">
|
|
325
|
+
<div class="font-medium text-gray-900">clearSelection() called</div>
|
|
326
|
+
<div class="text-gray-600">Placeholder visible: ${selectedOptions.length === 0 ? 'Yes' : 'No'}</div>
|
|
327
|
+
</div>
|
|
328
|
+
`;
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
});
|
|
333
|
+
</script>
|
|
334
|
+
<script src="../../dist/ktui.js"></script>
|
|
335
|
+
</body>
|
|
336
|
+
</html>
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
+
<title>Remote Data with Pre-Selected Options</title>
|
|
8
|
+
<link rel="stylesheet" href="../../dist/styles.css">
|
|
9
|
+
</head>
|
|
10
|
+
|
|
11
|
+
<body class="bg-gray-50 min-h-screen p-8">
|
|
12
|
+
<div class="max-w-4xl mx-auto">
|
|
13
|
+
<h1 class="text-3xl font-bold mb-8">Remote Data with Pre-Selected Options</h1>
|
|
14
|
+
|
|
15
|
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
16
|
+
<!-- Test 1: Native selected attribute with remote data -->
|
|
17
|
+
<div class="bg-white rounded-lg shadow p-6">
|
|
18
|
+
<h2 class="text-xl font-semibold mb-4">Test 1: Native <option selected></h2>
|
|
19
|
+
<p class="text-sm text-gray-600 mb-4">Single-select with native selected attribute (user ID 5)</p>
|
|
20
|
+
|
|
21
|
+
<select
|
|
22
|
+
id="test-1"
|
|
23
|
+
class="kt-select"
|
|
24
|
+
data-kt-select
|
|
25
|
+
data-kt-select-remote="true"
|
|
26
|
+
data-kt-select-data-url="https://jsonplaceholder.typicode.com/users"
|
|
27
|
+
data-kt-select-data-field-value="id"
|
|
28
|
+
data-kt-select-data-field-text="name"
|
|
29
|
+
data-kt-select-enable-search="true"
|
|
30
|
+
data-kt-select-debug="true"
|
|
31
|
+
placeholder="Select a user..."
|
|
32
|
+
>
|
|
33
|
+
<option value="5" selected>Loading...</option>
|
|
34
|
+
</select>
|
|
35
|
+
|
|
36
|
+
<div class="mt-4 p-3 bg-gray-100 rounded text-sm">
|
|
37
|
+
<strong>Expected:</strong> User with ID 5 should be selected after remote data loads
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
|
|
41
|
+
<!-- Test 2: data-kt-select-pre-selected attribute -->
|
|
42
|
+
<div class="bg-white rounded-lg shadow p-6">
|
|
43
|
+
<h2 class="text-xl font-semibold mb-4">Test 2: data-kt-select-pre-selected</h2>
|
|
44
|
+
<p class="text-sm text-gray-600 mb-4">Using pre-selected attribute (user ID 3)</p>
|
|
45
|
+
|
|
46
|
+
<select
|
|
47
|
+
id="test-2"
|
|
48
|
+
class="kt-select"
|
|
49
|
+
data-kt-select
|
|
50
|
+
data-kt-select-remote="true"
|
|
51
|
+
data-kt-select-data-url="https://jsonplaceholder.typicode.com/users"
|
|
52
|
+
data-kt-select-data-field-value="id"
|
|
53
|
+
data-kt-select-data-field-text="name"
|
|
54
|
+
data-kt-select-pre-selected="3"
|
|
55
|
+
data-kt-select-enable-search="true"
|
|
56
|
+
data-kt-select-debug="true"
|
|
57
|
+
placeholder="Select a user..."
|
|
58
|
+
></select>
|
|
59
|
+
|
|
60
|
+
<div class="mt-4 p-3 bg-gray-100 rounded text-sm">
|
|
61
|
+
<strong>Expected:</strong> User with ID 3 should be selected after remote data loads
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
|
|
65
|
+
<!-- Test 3: Multiple pre-selected with native selected -->
|
|
66
|
+
<div class="bg-white rounded-lg shadow p-6">
|
|
67
|
+
<h2 class="text-xl font-semibold mb-4">Test 3: Multiple Pre-Selected (Native)</h2>
|
|
68
|
+
<p class="text-sm text-gray-600 mb-4">Multiple select with native selected attributes</p>
|
|
69
|
+
|
|
70
|
+
<select
|
|
71
|
+
id="test-3"
|
|
72
|
+
class="kt-select"
|
|
73
|
+
multiple
|
|
74
|
+
data-kt-select
|
|
75
|
+
data-kt-select-remote="true"
|
|
76
|
+
data-kt-select-data-url="https://jsonplaceholder.typicode.com/users"
|
|
77
|
+
data-kt-select-data-field-value="id"
|
|
78
|
+
data-kt-select-data-field-text="name"
|
|
79
|
+
data-kt-select-multiple="true"
|
|
80
|
+
data-kt-select-enable-search="true"
|
|
81
|
+
data-kt-select-debug="true"
|
|
82
|
+
placeholder="Select users..."
|
|
83
|
+
>
|
|
84
|
+
<option value="2" selected>Loading...</option>
|
|
85
|
+
<option value="4" selected>Loading...</option>
|
|
86
|
+
<option value="7" selected>Loading...</option>
|
|
87
|
+
</select>
|
|
88
|
+
|
|
89
|
+
<div class="mt-4 p-3 bg-gray-100 rounded text-sm">
|
|
90
|
+
<strong>Expected:</strong> Users with IDs 2, 4, and 7 should be selected
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
|
|
94
|
+
<!-- Test 4: Multiple pre-selected with data attribute -->
|
|
95
|
+
<div class="bg-white rounded-lg shadow p-6">
|
|
96
|
+
<h2 class="text-xl font-semibold mb-4">Test 4: Multiple Pre-Selected (Attribute)</h2>
|
|
97
|
+
<p class="text-sm text-gray-600 mb-4">Multiple select with data-kt-select-pre-selected</p>
|
|
98
|
+
|
|
99
|
+
<select
|
|
100
|
+
id="test-4"
|
|
101
|
+
class="kt-select"
|
|
102
|
+
multiple
|
|
103
|
+
data-kt-select
|
|
104
|
+
data-kt-select-remote="true"
|
|
105
|
+
data-kt-select-data-url="https://jsonplaceholder.typicode.com/users"
|
|
106
|
+
data-kt-select-data-field-value="id"
|
|
107
|
+
data-kt-select-data-field-text="name"
|
|
108
|
+
data-kt-select-multiple="true"
|
|
109
|
+
data-kt-select-pre-selected="1,6,9"
|
|
110
|
+
data-kt-select-enable-search="true"
|
|
111
|
+
data-kt-select-debug="true"
|
|
112
|
+
placeholder="Select users..."
|
|
113
|
+
></select>
|
|
114
|
+
|
|
115
|
+
<div class="mt-4 p-3 bg-gray-100 rounded text-sm">
|
|
116
|
+
<strong>Expected:</strong> Users with IDs 1, 6, and 9 should be selected
|
|
117
|
+
</div>
|
|
118
|
+
</div>
|
|
119
|
+
|
|
120
|
+
<!-- Test 5: Combination of both methods -->
|
|
121
|
+
<div class="bg-white rounded-lg shadow p-6">
|
|
122
|
+
<h2 class="text-xl font-semibold mb-4">Test 5: Combined Methods</h2>
|
|
123
|
+
<p class="text-sm text-gray-600 mb-4">Both native selected and data attribute</p>
|
|
124
|
+
|
|
125
|
+
<select
|
|
126
|
+
id="test-5"
|
|
127
|
+
class="kt-select"
|
|
128
|
+
multiple
|
|
129
|
+
data-kt-select
|
|
130
|
+
data-kt-select-remote="true"
|
|
131
|
+
data-kt-select-data-url="https://jsonplaceholder.typicode.com/users"
|
|
132
|
+
data-kt-select-data-field-value="id"
|
|
133
|
+
data-kt-select-data-field-text="name"
|
|
134
|
+
data-kt-select-multiple="true"
|
|
135
|
+
data-kt-select-pre-selected="8,10"
|
|
136
|
+
data-kt-select-enable-search="true"
|
|
137
|
+
data-kt-select-debug="true"
|
|
138
|
+
placeholder="Select users..."
|
|
139
|
+
>
|
|
140
|
+
<option value="3" selected>Loading...</option>
|
|
141
|
+
<option value="5" selected>Loading...</option>
|
|
142
|
+
</select>
|
|
143
|
+
|
|
144
|
+
<div class="mt-4 p-3 bg-gray-100 rounded text-sm">
|
|
145
|
+
<strong>Expected:</strong> Users with IDs 3, 5, 8, and 10 should be selected
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
148
|
+
|
|
149
|
+
<!-- Test 6: Non-existent values -->
|
|
150
|
+
<div class="bg-white rounded-lg shadow p-6">
|
|
151
|
+
<h2 class="text-xl font-semibold mb-4">Test 6: Non-Existent Values</h2>
|
|
152
|
+
<p class="text-sm text-gray-600 mb-4">Pre-selected values that don't exist in remote data</p>
|
|
153
|
+
|
|
154
|
+
<select
|
|
155
|
+
id="test-6"
|
|
156
|
+
class="kt-select"
|
|
157
|
+
multiple
|
|
158
|
+
data-kt-select
|
|
159
|
+
data-kt-select-remote="true"
|
|
160
|
+
data-kt-select-data-url="https://jsonplaceholder.typicode.com/users"
|
|
161
|
+
data-kt-select-data-field-value="id"
|
|
162
|
+
data-kt-select-data-field-text="name"
|
|
163
|
+
data-kt-select-multiple="true"
|
|
164
|
+
data-kt-select-enable-search="true"
|
|
165
|
+
data-kt-select-debug="true"
|
|
166
|
+
placeholder="Select users..."
|
|
167
|
+
>
|
|
168
|
+
<option value="999" selected>Non-existent user</option>
|
|
169
|
+
<option value="4" selected>Should work</option>
|
|
170
|
+
<option value="888" selected>Another fake</option>
|
|
171
|
+
</select>
|
|
172
|
+
|
|
173
|
+
<div class="mt-4 p-3 bg-gray-100 rounded text-sm">
|
|
174
|
+
<strong>Expected:</strong> Only user with ID 4 should be selected (IDs 999 and 888 don't exist)
|
|
175
|
+
</div>
|
|
176
|
+
</div>
|
|
177
|
+
|
|
178
|
+
<!-- Test 7: Single select with multiple native selected (edge case) -->
|
|
179
|
+
<div class="bg-white rounded-lg shadow p-6">
|
|
180
|
+
<h2 class="text-xl font-semibold mb-4">Test 7: Single Select Edge Case</h2>
|
|
181
|
+
<p class="text-sm text-gray-600 mb-4">Single-select with multiple selected options (should use first)</p>
|
|
182
|
+
|
|
183
|
+
<select
|
|
184
|
+
id="test-7"
|
|
185
|
+
class="kt-select"
|
|
186
|
+
data-kt-select
|
|
187
|
+
data-kt-select-remote="true"
|
|
188
|
+
data-kt-select-data-url="https://jsonplaceholder.typicode.com/users"
|
|
189
|
+
data-kt-select-data-field-value="id"
|
|
190
|
+
data-kt-select-data-field-text="name"
|
|
191
|
+
data-kt-select-enable-search="true"
|
|
192
|
+
data-kt-select-debug="true"
|
|
193
|
+
placeholder="Select a user..."
|
|
194
|
+
>
|
|
195
|
+
<option value="6" selected>First selected</option>
|
|
196
|
+
<option value="8" selected>Second selected</option>
|
|
197
|
+
<option value="10" selected>Third selected</option>
|
|
198
|
+
</select>
|
|
199
|
+
|
|
200
|
+
<div class="mt-4 p-3 bg-gray-100 rounded text-sm">
|
|
201
|
+
<strong>Expected:</strong> Only user with ID 6 (first) should be selected in single-select mode
|
|
202
|
+
</div>
|
|
203
|
+
</div>
|
|
204
|
+
|
|
205
|
+
<!-- Test 8: With Tags enabled -->
|
|
206
|
+
<div class="bg-white rounded-lg shadow p-6">
|
|
207
|
+
<h2 class="text-xl font-semibold mb-4">Test 8: With Tags</h2>
|
|
208
|
+
<p class="text-sm text-gray-600 mb-4">Multiple select with tags and pre-selected values</p>
|
|
209
|
+
|
|
210
|
+
<select
|
|
211
|
+
id="test-8"
|
|
212
|
+
class="kt-select"
|
|
213
|
+
multiple
|
|
214
|
+
data-kt-select
|
|
215
|
+
data-kt-select-remote="true"
|
|
216
|
+
data-kt-select-data-url="https://jsonplaceholder.typicode.com/users"
|
|
217
|
+
data-kt-select-data-field-value="id"
|
|
218
|
+
data-kt-select-data-field-text="name"
|
|
219
|
+
data-kt-select-multiple="true"
|
|
220
|
+
data-kt-select-tags="true"
|
|
221
|
+
data-kt-select-enable-search="true"
|
|
222
|
+
data-kt-select-debug="true"
|
|
223
|
+
placeholder="Select users..."
|
|
224
|
+
>
|
|
225
|
+
<option value="1" selected>Loading...</option>
|
|
226
|
+
<option value="5" selected>Loading...</option>
|
|
227
|
+
<option value="9" selected>Loading...</option>
|
|
228
|
+
</select>
|
|
229
|
+
|
|
230
|
+
<div class="mt-4 p-3 bg-gray-100 rounded text-sm">
|
|
231
|
+
<strong>Expected:</strong> Users with IDs 1, 5, and 9 should be selected and displayed as tags
|
|
232
|
+
</div>
|
|
233
|
+
</div>
|
|
234
|
+
</div>
|
|
235
|
+
|
|
236
|
+
<!-- Debug Console -->
|
|
237
|
+
<div class="bg-white rounded-lg shadow p-6 mt-8">
|
|
238
|
+
<h2 class="text-xl font-semibold mb-4">Debug Console</h2>
|
|
239
|
+
<p class="text-sm text-gray-600 mb-4">Check browser console (F12) for debug output</p>
|
|
240
|
+
|
|
241
|
+
<div class="space-y-2">
|
|
242
|
+
<button onclick="checkAllSelections()" class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600">
|
|
243
|
+
Check All Selections
|
|
244
|
+
</button>
|
|
245
|
+
<button onclick="resetAll()" class="px-4 py-2 bg-gray-500 text-white rounded hover:bg-gray-600 ml-2">
|
|
246
|
+
Reset All
|
|
247
|
+
</button>
|
|
248
|
+
</div>
|
|
249
|
+
|
|
250
|
+
<pre id="debug-output" class="mt-4 p-4 bg-gray-900 text-green-400 rounded text-xs overflow-auto max-h-64"></pre>
|
|
251
|
+
</div>
|
|
252
|
+
</div>
|
|
253
|
+
|
|
254
|
+
<script src="../../dist/ktui.js"></script>
|
|
255
|
+
<script>
|
|
256
|
+
function checkAllSelections() {
|
|
257
|
+
const output = [];
|
|
258
|
+
for (let i = 1; i <= 8; i++) {
|
|
259
|
+
const select = document.getElementById(`test-${i}`);
|
|
260
|
+
if (select) {
|
|
261
|
+
const selectedOptions = Array.from(select.selectedOptions).map(opt => ({
|
|
262
|
+
value: opt.value,
|
|
263
|
+
text: opt.text
|
|
264
|
+
}));
|
|
265
|
+
output.push(`Test ${i}: ${selectedOptions.length > 0 ? JSON.stringify(selectedOptions, null, 2) : 'No selection'}`);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
document.getElementById('debug-output').textContent = output.join('\n\n');
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function resetAll() {
|
|
272
|
+
location.reload();
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// Auto-check selections after remote data loads
|
|
276
|
+
setTimeout(() => {
|
|
277
|
+
checkAllSelections();
|
|
278
|
+
}, 3000);
|
|
279
|
+
</script>
|
|
280
|
+
</body>
|
|
281
|
+
|
|
282
|
+
</html>
|
|
283
|
+
|
|
@@ -74,8 +74,11 @@ function createCheckboxHandler(element, config, fireEvent) {
|
|
|
74
74
|
return;
|
|
75
75
|
var value = input.value;
|
|
76
76
|
var selectedRows = getSelectedRows();
|
|
77
|
-
|
|
78
|
-
|
|
77
|
+
var wasChecked = selectedRows.includes(value);
|
|
78
|
+
var isNowChecked = input.checked;
|
|
79
|
+
// Update state first
|
|
80
|
+
if (isNowChecked) {
|
|
81
|
+
if (!wasChecked)
|
|
79
82
|
selectedRows.push(value);
|
|
80
83
|
}
|
|
81
84
|
else {
|
|
@@ -83,14 +86,24 @@ function createCheckboxHandler(element, config, fireEvent) {
|
|
|
83
86
|
}
|
|
84
87
|
setSelectedRows(selectedRows);
|
|
85
88
|
updateHeaderCheckboxState();
|
|
89
|
+
// Fire specific checked/unchecked events after state is updated
|
|
90
|
+
if (isNowChecked && !wasChecked) {
|
|
91
|
+
fireEvent('checked');
|
|
92
|
+
}
|
|
93
|
+
else if (!isNowChecked && wasChecked) {
|
|
94
|
+
fireEvent('unchecked');
|
|
95
|
+
}
|
|
96
|
+
// Always fire changed event for backward compatibility
|
|
86
97
|
fireEvent('changed');
|
|
87
98
|
}
|
|
88
99
|
// When the header checkbox is toggled
|
|
89
100
|
function checkboxToggle(event) {
|
|
90
101
|
var checked = !isChecked();
|
|
102
|
+
// Update state first, then fire events
|
|
103
|
+
change(checked);
|
|
104
|
+
// Fire checked/unchecked events after state is updated
|
|
91
105
|
var eventType = checked ? 'checked' : 'unchecked';
|
|
92
106
|
fireEvent(eventType);
|
|
93
|
-
change(checked);
|
|
94
107
|
}
|
|
95
108
|
// Change all visible checkboxes and update selectedRows
|
|
96
109
|
function change(checked) {
|