Features

  • Warm-up and cool-down time displayed using active areas
  • Custom moving handle allows drag and drop of the core event but not the additional time segments
  • Custom resizing handles for resizing the core event
  • Requires DayPilot Pro for JavaScript 2019.2.3825 or later
  • Trial version of DayPilot Pro for JavaScript included (see also License below)

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.

Live Demo

Event Data

Our JavaScript Scheduler project is generated using DayPilot UI Builder. We will modify the generated file (index.html) and customize the Scheduler to support warm-up and cool-down time (before and after the core event). 

The first step will be to add a sample event. Note the custom warmupHours and cooldownHours properties. The total duration (start/end) includes the warm-up and cool-down time.

dp.events.list = [{
  id: 1,
  start: "2019-04-17T10:00:00",
  end: "2019-04-17T15:00:00",
  resource: "R1",
  text: "Event 1",
  warmupHours: 1,
  cooldownHours: 1
}];

Displaying the Warm-Up and Cool-Down Time

javascript-scheduler-warmup-cooldown-displaying.png

We will split the event into three segments using active areas.

onBeforeEventRender: function(args) {
  var html = args.data.html;
  args.data.html = "";
  args.data.barHidden = true;
  args.data.areas = [
    {
      start: args.data.start,
      end: args.data.start.addHours(args.data.warmupHours),
      top:0,
      bottom:0,
      backColor: "#dd7e6b",
    },
    {
      start: args.data.end.addHours(-args.data.cooldownHours),
      end: args.data.end,
      top:0,
      bottom:0,
      backColor: "#dd7e6b",
    },
    {
      start: args.data.start.addHours(args.data.warmupHours),
      end: args.data.end.addHours(-args.data.cooldownHours),
      top:0,
      bottom:0,
      backColor: "#a61c00",
      style: "color: #fff; display: flex; justify-content: center; align-items: center;",
      html: html || args.data.text
    },
  ];
}

The segments are specified in hours, not using start and end time - this will simplify the data model. No additional modifications of the data are required during moving and resizing - the segments will be calculated in onBeforeEventRender whenever the event position changes.

Adjusting Drag and Drop (Moving, Resizing)

javascript-scheduler-warmup-cooldown-drag-drop.png

In this step, we will modify the default drag and drop behavior - the users will be able to move and resize the main event segment but not the warm-up and cool-down segments.

First, we will disable the default moving and resizing behavior using event properties (args.data.moveDisabled, args.data.resizeDisabled) and add custom drag and drop handles using active areas:

onBeforeEventRender: function(args) {
  var html = args.data.html;
  args.data.html = "";
  args.data.moveDisabled = true;
  args.data.resizeDisabled = true;
  args.data.deleteDisabled = true;
  args.data.barHidden = true;
  args.data.areas = [
    {
      start: args.data.start,
      end: args.data.start.addHours(args.data.warmupHours),
      top:0,
      bottom:0,
      backColor: "#dd7e6b",
    },
    {
      start: args.data.end.addHours(-args.data.cooldownHours),
      end: args.data.end,
      top:0,
      bottom:0,
      backColor: "#dd7e6b",
    },
    {
      start: args.data.start.addHours(args.data.warmupHours),
      end: args.data.end.addHours(-args.data.cooldownHours),
      top:0,
      bottom:0,
      action: "Move",
      backColor: "#a61c00",
      style: "color: #fff; display: flex; justify-content: center; align-items: center;",
      html: html || args.data.text
    },
    {
      start: args.data.start.addHours(args.data.warmupHours),
      width: 10,
      top:0,
      bottom:0,
      html: "|",
      style: "color: #fff; display: flex; justify-content: center; align-items: center;",
      action: "ResizeStart"
    },
    {
      end: args.data.end.addHours(-args.data.cooldownHours),
      width: 10,
      top:0,
      bottom:0,
      html: "|",
      style: "color: #fff; display: flex; justify-content: center; align-items: center;",
      action: "ResizeEnd"
    },
  ];
}

The next step will be adjusting the moving and resizing logic:

onEventMoving: function(args) {
  args.start = args.start.addHours(args.e.data.warmupHours);
  args.end = args.end.addHours(-args.e.data.cooldownHours);
},
onEventMove: function(args) {
  args.newStart = args.newStart.addHours(-args.e.data.warmupHours);
  args.newEnd = args.newEnd.addHours(args.e.data.cooldownHours);
},
onEventResizing: function(args) {
  if (args.what === "start") {
    args.end = args.end.addHours(-args.e.data.cooldownHours);
  }
  if (args.what === "end") {
    args.start = args.start.addHours(args.e.data.warmupHours);
  }
},
onEventResize: function(args) {
  args.newStart = args.newStart.addHours(-args.e.data.warmupHours);
  args.newEnd = args.newEnd.addHours(args.e.data.cooldownHours);
}