How to change Vuetify calendar date format

浪尽此生 提交于 2019-12-08 19:58:53

问题


I am attempting to enable inputted events on the following Vuetify calendar:

https://github.com/vuetifyjs/vuetify/blob/master/packages/docs/src/examples/calendars/complex/events.vue.

I have set up my calendar to accept inputted data submitted in a form, including name, details, start, end, color. When I submit the form, an error occurs saying that

the start and end properties are required on all events to be a valid timestamp in the format YYYY-MM-DD.

I am using type="date" in the start and end input fields, which render the dates in the MM-DD-YYYY. I tried using the Vuetify date picker instead in order to get the fields to render in YYYY-MM-DD format, but to no avail. How can I reconfigure this calendar to instead accept MM-DD-YYYY format for dates?

CALENDAR MODIFIED:

moment added to function

      async addEvent () {
        this.start = await new Date(this.start).toISOString().substring(0,10)
        this.end =  await new Date(this.end).toISOString().substring(0,10)
        this.events.push({name: this.name})
        this.events.push({details: this.details})
        this.events.push({start: this.start})
        this.events.push({end: this.end})
        this.events.push({color: this.color})
      },

Full Code

<template>
  <v-row class="fill-height">
    <v-col>
      <v-sheet height="64">
        <v-toolbar flat color="white">
          <v-btn outlined class="mr-4" @click="setToday">
            Today
          </v-btn>
          <v-btn fab text small @click="prev">
            <v-icon small>mdi-chevron-left</v-icon>
          </v-btn>
          <v-btn fab text small @click="next">
            <v-icon small>mdi-chevron-right</v-icon>
          </v-btn>
          <v-btn
            color="primary"
            dark
            @click.stop="dialog = true"
          >
            New Event
          </v-btn>
          <v-toolbar-title>{{ title }}</v-toolbar-title>
          <div class="flex-grow-1"></div>
        </v-toolbar>
      </v-sheet>

      <v-dialog v-model="dialog" max-width="500">
        <v-card>
          <v-container>
            <v-form @submit.prevent="addEvent">
              <v-text-field v-model="name" type="text" label="name"></v-text-field>
              <v-text-field v-model="details" type="text" label="detail"></v-text-field>
              <v-text-field v-model="start" type="date" label="start"></v-text-field>
              <v-text-field v-model="end" type="date" label="end"></v-text-field>
              <v-text-field v-model="color" label="color"></v-text-field>
              <v-btn type="submit" color="success" class="mr-4" @click.stop="dialog = false">
                submit
              </v-btn>
            </v-form>
          </v-container>
        </v-card>
      </v-dialog>

      <v-sheet height="600">
        <v-calendar
          ref="calendar"
          v-model="focus"
          color="primary"
          :events="events"
          :event-color="getEventColor"
          :event-margin-bottom="3"
          :now="today"
          :type="type"
          @click:event="showEvent"
          @click:more="viewDay"
          @click:date="viewDay"
          @change="updateRange"
        ></v-calendar>
        <v-menu
          v-model="selectedOpen"
          :close-on-content-click="false"
          :activator="selectedElement"
          full-width
          offset-x
        >
          <v-card
            color="grey lighten-4"
            min-width="350px"
            flat
          >
            <v-toolbar
              :color="selectedEvent.color"
              dark
            >
              <v-btn icon>
                <v-icon>mdi-pencil</v-icon>
              </v-btn>
              <v-toolbar-title v-html="selectedEvent.name"></v-toolbar-title>
              <div class="flex-grow-1"></div>
              <v-btn icon>
                <v-icon>mdi-heart</v-icon>
              </v-btn>
              <v-btn icon>
                <v-icon>mdi-dots-vertical</v-icon>
              </v-btn>
            </v-toolbar>
            <v-card-text>
              <span v-html="selectedEvent.details"></span>
            </v-card-text>
            <v-card-actions>
              <v-btn
                text
                color="secondary"
                @click="selectedOpen = false"
              >
                Cancel
              </v-btn>
            </v-card-actions>
          </v-card>
        </v-menu>
      </v-sheet>
    </v-col>
  </v-row>
</template>

<script>
  //import moment from 'moment'
  export default {
    data: () => ({
      today: '2019-01-08',
      focus: '2019-01-08',
      type: 'month',
      typeToLabel: {
        month: 'Month',
        week: 'Week',
        day: 'Day',
        '4day': '4 Days',
      },
      name: null,
      details: null,
      start: null,
      end: null,
      color: null,
      selectedEvent: {},
      selectedElement: null,
      selectedOpen: false,
      events: [
        {
          name: 'Vacation',
          details: 'Going to the beach!',
          start: '2018-12-29',
          end: '2019-01-01',
          color: 'blue',
        }
      ],
      dialog: false,
    }),
    computed: {
      title () {
        const { start, end } = this
        if (!start || !end) {
          return ''
        }
        const startMonth = this.monthFormatter(start)
        const endMonth = this.monthFormatter(end)
        const suffixMonth = startMonth === endMonth ? '' : endMonth
        const startYear = start.year
        const endYear = end.year
        const suffixYear = startYear === endYear ? '' : endYear
        const startDay = start.day + this.nth(start.day)
        const endDay = end.day + this.nth(end.day)
        switch (this.type) {
          case 'month':
            return `${startMonth} ${startYear}`
          case 'week':
          case '4day':
            return `${startMonth} ${startDay} ${startYear} - ${suffixMonth} ${endDay} ${suffixYear}`
          case 'day':
            return `${startMonth} ${startDay} ${startYear}`
        }
        return ''
      },
      monthFormatter () {
        return this.$refs.calendar.getFormatter({
          timeZone: 'UTC', month: 'long',
        })
      },
    },
    methods: {
      viewDay ({ date }) {
        this.focus = date
        this.type = 'day'
      },
      getEventColor (event) {
        return event.color
      },
      setToday () {
        this.focus = this.today
      },
      prev () {
        this.$refs.calendar.prev()
      },
      next () {
        this.$refs.calendar.next()
      },
      async addEvent () {
        this.start = await new Date(this.start).toISOString().substring(0,10)
        this.end =  await new Date(this.end).toISOString().substring(0,10)
        console.log(this.start)
        this.events.push({name: this.name})
        this.events.push({details: this.details})
        this.events.push({start: this.start})
        this.events.push({end: this.end})
        this.events.push({color: this.color})
      },
      showEvent ({ nativeEvent, event }) {
        const open = () => {
          this.selectedEvent = event
          this.selectedElement = nativeEvent.target
          setTimeout(() => this.selectedOpen = true, 10)
        }
        if (this.selectedOpen) {
          this.selectedOpen = false
          setTimeout(open, 10)
        } else {
          open()
        }
        nativeEvent.stopPropagation()
      },
      updateRange ({ start, end }) {
        // You could load events from an outside source (like database) now that we have the start and end dates on the calendar
        this.start = start
        this.end = end
      },
      nth (d) {
        return d > 3 && d < 21
          ? 'th'
          : ['th', 'st', 'nd', 'rd', 'th', 'th', 'th', 'th', 'th', 'th'][d % 10]
      },
    },
  }
</script>



回答1:


No need to moment.js which will be used only for 2 lines of code, so you could do it simply like :

   addEvent () {
        this.start = new Date(this.start).toISOString().substring(0,10);
        this.end =  new Date(this.end).toISOString().substring(0,10);
        ...
            this.events.push({name: this.name,
                              details: this.details,
                              start: this.start,
                              end: this.end,
                             color: this.color})
See the Pen Vuetify Example Pen by boussadjra (@boussadjra) on CodePen.


回答2:


I would advice to format your date to MM-DD-YYYY instead of modifying vuetify, then convert it to whatever format you need when you submit the form.

Moment.js is an awesome library for this type of conversions and has an easy API.

In your case, you could simply do this.end = moment(this.end).format('MM-DD-YYYY');



来源:https://stackoverflow.com/questions/57717902/how-to-change-vuetify-calendar-date-format

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!