Overview

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.

Overriding the Scheduler Grid Mousedown Behavior

If you want to override the default action that will be started on mousedown event on the JavaScript Scheduler grid, you can use the onGridMouseDown event. This event is fired for the inner Scheduler grid (cells and events).

By default, simple mousedown will trigger time range selecting for grid cells. For events, the behavior depends on the location and enabled features - it can be drag and drop event moving, resizing, click action or the action defined by active areas.

Shift + mousedown will start rectangle selection, if it is enabled:

onGridMouseDown: function(args) {
  if (args.shift) {
    args.action = "RectangleSelect";
  }
},

We will use this feature to allow time range selection to be started over events (for Shift+drag).

First, we need to enable rectangle selection:

rectangleSelectHandling: "Enabled",

The rectangle selection lets you select a specified Scheduler area. By default, it selects any rectangular area. We want it to limit the selection to just a single row:

rectangleSelectMode: "Row",

Now, we need to specify the action using onRectangleSelecting event handler. This event is fired in real time whenever the rectangle selection changes:

onRectangleSelecting: function(args) {
  args.visible = false;
  dp.multirange.clear();
  dp.multirange.add({start: args.start, end: args.end, resource: args.resources[0]});
},

In our event handler, we hide the rectangle element using args.visible and create a custom selection using the time range selection API.

As soon as the rectangle selection is complete (the mouse button is released) the Scheduler fires onRectangleSelected event. We will use the event handler to define the action - it will be the same action that you normally define for onTimeRangeSelected:

onRectangleSelected: function(args) {
  var selection = dp.multirange.get()[0];
  console.log("selection", selection);

  DayPilot.Modal.prompt("Create a new event:", "Event 2").then(function(modal) {
    dp.clearSelection();
    if (!modal.result) { return; }
    dp.events.add(new DayPilot.Event({
      start: selection.start,
      end: selection.end,
      id: DayPilot.guid(),
      resource: selection.resource,
      text: modal.result
    }));
  });
}

Full Source Code

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>JavaScript Scheduler: Selection over Events</title>

  <style type="text/css">
    <!-- ... -->
  </style>

  <!-- DayPilot library -->
  <script src="js/daypilot/daypilot-all.min.js"></script>
</head>
<body>
<div class="header">
  <h1><a href='https://code.daypilot.org/99871/javascript-scheduler-selection-over-events'>JavaScript Scheduler: Selection over Events</a></h1>
  <div><a href="https://javascript.daypilot.org/">DayPilot for JavaScript</a> - HTML5 Calendar/Scheduling Components for JavaScript/Angular/React/Vue</div>
</div>

<div class="main">
  <div id="dp"></div>
  <div class="generated">Generated using <a href="https://builder.daypilot.org/">DayPilot UI Builder</a>.</div>
</div>

<script>
  var dp = new DayPilot.Scheduler("dp", {
    timeHeaders: [{"groupBy":"Month"},{"groupBy":"Day","format":"d"}],
    scale: "Day",
    days: DayPilot.Date.today().daysInMonth(),
    startDate: DayPilot.Date.today().firstDayOfMonth(),
    timeRangeSelectedHandling: "Enabled",
    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
        }));
      });
    },
    treeEnabled: true,
    rectangleSelectHandling: "Enabled",
    rectangleSelectMode: "Row",
    onGridMouseDown: function(args) {
      if (args.shift) {
        args.action = "RectangleSelect";
      }
    },
    onRectangleSelecting: function(args) {
      args.visible = false;
      dp.multirange.clear();
      dp.multirange.add({start: args.start, end: args.end, resource: args.resources[0]});
    },
    onRectangleSelected: function(args) {
      var selection = dp.multirange.get()[0];
      console.log("selection", selection);

      DayPilot.Modal.prompt("Create a new event:", "Event 2").then(function(modal) {
        dp.clearSelection();
        if (!modal.result) { return; }
        dp.events.add(new DayPilot.Event({
          start: selection.start,
          end: selection.end,
          id: DayPilot.guid(),
          resource: selection.resource,
          text: modal.result
        }));
      });
    }
  });
  dp.resources = [
    {name: "Resource 1", id: "R1"},
    {name: "Resource 2", id: "R2"},
    {name: "Resource 3", id: "R3"},
    {name: "Resource 4", id: "R4"},
    {name: "Resource 5", id: "R5"},
    {name: "Resource 6", id: "R6"},
    {name: "Resource 7", id: "R7"},
    {name: "Resource 8", id: "R8"},
    {name: "Resource 9", id: "R9"},
  ];
  dp.events.list = [];
  dp.init();
</script>

</body>
</html>