Creating Event Calendar with dhtmlxScheduler and AngularJS

AngularJS is a modern JavaScript framework that allows creating rich client-side apps in a fast and productive way. It goes without saying that AngularJS is convenient and powerful in working with HTML. However, it doesn’t have ready to use complex UI components yet. In this article we’ll try to partially eliminate this drawback by showing how to add support of DHTMLX Scheduler for an AngularJS app.

Download dhtmlxScheduler to add a powerful scheduling calendar to your app

 
Angular Js Event Calendar with dhtmlxScheduler

 
You can check the online demo of a ready app or just grab the sources of the app from GitHub.

Adding dhxScheduler Directive

 
In order to build a custom HTML component in AngularJS we need to create a new directive. So let’s start integrating the Scheduler from writing a directive for it. For this purpose we need to create a .js file with the following content:

app.directive('dhxScheduler', function() {
  return {
    restrict: 'A',
    scope: false,
    transclude: true,
    template:'<div class="dhx_cal_navline" ng-transclude></div><div class="dhx_cal_header"></div><div class="dhx_cal_data"></div>',

    link:function ($scope, $element, $attrs, $controller){
      //adjust size of a scheduler
      $scope.$watch(function() {
        return $element[0].offsetWidth + "." + $element[0].offsetHeight;
      }, function() {
        scheduler.setCurrentView();
      });

      //styling for dhtmlx scheduler
      $element.addClass("dhx_cal_container");

      //init scheduler
      scheduler.init($element[0], new Date(), "month");
    }
  }

The above code may look a bit complicated, but the things the code produces are rather simple:

  • the code defines a new directive which can be used as a custom attribute
  • when the new directive (dhxScheduler) is initialized, it will create the dhtmlxScheduler object with the default settings
  • the watcher function will be constantly checking the size of scheduler’s container and will resize the component when the size of HTML container changes.


For creating an instance of dhtmlxScheduler on a page it’s actually enough to write the above code and place the directive somewhere on the page. If we want to create a simple app with a scheduler inside, the HTML code structure shown below is needed:

<!doctype html>
<html lang="en" ng-app="schedulerApp">
<head>
  <meta charset="utf-8">
  <title>Angular Calendar demo</title>

  <link rel="stylesheet" href="css/app.css">
    <link rel="stylesheet" href="https://cdn.dhtmlx.com/scheduler/edge/dhtmlxscheduler.css">
    <script src="https://cdn.dhtmlx.com/scheduler/edge/dhtmlxscheduler.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.7/angular.min.js"></script>

  <script src="js/app.js"></script>
</head>
<body>
    <div dhx-scheduler style="height:350px; width:600px;">
        <div class="dhx_cal_prev_button">&nbsp;</div>
        <div class="dhx_cal_next_button">&nbsp;</div>
        <div class="dhx_cal_today_button"></div>
        <div class="dhx_cal_date"></div>
        <div class="dhx_cal_tab" name="day_tab"></div>
        <div class="dhx_cal_tab" name="week_tab"></div>
        <div class="dhx_cal_tab" name="month_tab"></div>    
    <div>
</body>
</html>

As you can see, we’ve included the .js and .css files of both the AngularJS framework and the dhtmlxScheduler component. Our newly created dxhScheduler directive is used in the code of the page. The dhx-scheduler attribute is used to trigger the directive and to initialize the scheduler component. The HTML tags inside of dhx-scheduler div container are necessary to define the buttons on the top bar of the scheduler.

When you open a page with the described HTML code in a browser, you will see an appointment calendar component ready to be used:

 
dhtmlxScheduler - Using with AngularJS
 

Linking to the Scope

 
For now our AngularJS calendar just renders itself, which is good but not quite useful yet. Let’s link the scheduler’s state and content to the scope in order to expand the app’s functionality. For this purpose we need to extend the link method of the directive as follows:

link:function ($scope, $element, $attrs, $controller){
  //default state of the scheduler
  if (!$scope.scheduler)
    $scope.scheduler = {};
  $scope.scheduler.mode = $scope.scheduler.mode || "month";
  $scope.scheduler.date = $scope.scheduler.date || new Date();

  //watch data collection, reload on changes
  $scope.$watch($attrs.data, function(collection){
    scheduler.clearAll();
    scheduler.parse(collection, "json");
  }, true);

  //watch mode and date
  $scope.$watch(function(){
    return $scope.scheduler.mode + $scope.scheduler.date.toString();
  }, function(nv, ov) {
    var mode = scheduler.getState();
    if (nv.date != mode.date || nv.mode != mode.mode)
      scheduler.setCurrentView($scope.scheduler.date, $scope.scheduler.mode);
  }, true);

  //size of scheduler
  $scope.$watch(function() {
    return $element[0].offsetWidth + "." + $element[0].offsetHeight;
  }, function() {
    scheduler.setCurrentView();
  });

  //styling for dhtmlx scheduler
  $element.addClass("dhx_cal_container");

  //init scheduler
  scheduler.init($element[0], $scope.scheduler.date, $scope.scheduler.mode);
}

Let’s see what was added. The top block checks if there are settings for the scheduler in the scope. If there are no such settings, they will be created with default values.

After the top block, two new watch instructions follow. The first instruction will monitor the state of data collection and reload the scheduler with new data when the collection is changed. The second instruction will change the scheduler’s settings (mode and date) when the related parameters are changed in the scope.

Finally, we have slightly adjusted the scheduler.init command. Now it uses values from the scope as initial view and date values.

After applying all these changes we can do the following:

  • We can place custom buttons on the page. Clicking the first button will change the displayed date and clicking the second button will switch the mode of events view in the calendar:
     

        <button ng-click="scheduler.setCurrentView(null, 'week')">Week</button>
        <button ng-click="scheduler.setCurrentView(new Date())">Week</button>
  • We can load data from the scope to the scheduler:
     

    app.controller('MainSchedulerCtrl', function($scope) {
      $scope.events = [
        { id:1, text:"Task A-12458",
          start_date: new Date(2018, 09, 30, 9, 0),
          end_date: new Date(2018, 09, 30, 16, 0) },
        { id:2, text:"Task A-83473",
          start_date: new Date(2018, 09, 28, 9, 0),
          end_date: new Date(2018, 09, 30, 16, 0) }
      ];

    });

       <div dhx-scheduler data="events" style="height:350px; width:600px;">
  • We can use some input on the page to filter the scheduler:
     

       <div dhx-scheduler data="events | filter:search" style="height:350px; width:600px;">

 
Thus we have a scheduler populated with data. The scheduler has the functions of date and mode changing, and data filtering. Next we can customize the appearance of events in the scheduler.

The Look of Events

 
Well, we can now define the content and appearance of event bars in the calendar. dhtmlxScheduler provides JavaScript API for templating and we can take the advantage of this API to specify the look of events in our calendar. The code below will define one more directive which can be used to define the scheduler’s templates:

app.directive('dhxTemplate', ['$interpolate', function($interpolate){

  return {
    restrict: 'AE',
    terminal:true,

    link:function($scope, $element, $attrs, $controller){
      $element[0].style.display = 'none';

      var htmlTemplate = $interpolate($element.html());
      scheduler.templates[$attrs.dhxTemplate] = function(start, end, event){
        return htmlTemplate({event: event});
      };

    }
  };
}]);

This code defines the dhxTemplate directive. This directive can be used both as an attribute or as a custom tag. The content of the directive will be converted to JavaScript function and used as a template of the scheduler. To specify the template for the scheduler, you can use the native AngularJS templates. This syntax implies the use of the {{event.property}} expressions as placeholders in the template’s text.

For example, we can add the following code on the page:

<div dhx-template="event_bar_text">
   <strong>#{{event.id}}</strong>: {{event.text | uppercase}}
</div>

The above code will produce the result as follows:

 
dhtmlxScheduler and AngularJS - Custom Template
 

The dhx-template attribute’s name (“event_bar_text” ) is the name of scheduler’s template which needs to be defined. Check the full list of templates in the documentation.

Take into account the following points:

  • You need to use the format of the type {{event.some}} to define the template. Instead of “some” place the necessary property of event object. “event.” in our example is a fixed part that is used only by the scheduler to define the event’s property. It is not related to the current scope.
  • You can’t use the scope’s variables inside of the template.

 

Summing Up

 
So although there are no complex UI components in Angular JS, we can add such a component with the help of some additional code. Thus, by using the two directives defined above (dhxScheduler and dhxTemplate) you can easily add a rich-featured calendar on the page and customize its appearance.

download scheduler

The above described functionality of the scheduler component is just a tip of the iceberg. dhtmlxScheduler has a rich API and lots of properties and events. It makes no sense to wrap all of them into AngularJS directives, as you can easily make any necessary calls from Angular controller’s code (check the details of the dhtmlxScheduler API in the documentation).

The simplicity of integration shows the flexibility of both AngularJS and dhtmlxScheduler. While both of them are independent solutions, with a bit of glue code they work together in a neat way. By using the above code you can get a Google-like appointment calendar for your AngularJS web app.

Advance your web development with DHTMLX

Gantt chart
Event calendar
Diagram library
30+ other JS components