@keenthemes/ktui 1.0.25 → 1.0.27
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 +335 -36
- package/dist/ktui.min.js +1 -1
- package/dist/ktui.min.js.map +1 -1
- package/dist/styles.css +216 -13
- 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.html +205 -0
- package/examples/modal/remote-select-dropdown.html +166 -0
- package/examples/modal/select-dropdown-container.html +129 -0
- package/examples/select/formdata-remote.html +161 -0
- package/examples/select/modal-positioning-test.html +338 -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 +16 -2
- 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 +54 -3
- package/lib/cjs/components/select/dropdown.js.map +1 -1
- package/lib/cjs/components/select/select.js +241 -23
- 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 +16 -2
- 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 +54 -3
- package/lib/esm/components/select/dropdown.js.map +1 -1
- package/lib/esm/components/select/select.js +241 -23
- 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 +20 -2
- package/src/components/select/config.ts +6 -0
- package/src/components/select/dropdown.ts +69 -4
- package/src/components/select/select.ts +306 -36
- package/src/components/select/templates.ts +2 -1
- package/lib/cjs/components/config.js +0 -26
- package/lib/cjs/components/config.js.map +0 -1
- package/lib/cjs/components/config.umd.js +0 -23
- package/lib/cjs/components/config.umd.js.map +0 -1
- package/lib/cjs/components/menu/index.js +0 -6
- package/lib/cjs/components/menu/index.js.map +0 -1
- package/lib/cjs/components/menu/menu.js +0 -1021
- package/lib/cjs/components/menu/menu.js.map +0 -1
- package/lib/cjs/components/menu/types.js +0 -3
- package/lib/cjs/components/menu/types.js.map +0 -1
- package/lib/cjs/components/theme/index.js +0 -6
- package/lib/cjs/components/theme/index.js.map +0 -1
- package/lib/cjs/components/theme/theme.js +0 -147
- package/lib/cjs/components/theme/theme.js.map +0 -1
- package/lib/cjs/components/theme/types.js +0 -3
- package/lib/cjs/components/theme/types.js.map +0 -1
- package/lib/esm/components/config.js +0 -24
- package/lib/esm/components/config.js.map +0 -1
- package/lib/esm/components/config.umd.js +0 -23
- package/lib/esm/components/config.umd.js.map +0 -1
- package/lib/esm/components/menu/index.js +0 -2
- package/lib/esm/components/menu/index.js.map +0 -1
- package/lib/esm/components/menu/menu.js +0 -1018
- package/lib/esm/components/menu/menu.js.map +0 -1
- package/lib/esm/components/menu/types.js +0 -2
- package/lib/esm/components/menu/types.js.map +0 -1
- package/lib/esm/components/theme/index.js +0 -2
- package/lib/esm/components/theme/index.js.map +0 -1
- package/lib/esm/components/theme/theme.js +0 -144
- package/lib/esm/components/theme/theme.js.map +0 -1
- package/lib/esm/components/theme/types.js +0 -2
- package/lib/esm/components/theme/types.js.map +0 -1
- /package/examples/select/{dark-mode-test.html → dark-mode.html} +0 -0
- /package/examples/select/{dropdowncontainer-test.html → dropdowncontainer.html} +0 -0
- /package/examples/select/{global-config-test.html → global-config.html} +0 -0
|
@@ -0,0 +1,365 @@
|
|
|
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>DataTable Remote Data with Checkboxes Test</title>
|
|
8
|
+
<link rel="stylesheet" href="../../dist/styles.css">
|
|
9
|
+
</head>
|
|
10
|
+
|
|
11
|
+
<body class="bg-gray-50 min-h-screen p-4">
|
|
12
|
+
<div class="container mx-auto max-w-5xl">
|
|
13
|
+
<div class="bg-white rounded-lg shadow-lg p-8 mt-6 border border-gray-200">
|
|
14
|
+
<div class="mb-6">
|
|
15
|
+
<h1 class="text-xl font-bold text-gray-900">DataTable Remote Data with Checkboxes Test</h1>
|
|
16
|
+
<p class="text-sm text-gray-600 mt-2">Tests checkbox events with server-side data from JSONPlaceholder API</p>
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
<!-- Current Selection Display -->
|
|
20
|
+
<div class="mb-6">
|
|
21
|
+
<h2 class="text-lg font-semibold text-gray-800 mb-3">Current Selection</h2>
|
|
22
|
+
<div id="selectionDisplay" class="bg-blue-50 border border-blue-200 rounded-md p-4">
|
|
23
|
+
<div class="text-gray-700">
|
|
24
|
+
<strong>Checked IDs:</strong> <span id="checkedIds" class="font-mono">[]</span>
|
|
25
|
+
</div>
|
|
26
|
+
<div class="text-gray-700 mt-2">
|
|
27
|
+
<strong>Count:</strong> <span id="checkedCount" class="font-semibold">0</span>
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
<!-- Test Controls -->
|
|
33
|
+
<div class="mb-6 flex gap-3 flex-wrap">
|
|
34
|
+
<button
|
|
35
|
+
onclick="testCheckAll()"
|
|
36
|
+
class="px-4 py-2 bg-green-600 text-white rounded-md hover:bg-green-700 transition-colors font-medium">
|
|
37
|
+
Check All
|
|
38
|
+
</button>
|
|
39
|
+
<button
|
|
40
|
+
onclick="testUncheckAll()"
|
|
41
|
+
class="px-4 py-2 bg-red-600 text-white rounded-md hover:bg-red-700 transition-colors font-medium">
|
|
42
|
+
Uncheck All
|
|
43
|
+
</button>
|
|
44
|
+
<button
|
|
45
|
+
onclick="testToggle()"
|
|
46
|
+
class="px-4 py-2 bg-purple-600 text-white rounded-md hover:bg-purple-700 transition-colors font-medium">
|
|
47
|
+
Toggle All
|
|
48
|
+
</button>
|
|
49
|
+
<button
|
|
50
|
+
onclick="testGetChecked()"
|
|
51
|
+
class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors font-medium">
|
|
52
|
+
Get Checked
|
|
53
|
+
</button>
|
|
54
|
+
</div>
|
|
55
|
+
|
|
56
|
+
<!-- DataTable Container -->
|
|
57
|
+
<div class="kt-card">
|
|
58
|
+
<div class="kt-card-table" id="remote-datatable-container">
|
|
59
|
+
<div class="kt-table-wrapper kt-scrollable">
|
|
60
|
+
<table id="remote-checkbox-table" class="kt-table" data-kt-datatable-table="true">
|
|
61
|
+
<thead>
|
|
62
|
+
<tr>
|
|
63
|
+
<th scope="col" class="w-12" data-kt-datatable-column="checkbox">
|
|
64
|
+
<input
|
|
65
|
+
type="checkbox"
|
|
66
|
+
data-kt-datatable-check="true"
|
|
67
|
+
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 focus:ring-2">
|
|
68
|
+
</th>
|
|
69
|
+
<th scope="col" class="w-20" data-kt-datatable-column="id">
|
|
70
|
+
<span class="kt-table-col">
|
|
71
|
+
<span class="kt-table-col-label">ID</span>
|
|
72
|
+
<span class="kt-table-col-sort"></span>
|
|
73
|
+
</span>
|
|
74
|
+
</th>
|
|
75
|
+
<th scope="col" class="w-48" data-kt-datatable-column="name">
|
|
76
|
+
<span class="kt-table-col">
|
|
77
|
+
<span class="kt-table-col-label">Name</span>
|
|
78
|
+
<span class="kt-table-col-sort"></span>
|
|
79
|
+
</span>
|
|
80
|
+
</th>
|
|
81
|
+
<th scope="col" class="w-64" data-kt-datatable-column="email">
|
|
82
|
+
<span class="kt-table-col">
|
|
83
|
+
<span class="kt-table-col-label">Email</span>
|
|
84
|
+
<span class="kt-table-col-sort"></span>
|
|
85
|
+
</span>
|
|
86
|
+
</th>
|
|
87
|
+
<th scope="col" class="w-40" data-kt-datatable-column="company">
|
|
88
|
+
<span class="kt-table-col">
|
|
89
|
+
<span class="kt-table-col-label">Company</span>
|
|
90
|
+
<span class="kt-table-col-sort"></span>
|
|
91
|
+
</span>
|
|
92
|
+
</th>
|
|
93
|
+
</tr>
|
|
94
|
+
</thead>
|
|
95
|
+
<tbody>
|
|
96
|
+
<!-- Data will be loaded from API -->
|
|
97
|
+
</tbody>
|
|
98
|
+
</table>
|
|
99
|
+
</div>
|
|
100
|
+
|
|
101
|
+
<!-- Pagination Info -->
|
|
102
|
+
<div class="flex items-center justify-between mt-4">
|
|
103
|
+
<div class="flex items-center space-x-2">
|
|
104
|
+
<span class="text-sm text-gray-700">Show</span>
|
|
105
|
+
<select data-kt-datatable-size="true" class="border border-gray-300 rounded px-2 py-1 bg-white text-gray-900">
|
|
106
|
+
<option value="5" selected>5</option>
|
|
107
|
+
<option value="10">10</option>
|
|
108
|
+
</select>
|
|
109
|
+
<span class="text-sm text-gray-700">entries</span>
|
|
110
|
+
</div>
|
|
111
|
+
<div data-kt-datatable-info="true" class="text-sm text-gray-700"></div>
|
|
112
|
+
</div>
|
|
113
|
+
|
|
114
|
+
<!-- Pagination Controls -->
|
|
115
|
+
<div class="flex justify-center mt-4">
|
|
116
|
+
<div data-kt-datatable-pagination="true" class="flex space-x-1"></div>
|
|
117
|
+
</div>
|
|
118
|
+
</div>
|
|
119
|
+
</div>
|
|
120
|
+
</div>
|
|
121
|
+
|
|
122
|
+
<!-- Event Log Section -->
|
|
123
|
+
<div class="bg-white rounded-lg shadow-lg p-8 mt-6 border border-gray-200">
|
|
124
|
+
<div class="flex items-center justify-between mb-3">
|
|
125
|
+
<h2 class="text-lg font-semibold text-gray-800">Event Log</h2>
|
|
126
|
+
<button
|
|
127
|
+
id="clearLog"
|
|
128
|
+
onclick="clearEventLog()"
|
|
129
|
+
class="px-3 py-1 text-sm bg-gray-200 text-gray-700 rounded-md hover:bg-gray-300 transition-colors">
|
|
130
|
+
Clear Log
|
|
131
|
+
</button>
|
|
132
|
+
</div>
|
|
133
|
+
<div id="eventLog" class="bg-gray-50 border border-gray-200 rounded-md p-4 h-64 overflow-y-auto font-mono text-sm">
|
|
134
|
+
<div class="text-gray-500">No events yet. Interact with checkboxes to see events...</div>
|
|
135
|
+
</div>
|
|
136
|
+
</div>
|
|
137
|
+
</div>
|
|
138
|
+
|
|
139
|
+
<script src="../../dist/ktui.js"></script>
|
|
140
|
+
<script>
|
|
141
|
+
let datatableInstance = null;
|
|
142
|
+
|
|
143
|
+
// Event log helper functions
|
|
144
|
+
function addEventLog(eventName, details = '') {
|
|
145
|
+
const logElement = document.getElementById('eventLog');
|
|
146
|
+
const timestamp = new Date().toLocaleTimeString();
|
|
147
|
+
const logEntry = document.createElement('div');
|
|
148
|
+
logEntry.className = 'mb-2 pb-2 border-b border-gray-200';
|
|
149
|
+
|
|
150
|
+
let eventColor = 'text-gray-700';
|
|
151
|
+
if (eventName === 'checked') {
|
|
152
|
+
eventColor = 'text-green-600';
|
|
153
|
+
} else if (eventName === 'unchecked') {
|
|
154
|
+
eventColor = 'text-red-600';
|
|
155
|
+
} else if (eventName === 'changed') {
|
|
156
|
+
eventColor = 'text-blue-600';
|
|
157
|
+
} else if (eventName === 'fetch' || eventName === 'fetched') {
|
|
158
|
+
eventColor = 'text-purple-600';
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
logEntry.innerHTML = `
|
|
162
|
+
<div class="flex items-start gap-2">
|
|
163
|
+
<span class="text-gray-500 text-xs">[${timestamp}]</span>
|
|
164
|
+
<span class="font-semibold ${eventColor}">${eventName.toUpperCase()}</span>
|
|
165
|
+
${details ? `<span class="text-gray-600">${details}</span>` : ''}
|
|
166
|
+
</div>
|
|
167
|
+
`;
|
|
168
|
+
|
|
169
|
+
// Remove "No events yet" message if it exists
|
|
170
|
+
const firstChild = logElement.firstChild;
|
|
171
|
+
if (firstChild && firstChild.textContent.includes('No events yet')) {
|
|
172
|
+
logElement.removeChild(firstChild);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
logElement.insertBefore(logEntry, logElement.firstChild);
|
|
176
|
+
|
|
177
|
+
// Keep only last 50 entries
|
|
178
|
+
while (logElement.children.length > 50) {
|
|
179
|
+
logElement.removeChild(logElement.lastChild);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function clearEventLog() {
|
|
184
|
+
const logElement = document.getElementById('eventLog');
|
|
185
|
+
logElement.innerHTML = '<div class="text-gray-500">No events yet. Interact with checkboxes to see events...</div>';
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function updateSelectionDisplay() {
|
|
189
|
+
if (!datatableInstance || typeof datatableInstance.getChecked !== 'function') {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
try {
|
|
193
|
+
const checkedIds = datatableInstance.getChecked();
|
|
194
|
+
document.getElementById('checkedIds').textContent = JSON.stringify(checkedIds);
|
|
195
|
+
document.getElementById('checkedCount').textContent = checkedIds.length;
|
|
196
|
+
} catch (e) {
|
|
197
|
+
console.error('Error updating selection display:', e);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Test functions
|
|
202
|
+
function testCheckAll() {
|
|
203
|
+
if (datatableInstance) {
|
|
204
|
+
datatableInstance.check();
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function testUncheckAll() {
|
|
209
|
+
if (datatableInstance) {
|
|
210
|
+
datatableInstance.uncheck();
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function testToggle() {
|
|
215
|
+
if (datatableInstance) {
|
|
216
|
+
datatableInstance.toggle();
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function testGetChecked() {
|
|
221
|
+
if (datatableInstance) {
|
|
222
|
+
const checkedIds = datatableInstance.getChecked();
|
|
223
|
+
addEventLog('info', `Manual getChecked() call returned: [${checkedIds.join(', ')}]`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Initialize the datatable when page loads
|
|
228
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
229
|
+
setTimeout(() => {
|
|
230
|
+
try {
|
|
231
|
+
// Initialize KTUI components
|
|
232
|
+
if (typeof KTDataTable !== 'undefined') {
|
|
233
|
+
const container = document.getElementById('remote-datatable-container');
|
|
234
|
+
if (container) {
|
|
235
|
+
// Set data attributes for datatable initialization
|
|
236
|
+
container.setAttribute('data-kt-datatable', 'true');
|
|
237
|
+
container.setAttribute('data-kt-datatable-page-size', '5');
|
|
238
|
+
container.setAttribute('data-kt-datatable-api-endpoint', 'https://jsonplaceholder.typicode.com/users');
|
|
239
|
+
|
|
240
|
+
datatableInstance = new KTDataTable(container, {
|
|
241
|
+
apiEndpoint: 'https://jsonplaceholder.typicode.com/users',
|
|
242
|
+
requestMethod: 'GET',
|
|
243
|
+
requestHeaders: {
|
|
244
|
+
'Content-Type': 'application/json'
|
|
245
|
+
},
|
|
246
|
+
columns: {
|
|
247
|
+
'checkbox': {
|
|
248
|
+
render: function(cellData, rowData, context) {
|
|
249
|
+
const checkbox = document.createElement('input');
|
|
250
|
+
checkbox.type = 'checkbox';
|
|
251
|
+
checkbox.value = rowData.id;
|
|
252
|
+
checkbox.setAttribute('data-kt-datatable-row-check', 'true');
|
|
253
|
+
checkbox.className = 'w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 focus:ring-2';
|
|
254
|
+
return checkbox;
|
|
255
|
+
}
|
|
256
|
+
},
|
|
257
|
+
'id': {
|
|
258
|
+
render: function(cellData, rowData, context) {
|
|
259
|
+
return String(cellData);
|
|
260
|
+
}
|
|
261
|
+
},
|
|
262
|
+
'name': {
|
|
263
|
+
render: function(cellData, rowData, context) {
|
|
264
|
+
return String(cellData);
|
|
265
|
+
}
|
|
266
|
+
},
|
|
267
|
+
'email': {
|
|
268
|
+
render: function(cellData, rowData, context) {
|
|
269
|
+
return String(cellData);
|
|
270
|
+
}
|
|
271
|
+
},
|
|
272
|
+
'company': {
|
|
273
|
+
render: function(cellData, rowData, context) {
|
|
274
|
+
return String(cellData);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
mapResponse: function(response) {
|
|
279
|
+
// JSONPlaceholder returns an array directly
|
|
280
|
+
// Transform nested objects to flat structure and format for datatable
|
|
281
|
+
if (Array.isArray(response)) {
|
|
282
|
+
const transformedData = response.map(user => ({
|
|
283
|
+
checkbox: '', // Empty value for checkbox column
|
|
284
|
+
id: user.id,
|
|
285
|
+
name: user.name,
|
|
286
|
+
email: user.email,
|
|
287
|
+
company: user.company ? user.company.name : ''
|
|
288
|
+
}));
|
|
289
|
+
|
|
290
|
+
// Get current pagination state for client-side pagination
|
|
291
|
+
// Since JSONPlaceholder doesn't support server-side pagination
|
|
292
|
+
// Use 'this' context which refers to the datatable instance
|
|
293
|
+
const state = this.getState();
|
|
294
|
+
const page = state.page || 1;
|
|
295
|
+
const pageSize = state.pageSize || 10;
|
|
296
|
+
|
|
297
|
+
// Slice data for current page (client-side pagination)
|
|
298
|
+
const startIndex = (page - 1) * pageSize;
|
|
299
|
+
const endIndex = startIndex + pageSize;
|
|
300
|
+
const paginatedData = transformedData.slice(startIndex, endIndex);
|
|
301
|
+
|
|
302
|
+
return {
|
|
303
|
+
data: paginatedData,
|
|
304
|
+
totalCount: transformedData.length
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
// If already in correct format, return as is
|
|
308
|
+
return response;
|
|
309
|
+
},
|
|
310
|
+
checkbox: {
|
|
311
|
+
preserveSelection: true
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
console.log('✅ Remote DataTable with Checkboxes initialized successfully!');
|
|
316
|
+
|
|
317
|
+
// Attach event listeners using DOM events (without kt-datatable- prefix)
|
|
318
|
+
container.addEventListener('checked', function(event) {
|
|
319
|
+
const checkedIds = datatableInstance.getChecked();
|
|
320
|
+
addEventLog('checked', `Selected ${checkedIds.length} rows: [${checkedIds.join(', ')}]`);
|
|
321
|
+
updateSelectionDisplay();
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
container.addEventListener('unchecked', function(event) {
|
|
325
|
+
const checkedIds = datatableInstance.getChecked();
|
|
326
|
+
addEventLog('unchecked', `Deselected. Remaining: ${checkedIds.length} rows: [${checkedIds.join(', ')}]`);
|
|
327
|
+
updateSelectionDisplay();
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
container.addEventListener('changed', function(event) {
|
|
331
|
+
const checkedIds = datatableInstance.getChecked();
|
|
332
|
+
addEventLog('changed', `Selection changed. Total: ${checkedIds.length} rows: [${checkedIds.join(', ')}]`);
|
|
333
|
+
updateSelectionDisplay();
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
container.addEventListener('fetch', function() {
|
|
337
|
+
addEventLog('fetch', 'Fetching data from server...');
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
container.addEventListener('fetched', function() {
|
|
341
|
+
try {
|
|
342
|
+
const state = datatableInstance.getState();
|
|
343
|
+
addEventLog('fetched', `Loaded ${state.totalItems || 0} total records`);
|
|
344
|
+
// Update selection display after data is loaded
|
|
345
|
+
updateSelectionDisplay();
|
|
346
|
+
} catch (e) {
|
|
347
|
+
console.error('Error in fetched handler:', e);
|
|
348
|
+
}
|
|
349
|
+
});
|
|
350
|
+
} else {
|
|
351
|
+
console.error('❌ DataTable container not found');
|
|
352
|
+
}
|
|
353
|
+
} else {
|
|
354
|
+
console.error('❌ KTDataTable is not defined');
|
|
355
|
+
}
|
|
356
|
+
} catch (error) {
|
|
357
|
+
console.error('❌ Error initializing Remote DataTable: ' + error.message);
|
|
358
|
+
}
|
|
359
|
+
}, 100);
|
|
360
|
+
});
|
|
361
|
+
</script>
|
|
362
|
+
</body>
|
|
363
|
+
|
|
364
|
+
</html>
|
|
365
|
+
|
|
@@ -0,0 +1,205 @@
|
|
|
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 Persistent Property Test</title>
|
|
7
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
|
8
|
+
<link rel="stylesheet" href="../../dist/styles.css">
|
|
9
|
+
<style>
|
|
10
|
+
.test-case {
|
|
11
|
+
margin: 1rem 0;
|
|
12
|
+
padding: 1.5rem;
|
|
13
|
+
border: 1px solid #e5e7eb;
|
|
14
|
+
border-radius: 0.5rem;
|
|
15
|
+
background: #fafafa;
|
|
16
|
+
}
|
|
17
|
+
.expected {
|
|
18
|
+
color: #374151;
|
|
19
|
+
font-weight: 500;
|
|
20
|
+
}
|
|
21
|
+
</style>
|
|
22
|
+
</head>
|
|
23
|
+
<body class="p-8 bg-white min-h-screen flex items-start justify-center">
|
|
24
|
+
<div class="w-full max-w-3xl">
|
|
25
|
+
<h1 class="text-3xl font-bold mb-2 text-gray-900">Modal Persistent Property Test</h1>
|
|
26
|
+
<p class="text-gray-600 mb-8">Testing the interaction between <code class="bg-gray-100 px-2 py-1 rounded text-sm">persistent</code> and <code class="bg-gray-100 px-2 py-1 rounded text-sm">backdropStatic</code> properties.</p>
|
|
27
|
+
|
|
28
|
+
<div class="mb-8 p-4 border border-gray-200 rounded bg-gray-50">
|
|
29
|
+
<h2 class="text-lg font-semibold mb-3 text-gray-900">Test Instructions</h2>
|
|
30
|
+
<ol class="list-decimal list-inside space-y-2 text-gray-700">
|
|
31
|
+
<li>Click each "Open Modal" button below</li>
|
|
32
|
+
<li>Try clicking on the modal backdrop (gray area around the modal content)</li>
|
|
33
|
+
<li>Try clicking on the invisible area below the modal content</li>
|
|
34
|
+
<li>Verify the behavior matches the expected result</li>
|
|
35
|
+
</ol>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
<!-- Test Case 1: persistent=false, backdropStatic=false -->
|
|
39
|
+
<div class="test-case">
|
|
40
|
+
<h3 class="text-base font-semibold mb-3 text-gray-900">Test Case 1</h3>
|
|
41
|
+
<p class="mb-2 text-sm text-gray-700">
|
|
42
|
+
<code class="bg-white px-2 py-1 rounded border border-gray-200">persistent: false</code>,
|
|
43
|
+
<code class="bg-white px-2 py-1 rounded border border-gray-200">backdropStatic: false</code>
|
|
44
|
+
</p>
|
|
45
|
+
<p class="expected mb-4 text-sm">✓ Expected: Modal SHOULD close when clicking on backdrop or invisible area</p>
|
|
46
|
+
<button
|
|
47
|
+
data-kt-modal-toggle="#modal-test-1"
|
|
48
|
+
class="px-4 py-2 bg-gray-900 text-white rounded hover:bg-gray-700 text-sm font-medium">
|
|
49
|
+
Open Modal
|
|
50
|
+
</button>
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
<!-- Test Case 2: persistent=true, backdropStatic=false -->
|
|
54
|
+
<div class="test-case">
|
|
55
|
+
<h3 class="text-base font-semibold mb-3 text-gray-900">Test Case 2 <span class="text-xs font-normal text-gray-500">(Bug Fix Verification)</span></h3>
|
|
56
|
+
<p class="mb-2 text-sm text-gray-700">
|
|
57
|
+
<code class="bg-white px-2 py-1 rounded border border-gray-200">persistent: true</code>,
|
|
58
|
+
<code class="bg-white px-2 py-1 rounded border border-gray-200">backdropStatic: false</code>
|
|
59
|
+
</p>
|
|
60
|
+
<p class="expected mb-4 text-sm">✓ Expected: Modal should NOT close when clicking on backdrop or invisible area</p>
|
|
61
|
+
<button
|
|
62
|
+
data-kt-modal-toggle="#modal-test-2"
|
|
63
|
+
class="px-4 py-2 bg-gray-900 text-white rounded hover:bg-gray-700 text-sm font-medium">
|
|
64
|
+
Open Modal
|
|
65
|
+
</button>
|
|
66
|
+
</div>
|
|
67
|
+
|
|
68
|
+
<!-- Test Case 3: persistent=false, backdropStatic=true -->
|
|
69
|
+
<div class="test-case">
|
|
70
|
+
<h3 class="text-base font-semibold mb-3 text-gray-900">Test Case 3</h3>
|
|
71
|
+
<p class="mb-2 text-sm text-gray-700">
|
|
72
|
+
<code class="bg-white px-2 py-1 rounded border border-gray-200">persistent: false</code>,
|
|
73
|
+
<code class="bg-white px-2 py-1 rounded border border-gray-200">backdropStatic: true</code>
|
|
74
|
+
</p>
|
|
75
|
+
<p class="expected mb-4 text-sm">✓ Expected: Modal should NOT close when clicking on backdrop (backdropStatic takes precedence)</p>
|
|
76
|
+
<button
|
|
77
|
+
data-kt-modal-toggle="#modal-test-3"
|
|
78
|
+
class="px-4 py-2 bg-gray-900 text-white rounded hover:bg-gray-700 text-sm font-medium">
|
|
79
|
+
Open Modal
|
|
80
|
+
</button>
|
|
81
|
+
</div>
|
|
82
|
+
|
|
83
|
+
<!-- Test Case 4: persistent=true, backdropStatic=true -->
|
|
84
|
+
<div class="test-case">
|
|
85
|
+
<h3 class="text-base font-semibold mb-3 text-gray-900">Test Case 4</h3>
|
|
86
|
+
<p class="mb-2 text-sm text-gray-700">
|
|
87
|
+
<code class="bg-white px-2 py-1 rounded border border-gray-200">persistent: true</code>,
|
|
88
|
+
<code class="bg-white px-2 py-1 rounded border border-gray-200">backdropStatic: true</code>
|
|
89
|
+
</p>
|
|
90
|
+
<p class="expected mb-4 text-sm">✓ Expected: Modal should NOT close when clicking on backdrop or invisible area</p>
|
|
91
|
+
<button
|
|
92
|
+
data-kt-modal-toggle="#modal-test-4"
|
|
93
|
+
class="px-4 py-2 bg-gray-900 text-white rounded hover:bg-gray-700 text-sm font-medium">
|
|
94
|
+
Open Modal
|
|
95
|
+
</button>
|
|
96
|
+
</div>
|
|
97
|
+
</div>
|
|
98
|
+
|
|
99
|
+
<!-- Modal 1: persistent=false, backdropStatic=false -->
|
|
100
|
+
<div
|
|
101
|
+
id="modal-test-1"
|
|
102
|
+
class="hidden fixed inset-0 z-50 flex items-center justify-center"
|
|
103
|
+
data-kt-modal="true"
|
|
104
|
+
data-kt-modal-persistent="false"
|
|
105
|
+
data-kt-modal-backdrop-static="false">
|
|
106
|
+
<div class="bg-white rounded-lg shadow-xl p-6 max-w-md w-full mx-4 border border-gray-200">
|
|
107
|
+
<h2 class="text-lg font-semibold mb-4 text-gray-900">Test Case 1</h2>
|
|
108
|
+
<p class="mb-3 text-sm text-gray-700">
|
|
109
|
+
This modal has <code class="bg-gray-100 px-1 text-xs">persistent: false</code> and
|
|
110
|
+
<code class="bg-gray-100 px-1 text-xs">backdropStatic: false</code>.
|
|
111
|
+
</p>
|
|
112
|
+
<p class="mb-4 text-sm text-gray-600">
|
|
113
|
+
Click on the gray area around this modal or below it. The modal should close.
|
|
114
|
+
</p>
|
|
115
|
+
<button
|
|
116
|
+
data-kt-modal-dismiss="true"
|
|
117
|
+
class="px-4 py-2 bg-gray-900 text-white rounded hover:bg-gray-700 text-sm">
|
|
118
|
+
Close
|
|
119
|
+
</button>
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
|
|
123
|
+
<!-- Modal 2: persistent=true, backdropStatic=false -->
|
|
124
|
+
<div
|
|
125
|
+
id="modal-test-2"
|
|
126
|
+
class="hidden fixed inset-0 z-50 flex items-center justify-center"
|
|
127
|
+
data-kt-modal="true"
|
|
128
|
+
data-kt-modal-persistent="true"
|
|
129
|
+
data-kt-modal-backdrop-static="false">
|
|
130
|
+
<div class="bg-white rounded-lg shadow-xl p-6 max-w-md w-full mx-4 border border-gray-200">
|
|
131
|
+
<h2 class="text-lg font-semibold mb-4 text-gray-900">Test Case 2 <span class="text-xs font-normal text-gray-500">(Bug Fix)</span></h2>
|
|
132
|
+
<p class="mb-3 text-sm text-gray-700">
|
|
133
|
+
This modal has <code class="bg-gray-100 px-1 text-xs">persistent: true</code> and
|
|
134
|
+
<code class="bg-gray-100 px-1 text-xs">backdropStatic: false</code>.
|
|
135
|
+
</p>
|
|
136
|
+
<p class="mb-4 text-sm text-gray-600 border-l-2 border-gray-400 pl-3">
|
|
137
|
+
Click on the gray area around this modal or below it. The modal should NOT close.
|
|
138
|
+
</p>
|
|
139
|
+
<button
|
|
140
|
+
data-kt-modal-dismiss="true"
|
|
141
|
+
class="px-4 py-2 bg-gray-900 text-white rounded hover:bg-gray-700 text-sm">
|
|
142
|
+
Close
|
|
143
|
+
</button>
|
|
144
|
+
</div>
|
|
145
|
+
</div>
|
|
146
|
+
|
|
147
|
+
<!-- Modal 3: persistent=false, backdropStatic=true -->
|
|
148
|
+
<div
|
|
149
|
+
id="modal-test-3"
|
|
150
|
+
class="hidden fixed inset-0 z-50 flex items-center justify-center"
|
|
151
|
+
data-kt-modal="true"
|
|
152
|
+
data-kt-modal-persistent="false"
|
|
153
|
+
data-kt-modal-backdrop-static="true">
|
|
154
|
+
<div class="bg-white rounded-lg shadow-xl p-6 max-w-md w-full mx-4 border border-gray-200">
|
|
155
|
+
<h2 class="text-lg font-semibold mb-4 text-gray-900">Test Case 3</h2>
|
|
156
|
+
<p class="mb-3 text-sm text-gray-700">
|
|
157
|
+
This modal has <code class="bg-gray-100 px-1 text-xs">persistent: false</code> and
|
|
158
|
+
<code class="bg-gray-100 px-1 text-xs">backdropStatic: true</code>.
|
|
159
|
+
</p>
|
|
160
|
+
<p class="mb-4 text-sm text-gray-600">
|
|
161
|
+
Click on the gray area around this modal or below it. The modal should NOT close (backdropStatic prevents it).
|
|
162
|
+
</p>
|
|
163
|
+
<button
|
|
164
|
+
data-kt-modal-dismiss="true"
|
|
165
|
+
class="px-4 py-2 bg-gray-900 text-white rounded hover:bg-gray-700 text-sm">
|
|
166
|
+
Close
|
|
167
|
+
</button>
|
|
168
|
+
</div>
|
|
169
|
+
</div>
|
|
170
|
+
|
|
171
|
+
<!-- Modal 4: persistent=true, backdropStatic=true -->
|
|
172
|
+
<div
|
|
173
|
+
id="modal-test-4"
|
|
174
|
+
class="hidden fixed inset-0 z-50 flex items-center justify-center"
|
|
175
|
+
data-kt-modal="true"
|
|
176
|
+
data-kt-modal-persistent="true"
|
|
177
|
+
data-kt-modal-backdrop-static="true">
|
|
178
|
+
<div class="bg-white rounded-lg shadow-xl p-6 max-w-md w-full mx-4 border border-gray-200">
|
|
179
|
+
<h2 class="text-lg font-semibold mb-4 text-gray-900">Test Case 4</h2>
|
|
180
|
+
<p class="mb-3 text-sm text-gray-700">
|
|
181
|
+
This modal has <code class="bg-gray-100 px-1 text-xs">persistent: true</code> and
|
|
182
|
+
<code class="bg-gray-100 px-1 text-xs">backdropStatic: true</code>.
|
|
183
|
+
</p>
|
|
184
|
+
<p class="mb-4 text-sm text-gray-600">
|
|
185
|
+
Click on the gray area around this modal or below it. The modal should NOT close (both properties prevent it).
|
|
186
|
+
</p>
|
|
187
|
+
<button
|
|
188
|
+
data-kt-modal-dismiss="true"
|
|
189
|
+
class="px-4 py-2 bg-gray-900 text-white rounded hover:bg-gray-700 text-sm">
|
|
190
|
+
Close
|
|
191
|
+
</button>
|
|
192
|
+
</div>
|
|
193
|
+
</div>
|
|
194
|
+
|
|
195
|
+
<script src="../../dist/ktui.js"></script>
|
|
196
|
+
<script>
|
|
197
|
+
// Initialize modals
|
|
198
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
199
|
+
KTModal.init();
|
|
200
|
+
console.log('Modal test page loaded. All modals initialized.');
|
|
201
|
+
});
|
|
202
|
+
</script>
|
|
203
|
+
</body>
|
|
204
|
+
</html>
|
|
205
|
+
|