Features

  • A checkbox switches the Angular Scheduler component to read-only mode by disabling all actions

  • Selected context menu items are disabled

  • Active area icons with context-specific actions (row editing) are hidden

  • Trial version of DayPilot Pro for JavaScript included

  • Built using Angular CLI

For an introduction to Scheduler installation and configuration please see the basic tutorial:

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.

Which Drag and Drop Actions Are Enabled by Default?

angular scheduler read only moving

By default, the following actions are enabled in the Scheduler:

  • drag and drop event moving

  • drag and drop event resizing

  • drag and drop time range selecting

When a user completes event moving or resizing the event the Scheduler is updated automatically to display the new event position (the default handling type is set to "Update"). Time range selection stays active but nothing else happens by default (event creating has to be mapped using onTimeRangeSelected event handler).

The following actions are also enabled by default but there is no default action specified:

  • time range context menu (on right click)

  • event clicking (single click, right click, double click)

  • row header clicking

How to Switch Angular Scheduler to Read-Only Mode?

angular scheduler read only enabled

You can switch the Angular Scheduler to read-only mode by disabling individual actions.

The following code turns off and on all user actions. When activating the read-only mode, the current values are stored in this.original property. The original values are then restored when the read-only mode is deactivated:

import {Component, ViewChild, AfterViewInit, ChangeDetectorRef} from "@angular/core";
import {DayPilot, DayPilotSchedulerComponent} from "daypilot-pro-angular";
import {DataService} from "./data.service";
import EventData = DayPilot.EventData;
import SchedulerConfig = DayPilot.SchedulerConfig;

@Component({
  selector: 'scheduler-component',
  template: `
  <div class="space">
    <label for="readonly"><input type="checkbox" id="readonly" [(ngModel)]="readonly" (change)="changed()"> Read-Only</label>
  </div>
  <daypilot-scheduler [config]="config" [events]="events" #scheduler></daypilot-scheduler>
`,
  styles: [``]
})
export class SchedulerComponent implements AfterViewInit {

  @ViewChild("scheduler")
  scheduler!: DayPilotSchedulerComponent;

  readonly: boolean = false;

  events: EventData[] = [];

  config: SchedulerConfig = {
    timeHeaders : [
      {groupBy: "Month", format: "MMMM yyyy"},
      {groupBy: "Day", format: "d"}
    ],
    eventHeight: 40,
    scale: "Day",
    days: 30,
    startDate: "2022-06-01",
    eventDeleteHandling: "Update",
    contextMenu: new DayPilot.Menu({
      items: [
        { text: "Edit" },
        { text: "Details" }
        ],
      onShow: args => {
        args.menu.items[0].disabled = this.readonly;
      }
    }),
    onTimeRangeSelected: async (args) => {
      const dp = args.control;
      const modal = await DayPilot.Modal.prompt("Create a new event:", "Event 1");
      dp.clearSelection();
      if (modal.canceled) { return; }
      dp.events.add({
        start: args.start,
        end: args.end,
        id: DayPilot.guid(),
        resource: args.resource,
        text: modal.result,
        barColor: "#38761d"
      });
    },
    onBeforeRowHeaderRender: args => {
      if (!this.readonly) {
        args.row.areas = [
          { right: 3, top: 13, width: 14, height: 14, style: "color: #aaa", cssClass: "icon icon-edit", visibility: "Hover", onClick: args => { this.scheduler.control.rows.edit(args.source); } }
        ];
      }
    },
    onEventClick: args => {
      DayPilot.Modal.prompt("Event name:", args.e.data.text).then(modal => {
        if (modal.canceled) {
          return;
        }
        args.e.data.text = modal.result;
        this.scheduler.control.events.update(args.e);
      });
    }
  };

  constructor(private ds: DataService, private cdr: ChangeDetectorRef) {}

  ngAfterViewInit(): void {
    this.ds.getResources().subscribe(result => this.config.resources = result);

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

  original: any;

  changed():void {
    let properties = [
      "eventClickHandling",
      "eventDeleteHandling",
      "eventHoverHandling",
      "eventDoubleClickHandling",
      "eventMoveHandling",
      "eventResizeHandling",
      "rowClickHandling",
      "rowDoubleClickHandling",
      "rowCreateHandling",
      "rowSelectedHandling",
      "rowMoveHandling",
      "timeRangeClickHandling",
      "timeRangeDoubleClickHandling",
      "timeRangeSelectedHandling",
      "timeRangeRightClickHandling"
    ];

    if (this.readonly) {
      this.original = {};

      properties.forEach(name => {
        // @ts-ignore
        this.original[name] = this.scheduler.control[name];
        // @ts-ignore
        this.config[name] = "Disabled";
      });

      this.scheduler.control.clearSelection();

    }
    else {
      properties.forEach(name => {
        // @ts-ignore
        this.config[name] = this.original[name];
      });
    }
  }
}

How to Disable Scheduler Context Menu Items?

Event context menu in "edit" mode:

angular scheduler context menu edit mode

Event context menu in "read-only" mode:

angular scheduler context menu read only mode

The Scheduler event context menu supports onShow() event handler that will let you customize the context menu properties and items in runtime depending on the current application state. In this case, we will enable/disable the "Edit" menu item depending on the read-only checkbox state:

config: SchedulerConfig = {
  // ...
  contextMenu: new DayPilot.Menu({
    items: [
      { text: "Edit" },
      { text: "Details" }
      ],
    onShow: args => {
      args.menu.items[0].disabled = this.readonly;
    }
  }),
};

How to Disable Row Header Active Areas?

If you add any editing capabilities using active areas they need to be turned off/hidden as well.

Our example adds a row header active area that activates inline row editing:

angular scheduler row editing enabled

In the read-only mode, the active area is not visible:

angular scheduler row editing disabled

config: SchedulerConfig = {   
  // ...
  onBeforeRowHeaderRender: args => {
    if (!this.readonly) {
      args.row.areas = [
        { right: 3, top: 13, width: 14, height: 14, style: "color: #aaa", cssClass: "icon icon-edit", visibility: "Hover", onClick: args => { this.scheduler.control.rows.edit(args.source); } }
      ];
    }
  }
  // ...
}

History

  • March 3, 2020: Upgraded to Angular 13, DayPilot Pro for JavaScript 2022.1

  • August 31, 2020: Upgraded to Angular 10, DayPilot Pro for JavaScript 2020.3; event deleting and editing added

  • June 13, 2018: Upgraded to Angular 6, DayPilot Pro for JavaScript 2018.2.3297

  • January 19, 2017: Initial release (Angular 2)