@kikiloaw/simple-table 1.1.11 → 1.1.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -10
- package/package.json +1 -1
- package/src/SimpleTable.vue +93 -13
package/README.md
CHANGED
|
@@ -419,7 +419,7 @@ SimpleTable supports three data modes:
|
|
|
419
419
|
| Protocol | When to Use | Backend Compatibility |
|
|
420
420
|
|----------|-------------|-----------------------|
|
|
421
421
|
| **`laravel`** (default) | **Recommended for 99% of cases.** | Standard Laravel pagination, Resource Collections, and custom JSON responses (including simple DataTables-like backends). |
|
|
422
|
-
| **`datatables`** |
|
|
422
|
+
| **`datatables`** | Legacy integrations. | Sends full DataTables payload (`draw`, `columns[...]`, `order[...]`, `search[...]`). Use this if you are using `yajra/laravel-datatables` or a strict DataTables backend. |
|
|
423
423
|
|
|
424
424
|
---
|
|
425
425
|
|
|
@@ -1153,17 +1153,22 @@ $('#myTable').DataTable({
|
|
|
1153
1153
|
|
|
1154
1154
|
**SimpleTable sends:**
|
|
1155
1155
|
```
|
|
1156
|
-
GET /api/users?start=0&length=10&
|
|
1156
|
+
GET /api/users?draw=1&start=0&length=10&search[value]=john&search[regex]=false&order[0][column]=1&order[0][dir]=asc&columns[0][data]=id&columns[0][name]=id&columns[0][searchable]=true...
|
|
1157
1157
|
```
|
|
1158
1158
|
|
|
1159
|
-
| Parameter | Description |
|
|
1160
|
-
|
|
1161
|
-
| `
|
|
1162
|
-
| `
|
|
1163
|
-
| `
|
|
1164
|
-
| `search[value]` |
|
|
1165
|
-
| `
|
|
1166
|
-
| `order[0][
|
|
1159
|
+
| Parameter | Description |
|
|
1160
|
+
|-----------|-------------|
|
|
1161
|
+
| `draw` | Request counter |
|
|
1162
|
+
| `start` | Record offset (0, 10, 20...) |
|
|
1163
|
+
| `length` | Records per page (10, 25, 50...) |
|
|
1164
|
+
| `search[value]` | Global search term |
|
|
1165
|
+
| `search[regex]` | Regex flag (always false) |
|
|
1166
|
+
| `order[0][column]` | Index of column being sorted |
|
|
1167
|
+
| `order[0][dir]` | Sort direction (`asc`, `desc`) |
|
|
1168
|
+
| `columns[i][data]` | Column key |
|
|
1169
|
+
| `columns[i][name]` | Column name (or custom sort key) |
|
|
1170
|
+
| `columns[i][searchable]` | Searchable flag |
|
|
1171
|
+
| `columns[i][orderable]` | Sortable flag |
|
|
1167
1172
|
|
|
1168
1173
|
### Response Format
|
|
1169
1174
|
|
package/package.json
CHANGED
package/src/SimpleTable.vue
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script setup lang="ts" generic="T">
|
|
2
|
-
import { computed, ref, watch, onMounted } from 'vue'
|
|
2
|
+
import { computed, ref, watch, onMounted, nextTick } from 'vue'
|
|
3
3
|
import { router } from '@inertiajs/vue3'
|
|
4
4
|
import {
|
|
5
5
|
Table,
|
|
@@ -194,13 +194,18 @@ function getCacheKey(): string {
|
|
|
194
194
|
})
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
-
function clearCache(scope: 'all' | 'current' = 'all') {
|
|
197
|
+
async function clearCache(scope: 'all' | 'current' = 'all') {
|
|
198
198
|
if (scope === 'current') {
|
|
199
199
|
const key = getCacheKey()
|
|
200
200
|
responseCache.value.delete(key)
|
|
201
201
|
} else {
|
|
202
202
|
responseCache.value.clear()
|
|
203
203
|
}
|
|
204
|
+
|
|
205
|
+
// User requested behavior: clearCache triggers fresh fetch
|
|
206
|
+
if (props.fetchUrl) {
|
|
207
|
+
await fetchData()
|
|
208
|
+
}
|
|
204
209
|
}
|
|
205
210
|
|
|
206
211
|
// Internal data state to handle both props updates and ajax updates
|
|
@@ -399,6 +404,7 @@ async function fetchData(params: any = {}) {
|
|
|
399
404
|
}
|
|
400
405
|
|
|
401
406
|
isLoading.value = true
|
|
407
|
+
|
|
402
408
|
try {
|
|
403
409
|
// Construct Query Parameters
|
|
404
410
|
const url = new URL(props.fetchUrl, window.location.origin)
|
|
@@ -410,10 +416,29 @@ async function fetchData(params: any = {}) {
|
|
|
410
416
|
url.searchParams.append('length', String(currentPerPage.value))
|
|
411
417
|
url.searchParams.append('draw', String(drawCounter.value))
|
|
412
418
|
|
|
413
|
-
if
|
|
414
|
-
|
|
415
|
-
|
|
419
|
+
// Defensive: Remove standard pagination params if they exist in the base URL
|
|
420
|
+
url.searchParams.delete('page')
|
|
421
|
+
url.searchParams.delete('per_page')
|
|
422
|
+
|
|
423
|
+
// Add Columns Configuration (Required for strict DataTables backends like Yajra)
|
|
424
|
+
props.columns.forEach((col, index) => {
|
|
425
|
+
const colName = typeof col.sortable === 'string' ? col.sortable : col.key
|
|
426
|
+
const isSortable = !!col.sortable
|
|
427
|
+
const isSearchable = true // Default to true as SimpleTable global search applies to all usually
|
|
428
|
+
|
|
429
|
+
url.searchParams.append(`columns[${index}][data]`, col.key)
|
|
430
|
+
url.searchParams.append(`columns[${index}][name]`, colName)
|
|
431
|
+
url.searchParams.append(`columns[${index}][searchable]`, String(isSearchable))
|
|
432
|
+
url.searchParams.append(`columns[${index}][orderable]`, String(isSortable))
|
|
433
|
+
url.searchParams.append(`columns[${index}][search][value]`, '')
|
|
434
|
+
url.searchParams.append(`columns[${index}][search][regex]`, 'false')
|
|
435
|
+
})
|
|
436
|
+
|
|
437
|
+
// Global Search (Always send, even if empty)
|
|
438
|
+
url.searchParams.append('search[value]', searchQuery.value || '')
|
|
439
|
+
url.searchParams.append('search[regex]', 'false')
|
|
416
440
|
|
|
441
|
+
|
|
417
442
|
if (sortColumn.value) {
|
|
418
443
|
// Find column index
|
|
419
444
|
const columnIndex = props.columns.findIndex(col => {
|
|
@@ -470,7 +495,10 @@ async function fetchData(params: any = {}) {
|
|
|
470
495
|
|
|
471
496
|
let data = await response.json()
|
|
472
497
|
|
|
473
|
-
//
|
|
498
|
+
// Emit raw response immediately
|
|
499
|
+
emit('fetched', data)
|
|
500
|
+
|
|
501
|
+
// Transform DataTables response to internal format for internal use
|
|
474
502
|
if (props.protocol === 'datatables') {
|
|
475
503
|
// DataTables response: { draw, recordsTotal, recordsFiltered, data }
|
|
476
504
|
// Transform to Laravel format internally
|
|
@@ -492,7 +520,7 @@ async function fetchData(params: any = {}) {
|
|
|
492
520
|
}
|
|
493
521
|
|
|
494
522
|
internalData.value = data
|
|
495
|
-
emit('fetched', data)
|
|
523
|
+
// emit('fetched', data) // <-- Removed this, we emit raw data above
|
|
496
524
|
|
|
497
525
|
// Store in cache if enabled
|
|
498
526
|
if (props.enableCache) {
|
|
@@ -504,15 +532,55 @@ async function fetchData(params: any = {}) {
|
|
|
504
532
|
isLoading.value = false
|
|
505
533
|
}
|
|
506
534
|
} else if (isServerSide.value) {
|
|
507
|
-
|
|
508
|
-
|
|
535
|
+
|
|
536
|
+
let data: any = {}
|
|
537
|
+
|
|
538
|
+
if (props.protocol === 'datatables') {
|
|
539
|
+
const start = params.page
|
|
540
|
+
? (params.page - 1) * currentPerPage.value
|
|
541
|
+
: (currentPage.value - 1) * currentPerPage.value
|
|
542
|
+
|
|
543
|
+
data = {
|
|
544
|
+
draw: drawCounter.value,
|
|
545
|
+
start: start,
|
|
546
|
+
length: currentPerPage.value,
|
|
547
|
+
'search[value]': params.search ?? searchQuery.value ?? '',
|
|
548
|
+
...props.queryParams
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
// Add Sort
|
|
552
|
+
if (params.sort || sortColumn.value) {
|
|
553
|
+
const colKey = params.sort ?? sortColumn.value
|
|
554
|
+
const colDir = params.order ?? sortDirection.value
|
|
555
|
+
|
|
556
|
+
// Find column index
|
|
557
|
+
const columnIndex = props.columns.findIndex(col => {
|
|
558
|
+
const sortKey = typeof col.sortable === 'string' ? col.sortable : col.key
|
|
559
|
+
return sortKey === colKey
|
|
560
|
+
})
|
|
561
|
+
|
|
562
|
+
if (columnIndex !== -1) {
|
|
563
|
+
data['order[0][column]'] = columnIndex
|
|
564
|
+
data['order[0][dir]'] = colDir
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
drawCounter.value++
|
|
569
|
+
|
|
570
|
+
} else {
|
|
571
|
+
// Laravel format (default)
|
|
572
|
+
data = {
|
|
509
573
|
page: params.page ?? currentPage.value,
|
|
510
574
|
per_page: currentPerPage.value,
|
|
511
575
|
search: params.search ?? searchQuery.value,
|
|
512
576
|
sort: params.sort ?? sortColumn.value,
|
|
513
577
|
order: params.order ?? sortDirection.value,
|
|
514
578
|
...(props.queryParams || {})
|
|
515
|
-
}
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
router.visit(window.location.pathname, {
|
|
583
|
+
data,
|
|
516
584
|
preserveState: true,
|
|
517
585
|
preserveScroll: true,
|
|
518
586
|
replace: true,
|
|
@@ -663,8 +731,20 @@ function handlePageChange(page: number) {
|
|
|
663
731
|
emit('page-change', page)
|
|
664
732
|
}
|
|
665
733
|
|
|
666
|
-
|
|
734
|
+
|
|
735
|
+
// Reload (Reset): Go to page 1, clear cache, and refetch
|
|
736
|
+
async function reload() {
|
|
667
737
|
currentPage.value = 1
|
|
738
|
+
await nextTick()
|
|
739
|
+
|
|
740
|
+
// Clear cache for fresh start
|
|
741
|
+
if (props.enableCache) {
|
|
742
|
+
clearCache('current')
|
|
743
|
+
// Note: clearCache calls fetchData(), so we don't need to call it again explicitly here
|
|
744
|
+
// However, clearCache is async now.
|
|
745
|
+
return // clearCache already fetched
|
|
746
|
+
}
|
|
747
|
+
|
|
668
748
|
fetchData()
|
|
669
749
|
}
|
|
670
750
|
|
|
@@ -675,9 +755,9 @@ onMounted(() => {
|
|
|
675
755
|
})
|
|
676
756
|
|
|
677
757
|
defineExpose({
|
|
678
|
-
|
|
758
|
+
reload, // The new "Reset" function
|
|
679
759
|
fetchData,
|
|
680
|
-
clearCache
|
|
760
|
+
clearCache // The "Reload current page" function (effectively)
|
|
681
761
|
})
|
|
682
762
|
|
|
683
763
|
|