JavaScript/jQuery Scheduler - Getting Started
jQuery
Angular
Vue
React
The Scheduler component emulates the user interface of Calendar applications on Windows or Mac OS.
This tutorial shows you the basics of Scheduler configuration. The preview below shows the expected result:
This article breaks the setup procedure into a series of configuration steps. We recommend that you follow the sequence, although you can skip some steps and revisit them later. You can also download the complete code from the following GitHub repository: getting-started-with-scheduler.
Create a Scheduler
jQuery
Add DevExtreme to your jQuery application and use the following code to create a Scheduler:
$(function() { $("#scheduler").dxScheduler({ // Configuration goes here }); });
<html> <head> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/21.2.15/css/dx.light.css" /> <link rel="stylesheet" href="index.css"> <script src="https://cdn3.devexpress.com/jslib/21.2.15/js/dx.all.js"></script> <script src="index.js"></script> </head> <body class="dx-viewport"> <div id="scheduler"></div> </body> </html>
#scheduler { height: 600px; }
Angular
Add DevExtreme to your Angular application and use the following code to create a Scheduler:
<dx-scheduler id="scheduler"> <!-- Configuration goes here --> </dx-scheduler>
import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { }
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { DxSchedulerModule } from 'devextreme-angular'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, DxSchedulerModule ], providers: [ ], bootstrap: [AppComponent] }) export class AppModule { }
#scheduler { height: 600px; }
Vue
Add DevExtreme to your Vue application and use the following code to create a Scheduler:
<template> <DxScheduler id="scheduler> <!-- Configuration goes here --> </DxScheduler> </template> <script> import 'devextreme/dist/css/dx.light.css'; import { DxScheduler } from 'devextreme-vue/scheduler'; export default { components: { DxScheduler, } } </script> <style> #scheduler { height: 600px; } </style>
React
Add DevExtreme to your React application and use the following code to create a Scheduler:
import 'devextreme/dist/css/dx.light.css'; import './App.css'; import { Scheduler } from 'devextreme-react/scheduler'; function App() { return ( <Scheduler id="scheduler"> {/* Configuration goes here */} </Scheduler> ); } export default App;
#scheduler { height: 600px; }
Bind the Scheduler to Data
The Scheduler can load and update data from these data source types:
Use the dataSource property to specify a data source. In this tutorial, we use a local array.
Once you assign the data source, you need to map field values to appointment attributes. If data objects include fields that match the predefined structure, the Scheduler recognizes them automatically and displays appointments without further configuration. To map other fields, use ...Expr properties. In this tutorial, the startDate and endDate fields are recognized automatically, whereas other field names are specified in the textExpr, allDayExpr, and recurrenceRuleExpr properties.
jQuery
$(function() { $("#scheduler").dxScheduler({ dataSource: appointments, textExpr: "title", allDayExpr: "dayLong", recurrenceRuleExpr: "recurrence" }); });
const appointments = [ { title: "Install New Database", startDate: new Date("2021-05-23T08:45:00.000Z"), endDate: new Date("2021-05-23T09:45:00.000Z") }, { title: "Create New Online Marketing Strategy", startDate: new Date("2021-05-24T09:00:00.000Z"), endDate: new Date("2021-05-24T11:00:00.000Z") }, { title: "Upgrade Personal Computers", startDate: new Date("2021-05-25T10:15:00.000Z"), endDate: new Date("2021-05-25T13:30:00.000Z") }, { title: "Customer Workshop", startDate: new Date("2021-05-26T08:00:00.000Z"), endDate: new Date("2021-05-26T10:00:00.000Z"), dayLong: true, recurrence: "FREQ=WEEKLY;BYDAY=TU,FR;COUNT=10" }, { title: "Prepare Development Plan", startDate: new Date("2021-05-27T08:00:00.000Z"), endDate: new Date("2021-05-27T10:30:00.000Z") }, { title: "Testing", startDate: new Date("2021-05-23T09:00:00.000Z"), endDate: new Date("2021-05-23T10:00:00.000Z"), recurrence: "FREQ=WEEKLY;INTERVAL=2;COUNT=2" }, { title: "Meeting of Instructors", startDate: new Date("2021-05-24T10:00:00.000Z"), endDate: new Date("2021-05-24T11:15:00.000Z"), recurrence: "FREQ=DAILY;BYDAY=WE;UNTIL=20211001" }, { title: "Recruiting students", startDate: new Date("2021-05-25T08:00:00.000Z"), endDate: new Date("2021-05-25T09:00:00.000Z"), recurrence: "FREQ=YEARLY", }, { title: "Monthly Planning", startDate: new Date("2021-05-26T09:30:00.000Z"), endDate: new Date("2021-05-26T10:45:00.000Z"), recurrence: "FREQ=MONTHLY;BYMONTHDAY=28;COUNT=1" }, { title: "Open Day", startDate: new Date("2021-05-27T09:30:00.000Z"), endDate: new Date("2021-05-27T19:00:00.000Z"), } ];
<html> <head> <!-- ... --> <script src="data.js"></script> </head> <!-- ... --> </html>
Angular
<dx-scheduler [dataSource]="appointments" textExpr="title" allDayExpr="dayLong" recurrenceRuleExpr="recurrence"> </dx-scheduler>
import { Component } from '@angular/core'; import { Appointment, AppService } from './app.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], providers: [AppService] }) export class AppComponent { appointments: Appointment[]; constructor(service: AppService) { this.appointments = service.getAppointments(); } }
import { Injectable } from '@angular/core'; export class Appointment { title: string; startDate: Date; endDate: Date; dayLong?: boolean; recurrence?: string; } const appointments: Appointment[] = [ { title: "Install New Database", startDate: new Date("2021-05-23T08:45:00.000Z"), endDate: new Date("2021-05-23T09:45:00.000Z") }, { title: "Create New Online Marketing Strategy", startDate: new Date("2021-05-24T09:00:00.000Z"), endDate: new Date("2021-05-24T11:00:00.000Z") }, { title: "Upgrade Personal Computers", startDate: new Date("2021-05-25T10:15:00.000Z"), endDate: new Date("2021-05-25T13:30:00.000Z") }, { title: "Customer Workshop", startDate: new Date("2021-05-26T08:00:00.000Z"), endDate: new Date("2021-05-26T10:00:00.000Z"), dayLong: true, recurrence: "FREQ=WEEKLY;BYDAY=TU,FR;COUNT=10" }, { title: "Prepare Development Plan", startDate: new Date("2021-05-27T08:00:00.000Z"), endDate: new Date("2021-05-27T10:30:00.000Z") }, { title: "Testing", startDate: new Date("2021-05-23T09:00:00.000Z"), endDate: new Date("2021-05-23T10:00:00.000Z"), recurrence: "FREQ=WEEKLY;INTERVAL=2;COUNT=2" }, { title: "Meeting of Instructors", startDate: new Date("2021-05-24T10:00:00.000Z"), endDate: new Date("2021-05-24T11:15:00.000Z"), recurrence: "FREQ=DAILY;BYDAY=WE;UNTIL=20211001" }, { title: "Recruiting students", startDate: new Date("2021-05-25T08:00:00.000Z"), endDate: new Date("2021-05-25T09:00:00.000Z"), recurrence: "FREQ=YEARLY", }, { title: "Monthly Planning", startDate: new Date("2021-05-26T09:30:00.000Z"), endDate: new Date("2021-05-26T10:45:00.000Z"), recurrence: "FREQ=MONTHLY;BYMONTHDAY=28;COUNT=1" }, { title: "Open Day", startDate: new Date("2021-05-27T09:30:00.000Z"), endDate: new Date("2021-05-27T19:00:00.000Z"), } ]; @Injectable({ providedIn: 'root' }) export class AppService { getAppointments(): Appointment[] { return appointments; } }
Vue
<template> <DxScheduler :data-source="appointments" text-expr="title" all-day-expr="dayLong" recurrence-rule-expr="recurrence"> </DxScheduler> </template> <script> // ... import { appointments } from './data.js'; export default { // ... data() { return { appointments: appointments }; } } </script>
export const appointments = [ { title: "Install New Database", startDate: new Date("2021-05-23T08:45:00.000Z"), endDate: new Date("2021-05-23T09:45:00.000Z") }, { title: "Create New Online Marketing Strategy", startDate: new Date("2021-05-24T09:00:00.000Z"), endDate: new Date("2021-05-24T11:00:00.000Z") }, { title: "Upgrade Personal Computers", startDate: new Date("2021-05-25T10:15:00.000Z"), endDate: new Date("2021-05-25T13:30:00.000Z") }, { title: "Customer Workshop", startDate: new Date("2021-05-26T08:00:00.000Z"), endDate: new Date("2021-05-26T10:00:00.000Z"), dayLong: true, recurrence: "FREQ=WEEKLY;BYDAY=TU,FR;COUNT=10" }, { title: "Prepare Development Plan", startDate: new Date("2021-05-27T08:00:00.000Z"), endDate: new Date("2021-05-27T10:30:00.000Z") }, { title: "Testing", startDate: new Date("2021-05-23T09:00:00.000Z"), endDate: new Date("2021-05-23T10:00:00.000Z"), recurrence: "FREQ=WEEKLY;INTERVAL=2;COUNT=2" }, { title: "Meeting of Instructors", startDate: new Date("2021-05-24T10:00:00.000Z"), endDate: new Date("2021-05-24T11:15:00.000Z"), recurrence: "FREQ=DAILY;BYDAY=WE;UNTIL=20211001" }, { title: "Recruiting students", startDate: new Date("2021-05-25T08:00:00.000Z"), endDate: new Date("2021-05-25T09:00:00.000Z"), recurrence: "FREQ=YEARLY", }, { title: "Monthly Planning", startDate: new Date("2021-05-26T09:30:00.000Z"), endDate: new Date("2021-05-26T10:45:00.000Z"), recurrence: "FREQ=MONTHLY;BYMONTHDAY=28;COUNT=1" }, { title: "Open Day", startDate: new Date("2021-05-27T09:30:00.000Z"), endDate: new Date("2021-05-27T19:00:00.000Z"), } ];
React
// ... import { appointments } from './data.js'; function App() { return ( <Scheduler dataSource={appointments} textExpr="title" allDayExpr="dayLong" recurrenceRuleExpr="recurrence"> </Scheduler> ); } export default App;
export const appointments = [ { title: "Install New Database", startDate: new Date("2021-05-23T08:45:00.000Z"), endDate: new Date("2021-05-23T09:45:00.000Z") }, { title: "Create New Online Marketing Strategy", startDate: new Date("2021-05-24T09:00:00.000Z"), endDate: new Date("2021-05-24T11:00:00.000Z") }, { title: "Upgrade Personal Computers", startDate: new Date("2021-05-25T10:15:00.000Z"), endDate: new Date("2021-05-25T13:30:00.000Z") }, { title: "Customer Workshop", startDate: new Date("2021-05-26T08:00:00.000Z"), endDate: new Date("2021-05-26T10:00:00.000Z"), dayLong: true, recurrence: "FREQ=WEEKLY;BYDAY=TU,FR;COUNT=10" }, { title: "Prepare Development Plan", startDate: new Date("2021-05-27T08:00:00.000Z"), endDate: new Date("2021-05-27T10:30:00.000Z") }, { title: "Testing", startDate: new Date("2021-05-23T09:00:00.000Z"), endDate: new Date("2021-05-23T10:00:00.000Z"), recurrence: "FREQ=WEEKLY;INTERVAL=2;COUNT=2" }, { title: "Meeting of Instructors", startDate: new Date("2021-05-24T10:00:00.000Z"), endDate: new Date("2021-05-24T11:15:00.000Z"), recurrence: "FREQ=DAILY;BYDAY=WE;UNTIL=20211001" }, { title: "Recruiting students", startDate: new Date("2021-05-25T08:00:00.000Z"), endDate: new Date("2021-05-25T09:00:00.000Z"), recurrence: "FREQ=YEARLY", }, { title: "Monthly Planning", startDate: new Date("2021-05-26T09:30:00.000Z"), endDate: new Date("2021-05-26T10:45:00.000Z"), recurrence: "FREQ=MONTHLY;BYMONTHDAY=28;COUNT=1" }, { title: "Open Day", startDate: new Date("2021-05-27T09:30:00.000Z"), endDate: new Date("2021-05-27T19:00:00.000Z"), } ];
Run the code and ensure that the Scheduler properly displays all appointments.
Set the Current Date
To specify the current date, use the currentDate property:
jQuery
$(function() { $("#scheduler").dxScheduler({ //... currentDate: new Date(2021, 4, 25), }); });
Angular
<dx-scheduler ... [(currentDate)]="currentDate"> </dx-scheduler>
import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { currentDate: Date = new Date(2021, 4, 25); }
Vue
<template> <DxScheduler ... :current-date.sync="currentDate"> </DxScheduler> </template> <script> // ... export default { // ... data() { return { currentDate: new Date(2021, 4, 25), }; } } </script>
React
// ... import { useCallback, useState } from 'react'; function App() { const [currentDate, setCurrentDate] = useState(new Date(2021, 4, 25)); const handlePropertyChange = useCallback((e) => { if(e.name === 'currentDate') { setCurrentDate(e.value); } }, []) return ( <Scheduler ... currentDate={currentDate} onOptionChanged={handlePropertyChange}> </Scheduler> ); } export default App;
Configure Views
The Scheduler supports the following view types:
Use the views[] array to configure views. This array can contain strings (view types) and objects (view configurations). Use a string if the default view configuration suits you. Otherwise, declare an object that configures the view and specify the type and other properties within it. In the code below, the views[] array contains the Day, Week, and Month views. We specify the startDayHour and endDayHour properties for Day and Week; Month uses its default configuration.
To specify the view displayed initially, set the currentView property. In the following code, the initial view is Week.
jQuery
$(function() { $("#scheduler").dxScheduler({ // ... views: [{ type: "day", startDayHour: 10, endDayHour: 22 }, { type: "week", startDayHour: 10, endDayHour: 22 }, "month" ], currentView: "week" }); });
Angular
<dx-scheduler ... currentView="week"> <dxi-view type="day" [startDayHour]="10" [endDayHour]="22"> </dxi-view> <dxi-view type="week" [startDayHour]="10" [endDayHour]="22"> </dxi-view> <dxi-view type="month"></dxi-view> </dx-scheduler>
Vue
<template> <DxScheduler ... current-view="week"> <DxView type="day" :start-day-hour="10" :end-day-hour="22" /> <DxView type="week" :start-day-hour="10" :end-day-hour="22" /> <DxView type="month" /> </DxScheduler> </template> <script> // ... import { DxScheduler, DxView } from 'devextreme-vue/scheduler'; export default { components: { DxScheduler, DxView }, // ... } </script>
React
// ... import { Scheduler, View } from 'devextreme-react/scheduler'; function App() { return ( <Scheduler ... defaultCurrentView="week"> <View type="day" startDayHour={10} endDayHour={22} /> <View type="week" startDayHour={10} endDayHour={22} /> <View type="month" /> </Scheduler> ); } export default App;
Edit Appointments
Users can manage appointments in the following ways:
Add new appointments
Update appointments in an edit form
Resize an appointment to change its duration
Drag and drop an appointment to reschedule it
Remove appointments
Edit operations are enabled (the default setting). To disable an individual operation, set the corresponding property in the editing object to false. In this tutorial, we use the allowDragging property to disable appointment drag-and-drop.
jQuery
$(function() { $("#scheduler").dxScheduler({ // ... editing: { allowDragging: false }, }); });
Angular
<dx-scheduler ... > <dxo-editing [allowDragging]="false"> </dxo-editing> </dx-scheduler>
Vue
<template> <DxScheduler ... > <DxEditing :allow-dragging="false" /> </DxScheduler> </template> <script> // ... import { DxScheduler, // ... DxEditing } from 'devextreme-vue/scheduler'; export default { components: { DxScheduler, // ... DxEditing }, // ... } </script>
React
// ... import { Scheduler, // ... Editing } from 'devextreme-react/scheduler'; function App() { return ( <Scheduler ... > <Editing allowDragging={false} /> </Scheduler> ); } export default App;
Time Zone Support
The Scheduler displays all appointments in the client time zone. To change this default behavior, specify a different time zone in the timeZone property. It accepts values from the IANA database. This tutorial sets the time zone to "Europe/Berlin".
Users can edit the time zones of individual appointments. To enable this functionality, set the editing.allowTimeZoneEditing property to true.
jQuery
$(function() { $("#scheduler").dxScheduler({ // ... editing: { // ... allowTimeZoneEditing: true }, timeZone: "Europe/Berlin" }); });
Angular
<dx-scheduler ... timeZone="Europe/Berlin"> <!-- ... --> <dxo-editing ... [allowTimeZoneEditing]="true"> </dxo-editing> </dx-scheduler>
Vue
<template> <DxScheduler ... time-zone="Europe/Berlin"> <!-- ... --> <DxEditing ... :allow-editing-time-zones="true" /> </DxScheduler> </template> <script> // ... </script>
React
// ... function App() { return ( <Scheduler ... timeZone="Europe/Berlin"> {/* ... */} <Editing ... allowTimeZoneEditing={true} /> </Scheduler> ); } export default App;
Enable Adaptive Mode
The Scheduler can adapt its interface to small screens. To enable this behavior, set the adaptivityEnabled property to true. See the following demo description for a full list of adaptability features: Adaptability.
jQuery
$(function() { $("#scheduler").dxScheduler({ // ... adaptivityEnabled: true }); });
Angular
<dx-scheduler ... [adaptivityEnabled]="true"> </dx-scheduler>
Vue
<template> <DxScheduler ... :adaptivity-enabled="true"> </DxScheduler> </template> <script> // ... </script>
React
// ... function App() { return ( <Scheduler ... adaptivityEnabled={true}> </Scheduler> ); } export default App;
For further information on the Scheduler component, refer to the following resources: