Skip to content

Commit aed36a3

Browse files
authored
Merge pull request #23 from connorabbas/develop
Updated DataTable composable
2 parents e50a498 + 56db538 commit aed36a3

File tree

2 files changed

+71
-18
lines changed

2 files changed

+71
-18
lines changed

app/Http/Middleware/HandleInertiaRequests.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ public function share(Request $request): array
3434
'auth' => [
3535
'user' => $request->user(),
3636
],
37+
'request' => [
38+
'urlParams' => $request->all(),
39+
],
3740
];
3841
}
3942
}

resources/js/Composables/useDataTable.js renamed to resources/js/Composables/useLazyDataTable.js

Lines changed: 68 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
1-
import { ref, computed } from 'vue';
2-
import { router } from '@inertiajs/vue3';
1+
import { ref, computed, onMounted } from 'vue';
2+
import { router, usePage } from '@inertiajs/vue3';
3+
4+
export function useLazyDataTable(
5+
defaultFilters = {},
6+
only = ['request'],
7+
rows = 20
8+
) {
9+
const page = usePage();
310

4-
export function useDataTable(defaultFilters = {}, only = ['urlParams']) {
511
const dataTableDefaults = {
612
filters: defaultFilters,
713
sortField: '',
814
sortOrder: 1,
915
currentPage: 1,
10-
rowsPerPage: 20,
16+
rowsPerPage: rows,
1117
};
1218

1319
const filters = ref(dataTableDefaults.filters);
@@ -19,11 +25,21 @@ export function useDataTable(defaultFilters = {}, only = ['urlParams']) {
1925
const firstDatasetIndex = computed(() => {
2026
return (currentPage.value - 1) * rowsPerPage.value;
2127
});
28+
const hasFilteringApplied = computed(() => {
29+
const filters = page.props?.request?.urlParams?.filters || {};
30+
const sortField = page.props?.request?.urlParams?.sortField || null;
31+
const isFiltering = Object.values(filters).some(
32+
(filter) => filter.value !== null && filter.value !== ''
33+
);
34+
const isSorting = sortField !== null && sortField !== '';
35+
36+
return isFiltering || isSorting;
37+
});
2238

2339
function fetchData() {
2440
return new Promise((resolve, reject) => {
2541
router.reload({
26-
only,
42+
only: ['request', ...new Set(only)],
2743
data: {
2844
filters: filters.value,
2945
sortField: sortField.value,
@@ -42,12 +58,18 @@ export function useDataTable(defaultFilters = {}, only = ['urlParams']) {
4258
});
4359
}
4460

45-
function onPage(event) {
46-
currentPage.value = event.page + 1;
47-
rowsPerPage.value = event.rows;
48-
fetchData().then(() => {
49-
scrollToTop();
61+
function onFilter(event) {
62+
// TODO: debounce "contains" searches
63+
currentPage.value = 1;
64+
filters.value = event.filters;
65+
// empty arrays cause filtering issues, set to null instead
66+
Object.keys(filters.value).forEach((key) => {
67+
const filter = filters.value[key];
68+
if (Array.isArray(filter.value) && filter.value.length === 0) {
69+
filters.value[key].value = null;
70+
}
5071
});
72+
fetchData();
5173
}
5274

5375
function onSort(event) {
@@ -56,10 +78,12 @@ export function useDataTable(defaultFilters = {}, only = ['urlParams']) {
5678
fetchData();
5779
}
5880

59-
function onFilter(event) {
60-
currentPage.value = 1;
61-
filters.value = event.filters;
62-
fetchData();
81+
function onPage(event) {
82+
currentPage.value = event.page + 1;
83+
rowsPerPage.value = event.rows;
84+
fetchData().then(() => {
85+
scrollToTop();
86+
});
6387
}
6488

6589
function scrollToTop() {
@@ -69,7 +93,7 @@ export function useDataTable(defaultFilters = {}, only = ['urlParams']) {
6993
});
7094
}
7195

72-
function reset() {
96+
function resetFilters() {
7397
filters.value = dataTableDefaults.filters;
7498
sortField.value = dataTableDefaults.sortField;
7599
sortOrder.value = dataTableDefaults.sortOrder;
@@ -80,6 +104,27 @@ export function useDataTable(defaultFilters = {}, only = ['urlParams']) {
80104

81105
function parseUrlParams(urlParams) {
82106
filters.value = urlParams?.filters || dataTableDefaults.filters;
107+
// Cast strings to Numbers for v-model
108+
Object.keys(filters.value).forEach((key) => {
109+
const filter = filters.value[key];
110+
if (!filter.value) {
111+
return;
112+
}
113+
if (typeof filter.value === 'string' && !isNaN(filter.value)) {
114+
filters.value[key].value = Number(filter.value);
115+
}
116+
if (Array.isArray(filter.value)) {
117+
// TODO: find out why there are duplicate array values in multi-select filters
118+
// "Fixed" with reassigning to unique array
119+
const unique = [...new Set(filter.value)];
120+
filter.value = unique;
121+
filter.value.forEach((value, index) => {
122+
if (typeof value === 'string' && !isNaN(value)) {
123+
filter.value[index] = Number(value);
124+
}
125+
});
126+
}
127+
});
83128
sortField.value = urlParams?.sortField || dataTableDefaults.sortField;
84129
sortOrder.value =
85130
parseInt(urlParams?.sortOrder) || dataTableDefaults.sortOrder;
@@ -89,17 +134,22 @@ export function useDataTable(defaultFilters = {}, only = ['urlParams']) {
89134
parseInt(urlParams?.rows) || dataTableDefaults.rowsPerPage;
90135
}
91136

137+
onMounted(() => {
138+
parseUrlParams(page.props.request.urlParams);
139+
});
140+
92141
return {
93142
filters,
94143
sortField,
95144
sortOrder,
96145
currentPage,
97146
rowsPerPage,
98147
firstDatasetIndex,
99-
onPage,
100-
onSort,
148+
hasFilteringApplied,
101149
onFilter,
102-
reset,
150+
onSort,
151+
onPage,
152+
resetFilters,
103153
fetchData,
104154
parseUrlParams,
105155
};

0 commit comments

Comments
 (0)