Overview

  • Angular 8 Scheduler component
  • Quick start project that includes the required boilerplate
  • Requires Angular CLI 8
  • Includes basic Angular Scheduler configuration
  • You can generate your own Angular project with pre-configured Scheduler using Scheduler UI Builder application
  • 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.

Angular 8 Scheduler Component

angular-8-scheduler-component-typescript.png

This tutorial shows how to add Angular Scheduler component to an Angular 8 application and configure the appearance and behavior.

First, we need to create a new application using Angular CLI:

ng new angular8-scheduler

Now we can add daypilot-pro-angular package using NPM. This package includes the Angular Scheduler component. After adding the package reference we can start using all DayPilot components in our application.

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

This command install a specific DayPilot Pro version (2019.3.4012). You can get the NPM link for the latest release at npm.daypilot.org.

The next step is to import the DayPilotModule:

@NgModule({
  imports: [
    // ...
    DayPilotModule
  ],
  declarations: [
    SchedulerComponent
  ],
  exports:      [ SchedulerComponent ],
  providers:    [ DataService ]
})

Now create a new Angular component (scheduler.component.ts) with the following content:

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

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

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

  events: any[] = [];

  config: SchedulerPropsAndEvents = {
    timeHeaders: [{"groupBy":"Month"},{"groupBy":"Day","format":"d"}],
    scale: "Day",
    days: 30,
    startDate: "2019-09-01",
    treeEnabled: true,
  };

  constructor() {
  }

}

This component adds DayPilotSchedulerComponent instance and specifies its properties using config field. In the config object, you can use all properties and event handlers of the DayPilot.Scheduler class. It will let you customize the Scheduler and implement the required logic.

Instead of creating the Angular project manually (and adding the component and dependencies) you can also configure the Scheduler using the online UI Builder app and generate the Angular 8 project as a zip file:

Angular 8 Scheduler: Loading Data

In this step, we will extend the SchedulerComponent class to load data from a special DataService class.

It loads rows (resources) and events. As soon as the DataService returns the data the Scheduler UI is updated automatically.

scheduler.component.ts

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: `<daypilot-scheduler [config]="config" [events]="events" #scheduler></daypilot-scheduler>`,
  styles: [`
  ::ng-deep .scheduler_default_event_bar, ::ng-deep .scheduler_default_event_bar_inner{
      height: 10px;
  }
  ::ng-deep .scheduler_default_event_inner {
      top: 10px;
  }
  `]
})
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: 30,
    startDate: "2019-09-01",
    eventHeight: 50,
    cellWidth: 50,
    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);

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

}

Data Service

The data service provides connection to the data source (usually it's a database accessible using REST API). In our example, we define the data statically - but we add a short delay of 200 ms to simulate a server-side HTTP request:

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: '2019-09-02',
      end: '2019-09-04',
      text: 'Order #142',
      barColor: '#990000'
    },
    {
      id: '2',
      resource: 'R2',
      start: '2019-09-05',
      end: '2019-09-07',
      text: 'Order #212',
      barColor: '#b45f06'
    },
    {
      id: '3',
      resource: 'R2',
      start: '2019-09-08',
      end: '2019-09-10',
      text: 'Order #305',
      barColor: '#bf9000'
    },
    {
      id: '4',
      resource: 'R4',
      start: '2019-09-03',
      end: '2019-09-05',
      text: 'Order #442',
      barColor: '#38761d'
    },
    {
      id: '5',
      resource: 'R4',
      start: '2019-09-06',
      end: '2019-09-08',
      text: 'Order #512',
      barColor: '#134f5c'
    },
    {
      id: '6',
      resource: 'R4',
      start: '2019-09-09',
      end: '2019-09-11',
      text: 'Order #605',
      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": "angular8-scheduler",
  "license": "SEE LICENSE IN license/LicenseAgreement.pdf",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "~8.0.0",
    "@angular/common": "~8.0.0",
    "@angular/compiler": "~8.0.0",
    "@angular/core": "~8.0.0",
    "@angular/forms": "~8.0.0",
    "@angular/platform-browser": "~8.0.0",
    "@angular/platform-browser-dynamic": "~8.0.0",
    "@angular/router": "~8.0.0",
    "daypilot-pro-angular": "https://npm.daypilot.org/daypilot-pro-angular/trial/2019.3.4012.tar.gz",
    "rxjs": "~6.4.0",
    "tslib": "^1.9.0",
    "zone.js": "~0.9.1"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.800.0",
    "@angular/cli": "~8.0.1",
    "@angular/compiler-cli": "~8.0.0",
    "@angular/language-service": "~8.0.0",
    "@types/node": "~8.9.4",
    "@types/jasmine": "~3.3.8",
    "@types/jasminewd2": "~2.0.3",
    "codelyzer": "^5.0.0",
    "jasmine-core": "~3.4.0",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~4.1.0",
    "karma-chrome-launcher": "~2.2.0",
    "karma-coverage-istanbul-reporter": "~2.0.1",
    "karma-jasmine": "~2.0.1",
    "karma-jasmine-html-reporter": "^1.4.0",
    "protractor": "~5.4.0",
    "ts-node": "~7.0.0",
    "tslint": "~5.15.0",
    "typescript": "~3.4.3"
  }
}