Overview
Add checkboxes to the Scheduler row headers using
onBeforeRowHeaderRenderevent handler and active areas.Automatically select or deselect the Scheduler row when the checkbox is clicked.
Support both the default row header and the first custom row-header column.
Includes a trial version of DayPilot Pro for JavaScript (see License below)
License
Licensed for testing and evaluation purposes. Please see the license agreement included in the sample project. You can use the source code of the tutorial if you are a licensed user of DayPilot Pro for JavaScript. Buy a license.
Add a Checkbox to Scheduler Rows

The easiest way to add a checkbox to the JavaScript Scheduler row headers is to use onBeforeRowHeaderRender event handler and active areas (args.row.areas).
The following example adds a checkbox using a plain <input type='checkbox'> HTML snippet:
onBeforeRowHeaderRender: (args) => {
const row = args.row;
if (row.children().length !== 0) {
return;
}
row.areas = [
{
left: 3,
top: "calc(50% - 8px)",
width: 16,
height: 16,
style: "display: flex; align-items: center; justify-content: center;",
html: "<input type='checkbox'>"
}
];
},At this point, it is just a static checkbox that does not perform any action. The active area itself is a 16-pixel square with flex centering, so the native checkbox stays visually centered even though different browsers and operating systems can render checkboxes at slightly different sizes. This keeps the control aligned with the row text and avoids relying on extra CSS classes inside the injected HTML.
Select a Scheduler Row on Checkbox Click

Now we need to bind the row selection logic to the checkbox click.
First, we define an onClick event handler for the active area that toggles the row in the list of selected rows. The row can be selected and deselected using the row selection API (rows.selection.add() and rows.selection.remove() methods). You can check the current status of the row using rows.selection.isSelected().
onClick: () => {
if (dp.rows.selection.isSelected(row)) {
dp.rows.selection.remove(row);
return;
}
dp.rows.selection.add(row);
}We also need to change the active area HTML depending on the selected status:
html: selected ? "<input type='checkbox' checked>" : "<input type='checkbox'>",This is how onBeforeRowHeaderRender event handler looks now:
onBeforeRowHeaderRender: (args) => {
const row = args.row;
const selected = dp.rows.selection.isSelected(row);
if (row.children().length !== 0) {
return;
}
row.areas = [
{
left: 3,
top: "calc(50% - 8px)",
width: 16,
height: 16,
style: "display: flex; align-items: center; justify-content: center;",
html: selected ? "<input type='checkbox' checked>" : "<input type='checkbox'>",
onClick: () => {
if (dp.rows.selection.isSelected(row)) {
dp.rows.selection.remove(row);
return;
}
dp.rows.selection.add(row);
}
}
];
},Support for Row Header Columns

When displaying multiple row header columns in the JavaScript Scheduler, the active area needs to be added to the first column (args.row.columns[0].areas) instead of the row (args.row.areas).
rowHeaderColumns: [
{name: "Name"},
{name: "Id", display: "id"}
],The final sample project keeps this layout enabled, so the checkbox handler uses a column helper that targets the first row-header column when columns are present and falls back to the row itself otherwise:
onBeforeRowHeaderRender: (args) => {
const row = args.row;
const column = row.columns.length > 0 ? row.columns[0] : row;
const selected = dp.rows.selection.isSelected(row);
if (row.children().length !== 0) {
return;
}
column.areas = [
{
left: 3,
top: "calc(50% - 8px)",
width: 16,
height: 16,
style: "display: flex; align-items: center; justify-content: center;",
html: selected ? "<input type='checkbox' checked>" : "<input type='checkbox'>",
onClick: () => {
if (dp.rows.selection.isSelected(row)) {
dp.rows.selection.remove(row);
return;
}
dp.rows.selection.add(row);
}
}
];
},Full Source Code
And here is the full source code of the sample that adds checkboxes to the JavaScript Scheduler row headers:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>JavaScript Scheduler: Using Checkboxes to Select Rows</title>
<style type="text/css">
p, body, td, input, select, button { font-family: -apple-system,system-ui,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif; font-size: 14px; }
body { padding: 0px; margin: 0px; background-color: #ffffff; }
a { color: #1155a3; }
.space { margin: 10px 0px 10px 0px; }
.header { background: #003267; background: linear-gradient(to right, #011329 0%,#00639e 44%,#011329 100%); padding:20px 10px; color: white; box-shadow: 0px 0px 10px 5px rgba(0,0,0,0.75); }
.header a { color: white; }
.header h1 a { text-decoration: none; }
.header h1 { padding: 0px; margin: 0px; }
.main { padding: 10px; margin-top: 10px; }
.generated { color: #999; }
.generated a { color: #999; }
</style>
<!-- DayPilot library -->
<script src="js/daypilot/daypilot-all.min.js"></script>
</head>
<body>
<div class="header">
<h1><a href='https://code.daypilot.org/63820/javascript-scheduler-using-checkboxes-to-select-rows'>JavaScript Scheduler: Using Checkboxes to Select Rows</a></h1>
<div><a href="https://javascript.daypilot.org/">DayPilot for JavaScript</a> - HTML5 Calendar/Scheduling Components for JavaScript/Angular/React/Vue</div>
</div>
<div class="main">
<div id="dp"></div>
<div class="generated">Generated using <a href="https://builder.daypilot.org/">DayPilot UI Builder</a>.</div>
</div>
<script>
const dp = new DayPilot.Scheduler("dp", {
timeRangeSelectedHandling: "Enabled",
onTimeRangeSelected: async (args) => {
const scheduler = args.control;
const modal = await DayPilot.Modal.prompt("Create a new event:", "Event 1");
scheduler.clearSelection();
if (modal.canceled) { return; }
scheduler.events.add({
start: args.start,
end: args.end,
id: DayPilot.guid(),
resource: args.resource,
text: modal.result
});
},
rowHeaderColumns: [
{name: "Name"},
{name: "Id", display: "id"}
],
onBeforeRowHeaderRender: (args) => {
const row = args.row;
const column = row.columns.length > 0 ? row.columns[0] : row;
const selected = dp.rows.selection.isSelected(row);
if (row.children().length !== 0) {
return;
}
column.areas = [
{
left: 3,
top: "calc(50% - 8px)",
width: 16,
height: 16,
style: "display: flex; align-items: center; justify-content: center;",
html: selected ? "<input type='checkbox' checked>" : "<input type='checkbox'>",
onClick: () => {
if (dp.rows.selection.isSelected(row)) {
dp.rows.selection.remove(row);
return;
}
dp.rows.selection.add(row);
}
}
];
},
startDate: DayPilot.Date.today().firstDayOfMonth(),
days: DayPilot.Date.today().daysInMonth(),
treeEnabled: true,
timeHeaders: [{"groupBy":"Month"},{"groupBy":"Day","format":"d"}],
scale: "Day",
});
dp.init();
const app = {
init() {
const resources = [
{name: "Resource 1", id: "R1"},
{name: "Resource 2", id: "R2"},
{name: "Resource 3", id: "R3"},
{name: "Resource 4", id: "R4"},
{name: "Resource 5", id: "R5"},
{name: "Resource 6", id: "R6"},
{name: "Resource 7", id: "R7"},
{name: "Resource 8", id: "R8"},
{name: "Resource 9", id: "R9"},
];
const events = [];
dp.update({resources, events});
}
};
app.init();
</script>
</body>
</html>History
April 21, 2026: Updated the sample to DayPilot Pro for JavaScript 2026.2 and improved the checkbox alignment.
DayPilot




