16

HTML5 Scheduler: Splitting an Event

 3 years ago
source link: https://code.daypilot.org/31275/html5-scheduler-splitting-an-event
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Split events in HTML5 Scheduler at a specified location using right-click context menu.
html5 scheduler event splitting tutorial
Downloads
JavaScript project with source code for download.
233 kB
Languages
JavaScript, HTML5

Features

  • Split Scheduler events at a specified location using a context menu

  • Optional snap-to-grid mode splits the event at the cell start

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.

HTML5 Scheduler Config

html5-scheduler-events-splitting-configuration.png

This is the starting configuration of HTML5/JavaScript Scheduler component generated using Scheduler UI Builder. In the next steps, we will extend it with the splitting functionality.

<div id="dp"></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(),
    // ...
  });
  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"},
  ];
  dp.events.list = [
    {
      text: "Event 1",
      start: DayPilot.Date.today().firstDayOfMonth().addDays(1),
      end: DayPilot.Date.today().firstDayOfMonth().addDays(6),
      resource: "R1",
      id: 1
    }
  ];
  dp.init();
</script>

HTML5 Scheduler: Current Mouse Position (in Pixels)

The current mouse position in pixels (relative to the Scheduler grid) is accessible using getCoords() method:

var position = dp.getCoords().x;

HTML5 Scheduler: Current Mouse Position (as Date/Time)

We can use getDate() method to convert the pixel position to date/time value:

var position = dp.getDate(dp.getCoords().x, true);

The second parameter specifies whether an exact position should be calculated. If you use false value it will return the start of the current grid cell.

var position = dp.getDate(dp.getCoords().x, false);

Splitting Events using Context Menu

html5-scheduler-event-splitting-context-menu-javascript.png

In this step, we will add a context menu that will let users split an event into two new events at a specified location:

html5-scheduler-event-splitting-after.png

The context menu only has a single item ("Split"). It calculates the current date/time position, updates the event with a new end and creates another event starting at this time point:

var dp = new DayPilot.Scheduler("dp", {
  // ...
  contextMenu: new DayPilot.Menu({
    onShow: function(args) {
      dp.contextMenu._x = dp.getCoords().x;
    },
    items: [
      {text: "Split", onClick: function(args) {
        var time = dp.getDate(dp.contextMenu._x, true);
        var e = args.source;
        var originalEnd = e.end();

        e.data.end = time;
        dp.events.update(e);

        var newE = {
          start: time,
          end: originalEnd,
          id: DayPilot.guid(),
          resource: e.resource(),
          text: e.text() + ", part 2"
        };

        dp.events.add(newE);
      }
      }
    ]
  })
});

Snap-To-Grid Mode

html5-scheduler-event-splitting-snap-to-grid.png

We will also add a "Snap-to-grid" checkbox which will activate the snap-to-grid mode of the Scheduler. When this option is checked, the event will be split at the start of the current grid cell:

html5-scheduler-event-splitting-snap-to-grid-after.png

Source code:

<div class="main">
  <div class="space">
    <label><input type="checkbox" id="snap"> Snap-to-grid</label>
  </div>
  <div id="dp"></div>
</div>

<script>
  var elements = {
    snap: document.getElementById("snap")
  };

  elements.snap.addEventListener("click", function(ev) {
    var enabled = elements.snap.checked;
    dp.useEventBoxes = enabled ? "Always" : "Never";
    dp.snapToGrid = enabled;
    dp.update();
  });

  var dp = new DayPilot.Scheduler("dp", {
    cellWidth: 40,
    timeHeaders: [{"groupBy":"Month"},{"groupBy":"Day","format":"d"}],
    scale: "Day",
    days: DayPilot.Date.today().daysInMonth(),
    startDate: DayPilot.Date.today().firstDayOfMonth(),
    eventHeight: 30,
    headerHeight: 30,
    useEventBoxes: elements.snap.checked ? "Always" : "Never",
    snapToGrid: elements.snap.checked,
    onTimeRangeSelected: function (args) {
      var dp = this;
      DayPilot.Modal.prompt("Create a new event:", "Event 1").then(function(modal) {
        dp.clearSelection();
        if (modal.canceled) { return; }
        dp.events.add({
          start: args.start,
          end: args.end,
          id: DayPilot.guid(),
          resource: args.resource,
          text: modal.result
        });
      });
    },
    contextMenu: new DayPilot.Menu({
      onShow: function(args) {
        dp.contextMenu._x = dp.getCoords().x;
      },
      items: [
        {text: "Split", onClick: function(args) {
          var time = dp.getDate(dp.contextMenu._x, !elements.snap.checked);
          var e = args.source;
          var originalEnd = e.end();

          e.data.end = time;
          dp.events.update(e);

          var newE = {
            start: time,
            end: originalEnd,
            id: DayPilot.guid(),
            resource: e.resource(),
            text: e.text() + ", part 2"
          };

          dp.events.add(newE);
        }
        }
      ]
    })
  });
  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"},
  ];
  dp.events.list = [
    {
      text: "Event 1",
      start: DayPilot.Date.today().firstDayOfMonth().addDays(1),
      end: DayPilot.Date.today().firstDayOfMonth().addDays(6),
      resource: "R1",
      id: 1
    }
  ];
  dp.init();
</script>
Share
Related Questions
onClick should be onclick.... (1 reply) asked by arthur konrath on Aug 9, 2018
example not working (1 reply) asked by arthur konrath on Aug 9, 2018
See all related questions [forums.daypilot.org]

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK