Appointment Booking

Book single or multiple appointments depending on the use-case or set up recurring date and time selection. Limit the available dates with the min and max options. Make dates un-selectable with the invalid option. Load pricing, available spots on demand and show it as labels that help people book the appointment.

The calendar can be displayed inline with one or more months or linked to an input. Learn how to initialize the calendar.

Looking for flight or hotel booking?  Check out the range picker →
Download and try example

Demo

Single date selection

For enhanced validation set min and max dates. In addition to that disable invalid days by passing them to the invalid option.

If you need to show additional information, use the labels option and pass prices or availability. Invalids and things like pricing can be set on-load or on-demand in the onPageLoading lifecycle event.

html<div id="demo-booking-single"></div>
jsvar min = '2026-10-24T00:00';
var max = '2027-04-24T00:00';

mobiscroll.datepicker('#demo-booking-single', {
    controls: ['calendar'],
    display: 'inline',
    min: min,
    max: max,
    onPageLoading: function (event, inst) {
        getPrices(event.firstDay, function callback(bookings) {
            inst.setOptions({
                labels: bookings.labels,
                invalid: bookings.invalid
            });
        });
    }
});
                                  
function getPrices(d, callback) {
    var invalid = [],
        labels = [];

    mobiscroll.getJson('//trial.mobiscroll.com/getprices/?year=' + d.getFullYear() + '&month=' + d.getMonth(), function (bookings) {
        for (var i = 0; i < bookings.length; ++i) {
            var booking = bookings[i],
                d = new Date(booking.d);

            if (booking.price > 0) {
                labels.push({
                    start: d,
                    title: '$' + booking.price,
                    textColor: '#e1528f'
                });
            } else {
                invalid.push(d);
            }
        }
        callback({ labels: labels, invalid: invalid });
    }, 'jsonp');
}
Booking a date and time

Use a calendar in combination with a time picker or timegrid. Dynamically filter the time grid based on availability and add labels to the dates to inform users of free spots.

html<div id="demo-booking-multiple"></div>
jsmobiscroll.datepicker('#demo-booking-multiple', {
    controls: ['calendar', 'timegrid'],
    display: 'inline',
    min: '2026-10-24T00:00',
    max: '2027-04-24T00:00',
    minTime: '08:00',
    maxTime: '19:59',
    stepMinute: 60,
    // example for today's labels and invalids
    labels: [{
        start: '',
        textColor: '#e1528f',
        title: ''
    }],
    invalid: [{
        start: '2026-10-24T08:00',
        end: '2026-10-24T13:00'
    }, {
        start: '2026-10-24T15:00',
        end: '2026-10-24T17:00'
    }, {
        start: '2026-10-24T19:00',
        end: '2026-10-24T20:00'
    }]
});
Booking multiple appointments

For multiple event booking set the selectMultiple option to 'true'. min, max, invalid are essential for a great UX and labels can be used for showing extra information about available spots.

html<div id="demo-booking-multiple"></div>
jsvar min = '2026-10-24T00:00';
var max = '2027-04-24T00:00';

mobiscroll.datepicker('#demo-booking-multiple', {
    controls: ['calendar'],
    display: 'inline',
    min: min,
    max: max,
    selectMultiple: true,
    onInit: function (event, inst) {
        inst.setVal([
            '2026-10-11T00:00',
            '2026-10-16T00:00',
            '2026-10-17T00:00'
        ], true);
    },
    onPageLoading: function (event, inst) {
        getBookings(event.firstDay, function callback(bookings) {
            inst.setOptions({
                labels: bookings.labels,
                invalid: bookings.invalid
            });
        });
    }
});

function getBookings(d, callback) {
    var invalid = [],
        labels = [];

    mobiscroll.getJson('//trial.mobiscroll.com/getbookings/?year=' + d.getFullYear() + '&month=' + d.getMonth(), function (bookings) {
        for (var i = 0; i < bookings.length; ++i) {
            var booking = bookings[i],
                d = new Date(booking.d);

            if (booking.nr > 0) {
                labels.push({
                    start: d,
                    title: booking.nr + ' SPOTS',
                    textColor: '#e1528f'
                });
            } else {
                invalid.push(d);
            }
        }
        callback({ labels: labels, invalid: invalid });
    }, 'jsonp');
}

Duplicate Session

You have signed in on a different machine. To keep everything in sync, you have been signed out of this session.

If you need to invite team members, manage seats and accounts you can do it from the licenses page.

Duplicate Session

We noticed you are logged in on a different machine and have closed your old session.

If you need to invite team members, manage seats and accounts you can do it from the licenses page.