$(function () {
$("#scheduler").dxScheduler({
timeZone: "America/Los_Angeles",
dataSource: data,
views: ["workWeek", "month"],
currentView: "workWeek",
currentDate: new Date(2021, 4, 25),
firstDayOfWeek: 0,
startDayHour: 9,
endDayHour: 19,
showAllDayPanel: false,
height: 600,
dataCellTemplate: function(itemData, itemIndex, itemElement) {
var date = itemData.startDate;
var isDisabled = isHoliday(date) || isWeekend(date);
var element = $(`<div>${itemData.text}</div>`);
if (isDisabled) {
element.addClass('disable-date');
} else if (isDinner(date)) {
element.addClass('dinner');
}
return itemElement.append(element);
},
dateCellTemplate: function(itemData, itemIndex, itemElement) {
var element = $(`<div>${itemData.text}</div>`);
if (isWeekend(itemData.date)) {
element.addClass('disable-date');
}
return itemElement.append(element);
},
timeCellTemplate: function(itemData, itemIndex, itemElement) {
var element = $(`<div>${itemData.text}</div>`);
var date = itemData.date;
if (isDinner(date)) {
element.addClass('dinner');
}
if (hasCoffeeCupIcon(date)) {
element.append('<div class="cafe" />');
}
return itemElement.append(element);
},
onAppointmentFormOpening: function(e) {
var startDate = new Date(e.appointmentData.startDate);
if(!isValidAppointmentDate(startDate)) {
e.cancel = true;
notifyDisableDate();
}
applyDisableDatesToDateEditors(e.form);
},
onAppointmentAdding: function(e) {
if(!isValidAppointment(e.component, e.appointmentData)) {
e.cancel = true;
notifyDisableDate();
}
},
onAppointmentUpdating: function(e) {
if(!isValidAppointment(e.component, e.newData)) {
e.cancel = true;
notifyDisableDate();
}
}
});
});
var dinnerTime = { from: 12, to: 13 };
var holidays = [
new Date(2021, 4, 27),
new Date(2021, 6, 4)
];
function notifyDisableDate() {
DevExpress.ui.notify("Cannot create or move an appointment/event to disabled time/date regions.", "warning", 1000);
}
function isValidAppointment(component, appointmentData) {
var startDate = new Date(appointmentData.startDate);
var endDate = new Date(appointmentData.endDate);
var cellDuration = component.option('cellDuration');
return isValidAppointmentInterval(startDate, endDate, cellDuration);
}
function isValidAppointmentInterval(startDate, endDate, cellDuration) {
var edgeEndDate = new Date(endDate.getTime() - 1);
if (!isValidAppointmentDate(edgeEndDate)) {
return false;
}
var durationInMs = cellDuration * 60 * 1000;
var date = startDate;
while (date <= endDate) {
if (!isValidAppointmentDate(date)) {
return false;
}
var newDateTime = date.getTime() + durationInMs - 1;
date.setTime(newDateTime);
}
return true;
}
function isValidAppointmentDate(date) {
return !isHoliday(date) && !isDinner(date) && !isWeekend(date);
}
function isHoliday(date) {
var localeDate = date.toLocaleDateString();
return holidays.filter(function(holiday) {
return holiday.toLocaleDateString() === localeDate;
}).length > 0;
}
function isWeekend(date) {
var day = date.getDay();
return day === 0 || day === 6;
}
function isDinner(date) {
var hours = date.getHours();
return hours >= dinnerTime.from && hours < dinnerTime.to;
}
function hasCoffeeCupIcon(date) {
var hours = date.getHours();
var minutes = date.getMinutes();
return hours === dinnerTime.from && minutes === 0;
}
function applyDisableDatesToDateEditors(form) {
var startDateEditor = form.getEditor('startDate');
startDateEditor.option('disabledDates', holidays);
var endDateEditor = form.getEditor('endDate');
endDateEditor.option('disabledDates', holidays);
}
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>DevExtreme Demo</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>window.jQuery || document.write(decodeURIComponent('%3Cscript src="js/jquery.min.js"%3E%3C/script%3E'))</script>
<link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/20.2.4/css/dx.common.css" />
<link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/20.2.4/css/dx.light.css" />
<script src="https://cdn3.devexpress.com/jslib/20.2.4/js/dx.all.js"></script>
<script src="data.js"></script>
<link rel="stylesheet" type="text/css" href="styles.css" />
<script src="index.js"></script>
</head>
<body class="dx-viewport">
<div class="demo-container">
<div id="scheduler"></div>
</div>
</body>
</html>
.disable-date,
.dinner {
height: 100%;
}
.disable-date {
background-image: repeating-linear-gradient(135deg,
rgba(244, 67, 54, 0.1),
rgba(244, 67, 54, 0.1) 4px,
transparent 4px,
transparent 9px);
color: #9B6467;
}
.dx-scheduler-header-panel-cell .disable-date {
display: flex;
flex-direction: column;
justify-content: center;
}
.dinner {
background: rgba(255, 193, 7, 0.2);
}
.dx-scheduler-time-panel-cell .dinner {
color: rgba(255, 193, 7);
font-weight: 400;
background: transparent;
}
.dx-draggable {
cursor: auto;
}
td.dx-scheduler-time-panel-cell .dinner .cafe {
height: 200%;
width: 100%;
left: 50%;
-webkit-mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M20 3H4v10c0 2.21 1.79 4 4 4h6c2.21 0 4-1.79 4-4v-3h2c1.11 0 2-.9 2-2V5c0-1.11-.89-2-2-2zm0 5h-2V5h2v3zM4 19h16v2H4z"/></svg>');
-webkit-mask-repeat: no-repeat;
-webkit-mask-position-y: 50%;
-webkit-mask-position-x: 100%;
margin-top: -4px;
background-color: #ffc107;
}
.dx-scheduler-date-table-cell {
padding: 0;
opacity: 1;
}
var data = [
{
text: "Website Re-Design Plan",
startDate: new Date("2021-05-24T16:30:00.000Z"),
endDate: new Date("2021-05-24T18:30:00.000Z")
},
{
text: "Install New Router in Dev Room",
startDate: new Date("2021-05-24T20:00:00.000Z"),
endDate: new Date("2021-05-24T21:00:00.000Z"),
allDay: false
},
{
text: "Approve Personal Computer Upgrade Plan",
startDate: new Date("2021-05-25T17:00:00.000Z"),
endDate: new Date("2021-05-25T18:00:00.000Z")
},
{
text: "Final Budget Review",
startDate: new Date("2021-05-25T20:30:00.000Z"),
endDate: new Date("2021-05-25T22:00:00.000Z"),
allDay: false
},
{
text: "New Brochures",
startDate: new Date("2021-05-24T22:00:00.000Z"),
endDate: new Date("2021-05-24T23:15:00.000Z"),
allDay: false
},
{
text: "Install New Database",
startDate: new Date("2021-05-26T16:45:00.000Z"),
endDate: new Date("2021-05-26T19:00:00.000Z")
},
{
text: "Approve New Online Marketing Strategy",
startDate: new Date("2021-05-26T21:30:00.000Z"),
endDate: new Date("2021-05-26T23:30:00.000Z"),
allDay: false
},
{
text: "Upgrade Personal Computers",
startDate: new Date("2021-05-25T22:30:00.000Z"),
endDate: new Date("2021-05-25T23:45:00.000Z"),
allDay: false
},
{
text: "Prepare 2021 Marketing Plan",
startDate: new Date("2021-05-31T20:00:00.000Z"),
endDate: new Date("2021-05-31T22:00:00.000Z"),
allDay: false
},
{
text: "Brochure Design Review",
startDate: new Date("2021-06-01T22:30:00.000Z"),
endDate: new Date("2021-06-02T00:00:00.000Z"),
allDay: false
},
{
text: "Create Icons for Website",
startDate: new Date("2021-05-28T17:00:00.000Z"),
endDate: new Date("2021-05-28T19:00:00.000Z")
},
{
text: "Upgrade Server Hardware",
startDate: new Date("2021-05-28T23:30:00.000Z"),
endDate: new Date("2021-05-29T01:00:00.000Z"),
allDay: false
},
{
text: "Submit New Website Design",
startDate: new Date("2021-06-02T17:00:00.000Z"),
endDate: new Date("2021-06-02T18:30:00.000Z"),
allDay: false
},
{
text: "Launch New Website",
startDate: new Date("2021-05-28T21:30:00.000Z"),
endDate: new Date("2021-05-28T23:10:00.000Z"),
allDay: false
}
];