I'm getting one issue some strange, I have one table and I added the sort function, this is my code:
<script setup lang="ts">
import { ref, computed, watch } from 'vue'
const data = ref([
{
header: {
id_file: '11',
id_client: '0',
client_txid: '01TF 49608',
spa_status: 'A',
},
try_log: [
{
hac_id: '184',
exec_date: '2024-08-05T20:32:25.579Z',
api_env: 'PRODUCCION_REAL',
},
{
hac_id: '168',
exec_date: '2024-08-05T18:54:57.535Z',
api_env: 'PRODUCCION_REAL',
},
],
},
{
header: {
id_file: '11',
id_client: '0',
client_txid: '01MN 177338',
spa_status: 'TIMEOUT',
},
try_log: [
{
hac_id: '184',
exec_date: '2024-08-05T20:32:25.579Z',
api_env: 'PRODUCCION_REAL',
},
{
hac_id: '168',
exec_date: '2024-08-05T18:54:57.535Z',
api_env: 'PRODUCCION_REAL',
},
],
},
{
header: {
id_file: '11',
id_client: '0',
client_txid: '01MN 177338',
spa_status: 'PAGADA',
},
try_log: [
{
hac_id: '167',
exec_date: '2024-08-05T18:54:55.780Z',
api_env: 'PRODUCCION_REAL',
},
],
},
{
header: {
id_file: '500',
id_client: '850',
client_txid: 'TRX-VE4586-T3',
spa_status: '',
},
try_log: [
{
hac_id: '166',
exec_date: '2024-08-05T18:54:51.719Z',
api_env: 'PRODUCCION_REAL',
},
],
},
])
const page = ref(1)
const itemsPerPage = ref(10)
const sortBy = ref<string>('')
const sortDirection = ref<string>('asc')
const filteredData = ref(data.value)
const filters = ref({
search: '',
id_file: '',
})
const normalizeValue = (value: any) => {
if (typeof value === 'string') {
return value.toLowerCase()
}
if (typeof value === 'number' || typeof value === 'boolean') {
return value.toString()
}
return value
}
function sortTable(column: string) {
if (sortBy.value === column) {
sortDirection.value = sortDirection.value === 'asc' ? 'desc' : 'asc'
} else {
sortBy.value = column
sortDirection.value = 'asc'
}
const modifier = sortDirection.value === 'asc' ? 1 : -1
const sortedData = [...filteredData.value].sort((a, b) => {
const aValue = normalizeValue(a.header[column] ?? '');
const bValue = normalizeValue(b.header[column] ?? '');
if (!aValue && !bValue) return 0; // Both null, no change in order
if (!aValue) return 1; // a is null, move b before a (descending)
if (!bValue) return -1; // b is null, move a before b (ascending)
// Existing comparison logic
if (aValue < bValue) return -1 * modifier;
if (aValue > bValue) return 1 * modifier;
return 0
})
filteredData.value = sortedData
}
watch(
filters,
() => {
page.value = 1
filteredData.value = data.value.filter((item) => {
return Object.values(item.header).some((value) =>
String(value).toLowerCase().includes(filters.value.search.toLowerCase())
)
})
},
{ immediate: true }
)
const paginatedData = computed(() => {
if (itemsPerPage.value === 0) return filteredData.value
const start = (page.value - 1) * itemsPerPage.value
const end = start + itemsPerPage.value
return filteredData.value.slice(start, end)
})
watch(filters, () => {
page.value = 1
})
</script>
<template>
<div>
<div class="list-view-toolbar">
<div class="search-field">
<VField>
<VControl
icon="feather:search"
style="margin: 0"
>
<input
v-model="filters.search"
class="input custom-text-filter"
placeholder="Search..."
>
</VControl>
</VField>
</div>
</div>
</div>
<div class="datatable-wrapper">
<div
class="table-container"
style="overflow: auto"
>
<table class="table datatable-table is-fullwidth">
<thead>
<tr>
<th
class="col-estatus"
align="center"
@click="sortTable('id_client')"
>
id_client
<span v-if="sortBy === 'id_client'">
<i
v-if="sortDirection === 'asc'"
class="iconify"
data-icon="feather:chevron-up"
aria-hidden="true"
/>
<i
v-else
class="iconify"
data-icon="feather:chevron-down"
aria-hidden="true"
/>
</span>
</th>
<th
class="col-estatus"
align="center"
@click="sortTable('client_txid')"
>
client_txid
<span v-if="sortBy === 'client_txid'">
<i
v-if="sortDirection === 'asc'"
class="iconify"
data-icon="feather:chevron-up"
aria-hidden="true"
/>
<i
v-else
class="iconify"
data-icon="feather:chevron-down"
aria-hidden="true"
/>
</span>
</th>
<th
class="col-estatus"
align="center"
@click="sortTable('id_file')"
>
id_file
<span v-if="sortBy === 'id_file'">
<i
v-if="sortDirection === 'asc'"
class="iconify"
data-icon="feather:chevron-up"
aria-hidden="true"
/>
<i
v-else
class="iconify"
data-icon="feather:chevron-down"
aria-hidden="true"
/>
</span>
</th>
</tr>
</thead>
<tbody>
<tr
v-for="(item, index) in paginatedData"
:key="index"
>
<td
class="col-id-cliente"
align="center"
>
{{ item.header.id_client }}
</td>
<td
class="col-id-beneficiario"
align="center"
>
{{ item.header.client_txid }}
</td>
<td
class="col-id-cliente"
align="center"
>
{{ item.header.id_file }}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
so, the function sortTable
is for sort datatable asc or desc if I click on header client_txid
datatable sorted in ascending order but If I click again on header client_txid
I got this issue on console:
Uncaught (in promise) TypeError: Cannot read properties of null (reading 'insertBefore')
why I'm getting this issue??? and how I can fix it?