7

I have a table with date objects, which I transform for display like this:

{
   key: "date",
   formatter: (value, key, item) => {
     return moment(value).format("L");
   },
   sortable: true
}

This breaks the sorting function because is a localized string. I'd like to do something like

 sortingKey: value=>value

To override the string sorting of the rendered date and go back to sorting by dates, but I can't find anything like that.

Update: This is already sorted out, but to me the solution is not pretty. A prettier solution would have been:

field: {
  key: 'date',
  sorter: (value, item, fieldMeta) => {
    // returns something that reacts to <
    // key == fieldMeta.key
    // default (current) implementation
    return fieldMeta.formatter ? fieldMeta.formatter(value, fieldMeta.key, item) : value;
  }

3 Answers 3

7

The sort-compare function will be your fiend. the basic sort compare method compares two values, and requires a minimum of three arguments: item a, item b, and the field key being sorted on. Note a and b are the entire row data objects being compared.

For your above example, do the following:

export default {
  // ...
  methods: {
    mySortCompare(a, b, key) {
      if (key === 'date') {
        // Assuming the date field is a `Date` object, subtraction
        // works on the date serial number (epoch value)
        return a[key] - b[key]
      } else {
        // Let b-table handle sorting other fields (other than `date` field)
        return false
      }
    }
  }
  // ...
}
<b-table :items="items" :fields="fields" :sort-compare="mySortCompare">
  <!-- ... -->
</b-table>
Sign up to request clarification or add additional context in comments.

3 Comments

I'm not a fan of hard-coding things around, but I guess there's no other option since the field metadata is not available. This does the trick though.
Adding a function to the field definition is no more different than providing a function the sort-compare route. You have to add the code somewhere.
Yes, the difference is that you are at the place where it is being used. Having the key name hardcoded somewhere else is not an ideal design, and if you have 3 fields with this requirements, then you have a nice if cascade which isn't really nice to read. It just clutters the code, it will work, but nice is something different. Think about the return false in your example, you need to have the comment, because it's not understandable from the context. That's practical, but not really nice.
3

I believe the prop you need is sort-compare.

https://bootstrap-vue.js.org/docs/components/table#sort-compare-routine

You can see how it's used in the source code:

https://github.com/bootstrap-vue/bootstrap-vue/blob/a660dc518246167aa99cd3cac16b5f8bc0055f2d/src/components/table/helpers/mixin-sorting.js#L85

It is configured for the whole table, not an individual column. For columns that should just use the default sort order you can return undefined, null or false, which should cause it to fallback to the default sort order (see lines 104 to 107).

1 Comment

Thanks. I oversaw the return "fallback" functionally in the docs. Still not pretty, but it works.
3

In my case, all I needed to do was add sortByFormatted: true to the particular field:

{
  key: 'name',
  sortable: true,
  sortByFormatted: true,
  formatter: (value, key, item) => {
    return item.first_name + ' ' + item.last_name;
  },
},

1 Comment

This is using bootstrap-vue 2.0.0 by the way.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.