Overview

  • How to add next/previous buttons that will change the current view of the Angular Scheduler component
  • Event loading based on view change detection event that is fired after every Scheduler update
  • Includes a trial version of DayPilot Pro for JavaScript (see also 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.

How to Configure the Scheduler to Display the Current Month

angular-scheduler-next-previous-current-month.png

The visible date range of the Angular Scheduler component can be set using startDate and days properties of the config object. The following configuration will display the current month:

import {Component} from '@angular/core';
import {DayPilot, DayPilotSchedulerComponent} from 'daypilot-pro-angular';
import SchedulerPropsAndEvents = DayPilot.SchedulerPropsAndEvents;

@Component({
  selector: 'scheduler-component',
  template: `<daypilot-scheduler [config]="config"></daypilot-scheduler>`,
  styles: [`/* ... */`]
})
export class SchedulerComponent {

  config: SchedulerPropsAndEvents = {
    days: DayPilot.Date.today().daysInMonth(),
    startDate: DayPilot.Date.today().firstDayOfMonth(),
    
    // ...

    timeHeaders: [{"groupBy":"Month"},{"groupBy":"Day","format":"d"}],
    scale: "Day",
  };

}

How to Change the Month using Next, Previous and Today Buttons

angular-scheduler-next-previous-today-buttons.png

If you want to change the current range using Next/Today/Previous buttons you need to add a (click) handler that changes the startDate value. In case of a month view, it is also necessary to update the days value because the number of days depends on the selected month:

HTML template:

<button (click)="previous()">Previous</button>
<button (click)="today()">Today</button>
<button (click)="next()">Next</button>

TypeScript:

previous(): void {
  this.config.startDate = new DayPilot.Date(this.config.startDate).addMonths(-1);
  this.config.days = this.config.startDate.daysInMonth();
}

today(): void {
  this.config.startDate = DayPilot.Date.today().firstDayOfMonth();
  this.config.days = this.config.startDate.daysInMonth();
}

next(): void {
  this.config.startDate = new DayPilot.Date(this.config.startDate).addMonths(1);
  this.config.days = this.config.startDate.daysInMonth();
}

Loading Scheduler Events for the New Month

angular-scheduler-next-previous-loading-events.png

The Scheduler component detects the changes in the config object automatically and updates the view. When changing the visible month, it's necessary to load the events for the new date range. 

It's possible to add the event-loading code to the next(), previous() and today() methods but we will use (viewChange) event that is fired whenever the Scheduler component detects a config change and updates itself. This will ensure that Scheduler always loads the correct data set.

HTML template:

<daypilot-scheduler [config]="config" [events]="events" (viewChange)="schedulerViewChanged($event)"></daypilot-scheduler>

TypeScript

export class SchedulerComponent implements AfterViewInit {

  events: any[] = [];

  // ...

  schedulerViewChanged(args) {
    if (args.visibleRangeChanged) {
      const from = this.scheduler.control.visibleStart();
      const to = this.scheduler.control.visibleEnd();
      this.ds.getEvents(from, to).subscribe(result => {
        this.events = result;
      });
    }
  }

}

You can see that we detect that the view change included a date range change by checking args.visibleRangeChanged property.

Full Source Code

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

@Component({
  selector: 'scheduler-component',
  template: `
  
    <div class="toolbar">
        <button (click)="previous()">Previous</button>
        <button (click)="today()">Today</button>
        <button (click)="next()">Next</button>
    </div>
      <daypilot-scheduler [config]="config" [events]="events" (viewChange)="schedulerViewChanged($event)" #scheduler></daypilot-scheduler>
  
  `,
  styles: [`/* ... */`]
})
export class SchedulerComponent implements AfterViewInit {

  @ViewChild('scheduler', {static: false})
  scheduler: DayPilotSchedulerComponent;

  events: any[] = [];

  config: SchedulerPropsAndEvents = {
    timeHeaders: [{"groupBy":"Month"},{"groupBy":"Day","format":"d"}],
    scale: "Day",
    days: DayPilot.Date.today().daysInMonth(),
    startDate: DayPilot.Date.today().firstDayOfMonth(),
    timeRangeSelectedHandling: "Enabled",
    onTimeRangeSelected: function (args) {
      var dp = this;
      DayPilot.Modal.prompt("Create a new event:", "Event 1").then(function(modal) {
        dp.clearSelection();
        if (!modal.result) { return; }
        dp.events.add(new DayPilot.Event({
          start: args.start,
          end: args.end,
          id: DayPilot.guid(),
          resource: args.resource,
          text: modal.result
        }));
      });
    },
    treeEnabled: true,
  };

  constructor(private ds: DataService) {
  }

  ngAfterViewInit(): void {
    this.ds.getResources().subscribe(result => this.config.resources = result);
  }

  previous(): void {
    this.config.startDate = new DayPilot.Date(this.config.startDate).addMonths(-1);
    this.config.days = this.config.startDate.daysInMonth();
  }

  today(): void {
    this.config.startDate = DayPilot.Date.today().firstDayOfMonth();
    this.config.days = this.config.startDate.daysInMonth();
  }

  next(): void {
    this.config.startDate = new DayPilot.Date(this.config.startDate).addMonths(1);
    this.config.days = this.config.startDate.daysInMonth();
  }

  schedulerViewChanged(args) {
    if (args.visibleRangeChanged) {
      const from = this.scheduler.control.visibleStart();
      const to = this.scheduler.control.visibleEnd();
      this.ds.getEvents(from, to).subscribe(result => {
        this.events = result;
      });
    }
  }

}