Overview
The upper-left corner of the Angular Scheduler component is empty by default. You can add custom content using the cornerHtml property. However, this property only supports raw HTML and it won’t let you use an Angular template or elements with custom events.
In order to display dynamic content, it’s necessary to create a custom Angular component and add a new instance dynamically to the Scheduler corner using onBeforeCornerDomAdd
event handler.
The sample project 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.
Button: Custom Angular Component
First, let’s create a simple Button
Angular component.
import {Component, ViewChild, AfterViewInit, Input} from '@angular/core';
import {DayPilot} from "daypilot-pro-angular";
@Component({
selector: 'scheduler-component',
template: `<button (click)="click()">{{text}}</button>`,
styles: [`
button {
background-color: #3c78d8;
border: 1px solid #1155cc;
color: #fff;
}
`]
})
export class ButtonComponent {
@Input()
text: string = "button";
click() {
DayPilot.Modal.alert("Button clicked");
}
}
How to Add the Button to the Upper-Left Corner of the Angular Scheduler?
Now we will use the onBeforeCornerDomAdd
Scheduler event to add our Button component to the upper-left corner.
First, we need to create an instance of the component. Angular 13 provides a simplified API for dynamic component creation and the only thing we need is an instance of ViewContainerRef:
const component: ComponentRef<ButtonComponent> = this.viewContainerRef.createComponent(ButtonComponent);
As soon as we have created the component instance we can set its properties (if needed). Our Button component has a text
property and we will use it to set the button text. After changing the component properties, it is necessary to invoke change detection.
component.instance.text = this.scheduler.control.startDate?.toString("yyyy") || "";
component.changeDetectorRef.detectChanges();
Now we can get a reference to the native DOM element and display it in the Scheduler corner using args.element:
args.element = component.location.nativeElement;
This is how our onBeforeCornerDomAdd
event looks now:
import {Component, ViewChild, AfterViewInit, ViewContainerRef, ComponentRef} from '@angular/core';
import {DayPilot, DayPilotSchedulerComponent} from 'daypilot-pro-angular';
import {DataService} from './data.service';
import {ButtonComponent} from "./button.component";
@Component({
selector: 'scheduler-component',
template: `<daypilot-scheduler [config]="config" [events]="events" #scheduler></daypilot-scheduler>`,
styles: [``]
})
export class SchedulerComponent implements AfterViewInit {
// ...
config: DayPilot.SchedulerConfig = {
onBeforeCornerDomAdd: args => {
const component: ComponentRef<ButtonComponent> = this.viewContainerRef.createComponent(ButtonComponent);
component.instance.text = this.scheduler.control.startDate?.toString("yyyy") || "";
component.changeDetectorRef.detectChanges();
args.element = component.location.nativeElement;
(<any>args).component = component;
},
// ...
};
constructor(private ds: DataService,
private viewContainerRef: ViewContainerRef) {
}
}
Cleanup: Destroy the Component
When the Angular Scheduler corner content is updated or when the Scheduler component is destroyed, the old content is removed. At this point, it is necessary to destroy the dynamic Button component as well.
As you may have noticed, we saved the component object in the args
object in onBeforeCornerDomAdd
event. The same args
object will be available in onBeforeCornerDomRemove
event which we will use to destroy the component.
(<any>args).component = component;
The args
object doesn’t have any component
property so it was necessary to cast the args
object to any
.
In onBeforeCornerDomRemove
, we will load the component and call the destroy()
method:
onBeforeCornerDomRemove: args => {
const component = (<any>args).component;
component.destroy();
},