Features
Zoom using HTML5 slider control
Zoom using buttons: [+] and [-]
Custom zoom levels with defined properties (scale, visible days, time headers...)
Includes the open-source DayPilot Lite for JavaScript calendar/scheduling library (Apache License 2.0).
Scheduler Zoom Levels

The first steps is to define the zoom levels for the JavaScript Scheduler component that we want to make available in our application. The users will be able to change the Scheduler zoom level using an HTML5 slider control and (+)/(-) buttons that we add later.
The zoomLevels property holds an array of objects that specify the zoom level properties. You can include any Scheduler property, but in this case we will use:
name (custom zoom level name displayed to the user)
scale (Scheduler scale unit)
cellWidth (cell width in pixels)
cellDuration (cell duration which is used for custom scale)
timeHeaders (time header rows)
startDate (calculated start date)
days (calculated number of visible days)
Each object can also have arbitrary properties at the top level (like name in this case). There properties will be ignored by the Scheduler.
The properties items value can be either the target value (string, number, etc.) or a function. Using a function lets you calculate the return value using the Scheduler state (args.date holds the reference date, args.level holds the target level index);
zoomLevels: [
{
name: "Year",
properties: {
scale: "Day",
cellWidth: 40,
timeHeaders: [{groupBy: "Year"}, {groupBy: "Month", format: "MMMM"}, {groupBy: "Day", format: "d"}],
startDate: args => args.date.firstDayOfYear(),
days: args => args.date.daysInYear(),
}
},
{
name: "Month",
properties: {
scale: "CellDuration",
cellDuration: 720,
cellWidth: 40,
timeHeaders: [{groupBy: "Month"}, {groupBy: "Day", format: "ddd d"}, {groupBy: "Cell", format: "tt"}],
startDate: args => args.date.firstDayOfMonth(),
days: args => args.date.daysInMonth(),
}
},
{
name: "Week",
properties: {
scale: "Hour",
cellWidth: 40,
timeHeaders: [{groupBy: "Month"}, {groupBy: "Day", format: "dddd d"}, {groupBy: "Hour"}],
startDate: args => args.date.firstDayOfWeek(),
days: args => 7,
}
},
{
name: "Hour",
properties: {
scale: "CellDuration",
cellDuration: 15,
cellWidth: 40,
timeHeaders: [{groupBy: "Day", format: "dddd MMMM d, yyyy"}, {groupBy: "Hour"}, {groupBy: "Cell"}],
startDate: args => args.date.getDatePart(),
days: args => 1,
}
},
]Applying Zoom Level
The applyZoomLevel() function calls the update() method with the zoom property specifiedto apply the selected zoom level (specified using index parameter) to the JavaScript Scheduler component.
When the Scheduler is updated to display the new zoom level it scrolls to the reference date/time. The reference date is calculated using zoomPosition property before the zoom level is changed. We are using "middle" which means the date which was at the middle point of the Scheduler viewport will remain in the middle after the zoom level change.
Instead of update(), you can also use the zoom.setActive() method to change the zoom level. This method lets you override the default reference date position.
The applyZoomLevel() function also displays the current zoom level name using a <span> label element.
// Scheduler config
{
zoomPosition: "middle",
zoomLevels: [ ... ],
// ...
}
function applyZoomLevel(index, date) {
scheduler.update({zoom: index});
elements.range.value = index;
elements.label.innerText = "Current zoom level: " + scheduler.zoom.levels[index].name;
}Slider Control for Changing Scheduler Zoom Level

HTML5 slider control:
<input type="range" min="0" max="3" step="1" id="zoom-level" />Event handler:
const elements = {
range: document.getElementById("zoom-level"),
// ...
};
elements.range.addEventListener("input", ev => {
const val = parseInt(elements.range.value);
applyZoomLevel(val);
});Zoom Buttons

HTML5:
<div class="controls">
<button id="minus">-</button>
<button id="plus">+</button>
</div>CSS Styling:
.controls button {
width: 25px;
height: 25px;
background-color: #3c78d8;
color: white;
border: 0;
border-radius: 5px;
cursor: pointer;
}
.controls button:focus {
outline: none;
}Event handlers:
const elements = {
plus: document.getElementById("plus"),
minus: document.getElementById("minus"),
// ...
};
elements.plus.addEventListener("click", ev => {
let value = parseInt(elements.range.value);
if (value < scheduler.zoomLevels.length - 1) {
value += 1;
applyZoomLevel(value);
}
});
elements.minus.addEventListener("click", ev=> {
let value = parseInt(elements.range.value);
if (value > 0) {
value -= 1;
applyZoomLevel(value);
}
});
DayPilot