
Behavior:
You can apply the row filter by calling the rows.filter() with the filter parameter object as an argument.
The row visibility will be determined using the onRowFilter event handler (the
paramvalue from therows.filter(param)method call will be available asargs.filterParam).Resource hierarchy is supported. Use the rowFilterParentsAlwaysVisible property to specify whether the parent rows should always be visible.
JavaScript
The JavaScript Scheduler supports client-side row filtering since build 7.9.1246.
Example: Filtering based on row name
<div class="space">
Filter: <input id="filter" />
<a href="#" id="clear">Clear</a>
</div>
<div id="scheduler"></div>
<script>
const scheduler = new DayPilot.Scheduler("scheduler", {
onRowFilter: (args) => {
const filter = args.filterParam;
if (args.row.name.toUpperCase().indexOf(filter.toUpperCase()) === -1) {
args.visible = false;
}
},
// ...
});
scheduler.init();
const app = {
elements: {
filter: document.querySelector("#filter"),
clear: document.querySelector("#clear")
},
filter() {
const query = app.elements.filter.value.trim();
scheduler.rows.filter(query);
},
init() {
app.elements.filter.addEventListener("keyup", () => app.filter());
app.elements.clear.addEventListener("click", (e) => {
e.preventDefault();
app.elements.filter.value = "";
scheduler.rows.filter();
});
}
};
app.init();
</script>Example: Show all children of matching parents
Note that the hiddenUsingFilter property is supported since version 2019.3.3985.
onRowFilter: (args) => {
if (args.row.name.toUpperCase().indexOf(args.filter.toUpperCase()) === -1) {
args.visible = false;
}
const parent = args.row.parent();
if (parent && !parent.hiddenUsingFilter) {
args.visible = true;
}
}Example: Filtering based on custom data (tags)
Custom row tags are supported since build 8.0.1545.
Specifying custom row data (tags):
const resources = [
{ name: "Room A", id: "A"},
// ...
{ name: "Room J", id: "J" },
{ name: "Room K", id: "K", tags: {alwaysVisible: true} }
];
scheduler.update({resources});Using tags during filtering:
onRowFilter: (args) => {
if (args.row.name.toUpperCase().indexOf(args.filter.toUpperCase()) === -1) {
args.visible = args.row.tags && args.row.tags.alwaysVisible;
}
};Example: Complex filter (by name, hide empty rows checkbox)

This example combines two filter parameters (search string and "hide empty rows" checkbox):
<div class="space">
Filter: <input id="filter" /> <a href="#" id="clear">Clear</a>
<input type="checkbox" id="hideEmpty"> Hide empty
</div>
<div id="scheduler"></div>
<script>
const scheduler = new DayPilot.Scheduler("scheduler", {
onRowFilter: (args) => {
const query = args.filterParam.query;
const hideEmpty = args.filterParam.hideEmpty;
if (args.row.name.toUpperCase().indexOf(query.toUpperCase()) === -1) {
args.visible = false;
}
else if (hideEmpty && args.row.events.isEmpty()){
args.visible = false;
}
},
// ...
});
scheduler.init();
const app = {
elements: {
filter: document.querySelector("#filter"),
hideEmpty: document.querySelector("#hideEmpty"),
clear: document.querySelector("#clear")
},
filter() {
scheduler.rows.filter({
query: app.elements.filter.value,
hideEmpty: app.elements.hideEmpty.checked
});
},
init() {
app.elements.filter.addEventListener("keyup", () => app.filter());
app.elements.hideEmpty.addEventListener("change", () => app.filter());
app.elements.clear.addEventListener("click", (e) => {
e.preventDefault();
app.elements.filter.value = "";
app.filter();
});
}
};
app.init();
</script>Demo
Tutorials
API: onRowFilter.
The buttons show matching rooms or clear the filter without replacing the resource collection. onRowFilter compares each name with the supplied filter text.
The framework examples use DayPilot Pro. For installation, see the Angular, React or Vue Scheduler guide.
Angular
Define onRowFilter in config and call rows.filter() through the @ViewChild control from the button methods.
import {Component, ViewChild} from "@angular/core";
import {DayPilot, DayPilotModule, DayPilotSchedulerComponent} from "daypilot-pro-angular";
@Component({
selector: "app-scheduler-example",
standalone: true,
imports: [DayPilotModule],
template: `
<button (click)="action0()">Show Room A</button>
<button (click)="action1()">Clear filter</button>
<daypilot-scheduler [config]="config" #scheduler></daypilot-scheduler>
`
})
export class SchedulerExampleComponent {
@ViewChild("scheduler") scheduler!: DayPilotSchedulerComponent;
config: DayPilot.SchedulerConfig = {
startDate: "2026-11-01",
days: 30,
scale: "Day",
timeHeaders: [{groupBy: "Month"}, {groupBy: "Day", format: "d"}],
resources: [{id: "A", name: "Room A"}, {id: "B", name: "Room B"}],
events: [{id: 1, text: "Planning", resource: "A", start: "2026-11-03", end: "2026-11-06"}, {id: 2, text: "Delivery", resource: "B", start: "2026-11-08", end: "2026-11-11"}],
onRowFilter: args => { args.visible = args.row.name.toLowerCase().includes(args.filterParam.toLowerCase()); }
};
async action0() {
const dp = this.scheduler.control;
dp.rows.filter("room a");
}
async action1() {
const dp = this.scheduler.control;
dp.rows.filter(null);
}
}
Angular Scheduler: Row Filtering
Angular Restaurant Table Reservation (PHP/MySQL)
React
Pass the predicate as
onRowFilter; the buttons use the Scheduler control retained bycontrolRef.import React, {useRef} from "react"; import {DayPilot, DayPilotScheduler} from "daypilot-pro-react"; export default function SchedulerExample() { const scheduler = useRef(null); async function action0() { const dp = scheduler.current; dp.rows.filter("room a"); } async function action1() { const dp = scheduler.current; dp.rows.filter(null); } return <div> <button onClick={action0}>Show Room A</button> <button onClick={action1}>Clear filter</button> <DayPilotScheduler controlRef={control => { scheduler.current = control; }} startDate={"2026-11-01"} days={30} scale={"Day"} timeHeaders={[{groupBy: "Month"}, {groupBy: "Day", format: "d"}]} resources={[{id: "A", name: "Room A"}, {id: "B", name: "Room B"}]} events={[{id: 1, text: "Planning", resource: "A", start: "2026-11-03", end: "2026-11-06"}, {id: 2, text: "Delivery", resource: "B", start: "2026-11-08", end: "2026-11-11"}]} onRowFilter={args => { args.visible = args.row.name.toLowerCase().includes(args.filterParam.toLowerCase()); }} /> </div>; }Vue
Bind
:onRowFilterto the predicate and use the Scheduler template ref in the two@clickfunctions.<script setup> import {ref} from "vue"; import {DayPilot, DayPilotScheduler} from "daypilot-pro-vue"; const scheduler = ref(null); const startDate = "2026-11-01"; const days = 30; const scale = "Day"; const timeHeaders = [{groupBy: "Month"}, {groupBy: "Day", format: "d"}]; const resources = [{id: "A", name: "Room A"}, {id: "B", name: "Room B"}]; const events = [{id: 1, text: "Planning", resource: "A", start: "2026-11-03", end: "2026-11-06"}, {id: 2, text: "Delivery", resource: "B", start: "2026-11-08", end: "2026-11-11"}]; const onRowFilter = args => { args.visible = args.row.name.toLowerCase().includes(args.filterParam.toLowerCase()); }; async function action0() { const dp = scheduler.value.control; dp.rows.filter("room a"); } async function action1() { const dp = scheduler.value.control; dp.rows.filter(null); } </script> <template> <div> <button @click="action0">Show Room A</button> <button @click="action1">Clear filter</button> <DayPilotScheduler ref="scheduler" :startDate="startDate" :days="days" :scale="scale" :timeHeaders="timeHeaders" :resources="resources" :events="events" :onRowFilter="onRowFilter" /> </div> </template>Availability
Availability of this feature in DayPilot editions:
Product Lite Pro DayPilot for JavaScript DayPilot for ASP.NET WebForms DayPilot for ASP.NET MVC DayPilot for Java
DayPilot