Overview

  • Angular 12 Scheduler component

  • Includes the required boilerplate and it ready to run

  • Uses a local data source for simplicity

  • 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.

New Angular 12 Project

Create a new project using Angular CLI:

ng new angular12-scheduler

The next step is to install the Angular 12 package of DayPilot Pro for JavaScript:

npm install https://npm.daypilot.org/daypilot-pro-angular/trial/2021.2.4990.tar.gz

You can find the link to the latest release at npm.daypilot.org.

Instead of creating the Angular 12 project manually, you can also use the DayPilot UI Builder which lets you configure the Scheduler component using a visual editor and generate a corresponding Angular 12 project.

Angular 12 Scheduler Component

The Angular 12 Scheduler component (scheduler.component.ts) is simple. It creates a new instance of the Angular Scheduler and configures its properties using the config object. The config object can specify any of the Scheduler properties and events.

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

@Component({
  selector: 'scheduler-component',
  template: `<daypilot-scheduler [config]="config" [events]="events" #scheduler></daypilot-scheduler>`,
  styles: [`
    ::ng-deep .scheduler_default_event_bar, ::ng-deep .scheduler_default_event_bar_inner{
      height: 8px;
    }
    ::ng-deep .scheduler_default_event_inner {
      top: 8px;
    }
  `]
})
export class SchedulerComponent implements AfterViewInit {

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

  events: DayPilot.EventData[] = [];

  config: DayPilot.SchedulerConfig = {
    timeHeaders: [{"groupBy":"Month"},{"groupBy":"Day","format":"d"}],
    scale: "Day",
    days: 30,
    eventHeight: 45,
    startDate: "2021-09-01",
    timeRangeSelectedHandling: "Enabled",
    onTimeRangeSelected: async (args) => {
      const dp = args.control;
      const modal = await DayPilot.Modal.prompt("Create a new event:", "Event 1");
      dp.clearSelection();
      if (modal.canceled) { return; }
      dp.events.add({
        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);

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

}

We will include this new Scheduler component in a special module (scheduler.module.ts) which wraps all the scheduler-related logic:

import {DataService} from './data.service';
import {FormsModule} from '@angular/forms';
import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';
import {SchedulerComponent} from './scheduler.component';
import {DayPilotModule} from 'daypilot-pro-angular';
import {HttpClientModule} from '@angular/common/http';

@NgModule({
  imports:      [
    BrowserModule,
    FormsModule,
    HttpClientModule,
    DayPilotModule
  ],
  declarations: [
    SchedulerComponent
  ],
  exports:      [ SchedulerComponent ],
  providers:    [ DataService ]
})
export class SchedulerModule { }

Loading Angular 12 Scheduler Data

You can see that the Scheduler component defines [events] attribute that points to an array with event data. The events are loaded in ngAfterViewInit() method using DataService class (data.service.ts) which is injected by Angular in the SchedulerComponent constructor.

This sample implementation defines the data locally. In a real-world application, you’ll need to load the data from the server instead. To see how to load the data using an HTTP call, please see the Angular Scheduler Tutorial which shows how to load the Scheduler resources and events using a PHP backend.

The event data structure is defined by the DayPilot.EventData interface. Some of the properties are required:

  • id - the event ID (string or number); the ID identifies the event and it must be unique

  • resource - the resource ID (string or number); it is used to match the event with the correct row - it has to match with config.resources[].id value

  • start - event start (DayPilot.Date object or an ISO 8601 date/time string)

  • end - event end (DayPilot.Date object or an ISO 8601 date/time string)

  • text - the event text (string); it will be HTML-escaped automatically

You can find the list of all available event properties in DayPilot.Event.data documentation.

We have also defined barColor value to specify a custom event bar color.

import {Injectable} from '@angular/core';
import {DayPilot} from 'daypilot-pro-angular';
import {HttpClient} from '@angular/common/http';
import {Observable} from 'rxjs';

@Injectable()
export class DataService {

  resources: any[] = [
    { name: 'Factory A', id: 'GA', expanded: true, children: [
        { name: 'Production Line A.1', id: 'R1' },
        { name: 'Production Line A.2', id: 'R2' },
        { name: 'Production Line A.3', id: 'R3' },
        { name: 'Production Line A.4', id: 'R4' },
        { name: 'Production Line A.5', id: 'R5' },
        { name: 'Production Line A.6', id: 'R6' },
      ]},
  ];

  events: any[] = [
    {
      id: '1',
      resource: 'R2',
      start: '2021-09-02',
      end: '2021-09-05',
      text: 'Order #132',
      barColor: '#990000'
    },
    {
      id: '2',
      resource: 'R2',
      start: '2021-09-06',
      end: '2021-09-09',
      text: 'Order #272',
      barColor: '#b45f06'
    },
    {
      id: '3',
      resource: 'R2',
      start: '2021-09-10',
      end: '2021-09-13',
      text: 'Order #315',
      barColor: '#bf9000'
    },
    {
      id: '4',
      resource: 'R4',
      start: '2021-09-03',
      end: '2021-09-06',
      text: 'Order #452',
      barColor: '#38761d'
    },
    {
      id: '5',
      resource: 'R4',
      start: '2021-09-07',
      end: '2021-09-11',
      text: 'Order #502',
      barColor: '#134f5c'
    },
    {
      id: '6',
      resource: 'R4',
      start: '2021-09-12',
      end: '2021-09-14',
      text: 'Order #635',
      barColor: '#1155cc'
    },
  ];


  constructor(private http: HttpClient) {
  }

  getEvents(from: DayPilot.Date, to: DayPilot.Date): Observable<any[]> {

    // simulating an HTTP request
    return new Observable(observer => {
      setTimeout(() => {
        observer.next(this.events);
      }, 200);
    });

    // return this.http.get("/api/events?from=" + from.toString() + "&to=" + to.toString());
  }

  getResources(): Observable<any[]> {

    // simulating an HTTP request
    return new Observable(observer => {
      setTimeout(() => {
        observer.next(this.resources);
      }, 200);
    });

    // return this.http.get("/api/resources");
  }

}

package.json

{
  "name": "angular12-scheduler",
  "license": "SEE LICENSE IN license/LicenseAgreementTrial.pdf",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "watch": "ng build --watch --configuration development",
    "test": "ng test"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "~12.0.0",
    "@angular/common": "~12.0.0",
    "@angular/compiler": "~12.0.0",
    "@angular/core": "~12.0.0",
    "@angular/forms": "~12.0.0",
    "@angular/platform-browser": "~12.0.0",
    "@angular/platform-browser-dynamic": "~12.0.0",
    "@angular/router": "~12.0.0",
    "daypilot-pro-angular": "https://npm.daypilot.org/daypilot-pro-angular/trial/2021.2.4990.tar.gz",
    "rxjs": "~6.6.0",
    "tslib": "^2.1.0",
    "zone.js": "~0.11.4"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~12.0.0",
    "@angular/cli": "~12.0.0",
    "@angular/compiler-cli": "~12.0.0",
    "@types/jasmine": "~3.6.0",
    "@types/node": "^12.11.1",
    "jasmine-core": "~3.7.0",
    "karma": "~6.3.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage": "~2.0.3",
    "karma-jasmine": "~4.0.0",
    "karma-jasmine-html-reporter": "^1.5.0",
    "typescript": "~4.2.3"
  }
}