New Sep 17, 2024

Vue js sorting table

Libraries, Frameworks, etc. All from Newest questions tagged vue.js - Stack Overflow View Vue js sorting table on stackoverflow.com

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?

Scroll to top