@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 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`** | Rare. | Only use if your backend **strictly requires** `draw`, `start`, and `length` request parameters and fails with standard `page`/`per_page` params. |
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&draw=1&search[value]=john&order[0][column]=1&order[0][dir]=asc
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 | Example |
1160
- |-----------|-------------|---------|
1161
- | `start` | Record offset | `0`, `10`, `20` |
1162
- | `length` | Records per page | `10`, `25`, `50` |
1163
- | `draw` | Request counter | `1`, `2`, `3` |
1164
- | `search[value]` | Search query | `john`, `admin` |
1165
- | `order[0][column]` | Column index to sort | `0`, `1`, `2` |
1166
- | `order[0][dir]` | Sort direction | `asc`, `desc` |
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kikiloaw/simple-table",
3
- "version": "1.1.11",
3
+ "version": "1.1.19",
4
4
  "description": "A lightweight, dependency-light DataTable component for Vue 3 with Tailwind CSS",
5
5
  "main": "src/index.js",
6
6
  "module": "src/index.js",
@@ -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 (searchQuery.value) {
414
- url.searchParams.append('search[value]', searchQuery.value)
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
- // Transform DataTables response to internal format
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
- router.visit(window.location.pathname, {
508
- data: {
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
- function refresh() {
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
- refresh,
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