Home > other >  How to sort vuetify v-data-table by item value rather than template slot displayed value
How to sort vuetify v-data-table by item value rather than template slot displayed value

Time:10-22

I have a v-data-table that has an alphanumeric ID with JSON key name aid (ie, AZ-0001). I also have a field in the JSON array called id which is basically just the numeric version (ie, 0001). When I sort the datatable it always puts the A's first and is not really numerically sorting which is what I want so I created a v-slot template to adjust what is displayed so that ID is the item slot and AID is whats actually displayed in the v-slot template. However, even doing this when pressing the sort icon for ID column it still sorts alphanumerically on what is actually being displayed (AID) so A's first rather than numerically just going by id which is the actual value for that column. I have another column similar to this that displays the date as Calendar year or Fiscal Year (ie, CY2022 and FY2022) so I run into a similar issue with this alphanumberic sorting doing alphabetically. So the simple example I show below I am hoping to use it for multiple fields. I plan to use the solution to this problem on another column I am running into a similar issue that I did not include in this example. My code is as follows:

        <v-data-table :headers="headerset"
                  :items="filteredData"
                  :search="searchTable"
                  height="inherit"
                  :loading="loading"
                  loading-text="Loading... Please wait"
                  style="cursor: pointer">
        <template v-slot:item.id="{ item }">
            {{ item.aid}}
        </template>
    </v-data-table>

CodePudding user response:

You can provide a sort function in your headers that specify how your items should be sorted for a given column.

From there you should be able to implement the sort function you want.

export interface DataTableHeader<T extends any = any> {
  text: string
  value: string
  align?: 'start' | 'center' | 'end'
  sortable?: boolean
  filterable?: boolean
  groupable?: boolean
  divider?: boolean
  class?: string | string[]
  cellClass?: string | string[]
  width?: string | number
  filter?: (value: any, search: string | null, item: any) => boolean
  sort?: DataTableCompareFunction<T>
}

CodePudding user response:

I will try to explain @Takezoshi answer.

Assume you have a v-data-table:

<v-data-table
  :headers="headers"
  :items="desserts"
  :items-per-page="5"
></v-data-table>

The solution is to place custom sort function into your headers array. This way, by example:

data () {
  return {
    headers: [
      {
        text: 'Identifier',
        value: 'id',
        sort: this.customIdSort,
      },
      { text: 'Calories', value: 'calories' },
      ...
    ],
    desserts: [
      {
        id: 'AZ-0001',
        calories: 159,
        ...
      },
      {
        id: 'AB-0004',
        calories: 237,
        ...
      },
      ...
   ]
 }
}

Then you need to define this custom function. Unfortunately, I'm not clearly understand your sort logic, but you can write your own if this will not suit you:

methods: {
  customIdSort(a, b) {
    let aId = a.substring(3)
    let bId = b.substring(3)
    return aId.localeCompare(bId)
  }
}

Test this solution at CodePen.

  • Related