Features

  • This Angular project uses the Angular Scheduler component from DayPilot Pro for JavaScript to display a timeline with tasks/events for multiple resources.

  • A real-time filter feature updates the list of rows depending on the search criteria.

  • You can filter rows by name.

  • You can display only rows with tasks/events.

  • Both filters can be combined.

  • Angular 16 project with source code is attached.

For an introduction to using Angular Scheduler, please see the following tutorial:

See also a similar tutorial on event filtering:

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.

Live Demo

You can test this project in a live demo:

Filtering Scheduler Rows by Name

On startup, our Angular application displays the full Scheduler with all rows visible:

Angular Scheduler Row Filtering All Resources

When you type text into the “Filter” field, the Scheduler updates immediately. Only resources containing the filter text will be displayed.

Angular Scheduler Row Filtering by Text

The row filter implementation consists of three parts:

  1. The application displays a toolbar with the filter UI, which includes an input element for the filter text.

  2. Whenever there's a change in the filter UI, the rows.filter() method is invoked. This method passes the filter parameters to the Scheduler and requests an update.

  3. The onRowFilter event handler, defined in the Scheduler config, evaluates the filter parameters for each row to determine whether a row should be visible or not.

Filter toolbar input UI:

<div class="toolbar">
  Filter: <input type="text" [ngModel]="filter.text" (ngModelChange)="changeText($event)" />
</div>

Filter update logic:

export class SchedulerComponent implements AfterViewInit {

  @ViewChild("scheduler") scheduler!: DayPilotSchedulerComponent;

  filter = {
    text: ""
  };
  
  // ...

  changeText(text: string): void {
    this.filter.text = text;
    this.applyFilter();
  }

  applyFilter(): void {
    this.scheduler.control.rows.filter(this.filter);
  }

}

Row filter event handler:

config: DayPilot.SchedulerConfig = {
  // ...
  onRowFilter: args => {
    if (args.row.name.toLowerCase().indexOf(args.filterParam.text.toLowerCase()) < 0) {
      args.visible = false;
    }
  }
};

By default all rows are visible (args.visible is set to false). The onRowFilter event handler checks the filter condition sent from the rows.filter() method (it's available as args.filterParam in the event handler). If the row doesn't meet the filter condition it's marked as not visible (args.visible = false).

Note that the parent rows will always be displayed (even if marked with args.visible = false).

Here is the full row name filter implementation (scheduler.component.ts):

import {Component, ViewChild, AfterViewInit, ChangeDetectorRef} from "@angular/core";
import {DayPilot, DayPilotSchedulerComponent} from "daypilot-pro-angular";
import {DataService} from "./data.service";

@Component({
  selector: 'scheduler-component',
  template: `
  <div class="space">
    Filter: <input type="text" [ngModel]="filter.text" (ngModelChange)="changeText($event)" />
    ...
  </div>
  <daypilot-scheduler [config]="config" [events]="events" #scheduler></daypilot-scheduler>
`,
  styles: [``]
})
export class SchedulerComponent implements AfterViewInit {

  @ViewChild("scheduler") scheduler!: DayPilotSchedulerComponent;

  events: any[] = [];

  filter = {
    text: ""
  };

  config: DayPilot.SchedulerConfig = {
    // ...
    onRowFilter: args => {
      if (args.row.name.toLowerCase().indexOf(args.filterParam.text.toLowerCase()) < 0) {
        args.visible = false;
      }
    }
  };


  changeText(text: string): void {
    this.filter.text = text;
    this.applyFilter();
  }

  applyFilter(): void {
    this.scheduler.control.rows.filter(this.filter);
  }

}

Filtering Scheduler Rows by Events

Angular Scheduler Row FIltering Resources with Events

The same approach is used for filtering the rows depending on their content. The onRowFilter event handler checks if there are any events in the row using args.row.events.all():

onRowFilter: args => {
  if (args.filterParam.eventsOnly && args.row.events.all().length === 0) {
    args.visible = false;
  }
}

scheduler.component.ts

import {Component, ViewChild, AfterViewInit, ChangeDetectorRef} from "@angular/core";
import {DayPilot, DayPilotSchedulerComponent} from "daypilot-pro-angular";
import {DataService} from "./data.service";

@Component({
  selector: 'scheduler-component',
  template: `
  <div class="space">
    ... 
    <label for="eventsonly"><input type="checkbox" id="eventsonly" [ngModel]="filter.eventsOnly" (ngModelChange)="changeWithEvents($event)"> Only rows with events</label>
    ...
  </div>
  <daypilot-scheduler [config]="config" [events]="events" #scheduler></daypilot-scheduler>
`,
  styles: [``]
})
export class SchedulerComponent implements AfterViewInit {

  @ViewChild("scheduler") scheduler!: DayPilotSchedulerComponent;

  events: any[] = [];

  filter = {
    eventsOnly: false
  };

  config: DayPilot.SchedulerConfig = {
    // ...
    onRowFilter: args => {
      if (args.filterParam.eventsOnly && args.row.events.all().length === 0) {
        args.visible = false;
      }
    }
  };

  changeWithEvents(val: string): void {
    this.filter.eventsOnly = val;
    this.applyFilter();
  }

  applyFilter(): void {
    this.scheduler.control.rows.filter(this.filter);
  }

}

Clearing the Filter

Angular Scheduler Row Filtering Clear

In order to clear the filter, we simply reset the filter object and apply the filter:

export class SchedulerComponent implements AfterViewInit {

  filter = {
    text: "",
    eventsOnly: false
  };
  
  // ...

  applyFilter(): void {
    this.scheduler.control.rows.filter(this.filter);
  }

  clearFilter(): boolean {
    this.filter.text = "";
    this.filter.eventsOnly = false;
    this.applyFilter();
    return false;
  }

}