Overview

  • You can implement custom time range selection limits using onTimeRangeSelecting event handler.

  • This example implements a dynamic limit for minimum and maximum selection duration.

  • Requires DayPilot Pro for JavaScript version 2020.4.4728 or later

  • Includes a trial version of DayPilot Pro for JavaScript (see 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.

Limit Time Range Selection to One Cell

By default, the JavaScript Scheduler lets users select a time range without limitations. You can implement your own rules for the time range selection using onTimeRangeSelecting event handler.

javascript-scheduler-limit-time-range-selection-one-cell-day.png

This example limits the selection to one day. In combination with scale: "Day" this will let users select just a single cell.

onTimeRangeSelecting: function(args) {

  var movingEnd = args.anchor === args.start;

  var maxDuration = DayPilot.Duration.ofDays(1);
  if (args.duration > maxDuration) {
    if (movingEnd) {
      args.end = args.start.addTime(maxDuration.ticks);
    }
    else {
      args.start = args.end.addTime(-maxDuration.ticks);
    }
  }

},

In the first step, we detect whether it’s the event start or end that is being extended:

var movingEnd = args.anchor === args.start;

We create a DayPilot.Duration object representing one day:

var maxDuration = DayPilot.Duration.ofDays(1);

If the current duration extends the maximum allowed duration, we reset the args.start or args.end value:

if (args.duration > maxDuration) {
  if (movingEnd) {
    args.end = args.start.addTime(maxDuration.ticks);
  }
  else {
    args.start = args.end.addTime(-maxDuration.ticks);
  }
}

Dynamic Time Range Selection Limit

javascript-scheduler-limit-time-range-selection-dynamic.png

It is possible to extend this logic to include more advanced rules. The following example lets you set the minimum and maximum time range selection length:

onTimeRangeSelecting: function(args) {
  var movingEnd = args.anchor === args.start;

  var min = parseInt(document.querySelector("#min").value, 10);
  var minEnabled = min !== 0;

  var max = parseInt(document.querySelector("#max").value, 10);
  var maxEnabled = max !== 0;

  if (minEnabled) {
    var duration = DayPilot.Duration.ofDays(min);
    if (args.duration < duration) {
      if (movingEnd) {
        args.end = args.start.addTime(duration.ticks);
      }
      else {
        args.start = args.end.addTime(-duration.ticks);
      }
    }
  }
  if (maxEnabled) {
    var duration = DayPilot.Duration.ofDays(max);
    if (args.duration > duration) {
      if (movingEnd) {
        args.end = args.start.addTime(duration.ticks);
      }
      else {
        args.start = args.end.addTime(-duration.ticks);
      }
    }
  }
},

Full Source Code

And this is the full source code of the example that limits the Scheduler time range selection duration:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>JavaScript Scheduler: Limit Time Range Selection (Min/Max)</title>

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

  <!-- DayPilot library -->
  <script src="js/daypilot/daypilot-all.min.js"></script>

  <style>
    .toolbar {
      margin: 10px 0px;
      font-size: 14px;
      display: flex;
      align-items: center;
    }

    .toolbar-item {
      display: flex;
      align-items: center;
      margin-left: 5px;
    }

    .toolbar-item select  {
      margin-left: 5px;
      font-size: 14px;
      padding: 3px;
    }
  </style>
</head>
<body>
<div class="header">
  <h1><a href='https://code.daypilot.org/44990/javascript-scheduler-limit-time-range-selection-min-max'>JavaScript Scheduler: Limit Time Range Selection (Min/Max)</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 class="toolbar">
    Time range selection limit:
    <div class="toolbar-item">
      min:
      <select id="min">
        <option value="0">any</option>
        <option value="1">1 day</option>
        <option value="2">2 days</option>
        <option value="3">3 days</option>
      </select>
    </div>

    <div class="toolbar-item">
      max:
      <select id="max">
        <option value="0">any</option>
        <option value="4">4 day</option>
        <option value="5">5 days</option>
        <option value="6">6 days</option>
      </select>
    </div>

  </div>

  <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(),
    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
        }));
      });
    },
    onTimeRangeSelecting: function(args) {
      var movingEnd = args.anchor === args.start;

      var min = parseInt(document.querySelector("#min").value, 10);
      var minEnabled = min !== 0;

      var max = parseInt(document.querySelector("#max").value, 10);
      var maxEnabled = max !== 0;

      if (minEnabled) {
        var duration = DayPilot.Duration.ofDays(min);
        if (args.duration < duration) {
          if (movingEnd) {
            args.end = args.start.addTime(duration.ticks);
          }
          else {
            args.start = args.end.addTime(-duration.ticks);
          }
        }
      }
      if (maxEnabled) {
        var duration = DayPilot.Duration.ofDays(max);
        if (args.duration > duration) {
          if (movingEnd) {
            args.end = args.start.addTime(duration.ticks);
          }
          else {
            args.start = args.end.addTime(-duration.ticks);
          }
        }
      }
    },
    treeEnabled: true,
  });
  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>