Features

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. Buy a license.

Event Context Menu

angular-scheduler-dynamic-context-menu-enabled.png

The event context menu is defined using contextMenu property of the config object.

config: any = {
  contextMenu: new DayPilot.Menu({
    items: [
      { text: "Delete", onClick: function(args) { var dp = args.source.calendar; dp.events.remove(args.source); } },
      { text: "-"},
      {
        text: "Blue",
        icon: "icon icon-blue",
        tags: { color: "#1155cc" },
        onClick: args => { this.updateColor(args.source, args.item.tags.color); }
      },
      {
        text: "Green",
        icon: "icon icon-green",
        tags: { color: "#6aa84f" },
        onClick: args => { this.updateColor(args.source, args.item.tags.color); }
      },
      {
        text: "Yellow",
        icon: "icon icon-yellow",
        tags: { color: "#f1c232" },
        onClick: args => { this.updateColor(args.source, args.item.tags.color); }
      },
      {
        text: "Red",
        icon: "icon icon-red",
        tags: { color: "#cc0000" },
        onClick: args => { this.updateColor(args.source, args.item.tags.color); }
      },
    ],
    onShow: args => {
      let e = args.source;

      // disable deleting for events that start in the past
      if (e.start() < DayPilot.Date.today()) {
        args.menu.items[0].disabled = true;
      }
      else {
        args.menu.items[0].disabled = false;
      }
    }
  }),
  // ...
}

Dynamic Modification of the Event Context Menu

angular-scheduler-dynamic-context-menu-disabled.png

You can modify the context menu properties upon invocation by handling onShow event handler.

This event handler checks the event start date. If the event starts before today, the first menu item ("Delete" action) is disabled.

config: any = {
  contextMenu: new DayPilot.Menu({
    items: [
      { text: "Delete", onClick: function(args) { var dp = args.source.calendar; dp.events.remove(args.source); } },
      // ...
    ],
    onShow: args => {
      let e = args.source;

      // disable deleting for events that start in the past
      if (e.start() < DayPilot.Date.today()) {
        args.menu.items[0].disabled = true;
      }
      else {
        args.menu.items[0].disabled = false;
      }
    }
  }),
  // ...
}

Dynamic Row Header Context Menu

The same method can be used to customize the row header context menu depending on the row. This example displays a different menu for resource groups and resources.

Context menu for parent rows (groups):

angular-scheduler-dynamic-context-menu-group.png

Context menu for resources (rows without children):

angular-scheduler-dynamic-context-menu-resource.png

In this example, we have defined two different menu item arrays. We use the onShow event handler to set the items property as needed.

config: any = {
  contextMenuResource: new DayPilot.Menu({
    onShow: args => {
      let hasChildren = args.source.children().length > 0;
      if (hasChildren) {
        args.menu.items = this.menuItemsGroup;
      }
      else {
        args.menu.items = this.menuItemsResource;
      }
    }
  })
}

menuItemsGroup: any[] = [
  { text: "Group Details"}
];

menuItemsResource: any[] = [
  { text: "Resource Details"}
];

Source Code

scheduler.component.ts

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

@Component({
  selector: 'scheduler-component',
  template: `<daypilot-scheduler [config]="config" [events]="events" #scheduler></daypilot-scheduler>`,
  styles: [``]
})
export class SchedulerComponent implements AfterViewInit {

  @ViewChild("scheduler")
  scheduler: DayPilotSchedulerComponent;

  events: any[] = [];

  config: any = {
    timeHeaders: [{"groupBy":"Month"},{"groupBy":"Day","format":"d"}],
    scale: "Day",
    eventHeight: 30,
    days: 31,
    startDate: "2018-03-01",
    treeEnabled: true,
    separators: [
      {color: "red", date: DayPilot.Date.today() }
    ],
    onTimeRangeSelected: function (args) {
      var dp = this;
      DayPilot.Modal.prompt("Create a new event:", "Event 1").then(function(modal) {
        dp.clearSelection();
        if (!modal.result) { return; }
        dp.events.add(new DayPilot.Event({
          start: args.start,
          end: args.end,
          id: DayPilot.guid(),
          resource: args.resource,
          text: modal.result
        }));
      });
    },
    contextMenu: new DayPilot.Menu({
      items: [
        { text: "Delete", onClick: function(args) { var dp = args.source.calendar; dp.events.remove(args.source); } },
        { text: "-"},
        {
          text: "Blue",
          icon: "icon icon-blue",
          tags: { color: "#1155cc" },
          onClick: args => { this.updateColor(args.source, args.item.tags.color); }
        },
        {
          text: "Green",
          icon: "icon icon-green",
          tags: { color: "#6aa84f" },
          onClick: args => { this.updateColor(args.source, args.item.tags.color); }
        },
        {
          text: "Yellow",
          icon: "icon icon-yellow",
          tags: { color: "#f1c232" },
          onClick: args => { this.updateColor(args.source, args.item.tags.color); }
        },
        {
          text: "Red",
          icon: "icon icon-red",
          tags: { color: "#cc0000" },
          onClick: args => { this.updateColor(args.source, args.item.tags.color); }
        },
      ],
      onShow: args => {
        let e = args.source;

        // disable deleting for events that start in the past
        if (e.start() < DayPilot.Date.today()) {
          args.menu.items[0].disabled = true;
        }
        else {
          args.menu.items[0].disabled = false;
        }
      }
    }),
    contextMenuResource: new DayPilot.Menu({
      onShow: args => {
        let hasChildren = args.source.children().length > 0;
        if (hasChildren) {
          args.menu.items = this.menuItemsGroup;
        }
        else {
          args.menu.items = this.menuItemsResource;
        }
      }
    })
  };

  menuItemsGroup: any[] = [
    { text: "Group Details"}
  ];

  menuItemsResource: any[] = [
    { text: "Resource Details"}
  ];

  constructor(private ds: DataService) {
  }

  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;
    });
  }

  updateColor(e, color) {
    e.data.color = color;
    this.scheduler.control.events.update(e);
  }

}