Vuetify v-calendar next day

731 Views Asked by At

I'm trying to create a v-calendar with vuetify.
The problem is that I can't start at 10:00 and show 3:00 the next day.
How can I display it until 3 o'clock the next day?

<v-calendar
  ref="calendar"
  v-model="focus"
  color="primary"
  type="category"
  category-show-all
  :categories="categories"
  :events="events"
  :event-color="getEventColor"
  first-interval=10
  interval-minutes= 60  
  @change="fetchEvents()"
></v-calendar>

The problem photo

The problem photo

1

There are 1 best solutions below

1
yoduh On

There is a solution but it's a bit hacky (doesn't seem natively supported by Vuetify). First, you'll need to use the prop interval-count

The number of intervals to display in the day view.

When you use this to show hours past midnight, the calendar will grow vertically to accommodate the additional hours, but will still not show the interval labels for those hours.

If we use another prop called show-interval-label, it takes a function that:

Checks if a given day and time should be displayed in the interval gutter of the day view.

Using the props together:

first-interval="10"
interval-minutes="60"
interval-count="18"
:show-interval-label="showInterval"

Here I define a method showInterval and in showInterval if I console.log all the intervals it receives, the first interval that is not displayed (1:00am) looks like this:

{
  "date": "2022-11-14",
  "time": "25:00",
  "year": 2022,
  "month": 11,
  "day": 14,
  "weekday": 1,
  "hour": 26,
  "minute": 0,
  "hasDay": true,
  "hasTime": true,
  "past": false,
  "present": false,
  "future": true
}

Even if we return true for all intervals, the intervals after midnight still won't be displayed on the calendar. That is because the v-calendar template code knows after midnight it should only display intervals for the next day, but the interval object itself still has properties defining it using the previous day (date, day, weekday, etc)

To get these intervals to display we have to modify the object to look like this instead:

{
  "date": "2022-11-15",
  "time": "1:00",
  "year": 2022,
  "month": 11,
  "day": 15,
  "weekday": 2,
  "hour": 1,
  "minute": 0,
  "hasDay": true,
  "hasTime": true,
  "past": false,
  "present": false,
  "future": true
}

The full code for doing so is below which I also included in a codepen

showInterval(dateObj) {
  console.log('dateObj', dateObj);
  if (dateObj.hour > 24) {
    const extraDays = Math.floor(dateObj.hour / 24);
    const newHour = dateObj.hour === 24 ? 24 : dateObj.hour % 24;
    const newDay = dateObj.weekday + extraDays === 7 ? 7 : (dateObj.weekday + extraDays) % 7;
    dateObj.hour = newHour;
    dateObj.weekday = newDay;
    dateObj.day = dateObj.day + extraDays;
    dateObj.date = this.addDays(dateObj.date, extraDays);
    dateObj.time = this.subtractTime(dateObj.time, extraDays);
  }
  return true;
},
addDays(date, days) {
  var result = new Date(date);
  result.setDate(result.getDate() + days);
  return result.toISOString().slice(0, 10);
},
subtractTime(time, days) {
  const timeArr = time.split(':');
  const newHour = Number(timeArr[0]) - 24 * days;
  return newHour + ':' + timeArr.slice(1).join();
}