Rental Availability
Usage
theme: 'ios' You can turn auto theming on and let it decide based on the platform.
Usage
themeVariant: 'light' You can turn auto dark mode on based on system settings.
Usage
touchUi: true
// touch interaction is enabled Use touch interaction on mobile or pointer interaction on desktop.
Usage
locale: localeEn Selecting the locale loads the localized settings and the translated UI text.
Rental Availability
Use the multiple month view of the date picker for building an availability calendar for a vacation rental. The colored backgrounds and labels can be used to display season and pricing information and half-day styling to show check-in and check-out dates.
Booked dates are disabled and validation on check-in and check-out dates is automatic based on the data as a range for a new booking is applied.
Demo
Code
View code on GitHub
<script setup>
import {
formatDate,
getJson,
MbscCalendarNav,
MbscCalendarNext,
MbscCalendarPrev,
MbscDatepicker,
setOptions
} from '@mobiscroll/vue'
import { onMounted, ref } from 'vue'
setOptions({
locale: ,
theme: ' ',
themeVariant: ' '
})
const now = new Date()
const monthColors = [
{
background: '#b2f1c080',
start: '2026-01-01T00:00',
end: '2026-01-31T00:00',
cellCssClass: 'md-book-rental-bg-off',
recurring: {
repeat: 'yearly',
month: 1,
day: 1
}
},
{
background: '#b2f1c080',
start: '2026-02-01T00:00',
end: '2026-02-28T00:00',
cellCssClass: 'md-book-rental-bg-off',
recurring: {
repeat: 'yearly',
month: 2,
day: 1
}
},
{
background: '#b2f1c080',
cellCssClass: 'md-book-rental-bg-off',
recurring: {
repeat: 'yearly',
month: 2,
day: 29
}
},
{
background: '#a3cdff80',
start: '2026-03-01T00:00',
end: '2026-03-31T23:59',
cellCssClass: 'md-book-rental-bg-pre',
recurring: {
repeat: 'yearly',
month: 3,
day: 1
}
},
{
background: '#a3cdff80',
start: '2026-04-01T00:00',
end: '2026-04-30T00:00',
cellCssClass: 'md-book-rental-bg-pre',
recurring: {
repeat: 'yearly',
month: 4,
day: 1
}
},
{
background: '#a3cdff80',
start: '2026-05-01T00:00',
end: '2026-05-31T00:00',
cellCssClass: 'md-book-rental-bg-pre',
recurring: {
repeat: 'yearly',
month: 5,
day: 1
}
},
{
background: '#f7f7bb80',
start: '2026-06-01T00:00',
end: '2026-06-30T00:00',
cellCssClass: 'md-book-rental-bg-in',
recurring: {
repeat: 'yearly',
month: 6,
day: 1
}
},
{
background: '#f7f7bb80',
start: '2026-07-01T00:00',
end: '2026-07-31T00:00',
cellCssClass: 'md-book-rental-bg-in',
recurring: {
repeat: 'yearly',
month: 7,
day: 1
}
},
{
background: '#f7f7bb80',
start: '2026-08-01T00:00',
end: '2026-08-31T00:00',
cellCssClass: 'md-book-rental-bg-in',
recurring: {
repeat: 'yearly',
month: 8,
day: 1
}
},
{
background: '#f7f7bb80',
start: '2026-09-01T00:00',
end: '2026-09-30T00:00',
cellCssClass: 'md-book-rental-bg-in',
recurring: {
repeat: 'yearly',
month: 9,
day: 1
}
},
{
background: '#f7f7bb80',
start: '2026-10-01T00:00',
end: '2026-10-31T23:59',
cellCssClass: 'md-book-rental-bg-in',
recurring: {
repeat: 'yearly',
month: 10,
day: 1
}
},
{
background: '#b2f1c080',
start: '2026-11-01T00:00',
end: '2026-11-30T00:00',
cellCssClass: 'md-book-rental-bg-off',
recurring: {
repeat: 'yearly',
month: 11,
day: 1
}
},
{
background: '#b2f1c080',
start: '2026-12-01T00:00',
end: '2026-12-31T00:00',
cellCssClass: 'md-book-rental-bg-off',
recurring: {
repeat: 'yearly',
month: 12,
day: 1
}
}
]
const myMin = '2026-10-27T00:00'
const myLabels = ref()
const myInvalid = ref()
const myColors = ref()
function getColors(start, end) {
return [
{
date: start,
cellCssClass: 'vacation-check-in'
},
{
date: end,
cellCssClass: 'vacation-check-out'
},
{
start: new Date(start.getFullYear(), start.getMonth(), start.getDate() + 1),
end: new Date(end.getFullYear(), end.getMonth(), end.getDate() - 1),
background: '#ffbaba80',
cellCssClass: 'vacation-booked'
}
]
}
onMounted(() => {
const y = now.getFullYear()
const m = now.getMonth()
getJson(
'https://trial.mobiscroll.com/getrentals/?year=' + y + '&month=' + m,
(data) => {
const prices = data.prices
const bookings = data.bookings
const labels = []
const invalids = []
let colors = []
let endDate = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0)
for (const price of prices) {
const booked = bookings.find(
(b) => formatDate('YYYY-M-D', new Date(b.checkIn)) === price.date
)
if (booked) {
const checkIn = new Date(booked.checkIn)
const checkOut = new Date(booked.checkOut)
const newCheckOut = new Date(
checkOut.getFullYear(),
checkOut.getMonth(),
checkOut.getDate() - 1
)
colors = [...colors, ...getColors(checkIn, checkOut)]
labels.push({
start: checkIn,
end: newCheckOut,
text: 'booked',
textColor: '#1e1e1ecc'
})
invalids.push({
start: checkIn,
end: newCheckOut
})
endDate = checkOut
} else if (new Date(price.date) >= endDate) {
labels.push({
date: new Date(price.date),
text: price.text,
textColor: price.textColor
})
}
}
myLabels.value = labels
myInvalid.value = invalids
myColors.value = [...colors, ...monthColors]
},
'jsonp'
)
})
</script>
<template>
<MbscDatepicker
className="md-book-rental"
select="range"
display="inline"
calendarType="month"
:calendarSize="6"
:controls="['calendar']"
:min="myMin"
:labels="myLabels"
:invalid="myInvalid"
:colors="myColors"
:showRangeLabels="false"
:inRangeInvalid="false"
:rangeEndInvalid="true"
>
<template #header>
<MbscCalendarNav />
<div class="md-book-rental-header">
<div class="md-book-rental-zone md-book-rental-pre">pre-season</div>
<div class="md-book-rental-zone md-book-rental-in">in-season</div>
<div class="md-book-rental-zone md-book-rental-off">off-season</div>
<div class="md-book-rental-zone md-book-rental-booked">booked</div>
</div>
<MbscCalendarPrev />
<MbscCalendarNext />
</template>
</MbscDatepicker>
</template>
<style>
.mbsc-datepicker .md-book-rental-bg-off.vacation-check-in.mbsc-ltr {
background: linear-gradient(to left top, #ffbaba80 50%, #b2f1c080 50%) no-repeat;
}
.mbsc-datepicker .md-book-rental-bg-pre.vacation-check-in.mbsc-ltr {
background: linear-gradient(to left top, #ffbaba80 50%, #a3cdff80 50%) no-repeat;
}
.mbsc-datepicker .md-book-rental-bg-in.vacation-check-in.mbsc-ltr {
background: linear-gradient(to left top, #ffbaba80 50%, #f7f7bb80 50%) no-repeat;
}
.mbsc-datepicker .md-book-rental-bg-off.vacation-check-out.mbsc-ltr {
background: linear-gradient(to left top, #b2f1c080 50%, #ffbaba80 50%) no-repeat;
}
.mbsc-datepicker .md-book-rental-bg-pre.vacation-check-out.mbsc-ltr {
background: linear-gradient(to left top, #a3cdff80 50%, #ffbaba80 50%) no-repeat;
}
.mbsc-datepicker .md-book-rental-bg-in.vacation-check-out.mbsc-ltr {
background: linear-gradient(to left top, #f7f7bb80 50%, #ffbaba80 50%) no-repeat;
}
.mbsc-datepicker .md-book-rental-bg-off.vacation-check-in.mbsc-rtl {
background: linear-gradient(to right bottom, #ffbaba80 50%, #b2f1c080 50%) no-repeat;
}
.mbsc-datepicker .md-book-rental-bg-pre.vacation-check-in.mbsc-rtl {
background: linear-gradient(to right bottom, #ffbaba80 50%, #a3cdff80 50%) no-repeat;
}
.mbsc-datepicker .md-book-rental-bg-in.vacation-check-in.mbsc-rtl {
background: linear-gradient(to right bottom, #ffbaba80 50%, #f7f7bb80 50%) no-repeat;
}
.mbsc-datepicker .md-book-rental-bg-off.vacation-check-out.mbsc-rtl {
background: linear-gradient(to right bottom, #b2f1c080 50%, #ffbaba80 50%) no-repeat;
}
.mbsc-datepicker .md-book-rental-bg-pre.vacation-check-out.mbsc-rtl {
background: linear-gradient(to right bottom, #a3cdff80 50%, #ffbaba80 50%) no-repeat;
}
.mbsc-datepicker .md-book-rental-bg-in.vacation-check-out.mbsc-rtl {
background: linear-gradient(to right bottom, #f7f7bb80 50%, #ffbaba80 50%) no-repeat;
}
.mbsc-datepicker .vacation-check-out,
.mbsc-datepicker .vacation-check-in {
color: initial;
}
.mbsc-datepicker .vacation-check-in.mbsc-calendar-cell.mbsc-calendar-day-empty,
.mbsc-datepicker .vacation-check-out.mbsc-calendar-cell.mbsc-calendar-day-empty {
background: transparent;
}
.md-book-rental-header {
display: flex;
align-items: center;
justify-content: end;
margin-left: auto;
flex: 1 1;
overflow: hidden;
}
.md-book-rental-zone {
font-size: 12px;
padding: 3px 6px;
margin: 0 5px;
border-radius: 16px;
color: #1e1e1ecc;
}
.md-book-rental .mbsc-calendar-label-text {
text-align: center;
font-weight: bold;
}
.md-book-rental-in {
background: #f7f7bb80;
}
.md-book-rental-pre {
background: #a3cdff80;
}
.md-book-rental-off {
background: #b2f1c080;
}
.md-book-rental-booked {
background: #ffbaba80;
}
</style> <script setup lang="ts">
import {
formatDate,
getJson,
MbscCalendarNav,
MbscCalendarNext,
MbscCalendarPrev,
MbscDatepicker,
setOptions
} from '@mobiscroll/vue'
import { onMounted, ref } from 'vue'
setOptions({
locale: ,
theme: ' ',
themeVariant: ' '
})
const now = new Date()
const monthColors = [
{
background: '#b2f1c080',
start: '2026-01-01T00:00',
end: '2026-01-31T00:00',
cellCssClass: 'md-book-rental-bg-off',
recurring: {
repeat: 'yearly',
month: 1,
day: 1
}
},
{
background: '#b2f1c080',
start: '2026-02-01T00:00',
end: '2026-02-28T00:00',
cellCssClass: 'md-book-rental-bg-off',
recurring: {
repeat: 'yearly',
month: 2,
day: 1
}
},
{
background: '#b2f1c080',
cellCssClass: 'md-book-rental-bg-off',
recurring: {
repeat: 'yearly',
month: 2,
day: 29
}
},
{
background: '#a3cdff80',
start: '2026-03-01T00:00',
end: '2026-03-31T23:59',
cellCssClass: 'md-book-rental-bg-pre',
recurring: {
repeat: 'yearly',
month: 3,
day: 1
}
},
{
background: '#a3cdff80',
start: '2026-04-01T00:00',
end: '2026-04-30T00:00',
cellCssClass: 'md-book-rental-bg-pre',
recurring: {
repeat: 'yearly',
month: 4,
day: 1
}
},
{
background: '#a3cdff80',
start: '2026-05-01T00:00',
end: '2026-05-31T00:00',
cellCssClass: 'md-book-rental-bg-pre',
recurring: {
repeat: 'yearly',
month: 5,
day: 1
}
},
{
background: '#f7f7bb80',
start: '2026-06-01T00:00',
end: '2026-06-30T00:00',
cellCssClass: 'md-book-rental-bg-in',
recurring: {
repeat: 'yearly',
month: 6,
day: 1
}
},
{
background: '#f7f7bb80',
start: '2026-07-01T00:00',
end: '2026-07-31T00:00',
cellCssClass: 'md-book-rental-bg-in',
recurring: {
repeat: 'yearly',
month: 7,
day: 1
}
},
{
background: '#f7f7bb80',
start: '2026-08-01T00:00',
end: '2026-08-31T00:00',
cellCssClass: 'md-book-rental-bg-in',
recurring: {
repeat: 'yearly',
month: 8,
day: 1
}
},
{
background: '#f7f7bb80',
start: '2026-09-01T00:00',
end: '2026-09-30T00:00',
cellCssClass: 'md-book-rental-bg-in',
recurring: {
repeat: 'yearly',
month: 9,
day: 1
}
},
{
background: '#f7f7bb80',
start: '2026-10-01T00:00',
end: '2026-10-31T23:59',
cellCssClass: 'md-book-rental-bg-in',
recurring: {
repeat: 'yearly',
month: 10,
day: 1
}
},
{
background: '#b2f1c080',
start: '2026-11-01T00:00',
end: '2026-11-30T00:00',
cellCssClass: 'md-book-rental-bg-off',
recurring: {
repeat: 'yearly',
month: 11,
day: 1
}
},
{
background: '#b2f1c080',
start: '2026-12-01T00:00',
end: '2026-12-31T00:00',
cellCssClass: 'md-book-rental-bg-off',
recurring: {
repeat: 'yearly',
month: 12,
day: 1
}
}
]
const myMin = '2026-10-27T00:00'
const myLabels = ref()
const myInvalid = ref()
const myColors = ref()
function getColors(start: Date, end: Date) {
return [
{
date: start,
cellCssClass: 'vacation-check-in'
},
{
date: end,
cellCssClass: 'vacation-check-out'
},
{
start: new Date(start.getFullYear(), start.getMonth(), start.getDate() + 1),
end: new Date(end.getFullYear(), end.getMonth(), end.getDate() - 1),
background: '#ffbaba80',
cellCssClass: 'vacation-booked'
}
]
}
onMounted(() => {
const y = now.getFullYear()
const m = now.getMonth()
getJson(
'https://trial.mobiscroll.com/getrentals/?year=' + y + '&month=' + m,
(data) => {
const prices = data.prices
const bookings = data.bookings
const labels = []
const invalids = []
let colors: any[] = []
let endDate = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0)
for (const price of prices) {
const booked = bookings.find(
(b: any) => formatDate('YYYY-M-D', new Date(b.checkIn)) === price.date
)
if (booked) {
const checkIn = new Date(booked.checkIn)
const checkOut = new Date(booked.checkOut)
const newCheckOut = new Date(
checkOut.getFullYear(),
checkOut.getMonth(),
checkOut.getDate() - 1
)
colors = [...colors, ...getColors(checkIn, checkOut)]
labels.push({
start: checkIn,
end: newCheckOut,
text: 'booked',
textColor: '#1e1e1ecc'
})
invalids.push({
start: checkIn,
end: newCheckOut
})
endDate = checkOut
} else if (new Date(price.date) >= endDate) {
labels.push({
date: new Date(price.date),
text: price.text,
textColor: price.textColor
})
}
}
myLabels.value = labels
myInvalid.value = invalids
myColors.value = [...colors, ...monthColors]
},
'jsonp'
)
})
</script>
<template>
<MbscDatepicker
className="md-book-rental"
select="range"
display="inline"
calendarType="month"
:calendarSize="6"
:controls="['calendar']"
:min="myMin"
:labels="myLabels"
:invalid="myInvalid"
:colors="myColors"
:showRangeLabels="false"
:inRangeInvalid="false"
:rangeEndInvalid="true"
>
<template #header>
<MbscCalendarNav />
<div class="md-book-rental-header">
<div class="md-book-rental-zone md-book-rental-pre">pre-season</div>
<div class="md-book-rental-zone md-book-rental-in">in-season</div>
<div class="md-book-rental-zone md-book-rental-off">off-season</div>
<div class="md-book-rental-zone md-book-rental-booked">booked</div>
</div>
<MbscCalendarPrev />
<MbscCalendarNext />
</template>
</MbscDatepicker>
</template>
<style>
.mbsc-datepicker .md-book-rental-bg-off.vacation-check-in.mbsc-ltr {
background: linear-gradient(to left top, #ffbaba80 50%, #b2f1c080 50%) no-repeat;
}
.mbsc-datepicker .md-book-rental-bg-pre.vacation-check-in.mbsc-ltr {
background: linear-gradient(to left top, #ffbaba80 50%, #a3cdff80 50%) no-repeat;
}
.mbsc-datepicker .md-book-rental-bg-in.vacation-check-in.mbsc-ltr {
background: linear-gradient(to left top, #ffbaba80 50%, #f7f7bb80 50%) no-repeat;
}
.mbsc-datepicker .md-book-rental-bg-off.vacation-check-out.mbsc-ltr {
background: linear-gradient(to left top, #b2f1c080 50%, #ffbaba80 50%) no-repeat;
}
.mbsc-datepicker .md-book-rental-bg-pre.vacation-check-out.mbsc-ltr {
background: linear-gradient(to left top, #a3cdff80 50%, #ffbaba80 50%) no-repeat;
}
.mbsc-datepicker .md-book-rental-bg-in.vacation-check-out.mbsc-ltr {
background: linear-gradient(to left top, #f7f7bb80 50%, #ffbaba80 50%) no-repeat;
}
.mbsc-datepicker .md-book-rental-bg-off.vacation-check-in.mbsc-rtl {
background: linear-gradient(to right bottom, #ffbaba80 50%, #b2f1c080 50%) no-repeat;
}
.mbsc-datepicker .md-book-rental-bg-pre.vacation-check-in.mbsc-rtl {
background: linear-gradient(to right bottom, #ffbaba80 50%, #a3cdff80 50%) no-repeat;
}
.mbsc-datepicker .md-book-rental-bg-in.vacation-check-in.mbsc-rtl {
background: linear-gradient(to right bottom, #ffbaba80 50%, #f7f7bb80 50%) no-repeat;
}
.mbsc-datepicker .md-book-rental-bg-off.vacation-check-out.mbsc-rtl {
background: linear-gradient(to right bottom, #b2f1c080 50%, #ffbaba80 50%) no-repeat;
}
.mbsc-datepicker .md-book-rental-bg-pre.vacation-check-out.mbsc-rtl {
background: linear-gradient(to right bottom, #a3cdff80 50%, #ffbaba80 50%) no-repeat;
}
.mbsc-datepicker .md-book-rental-bg-in.vacation-check-out.mbsc-rtl {
background: linear-gradient(to right bottom, #f7f7bb80 50%, #ffbaba80 50%) no-repeat;
}
.mbsc-datepicker .vacation-check-out,
.mbsc-datepicker .vacation-check-in {
color: initial;
}
.mbsc-datepicker .vacation-check-in.mbsc-calendar-cell.mbsc-calendar-day-empty,
.mbsc-datepicker .vacation-check-out.mbsc-calendar-cell.mbsc-calendar-day-empty {
background: transparent;
}
.md-book-rental-header {
display: flex;
align-items: center;
justify-content: end;
margin-left: auto;
flex: 1 1;
overflow: hidden;
}
.md-book-rental-zone {
font-size: 12px;
padding: 3px 6px;
margin: 0 5px;
border-radius: 16px;
color: #1e1e1ecc;
}
.md-book-rental .mbsc-calendar-label-text {
text-align: center;
font-weight: bold;
}
.md-book-rental-in {
background: #f7f7bb80;
}
.md-book-rental-pre {
background: #a3cdff80;
}
.md-book-rental-off {
background: #b2f1c080;
}
.md-book-rental-booked {
background: #ffbaba80;
}
</style>