@keenthemes/ktui 1.0.21 → 1.0.23
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 +23 -12
- package/dist/ktui.min.js +1 -1
- package/dist/ktui.min.js.map +1 -1
- package/dist/styles.css +181 -1
- package/examples/datatable/sorting-test.html +398 -0
- package/examples/select/modal.html +3 -1
- package/examples/select/{remote-data_.html → remote-data.html} +13 -12
- package/examples/select/tags-enhanced.html +86 -0
- package/examples/select/{tags-icons_.html → tags-icons.html} +1 -2
- package/examples/select/template-customization.html +0 -1
- package/lib/cjs/components/datatable/datatable.js +4 -0
- package/lib/cjs/components/datatable/datatable.js.map +1 -1
- package/lib/cjs/components/select/dropdown.js +1 -4
- package/lib/cjs/components/select/dropdown.js.map +1 -1
- package/lib/cjs/components/select/select.js +8 -2
- package/lib/cjs/components/select/select.js.map +1 -1
- package/lib/cjs/components/select/tags.js +9 -5
- package/lib/cjs/components/select/tags.js.map +1 -1
- package/lib/cjs/components/select/templates.js +1 -1
- package/lib/cjs/components/select/templates.js.map +1 -1
- package/lib/esm/components/datatable/datatable.js +4 -0
- package/lib/esm/components/datatable/datatable.js.map +1 -1
- package/lib/esm/components/select/dropdown.js +1 -4
- package/lib/esm/components/select/dropdown.js.map +1 -1
- package/lib/esm/components/select/select.js +8 -2
- package/lib/esm/components/select/select.js.map +1 -1
- package/lib/esm/components/select/tags.js +9 -5
- package/lib/esm/components/select/tags.js.map +1 -1
- package/lib/esm/components/select/templates.js +1 -1
- package/lib/esm/components/select/templates.js.map +1 -1
- package/package.json +1 -1
- package/src/components/datatable/datatable.ts +5 -0
- package/src/components/select/dropdown.ts +1 -3
- package/src/components/select/select.css +44 -0
- package/src/components/select/select.ts +10 -2
- package/src/components/select/tags.ts +10 -8
- package/src/components/select/templates.ts +1 -1
- package/examples/select/combobox-icons_.html +0 -59
- package/examples/select/combobox_.html +0 -46
- package/examples/select/tags-selected_.html +0 -59
- package/examples/select/tags_.html +0 -58
- package/examples/select/test-optimizations.html +0 -227
- package/examples/select/test-remote-search.html +0 -151
package/dist/styles.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! tailwindcss v4.1.
|
|
1
|
+
/*! tailwindcss v4.1.14 | MIT License | https://tailwindcss.com */
|
|
2
2
|
@layer properties;
|
|
3
3
|
@layer theme, base, components, utilities;
|
|
4
4
|
@layer theme {
|
|
@@ -98,6 +98,7 @@
|
|
|
98
98
|
--font-weight-semibold: 600;
|
|
99
99
|
--font-weight-bold: 700;
|
|
100
100
|
--tracking-tight: -0.025em;
|
|
101
|
+
--leading-tight: 1.25;
|
|
101
102
|
--leading-relaxed: 1.625;
|
|
102
103
|
--radius-sm: calc(var(--radius) - 4px);
|
|
103
104
|
--radius-md: calc(var(--radius) - 2px);
|
|
@@ -368,6 +369,9 @@
|
|
|
368
369
|
.mt-3 {
|
|
369
370
|
margin-top: calc(var(--spacing) * 3);
|
|
370
371
|
}
|
|
372
|
+
.mt-4 {
|
|
373
|
+
margin-top: calc(var(--spacing) * 4);
|
|
374
|
+
}
|
|
371
375
|
.mt-8 {
|
|
372
376
|
margin-top: calc(var(--spacing) * 8);
|
|
373
377
|
}
|
|
@@ -472,6 +476,18 @@
|
|
|
472
476
|
.w-12 {
|
|
473
477
|
width: calc(var(--spacing) * 12);
|
|
474
478
|
}
|
|
479
|
+
.w-20 {
|
|
480
|
+
width: calc(var(--spacing) * 20);
|
|
481
|
+
}
|
|
482
|
+
.w-24 {
|
|
483
|
+
width: calc(var(--spacing) * 24);
|
|
484
|
+
}
|
|
485
|
+
.w-32 {
|
|
486
|
+
width: calc(var(--spacing) * 32);
|
|
487
|
+
}
|
|
488
|
+
.w-40 {
|
|
489
|
+
width: calc(var(--spacing) * 40);
|
|
490
|
+
}
|
|
475
491
|
.w-full {
|
|
476
492
|
width: 100%;
|
|
477
493
|
}
|
|
@@ -566,6 +582,9 @@
|
|
|
566
582
|
.gap-6 {
|
|
567
583
|
gap: calc(var(--spacing) * 6);
|
|
568
584
|
}
|
|
585
|
+
.gap-8 {
|
|
586
|
+
gap: calc(var(--spacing) * 8);
|
|
587
|
+
}
|
|
569
588
|
.space-y-2 {
|
|
570
589
|
:where(& > :not(:last-child)) {
|
|
571
590
|
--tw-space-y-reverse: 0;
|
|
@@ -580,6 +599,13 @@
|
|
|
580
599
|
margin-block-end: calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)));
|
|
581
600
|
}
|
|
582
601
|
}
|
|
602
|
+
.space-x-1 {
|
|
603
|
+
:where(& > :not(:last-child)) {
|
|
604
|
+
--tw-space-x-reverse: 0;
|
|
605
|
+
margin-inline-start: calc(calc(var(--spacing) * 1) * var(--tw-space-x-reverse));
|
|
606
|
+
margin-inline-end: calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-x-reverse)));
|
|
607
|
+
}
|
|
608
|
+
}
|
|
583
609
|
.space-x-2 {
|
|
584
610
|
:where(& > :not(:last-child)) {
|
|
585
611
|
--tw-space-x-reverse: 0;
|
|
@@ -4511,6 +4537,13 @@
|
|
|
4511
4537
|
line-height: var(--tw-leading, var(--text-sm--line-height));
|
|
4512
4538
|
color: var(--muted-foreground);
|
|
4513
4539
|
}
|
|
4540
|
+
.kt-select-loading {
|
|
4541
|
+
padding-inline: calc(var(--spacing) * 3.5);
|
|
4542
|
+
padding-block: calc(var(--spacing) * 1);
|
|
4543
|
+
font-size: var(--text-sm);
|
|
4544
|
+
line-height: var(--tw-leading, var(--text-sm--line-height));
|
|
4545
|
+
color: var(--muted-foreground);
|
|
4546
|
+
}
|
|
4514
4547
|
.kt-select-dropdown {
|
|
4515
4548
|
border-radius: calc(var(--radius) - 2px);
|
|
4516
4549
|
border-style: var(--tw-border-style);
|
|
@@ -4627,6 +4660,135 @@
|
|
|
4627
4660
|
white-space: nowrap;
|
|
4628
4661
|
text-overflow: ellipsis;
|
|
4629
4662
|
}
|
|
4663
|
+
.kt-select-tag {
|
|
4664
|
+
display: inline-flex;
|
|
4665
|
+
align-items: center;
|
|
4666
|
+
gap: calc(var(--spacing) * 2);
|
|
4667
|
+
border-radius: var(--radius);
|
|
4668
|
+
padding-inline: calc(var(--spacing) * 3);
|
|
4669
|
+
padding-block: calc(var(--spacing) * 1.5);
|
|
4670
|
+
font-size: var(--text-sm);
|
|
4671
|
+
line-height: var(--tw-leading, var(--text-sm--line-height));
|
|
4672
|
+
--tw-font-weight: var(--font-weight-medium);
|
|
4673
|
+
font-weight: var(--font-weight-medium);
|
|
4674
|
+
border-style: var(--tw-border-style);
|
|
4675
|
+
border-width: 1px;
|
|
4676
|
+
border-color: var(--color-gray-200);
|
|
4677
|
+
background-color: var(--color-gray-50);
|
|
4678
|
+
color: var(--color-gray-700);
|
|
4679
|
+
transition-property: all;
|
|
4680
|
+
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
|
|
4681
|
+
transition-duration: var(--tw-duration, var(--default-transition-duration));
|
|
4682
|
+
--tw-duration: 200ms;
|
|
4683
|
+
transition-duration: 200ms;
|
|
4684
|
+
&:hover {
|
|
4685
|
+
@media (hover: hover) {
|
|
4686
|
+
border-color: var(--color-gray-300);
|
|
4687
|
+
}
|
|
4688
|
+
}
|
|
4689
|
+
&:hover {
|
|
4690
|
+
@media (hover: hover) {
|
|
4691
|
+
background-color: var(--color-gray-100);
|
|
4692
|
+
}
|
|
4693
|
+
}
|
|
4694
|
+
max-width: 200px;
|
|
4695
|
+
flex-shrink: 0;
|
|
4696
|
+
overflow: hidden;
|
|
4697
|
+
text-overflow: ellipsis;
|
|
4698
|
+
white-space: nowrap;
|
|
4699
|
+
--tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
|
|
4700
|
+
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
|
4701
|
+
&:hover {
|
|
4702
|
+
@media (hover: hover) {
|
|
4703
|
+
--tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
|
|
4704
|
+
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
|
4705
|
+
}
|
|
4706
|
+
}
|
|
4707
|
+
--tw-leading: var(--leading-tight);
|
|
4708
|
+
line-height: var(--leading-tight);
|
|
4709
|
+
}
|
|
4710
|
+
.kt-select-tag-remove {
|
|
4711
|
+
display: flex;
|
|
4712
|
+
height: calc(var(--spacing) * 5);
|
|
4713
|
+
width: calc(var(--spacing) * 5);
|
|
4714
|
+
align-items: center;
|
|
4715
|
+
justify-content: center;
|
|
4716
|
+
border-radius: calc(infinity * 1px);
|
|
4717
|
+
color: var(--color-gray-500);
|
|
4718
|
+
&:hover {
|
|
4719
|
+
@media (hover: hover) {
|
|
4720
|
+
background-color: var(--color-gray-200);
|
|
4721
|
+
}
|
|
4722
|
+
}
|
|
4723
|
+
&:hover {
|
|
4724
|
+
@media (hover: hover) {
|
|
4725
|
+
color: var(--color-gray-700);
|
|
4726
|
+
}
|
|
4727
|
+
}
|
|
4728
|
+
cursor: pointer;
|
|
4729
|
+
transition-property: all;
|
|
4730
|
+
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
|
|
4731
|
+
transition-duration: var(--tw-duration, var(--default-transition-duration));
|
|
4732
|
+
--tw-duration: 200ms;
|
|
4733
|
+
transition-duration: 200ms;
|
|
4734
|
+
flex-shrink: 0;
|
|
4735
|
+
opacity: 70%;
|
|
4736
|
+
&:hover {
|
|
4737
|
+
@media (hover: hover) {
|
|
4738
|
+
--tw-scale-x: 110%;
|
|
4739
|
+
--tw-scale-y: 110%;
|
|
4740
|
+
--tw-scale-z: 110%;
|
|
4741
|
+
scale: var(--tw-scale-x) var(--tw-scale-y);
|
|
4742
|
+
}
|
|
4743
|
+
}
|
|
4744
|
+
}
|
|
4745
|
+
.kt-select-tag:hover .kt-select-tag-remove {
|
|
4746
|
+
opacity: 100%;
|
|
4747
|
+
}
|
|
4748
|
+
.kt-select-tag-remove svg {
|
|
4749
|
+
height: calc(var(--spacing) * 3.5);
|
|
4750
|
+
width: calc(var(--spacing) * 3.5);
|
|
4751
|
+
transition-property: transform, translate, scale, rotate;
|
|
4752
|
+
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
|
|
4753
|
+
transition-duration: var(--tw-duration, var(--default-transition-duration));
|
|
4754
|
+
--tw-duration: 200ms;
|
|
4755
|
+
transition-duration: 200ms;
|
|
4756
|
+
}
|
|
4757
|
+
.kt-select-tag-remove:hover svg {
|
|
4758
|
+
--tw-scale-x: 110%;
|
|
4759
|
+
--tw-scale-y: 110%;
|
|
4760
|
+
--tw-scale-z: 110%;
|
|
4761
|
+
scale: var(--tw-scale-x) var(--tw-scale-y);
|
|
4762
|
+
}
|
|
4763
|
+
.kt-select-display[data-multiple='true'] {
|
|
4764
|
+
display: flex;
|
|
4765
|
+
min-height: 3rem;
|
|
4766
|
+
flex-wrap: wrap;
|
|
4767
|
+
align-items: center;
|
|
4768
|
+
gap: calc(var(--spacing) * 2);
|
|
4769
|
+
padding: calc(var(--spacing) * 3);
|
|
4770
|
+
width: 100%;
|
|
4771
|
+
border-radius: calc(var(--radius) - 2px);
|
|
4772
|
+
border-style: var(--tw-border-style);
|
|
4773
|
+
border-width: 1px;
|
|
4774
|
+
border-color: var(--color-gray-200);
|
|
4775
|
+
background-color: var(--color-white);
|
|
4776
|
+
&:focus-within {
|
|
4777
|
+
border-color: var(--color-blue-300);
|
|
4778
|
+
}
|
|
4779
|
+
&:focus-within {
|
|
4780
|
+
--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
|
|
4781
|
+
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
|
4782
|
+
}
|
|
4783
|
+
&:focus-within {
|
|
4784
|
+
--tw-ring-color: var(--color-blue-100);
|
|
4785
|
+
}
|
|
4786
|
+
transition-property: all;
|
|
4787
|
+
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
|
|
4788
|
+
transition-duration: var(--tw-duration, var(--default-transition-duration));
|
|
4789
|
+
--tw-duration: 200ms;
|
|
4790
|
+
transition-duration: 200ms;
|
|
4791
|
+
}
|
|
4630
4792
|
}
|
|
4631
4793
|
@layer components {
|
|
4632
4794
|
.kt-select {
|
|
@@ -5898,6 +6060,21 @@
|
|
|
5898
6060
|
syntax: "*";
|
|
5899
6061
|
inherits: false;
|
|
5900
6062
|
}
|
|
6063
|
+
@property --tw-scale-x {
|
|
6064
|
+
syntax: "*";
|
|
6065
|
+
inherits: false;
|
|
6066
|
+
initial-value: 1;
|
|
6067
|
+
}
|
|
6068
|
+
@property --tw-scale-y {
|
|
6069
|
+
syntax: "*";
|
|
6070
|
+
inherits: false;
|
|
6071
|
+
initial-value: 1;
|
|
6072
|
+
}
|
|
6073
|
+
@property --tw-scale-z {
|
|
6074
|
+
syntax: "*";
|
|
6075
|
+
inherits: false;
|
|
6076
|
+
initial-value: 1;
|
|
6077
|
+
}
|
|
5901
6078
|
@property --tw-content {
|
|
5902
6079
|
syntax: "*";
|
|
5903
6080
|
inherits: false;
|
|
@@ -5960,6 +6137,9 @@
|
|
|
5960
6137
|
--tw-duration: initial;
|
|
5961
6138
|
--tw-tracking: initial;
|
|
5962
6139
|
--tw-ease: initial;
|
|
6140
|
+
--tw-scale-x: 1;
|
|
6141
|
+
--tw-scale-y: 1;
|
|
6142
|
+
--tw-scale-z: 1;
|
|
5963
6143
|
--tw-content: "";
|
|
5964
6144
|
}
|
|
5965
6145
|
}
|
|
@@ -0,0 +1,398 @@
|
|
|
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>KT DataTable Sorting Test - Official Structure</title>
|
|
7
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
|
8
|
+
<link rel="stylesheet" href="../../dist/styles.css">
|
|
9
|
+
<style>
|
|
10
|
+
/* Custom styles for the test */
|
|
11
|
+
.test-container {
|
|
12
|
+
max-width: 1200px;
|
|
13
|
+
margin: 0 auto;
|
|
14
|
+
padding: 20px;
|
|
15
|
+
}
|
|
16
|
+
.test-header {
|
|
17
|
+
background: #f8f9fa;
|
|
18
|
+
padding: 20px;
|
|
19
|
+
border-radius: 8px;
|
|
20
|
+
margin-bottom: 20px;
|
|
21
|
+
}
|
|
22
|
+
.test-controls {
|
|
23
|
+
display: flex;
|
|
24
|
+
gap: 10px;
|
|
25
|
+
margin-bottom: 20px;
|
|
26
|
+
flex-wrap: wrap;
|
|
27
|
+
}
|
|
28
|
+
.test-button {
|
|
29
|
+
background: #007bff;
|
|
30
|
+
color: white;
|
|
31
|
+
border: none;
|
|
32
|
+
padding: 8px 16px;
|
|
33
|
+
border-radius: 4px;
|
|
34
|
+
cursor: pointer;
|
|
35
|
+
}
|
|
36
|
+
.test-button:hover {
|
|
37
|
+
background: #0056b3;
|
|
38
|
+
}
|
|
39
|
+
.test-status {
|
|
40
|
+
padding: 10px;
|
|
41
|
+
border-radius: 4px;
|
|
42
|
+
margin-top: 10px;
|
|
43
|
+
font-weight: bold;
|
|
44
|
+
}
|
|
45
|
+
.test-pass {
|
|
46
|
+
background: #d4edda;
|
|
47
|
+
color: #155724;
|
|
48
|
+
border: 1px solid #c3e6cb;
|
|
49
|
+
}
|
|
50
|
+
.test-fail {
|
|
51
|
+
background: #f8d7da;
|
|
52
|
+
color: #721c24;
|
|
53
|
+
border: 1px solid #f5c6cb;
|
|
54
|
+
}
|
|
55
|
+
</style>
|
|
56
|
+
</head>
|
|
57
|
+
<body>
|
|
58
|
+
<div class="test-container">
|
|
59
|
+
<div class="test-header">
|
|
60
|
+
<h1 class="text-2xl font-bold mb-4">KT DataTable Sorting Test - Official Structure</h1>
|
|
61
|
+
<p class="text-gray-600 mb-4">
|
|
62
|
+
This test uses the official KTUI DataTable HTML structure from the documentation
|
|
63
|
+
and verifies that sorting functionality works correctly after table updates,
|
|
64
|
+
pagination, and search operations. The sorting fix should restore click handlers
|
|
65
|
+
after each table redraw.
|
|
66
|
+
</p>
|
|
67
|
+
|
|
68
|
+
<div class="test-controls">
|
|
69
|
+
<button class="test-button" onclick="testSorting()">Test Sorting</button>
|
|
70
|
+
<button class="test-button" onclick="testPagination()">Test Pagination</button>
|
|
71
|
+
<button class="test-button" onclick="testSearch()">Test Search</button>
|
|
72
|
+
<button class="test-button" onclick="testReload()">Test Reload</button>
|
|
73
|
+
<button class="test-button" onclick="clearStatus()">Clear Status</button>
|
|
74
|
+
</div>
|
|
75
|
+
|
|
76
|
+
<div id="test-status"></div>
|
|
77
|
+
</div>
|
|
78
|
+
|
|
79
|
+
<!-- Search Input -->
|
|
80
|
+
<div class="mb-4">
|
|
81
|
+
<input
|
|
82
|
+
type="text"
|
|
83
|
+
id="search-input"
|
|
84
|
+
placeholder="Search data..."
|
|
85
|
+
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
86
|
+
data-kt-datatable-search="#sorting-test-table"
|
|
87
|
+
>
|
|
88
|
+
</div>
|
|
89
|
+
|
|
90
|
+
<!-- DataTable Container using official structure -->
|
|
91
|
+
<div class="kt-card">
|
|
92
|
+
<div class="kt-card-table" data-kt-datatable="true" data-kt-datatable-page-size="5" data-kt-datatable-state-save="true">
|
|
93
|
+
<div class="kt-table-wrapper kt-scrollable">
|
|
94
|
+
<table id="sorting-test-table" class="kt-table" data-kt-datatable-table="true">
|
|
95
|
+
<thead>
|
|
96
|
+
<tr>
|
|
97
|
+
<th scope="col" class="w-20" data-kt-datatable-column="id">
|
|
98
|
+
<span class="kt-table-col">
|
|
99
|
+
<span class="kt-table-col-label">ID</span>
|
|
100
|
+
<span class="kt-table-col-sort"></span>
|
|
101
|
+
</span>
|
|
102
|
+
</th>
|
|
103
|
+
<th scope="col" class="w-32" data-kt-datatable-column="name">
|
|
104
|
+
<span class="kt-table-col">
|
|
105
|
+
<span class="kt-table-col-label">Name</span>
|
|
106
|
+
<span class="kt-table-col-sort"></span>
|
|
107
|
+
</span>
|
|
108
|
+
</th>
|
|
109
|
+
<th scope="col" class="w-40" data-kt-datatable-column="email">
|
|
110
|
+
<span class="kt-table-col">
|
|
111
|
+
<span class="kt-table-col-label">Email</span>
|
|
112
|
+
<span class="kt-table-col-sort"></span>
|
|
113
|
+
</span>
|
|
114
|
+
</th>
|
|
115
|
+
<th scope="col" class="w-32" data-kt-datatable-column="department">
|
|
116
|
+
<span class="kt-table-col">
|
|
117
|
+
<span class="kt-table-col-label">Department</span>
|
|
118
|
+
<span class="kt-table-col-sort"></span>
|
|
119
|
+
</span>
|
|
120
|
+
</th>
|
|
121
|
+
<th scope="col" class="w-24" data-kt-datatable-column="salary">
|
|
122
|
+
<span class="kt-table-col">
|
|
123
|
+
<span class="kt-table-col-label">Salary</span>
|
|
124
|
+
<span class="kt-table-col-sort"></span>
|
|
125
|
+
</span>
|
|
126
|
+
</th>
|
|
127
|
+
<th scope="col" class="w-24" data-kt-datatable-column="status">
|
|
128
|
+
<span class="kt-table-col">
|
|
129
|
+
<span class="kt-table-col-label">Status</span>
|
|
130
|
+
<span class="kt-table-col-sort"></span>
|
|
131
|
+
</span>
|
|
132
|
+
</th>
|
|
133
|
+
</tr>
|
|
134
|
+
</thead>
|
|
135
|
+
<tbody>
|
|
136
|
+
<tr>
|
|
137
|
+
<td>1</td>
|
|
138
|
+
<td>John Doe</td>
|
|
139
|
+
<td>john.doe@example.com</td>
|
|
140
|
+
<td>Engineering</td>
|
|
141
|
+
<td>$75,000</td>
|
|
142
|
+
<td><span class="kt-badge kt-badge-success">Active</span></td>
|
|
143
|
+
</tr>
|
|
144
|
+
<tr>
|
|
145
|
+
<td>2</td>
|
|
146
|
+
<td>Jane Smith</td>
|
|
147
|
+
<td>jane.smith@example.com</td>
|
|
148
|
+
<td>Marketing</td>
|
|
149
|
+
<td>$65,000</td>
|
|
150
|
+
<td><span class="kt-badge kt-badge-success">Active</span></td>
|
|
151
|
+
</tr>
|
|
152
|
+
<tr>
|
|
153
|
+
<td>3</td>
|
|
154
|
+
<td>Mike Johnson</td>
|
|
155
|
+
<td>mike.johnson@example.com</td>
|
|
156
|
+
<td>Engineering</td>
|
|
157
|
+
<td>$80,000</td>
|
|
158
|
+
<td><span class="kt-badge kt-badge-destructive">Inactive</span></td>
|
|
159
|
+
</tr>
|
|
160
|
+
<tr>
|
|
161
|
+
<td>4</td>
|
|
162
|
+
<td>Sarah Wilson</td>
|
|
163
|
+
<td>sarah.wilson@example.com</td>
|
|
164
|
+
<td>Sales</td>
|
|
165
|
+
<td>$70,000</td>
|
|
166
|
+
<td><span class="kt-badge kt-badge-success">Active</span></td>
|
|
167
|
+
</tr>
|
|
168
|
+
<tr>
|
|
169
|
+
<td>5</td>
|
|
170
|
+
<td>David Brown</td>
|
|
171
|
+
<td>david.brown@example.com</td>
|
|
172
|
+
<td>HR</td>
|
|
173
|
+
<td>$60,000</td>
|
|
174
|
+
<td><span class="kt-badge kt-badge-success">Active</span></td>
|
|
175
|
+
</tr>
|
|
176
|
+
<tr>
|
|
177
|
+
<td>6</td>
|
|
178
|
+
<td>Lisa Davis</td>
|
|
179
|
+
<td>lisa.davis@example.com</td>
|
|
180
|
+
<td>Engineering</td>
|
|
181
|
+
<td>$85,000</td>
|
|
182
|
+
<td><span class="kt-badge kt-badge-primary">Verified</span></td>
|
|
183
|
+
</tr>
|
|
184
|
+
<tr>
|
|
185
|
+
<td>7</td>
|
|
186
|
+
<td>Tom Anderson</td>
|
|
187
|
+
<td>tom.anderson@example.com</td>
|
|
188
|
+
<td>Marketing</td>
|
|
189
|
+
<td>$68,000</td>
|
|
190
|
+
<td><span class="kt-badge kt-badge-destructive">Inactive</span></td>
|
|
191
|
+
</tr>
|
|
192
|
+
<tr>
|
|
193
|
+
<td>8</td>
|
|
194
|
+
<td>Emma Taylor</td>
|
|
195
|
+
<td>emma.taylor@example.com</td>
|
|
196
|
+
<td>Sales</td>
|
|
197
|
+
<td>$72,000</td>
|
|
198
|
+
<td><span class="kt-badge kt-badge-success">Active</span></td>
|
|
199
|
+
</tr>
|
|
200
|
+
<tr>
|
|
201
|
+
<td>9</td>
|
|
202
|
+
<td>Chris Miller</td>
|
|
203
|
+
<td>chris.miller@example.com</td>
|
|
204
|
+
<td>Engineering</td>
|
|
205
|
+
<td>$78,000</td>
|
|
206
|
+
<td><span class="kt-badge kt-badge-success">Active</span></td>
|
|
207
|
+
</tr>
|
|
208
|
+
<tr>
|
|
209
|
+
<td>10</td>
|
|
210
|
+
<td>Amy Garcia</td>
|
|
211
|
+
<td>amy.garcia@example.com</td>
|
|
212
|
+
<td>HR</td>
|
|
213
|
+
<td>$62,000</td>
|
|
214
|
+
<td><span class="kt-badge kt-badge-success">Active</span></td>
|
|
215
|
+
</tr>
|
|
216
|
+
</tbody>
|
|
217
|
+
</table>
|
|
218
|
+
</div>
|
|
219
|
+
|
|
220
|
+
<!-- Pagination Info -->
|
|
221
|
+
<div class="flex items-center justify-between mt-4">
|
|
222
|
+
<div class="flex items-center space-x-2">
|
|
223
|
+
<span class="text-sm text-gray-700">Show</span>
|
|
224
|
+
<select data-kt-datatable-size="true" class="border border-gray-300 rounded px-2 py-1">
|
|
225
|
+
<option value="5">5</option>
|
|
226
|
+
<option value="10" selected>10</option>
|
|
227
|
+
<option value="20">20</option>
|
|
228
|
+
<option value="50">50</option>
|
|
229
|
+
</select>
|
|
230
|
+
<span class="text-sm text-gray-700">entries</span>
|
|
231
|
+
</div>
|
|
232
|
+
<div data-kt-datatable-info="true" class="text-sm text-gray-700"></div>
|
|
233
|
+
</div>
|
|
234
|
+
|
|
235
|
+
<!-- Pagination Controls -->
|
|
236
|
+
<div class="flex justify-center mt-4">
|
|
237
|
+
<div data-kt-datatable-pagination="true" class="flex space-x-1"></div>
|
|
238
|
+
</div>
|
|
239
|
+
</div>
|
|
240
|
+
</div>
|
|
241
|
+
</div>
|
|
242
|
+
|
|
243
|
+
<!-- Load KTUI -->
|
|
244
|
+
<script src="../../dist/ktui.js"></script>
|
|
245
|
+
|
|
246
|
+
<script>
|
|
247
|
+
let datatableInstance = null;
|
|
248
|
+
|
|
249
|
+
// Initialize the datatable when page loads
|
|
250
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
251
|
+
// Wait a bit for the DOM to be fully ready
|
|
252
|
+
setTimeout(() => {
|
|
253
|
+
try {
|
|
254
|
+
// Initialize KTUI components using official method
|
|
255
|
+
if (typeof KTDataTable !== 'undefined') {
|
|
256
|
+
KTDataTable.init();
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Get the datatable instance using official API
|
|
260
|
+
const container = document.querySelector('[data-kt-datatable="true"]');
|
|
261
|
+
if (container) {
|
|
262
|
+
datatableInstance = KTDataTable.getInstance(container);
|
|
263
|
+
if (datatableInstance) {
|
|
264
|
+
updateStatus('✅ DataTable initialized successfully using official API!', 'pass');
|
|
265
|
+
} else {
|
|
266
|
+
updateStatus('❌ Failed to get DataTable instance', 'fail');
|
|
267
|
+
}
|
|
268
|
+
} else {
|
|
269
|
+
updateStatus('❌ DataTable container not found', 'fail');
|
|
270
|
+
}
|
|
271
|
+
} catch (error) {
|
|
272
|
+
updateStatus('❌ Error initializing DataTable: ' + error.message, 'fail');
|
|
273
|
+
}
|
|
274
|
+
}, 100);
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
// Test sorting functionality using official API
|
|
278
|
+
function testSorting() {
|
|
279
|
+
if (!datatableInstance) {
|
|
280
|
+
updateStatus('❌ DataTable not initialized', 'fail');
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
try {
|
|
285
|
+
// Test sorting by name column using official API
|
|
286
|
+
datatableInstance.sort('name');
|
|
287
|
+
updateStatus('✅ Sorting test passed! Used official sort() API on name column.', 'pass');
|
|
288
|
+
|
|
289
|
+
// Test sorting by salary column
|
|
290
|
+
setTimeout(() => {
|
|
291
|
+
datatableInstance.sort('salary');
|
|
292
|
+
updateStatus('✅ Sorting test passed! Also tested salary column sorting with official API.', 'pass');
|
|
293
|
+
}, 1000);
|
|
294
|
+
|
|
295
|
+
} catch (error) {
|
|
296
|
+
updateStatus('❌ Sorting test failed: ' + error.message, 'fail');
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// Test pagination using official API
|
|
301
|
+
function testPagination() {
|
|
302
|
+
if (!datatableInstance) {
|
|
303
|
+
updateStatus('❌ DataTable not initialized', 'fail');
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
try {
|
|
308
|
+
// Set page size to 5 to enable pagination using official API
|
|
309
|
+
datatableInstance.setPageSize(5);
|
|
310
|
+
updateStatus('✅ Pagination test passed! Used official setPageSize(5) API. Now test sorting on different pages.', 'pass');
|
|
311
|
+
|
|
312
|
+
// Go to page 2 using official API
|
|
313
|
+
setTimeout(() => {
|
|
314
|
+
datatableInstance.goPage(2);
|
|
315
|
+
updateStatus('✅ Pagination test passed! Used official goPage(2) API. Try clicking column headers to sort.', 'pass');
|
|
316
|
+
}, 500);
|
|
317
|
+
|
|
318
|
+
} catch (error) {
|
|
319
|
+
updateStatus('❌ Pagination test failed: ' + error.message, 'fail');
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// Test search functionality using official API
|
|
324
|
+
function testSearch() {
|
|
325
|
+
if (!datatableInstance) {
|
|
326
|
+
updateStatus('❌ DataTable not initialized', 'fail');
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
try {
|
|
331
|
+
// Test search using official API
|
|
332
|
+
datatableInstance.search('John');
|
|
333
|
+
updateStatus('✅ Search test passed! Used official search("John") API. Try sorting the filtered results.', 'pass');
|
|
334
|
+
|
|
335
|
+
// Clear search after 3 seconds
|
|
336
|
+
setTimeout(() => {
|
|
337
|
+
datatableInstance.search('');
|
|
338
|
+
updateStatus('✅ Search test passed! Used official search("") API to clear. Sorting should still work.', 'pass');
|
|
339
|
+
}, 3000);
|
|
340
|
+
|
|
341
|
+
} catch (error) {
|
|
342
|
+
updateStatus('❌ Search test failed: ' + error.message, 'fail');
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// Test reload functionality using official API
|
|
347
|
+
function testReload() {
|
|
348
|
+
if (!datatableInstance) {
|
|
349
|
+
updateStatus('❌ DataTable not initialized', 'fail');
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
try {
|
|
354
|
+
// Reload the table using official API
|
|
355
|
+
datatableInstance.reload();
|
|
356
|
+
updateStatus('✅ Reload test passed! Used official reload() API. Try sorting now.', 'pass');
|
|
357
|
+
|
|
358
|
+
} catch (error) {
|
|
359
|
+
updateStatus('❌ Reload test failed: ' + error.message, 'fail');
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// Update status display
|
|
364
|
+
function updateStatus(message, type) {
|
|
365
|
+
const statusDiv = document.getElementById('test-status');
|
|
366
|
+
statusDiv.innerHTML = message;
|
|
367
|
+
statusDiv.className = `test-status ${type === 'pass' ? 'test-pass' : 'test-fail'}`;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// Clear status
|
|
371
|
+
function clearStatus() {
|
|
372
|
+
const statusDiv = document.getElementById('test-status');
|
|
373
|
+
statusDiv.innerHTML = '';
|
|
374
|
+
statusDiv.className = 'test-status';
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// Add manual testing instructions based on official documentation
|
|
378
|
+
console.log('🔧 Manual Testing Instructions (Official KTUI API):');
|
|
379
|
+
console.log('1. Click on any column header to test sorting');
|
|
380
|
+
console.log('2. Try pagination and then click headers to sort');
|
|
381
|
+
console.log('3. Use search and then try sorting filtered results');
|
|
382
|
+
console.log('4. All sorting should work consistently!');
|
|
383
|
+
console.log('5. Check browser dev tools for any console errors');
|
|
384
|
+
console.log('');
|
|
385
|
+
console.log('📚 This test uses the official KTUI DataTable structure from:');
|
|
386
|
+
console.log(' https://ktui.io/docs/datatable');
|
|
387
|
+
console.log('');
|
|
388
|
+
console.log('🔧 Official API Methods tested:');
|
|
389
|
+
console.log(' - KTDataTable.init()');
|
|
390
|
+
console.log(' - KTDataTable.getInstance()');
|
|
391
|
+
console.log(' - datatable.sort()');
|
|
392
|
+
console.log(' - datatable.setPageSize()');
|
|
393
|
+
console.log(' - datatable.goPage()');
|
|
394
|
+
console.log(' - datatable.search()');
|
|
395
|
+
console.log(' - datatable.reload()');
|
|
396
|
+
</script>
|
|
397
|
+
</body>
|
|
398
|
+
</html>
|
|
@@ -30,12 +30,14 @@
|
|
|
30
30
|
class="absolute top-3 right-3 text-gray-400 hover:text-gray-600 focus:outline-none"
|
|
31
31
|
aria-label="Close Modal">×</button>
|
|
32
32
|
<h2 class="text-lg font-semibold mb-4">Select a Field</h2>
|
|
33
|
+
<!-- Note: dropdownContainer is set to "#selectModal" to attach dropdown to modal container -->
|
|
33
34
|
<select
|
|
34
35
|
class="kt-select"
|
|
35
36
|
data-kt-select="true"
|
|
36
37
|
data-kt-select-placeholder="Select a framework..."
|
|
37
38
|
data-kt-select-config='{
|
|
38
|
-
"optionsClass": "kt-scrollable overflow-auto max-h-[250px]"
|
|
39
|
+
"optionsClass": "kt-scrollable overflow-auto max-h-[250px]",
|
|
40
|
+
"dropdownContainer": "#selectModal"
|
|
39
41
|
}'
|
|
40
42
|
>
|
|
41
43
|
<option value="react">React</option>
|