How to format Vuetify data table date column?
Asked Answered
F

6

42

I have a simple data table using Vuetify data table. One of the column is a createdOn (date time), I want to format it. How can I do it ?

This is what i get now:

This is what i get now

<template>
   <v-layout>
      <v-data-table :headers="headers" :items="logs">
      </v-data-table>
   <v-layout>
</template>
<script>
      headers: [
        { text: "Time", value: "createdOn", dataType: "Date" },
        { text: "Event Source", value: "eventSourceName" },
        { text: "Event Details", value: "eventDetails" },
        { text: "User", value: "user" }
      ],
      items: [],
</script>
Frederickafredericks answered 15/9, 2019 at 14:9 Comment(2)
how do you want to format it?Incorruptible
hi @Boussadjra Brahim I get "2019-09-14T17:03:24.3949548" format now. I want to make it "2019-09-14 3:24 AM". Is there a way to do it like pipes in angular?Frederickafredericks
I
81

You should use a custom row cell :

<v-data-table :headers="headers" :items="logs">
  <template v-slot:item.createdOn="{ item }">
    <span>{{ new Date(item.createdOn).toLocaleString() }}</span>
  </template>
</v-data-table>
Incorruptible answered 15/9, 2019 at 14:24 Comment(8)
You may have a typo, I needed to use singular item.createdOn as the v-slot attribute, plural items.createdOn did not work.Protero
For me there is an issue: If I pass '2020-07-01' it gets rendered as "1.7.2020, 02:00:00", which is most often not what you want. Javascript takes the given value as UTC and displays it with the offset of the user.Feverwort
@MathiasF i think the problem is with your locale, i answered the question with the given input 2019-09-14T17... i recommend to ask a new question with more detailsIncorruptible
This answer could be updated to avoid the "'v-slot' directive doesn't support any modifier" error by changing <template v-slot:item.createdOn="{ item }"> to <template v-slot:[`item.createdOn`]="{ item }">. See 'v-slot' directive doesn't support any modifier.Allamerican
thank you for your comment, it could be updated to what?Incorruptible
To <template v-slot:[`item.createdOn`]="{ item }">.Allamerican
That called a dynamic slot, for example you could do v-slot:[someprop]="{}" knowing that someprop is a property defined in script or template that represent a string of a valid slotIncorruptible
for some reason you want a dynamic timestamp based on a condition returned from a computed property myTimestamp(){return this.updated?'updatedOn':'createdOn'} then in template you could do v-slot:[myTimestamp]="{item}"Incorruptible
H
23

I found out a way to format cell values using dynamic slot names and a function in the header object:

In the <v-data-table> I did:

<template v-for="header in headers.filter((header) => header.hasOwnProperty('formatter'))" v-slot:[`item.${header.value}`]="{ header, value }">
  {{ header.formatter(value) }}
</template>

and in the vue data property I did:

headers: [
  // ...
  { text: 'Value for example', value: '10000', formatter: formatCurrency },
  // ...
]

And finally in the methods prop I did:

formatCurrency (value) {
  return "$ " + (value / 100).toFixed(2);
}

Here's a sandbox to see it in action: https://codesandbox.io/s/vuetify-datatable-value-formatter-jdtxj?file=/src/App.vue

EDIT:

In this specific case you could use momentjs or javascript's Date(). I've added a momentjs example to the codesandbox.

Hortensiahorter answered 26/1, 2021 at 15:27 Comment(4)
Yes - great work @SneakyLenny! Saved me like 2 hrs. Got this to work for a more generic "customize every column" approach: ` <template v-for="header in headers" v-slot:[item.${header.value}]="{ header, value }" > {{ formatCell(value) }} </template> `Kerianne
can use still sort/filter on date columns irrespective of chosen format after that? i.e. does the table use the underlying Dates or the newly formatted strings for its internal sorting/filtering algorithm after that?Niello
@Niello Sorting is based on the data given, otherwise you could have formatted the data beforehand. Example: if the data would be 4 - 2 - 1 - 3 and a formatter would add random letters to the format the display is sorted as y1 - x2 - u3 - a4. If that makes sense.Hortensiahorter
This is also useful to create <template> based on the data dynamically, say if you have "dynamic headers", then you can inspect the headers and create templates. Very useful, thanks!Telepathy
J
1

If you want an even simpler solution or at least one where you can format other columns as well:

<v-data-table :headers="headers" :items="logs">
  <template v-slot:body="{ items }">
    <tbody>
      <tr v-for="item in items" :key="logs.id">
        <td> {{ new Date(item.createdOn).toLocaleString() }} </td>
        ...
      </tr>
    </tbody>
  </template>
</v-data-table>

The trick is using the body slot of v-data-table. More information here.

Jacquie answered 19/10, 2021 at 7:37 Comment(0)
S
0

I have also used global filter with v-slot:

<v-data-table :headers="headers" :items="logs">
  <template v-slot:item.createdOn="{ item }">
    <span>{{ item.createdOn | myGlobalDateFilter }}</span>
  </template>
</v-data-table>
Sheik answered 27/5, 2021 at 22:18 Comment(0)
I
0

In datatable component Datatable.vue

<template v-for="slot in slots" v-slot:[`item.${slot.slotName}`]="{ item }">
  <slot :name="slot.slotName" :variable="item"></slot>
</template>

export default {
props:
slots:{
  type:Array,
  default:null
},

and parent component

<Datatable
 :headers="headers"
  :items="stokhareketleri"
  :title="title"
  :slots="slots">
<template v-slot:column_name="{ variable }">
  <v-chip
        color="green"
        dark
      >
      {{variable.column_name}}
      </v-chip>
</template>
  </Datatable>


data () {
      return {
        slots:[{ 
          Id: 1, slotName: 'column_name'
          }],
Impeccable answered 30/6, 2021 at 19:49 Comment(0)
F
0

You can use the date composable provided in Vuetify version 3.4.0+

<template>
  <v-data-table :headers="headers" :items="logs">
     <template #item.createdOn="{ item }">
        {{ date.format(item.createdOn, 'fullDateTime24h') }}
     </template>
  </v-data-table>
</template>

<script setup>
import { useDate } from 'vuetify';
const date = useDate();
</script>
Foregut answered 13/6 at 12:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.