Cato Minor
Cato Minor

Reputation: 3099

Make Vuetify v-data-table column sort first in descending order, second in ascending order?

In the Vuetify v-data-table examples, when the user clicks on a data table's column heading, the table is sorted first in the column's ascending order. Upon a second click of the heading, the table is sorted in the column's descending order.

I would like to reverse the order of sorting: first click causes sort by descending order, second click causes sort by ascending order.

Is there a way to do this with Vuetify's v-data-table?

Upvotes: 2

Views: 10808

Answers (2)

Cato Minor
Cato Minor

Reputation: 3099

I imagined there might be a simpler solution, but it seems the best answer is to use the custom-sort prop of v-data-table.

In a single file component's template:

    <v-data-table
        :headers="myHeaders"
        :items="myItems"   
        :custom-sort="customSort"
    ></v-data-table>

In a single file component's JS:

    methods: {
      customSort(items, index, isDesc) {
        items.sort((a, b) => {
          if (isDesc != "false") {
            return a[index] < b[index] ? -1 : 1
          } else {
            return b[index] < a[index] ? -1 : 1
          }
        })
        return items
      }
    },

Note: Since this essentially flips the 'descending'/'ascending' items, You may want to change the default sort icon as well:

    new Vuetify({
      icons: {
        values: {
          sort: 'mdi-arrow-down',
        },
      },
    })

JSFiddle

Upvotes: 3

User 28
User 28

Reputation: 5168

I come up with another hack which use sort-by and sort-desc props.

Example code:

<div id="app">
  <v-app>
    <v-data-table
      :headers="headers"
      :items="desserts"
      :sort-by.sync="sortBy"
      :sort-desc.sync="sortDesc"
      @update:options="handleOptionsUpdate">
    </v-data-table>
  </v-app>
</div>
...
  handleOptionsUpdate({ sortBy, sortDesc }) {
    if (
      sortBy[0] === this.sortBy[0] &&
      sortDesc[0] === this.sortDesc[0]
    ) return

    if (sortBy[0] && sortDesc[0] === false) {
      this.sortDesc = [true]
      return
    }

    if (sortBy.length === 0 && sortDesc.length === 0) {
      this.sortBy = [this.sortBy[0]]
      this.sortDesc = [false]
      return
    }

    if (sortBy[0] && sortDesc[0] === true) {
      this.sortBy = []
      this.sortDesc = []
      return
    }
  }
...

JSFiddle

The one disadvantage of this hack is it's actually sort twice for each click. But you can also solve this by create your own header slot and change sort-by and sort-desc by your self.

Upvotes: 1

Related Questions