DHTMLX Scheduler Usage with Angular Framework

Angular is one of the most popular frameworks for building single-page mobile and web applications. In one of the previous tutorials, you’ve seen that you can embed DHTMLX Gantt in Angular apps. You can also embed DHTMLX Scheduler.

To be able to follow along with the tutorial, you should have node.js installed. So if you don’t have it, go ahead and get it. Besides, you’ll need Angular CLI to set up the environment, you can get it with the package manager (npm install -g @angular/cli). For more info, you can check Angular documentation.

Basic App Structure

Now that the starting ground is ready, you can begin setting up the environment. Let’s use Angular CLI and create the basic structure of the app. Run the following command:

ng new scheduler-angular

This is quite time-consuming, because even the simplest Angular app requires a lot of files and configuration. After the operation has finished, you can go to the app directory and run the application:

cd scheduler-angular
ng serve --open

When the app is ready, a new browser tab will open, and you’ll see the start page. This happens automatically due to the –open parameter. Without it, you would have to open http://127.0.0.1:4200 by yourself. ng serve will also watch the source file and rebuild the app if any changes have been made.

Later in the tutorial, you are going to create new components, models, and services for the app. So you need to create folders for them in src/app with the same names.

Creating Scheduler Component

To be able to embed Scheduler into the app, you should get DHTMLX Scheduler code and the type declaration for the Scheduler API. Run the following commands:

To add dhtmlxScheduler to an Angular app, you should also create a new component. Let’s store the code for the scheduler in three files. The first file, scheduler.component.html, will contain the template for the scheduler. Let’s create the file in the components folder:

The last one, ViewEncapsulation, is needed to correctly apply the styles for the scheduler. By default, Angular encapsulates styles of components by adding unique attributes to their CSS and HTML. As the scheduler HTML template is created dynamically, using the default technique is impossible. The alternatives are to enable the native Shadow DOM view encapsulation or to disable it at all. Since the Shadow DOM isn’t supported everywhere, we’ll choose to disable encapsulation.

Let’s define the scheduler component, include the styles and the template that we’ve created, and disable the Shadow DOM view encapsulation:

Now that the Scheduler module is created and recognized by Angular, you can add the new component to the page. Open app.component.html (located in src/app) and insert the scheduler tag in there:

<scheduler></scheduler>

Now if you open the page again, you will see an empty Scheduler on it.

Providing Data

At this stage, an empty Scheduler is good to look at, but I bet you want more than that. Scheduler needs data. To add data loading to the Angular Scheduler, you need to add an event service. But before that, let’s define the event model. Create event.ts (in the models folder) and add the definition:

Now let’s create an event service. A service is a class that will be responsible for creating a specific event. Services in Angular can be injected by using the Dependency Injection mechanism. They can include data, functions or some features necessary for the application. You need to create a data service that will be used to provide the scheduler with events. Add the event.service.ts file and import the event model and the Injectable decorator:

import{Injectable} from "@angular/core";import{Event} from "../models/event";

Next, add the @Injectable() decorator to the service. The decorator marks a class as available to an injector for instantiation. You’ll inject it into the component later in the tutorial.

Currently, the get method returns a resolved promise with hard coded data. However, you can load data from the server side and also return a promise. The issue will be discussed a little further below.

The scheduler component is supposed to use EventService to get events. To enable this, let’s add EventService to the component. First, import the necessary module for the service in scheduler.component.ts:

import{EventService} from "../services/event.service";

You should also specify EventService as a provider in the @Component decorator:

providers:[EventService]

Now every time a new SchedulerComponent is initialized, a fresh instance of the service will be created.

The service should be prepared to be injected into the component. For this purpose, add the following constructor to the SchedulerComponent class:

constructor(private eventService: EventService){}

Modify the ngOnInit function:

▸ it should set the data format for loading events (XML in this case),
▸ call the services to get the function and then wait for a response to put the data to the scheduler.

Now, if you reopen the app page, you should see a scheduler with events.

Saving Data

Creating an actual database and writing a backend is beyond the issues in this tutorial. Instead, we’ll mock the backend with the help of angular-in-memory-web-api library. It’ll catch an XMLHttpRequest and call the data storage defined on the client side. If you want the app to call the real backend, you can skip the first step.

1. Install angular-in-memory-web-api

First, you should install angular-in-memory-web-api. Run the following command:

npm install angular-in-memory-web-api --save

To define the mock database initialization, open app.module.ts and add InMemoryWebApiModule. The necessary class will be defined on the next step. For now, make the following changes to app.module.ts:

▸ add imports:

import{InMemoryWebApiModule} from 'angular-in-memory-web-api';import{InMemoryDataService} from './services/in-memory-data.service'import{AppComponent} from './app.component';import{SchedulerComponent} from "./components/scheduler.component";

Next, attach several event handlers to the scheduler object. They’ll catch adding, updating and deleting events in the scheduler. Inside the event handlers, services that’ll save changes to the backend will be called.

Before sending events to the service, we should preprocess them. It’s necessary to clean private properties that are assigned by the scheduler and shouldn’t be saved and also convert the dates to strings. Here’s a private method that will be called inside the event handlers:

Besides, you must remember that after you insert events into the database, they obtain database IDs. When it happens, you’ll update scheduler with the new ID using the scheduler.changeEventId method.

Well, Angular Scheduler is ready, you are welcome to check out the source code. The app can use RESTful API for CRUD operations. Keep in mind that in this demo angular-in-memory-api library was used to emulate the data storage. However, in real life apps, you’ll probably want to save changes to a real database. There are two solutions. First, you can remove in-memory-web-api from the app (in case you’ve skipped that step, you don’t need to do this). Second, you can configure it to pass requests through to the real backend and thus implement data storage. Feel free to send us feedback in the comments and stay tuned for new tutorials.

We’ve already described how to integrate our Scheduler component into meteor app using special packages. Though it was easiest way to integrate dhtmlxScheduler, we now...

Comments

Sylvain AnselminoOctober 6, 2017 at 11:51 am

I run your tuto and hade to resolve an error like “cannot read property ‘0’ of undefined”

Indeed, the html sample in the “Creating Scheduler Component” (content of scheduler.component.html) has an extra “” on the first line. I resolve my problem by removing it. The content of the scheduler.component.html should be :

Hi Jack,
To use extensions you should add them with dhtmlxScheduler.
You should get something like this:
import “dhtmlx-scheduler”
and import “dhtmlx-scheduler/codebase/ext/[extension]”.
E.g. import “dhtmlx-scheduler/codebase/ext/dhtmlxscheduler_timeline” for timeline extension.

Hi Laura,
Timeline view is a PRO feature of dhtmlxScheduler.
Currently, we don’t provide an npm package of the PRO version of dhtmlxScheduler.
Right now the available solution is to add a PRO package of dhtmlxScheduler to your project by hand.
If you want to use it with npm – you could put the package to your private npm feed and install it from there.

Hi lne,
Unfortunately, the installation of dhtmlxScheduler PRO edition via NPM is not available at the moment.
But as you are the licensed user, please create a ticket in our support system and we’ll provide you a personal NPM link.

Extensions of dhtmlxScheduler must be included only after the core file dhtmlxsheduler.js
When you are working with script includes it means that you are adding a script tag for dhtmlxscheduler.js first, and script tags for extensions after that.

In case of import, the situation is a more complicated, as import doesn’t guarantee that imported sources will be processed in the defined orders. If you are using webpack – try to use script-loader for scheduler’s file, which will preserve an order of includes and will fix the issue.

I implemented this in an Angular 6 application and I am facing 2 issues:
1. The import statement import {} from “@types/dhtmlxscheduler”; returns an error saying:
File ‘…../node_modules/@types/dhtmlxscheduler/index.d.ts’ is not a module.
I commented this part and the scheduler is rendered, however not sure whether this will impact some functionality which I have not implemented yet.
2. The ng build process also returns an error:
ERROR in src/app/components/admin/scheduler/scheduler.component.ts(20,5): error TS2304: Cannot find name ‘scheduler’.
when scheduler is being used like so:
scheduler.config.xml_date = “%Y-%m-%d %H:%i”;

So is this scheduler for Angular ready or it is still a work in progress?