search envelope-o feed check
Home Unanswered Active Tags New Question
user comment-o

Scheduler: issue with resources spanning multiple rows

Asked by Julien
20 days ago.

I'm starting to use the Scheduler to display Events from multiple sources but the Events should not be displayed on a row depending on their source (resource). In other words, the minimum number of rows must be used in order to display the Events, whatever their source is.

For example, if I have EventA that is 9:00-10:00 and EventB that is 10:00-11:00, they would appear on the same row, one after the other (there would be only one row only in the Scheduler). But if both events are 9:00-10:00, then they would be one on top of the other and there would be two rows visible in the Scheduler.

To achieve that, it seems that using a single "resource" works well... I first hide the left bar:

rowHeaderWidth: 0
rowHeaderColumns: []
treeEnabled: false

and then I add all the Events to the same resource.

My issue is that it seems that when there are multiple rows required for that a single resource (both Events are 9:00-10:00 for example), that doesn't create cells everywhere on the second row!

So when I try to highlight "today" as such:

onBeforeCellRender: (args) => {
  if (args.cell.start.getDay() === DayPilot.Date.now().getDay()) {
    (args.cell as any).backColor = Colors.yellowVeryLight;
  }
}

there are parts of the second row that are not colored! (By the way, the backColor type is missing in Typescript on args.cell).

Any tips about this? Am I using the proper pattern to achieve what I need? If so, is there a way to properly color all rows for "today"?

Comment posted by Julien
20 days ago.

I have a workaround but I think it’s very ugly and may break with a future update:

.scheduler_default_matrix > div {
  height: 100%;
}

.scheduler_default_cell {
  height: 100% !important;
}

Then all the cells of my single resource’s row take 100% and the “today” color seems to work correctly.

On a side note, I have to admit I would also like to have horizontal lines for the grid (under each stacked Events), but that seems impossible since there is only one row in my current solution…

Comment posted by Julien
20 days ago.

Another kind of pseudo-solution I found to have working horizontal lines is to create multiple unused resources in the Scheduler, event if all Events are added to the firs one:

resources: [
  { name: '', id: 'singleResource' },
  { name: '', id: 'dummy2' },
  { name: '', id: 'dummy3' },
  { name: '', id: 'dummy4' },
],

(and all events use the “singleResource” resource.)

It seems that even when multiple events are stacked, their row height stays the same? It is surprising to me, but that actually helps my case since then horizontal lines are correct (here all Events are in the same “singleResource” resource):

Obviously, the issue with this workaround is that I have to compute how many “dummy” resources I need to add and this depends on if some Events are stacked and how deep. I' guess it’s possible to compute but doesn’t look fun!

Anyway, I’ll wait for your reply! Maybe I’m missing something obvious to achieve what I want. Thanks in advance!

Comment posted by Julien
19 days ago.

I have a workaround I’m going to use for now but I’m afraid it’s going to break someday:

eventHeight: 60,
rowMinHeight: 60,

And, CSS:

.scheduler_default_matrix > div {
  height: 100% !important;
}

.scheduler_default_cell {
  height: 100% !important;
  background: repeating-linear-gradient(
    to bottom,
    var(--color-grayLight) 0,
    var(--color-grayLight) 1px,
    transparent 1px,
    transparent 60px
  );
}

Using this, with all Events added to the same single resource, the “today” coloring works and “horizontal lines” are displayed.

I’m still open to a better solution though, even if I have to restart from scratch everything I did in the Scheduler.

Answer posted by Dan Letecky [DayPilot]
18 days ago.

These two things don’t seem to work correctly in your setup:

1. Coloring the cells

All cells in a column should be colored correctly with this event handler:

onBeforeCellRender: (args) => {
  if (args.cell.start.getDatePart() === DayPilot.Date.today()) {
    args.cell.properties.backColor = Colors.yellowVeryLight;
  }
}

There are minor changes in this example - but your code should work as well.

2. Row height

The row height should extend automatically to cover all concurrent events. This should be enough to add the horizontal lines:

.scheduler_default_cell {
  background: repeating-linear-gradient(
    to bottom,
    var(--color-grayLight) 0,
    var(--color-grayLight) 1px,
    transparent 1px,
    transparent 60px
  );
}
Comment posted by Dan Letecky [DayPilot]
18 days ago.

I’m posting a sample that works fine:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>test-scheduler-row-lines</title>

  <style type="text/css">
    p, body, td, input, select, button { font-family: -apple-system,system-ui,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif; font-size: 14px; }
    body { padding: 0px; margin: 0px; background-color: #ffffff; }
    a { color: #1155a3; }
    .space { margin: 10px 0px 10px 0px; }
    .header { background: #003267; background: linear-gradient(to right, #011329 0%,#00639e 44%,#011329 100%); padding:20px 10px; color: white; box-shadow: 0px 0px 10px 5px rgba(0,0,0,0.75); }
    .header a { color: white; }
    .header h1 a { text-decoration: none; }
    .header h1 { padding: 0px; margin: 0px; }
    .main { padding: 10px; margin-top: 10px; }
    .generated { color: #999; }
    .generated a { color: #999; }
  </style>

  <!-- DayPilot library -->
  <script src="js/daypilot/daypilot-all.min.js"></script>
</head>
<body>
<div class="header">
  <h1>test-scheduler-row-lines</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>

<style>
  .scheduler_default_cell {
    background: repeating-linear-gradient(
      to bottom,
      #e0e0e0 0,
      #e0e0e0 1px,
      transparent 1px,
      transparent 60px
    );
  }
</style>

<script>
  const dp = new DayPilot.Scheduler("dp", {
    timeHeaders: [{"groupBy":"Month"},{"groupBy":"Day","format":"d"}, {groupBy: "Hour", format: "hh:mm"}],
    scale: "Hour",
    days: DayPilot.Date.today().daysInMonth(),
    startDate: DayPilot.Date.today().firstDayOfMonth(),
    onTimeRangeSelected: async (args) => {
      const scheduler = args.control;
      const modal = await DayPilot.Modal.prompt("Create a new event:", "Event 1");
      scheduler.clearSelection();
      if (modal.canceled) { return; }
      scheduler.events.add({
        start: args.start,
        end: args.end,
        id: DayPilot.guid(),
        resource: args.resource,
        text: modal.result
      });
    },
    eventHeight: 60,
    rowHeaderWidth: 0,
    rowHeaderWidthAutoFit: false,
    onBeforeCellRender: (args) => {
      if (args.cell.start.getDatePart() === DayPilot.Date.today()) {
        // light yellow
        args.cell.properties.backColor = "#ffffe0";
      }
    }
  });
  dp.init();

  const app = {
    init() {
      const resources = [
        {name: "Resource 1", id: "R1"},
      ];
      const events = [
        {
          start: DayPilot.Date.today().addHours(10),
          end: DayPilot.Date.today().addHours(12),
          id: DayPilot.guid(),
          resource: "R1",
          text: "Event 1"
        },
        {
          start: DayPilot.Date.today().addHours(11),
          end: DayPilot.Date.today().addHours(13),
          id: DayPilot.guid(),
          resource: "R1",
          text: "Event 2"
        }
      ];

      dp.update({
        resources,
        events,
        scrollTo: DayPilot.Date.today().addHours(8)
      });
    }
  };
  app.init();
</script>

</body>
</html>
Comment posted by Julien
18 days ago.

I have to admit that I’m unable to reproduce the bug I had where there were some missing “today” colored zones (I though there were missing cells, but I guess there were rather cells that did not take the full 100% height for some reason)! I know I’m not crazy though, you can even see it on the first screenshot I posted.

But I think my height: 100% !important; fixes are still required. Add this to your example:

CSS:

.main {
  height: 300px;
}

(and remove the <div class="generated"> div maybe).

And, on the Scheduler:

heightSpec: 'Parent100Pct',


Then the cells (and the grid) do not reach the bottom (which is what I want).

Thanks for the help!

Comment posted by Julien
17 days ago.

For the records, this CSS is also required in my current workaround (so the vertical lines reach the bottom):

.scheduler_default_matrix_vertical_line {
  background-color: var(--color-grayLight);
  height: 100% !important;
}

Comment posted by Dan Letecky [DayPilot]
17 days ago.

Thanks for the update.

Yes, in this case your workaround is necessary. With heightSpec: 'Parent100Pct', the Scheduler height is set to fill the parent. But it doesn’t affect the row height which is still derived from event height.

Comment posted by Julien
17 days ago.

As long as you tell me updates won’t break this workaround in the future, I’m happy! ;-)

Thanks again for the help Dan.

Comment posted by Dan Letecky [DayPilot]
17 days ago.

Of course this is not guaranteed, but even if it changes I believe you will be able to update the CSS to fix it. ;-)

But I don’t expect the cell layout to change in the near future.

New Reply
This reply is
Attachments:
or drop files here
Your name (optional):