Zum Hauptinhalt springen

Quick Start with Angular Scheduler

Hinweis

This tutorial covers the Angular wrapper included in the Commercial, Enterprise, and Ultimate editions of DHTMLX Scheduler. If you are using the Individual or GPL edition, follow the alternative guide: How to Start with Angular.

This guide renders a working Angular Scheduler in a standalone Angular application. It creates Scheduler inside a dedicated Angular component and mounts that component in the app shell.

Check a complete working project that follows this tutorial on GitHub.

1. Create An Angular Project

Create a standalone Angular app (Angular CLI):

ng new angular-scheduler-quick-start --standalone --routing=false --style=css
cd angular-scheduler-quick-start

If Angular CLI is not installed yet, install it first (npm install -g @angular/cli).

2. Install Angular Scheduler

Install Angular Scheduler as described in the installation guide.

In this tutorial we use the evaluation package:

npm install @dhtmlx/trial-angular-scheduler

or

yarn add @dhtmlx/trial-angular-scheduler

If you already use the Professional package, replace @dhtmlx/trial-angular-scheduler with @dhx/angular-scheduler in the commands and imports.

3. Add Global Styles

Open src/styles.css and add the Scheduler styles:

src/styles.css
@import "@dhtmlx/trial-angular-scheduler/dist/angular-scheduler.css";

html,
body {
height: 100%;
margin: 0;
}

app-root {
display: block;
height: 100vh;
}

This quick start uses a global CSS import, so you do not need ViewEncapsulation.None in the Scheduler component.

If you later move the Scheduler CSS import or overrides for internal Scheduler classes into a component stylesheet, Angular's default style encapsulation may scope those selectors. In that case, set encapsulation: ViewEncapsulation.None on that component, or keep the styles global.

4. Add Demo Data

Create src/app/demo-data.ts:

src/app/demo-data.ts
import type { Event } from "@dhtmlx/trial-angular-scheduler";

export const mainDate = new Date("2026-08-15T00:00:00Z");

export const schedulerEvents: Event[] = [
{ id: 1, start_date: new Date("2026-08-10T02:00:00Z"), end_date: new Date("2026-08-10T10:20:00Z"), text: "Product Strategy Hike" },
{ id: 2, start_date: new Date("2026-08-10T12:00:00Z"), end_date: new Date("2026-08-10T16:00:00Z"), text: "Agile Meditation and Release" },
{ id: 3, start_date: new Date("2026-08-11T06:00:00Z"), end_date: new Date("2026-08-11T11:00:00Z"), text: "Tranquil Tea Time" },
{ id: 4, start_date: new Date("2026-08-11T11:30:00Z"), end_date: new Date("2026-08-11T19:00:00Z"), text: "Sprint Review and Retreat" },
{ id: 5, start_date: new Date("2026-08-12T01:00:00Z"), end_date: new Date("2026-08-12T03:00:00Z"), text: "Kayaking Workshop" },
{ id: 6, start_date: new Date("2026-08-12T06:00:00Z"), end_date: new Date("2026-08-12T08:00:00Z"), text: "Stakeholder Sunset Yoga Session" },
{ id: 7, start_date: new Date("2026-08-12T07:00:00Z"), end_date: new Date("2026-08-12T12:00:00Z"), text: "Roadmap Alignment Walk" },
{ id: 8, start_date: new Date("2026-08-12T13:00:00Z"), end_date: new Date("2026-08-12T18:00:00Z"), text: "Mindful Team Building" },
{ id: 9, start_date: new Date("2026-08-13T01:00:00Z"), end_date: new Date("2026-08-13T18:00:00Z"), text: "Cross-Functional Expedition" },
{ id: 10, start_date: new Date("2026-08-13T14:00:00Z"), end_date: new Date("2026-08-13T20:00:00Z"), text: "User Feedback Picnic" },
{ id: 11, start_date: new Date("2026-08-14T03:00:00Z"), end_date: new Date("2026-08-14T08:00:00Z"), text: "Demo and Showcase" },
{ id: 12, start_date: new Date("2026-08-14T11:00:00Z"), end_date: new Date("2026-08-14T17:00:00Z"), text: "Quality Assurance Spa Day" },
{ id: 13, start_date: new Date("2026-08-15T01:00:00Z"), end_date: new Date("2026-08-15T03:00:00Z"), text: "Motion Cycling Adventure" },
{ id: 14, start_date: new Date("2026-08-15T10:00:00Z"), end_date: new Date("2026-08-15T16:00:00Z"), text: "Competitor Analysis Beach Day" },
{ id: 15, start_date: new Date("2026-08-16T02:00:00Z"), end_date: new Date("2026-08-16T06:00:00Z"), text: "Creativity Painting Retreat" },
];

5. Create A Scheduler Component

Create src/app/scheduler.component.ts:

src/app/scheduler.component.ts
import { Component } from "@angular/core";
import {
DhxSchedulerComponent,
type AngularSchedulerDataConfig,
type Event,
type SchedulerConfig,
} from "@dhtmlx/trial-angular-scheduler";
import { mainDate, schedulerEvents } from "./demo-data";

@Component({
selector: "app-scheduler",
standalone: true,
imports: [DhxSchedulerComponent],
host: { style: "display:block;height:100%;" },
template: `
<dhx-scheduler
[events]="events"
[date]="date"
[config]="config"
[data]="dataConfig"
view="week">
</dhx-scheduler>
`,
})
export class SchedulerComponent {
events: Event[] = schedulerEvents;
date = mainDate;

config: SchedulerConfig = {
first_hour: 6,
last_hour: 22,
};

dataConfig: AngularSchedulerDataConfig = {
save: (entity, action, data, id) => {
console.log("[data.save]", entity, action, data, id);
},
};
}

6. Render Scheduler In The App Shell

Replace src/app/app.ts:

src/app/app.ts
import { Component } from "@angular/core";
import { SchedulerComponent } from "./scheduler.component";

@Component({
selector: "app-root",
standalone: true,
imports: [SchedulerComponent],
template: `<app-scheduler></app-scheduler>`,
})
export class App {}

If your Angular project uses app.component.ts instead of app.ts, apply the same component code there and keep the class name expected by your main.ts.

7. Start The App

ng serve

Open http://localhost:4200. You should see Scheduler rendered in week view with the demo events. Edits will be logged through data.save.

If you are adding Scheduler to an existing app, keep your current app shell and place <app-scheduler> in the target page or route component. Make sure the parent layout provides a height to the Scheduler area.

Optional: Minimal Local Save Handling

As a next step, replace logging with local array synchronization:

src/app/scheduler.component.ts
dataConfig: AngularSchedulerDataConfig = {
save: (entity, action, item, id) => {
if (entity !== "event") return;

if (action === "create") {
this.events = [...this.events, item as Event];
return;
}

if (action === "update") {
this.events = this.events.map(event =>
String(event.id) === String(id) ? { ...(item as Event) } : event
);
return;
}

if (action === "delete") {
this.events = this.events.filter(event => String(event.id) !== String(id));
}
},
};

For grouped updates, prefer data.batchSave and handle all changes in one state transaction.

GitHub demo repository

A complete working project that follows this tutorial is provided on GitHub.

Continue With

Need help?
Got a question about the documentation? Reach out to our technical support team for help and guidance. For custom component solutions, visit the Services page.