The Scheduler time headers can be configured to display a custom number of rows, each with custom resolution.

Features

  • Custom time header formatting in DayPilot Pro JavaScript Scheduler
  • The default content is replaced with time-positioned elements to draw a customized timeline
  • Downloadable JavaScript/HTML5 project that includes a trial version of DayPilot Pro for JavaScript

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.

Basic Configuration

Example that displays two time headers rows grouped by month/day:

javascript-scheduler-time-header-month-day.png

dp.timeHeaders = [
  { groupBy: "Month" },
  { groupBy: "Day", format: "d" }
];
dp.scale = "Day";   // sets the grid cell size

You can use the "format" property to set custom format if the default value doesn't work well. See the available patterns in DayPilot.Date.toString() documentation.

Another example with time headers grouped by day/hour:

javascript-scheduler-time-header-day-hour.png

dp.timeHeaders = [
  { groupBy: "Day" },
  { groupBy: "Hour" }
];
dp.scale = "Hour";

For all options, see the documentation:

Custom Appearance

If the basic formatting isn't enough, you can use onBeforeTimeHeaderRender event handler to customize the time header.

It lets you set custom HTML, CSS and other properties for every time header cell. This example displays the hours in a more compact, lowercase format:

javascript-scheduler-time-header-day-hour-lowercase.png

dp.timeHeaders = [
    { groupBy: "Day" },
    { groupBy: "Hour" }
];
dp.scale = "Hour";
dp.onBeforeTimeHeaderRender = function(args) {
    if (args.header.level === 1) {
        args.header.html = args.header.start.toString("htt").toLowerCase();
    }
};

In addition to setting custom HTML and CSS, there is also another very powerful tool which lets you customize the time header by inserting custom objects at the specified locations (defined by pixels or time): time header active areas.

Let's insert a custom separator in each cell that will display a 30-minute mark:

javascript-scheduler-time-header-30-minute-mark.png

dp.timeHeaders = [
  { groupBy: "Day" },
  { groupBy: "Hour", height: 30 }
];
dp.scale = "Hour";
dp.onBeforeTimeHeaderRender = function(args) {
  if (args.header.level === 1) {
      args.header.html = args.header.start.toString("htt").toLowerCase();

      args.header.areas = [];
      args.header.areas.push({
          start: args.header.start.addMinutes(30),
          width: 1,
          top: 20,
          height: 10,
          backColor: "black"
      });
  }
};

We have slightly increased the second time header row using timeHeaders[x].height and inserted a new active area in 30-minute distance from the cell start.

We can use this approach to build a completely customized time header:

javascript-scheduler-time-header-custom.png

dp.timeHeaders = [
  { groupBy: "Day" },
  { groupBy: "Day", height: 30}
];
dp.scale = "Hour";
dp.onBeforeTimeHeaderRender = function(args) {
  if (args.header.level === 1) {
      args.header.areas = [];
      for (var i = 1; i < 24; i++) {
          var point1 = args.header.start.addHours(i);
          args.header.areas.push({
              start: point1.addMinutes(-1),
              width: 1,
              top: 20,
              height: 10,
              backColor: "black"
          });
          args.header.areas.push({
              start: point1.addMinutes(-30),
              end: point1.addMinutes(30),
              top: 0,
              height: 10,
              html: point1.toString("htt").toLowerCase()
          });
      }
      for (var i = 0; i < 24; i++) {
          var point1 = args.header.start.addHours(i);
          args.header.areas.push({
              start: point1.addMinutes(15),
              width: 1,
              top: 20,
              height: 5,
              backColor: "black"
          });
          args.header.areas.push({
              start: point1.addMinutes(30),
              width: 1,
              top: 20,
              height: 10,
              backColor: "black"
          });
          args.header.areas.push({
              start: point1.addMinutes(45),
              width: 1,
              top: 20,
              height: 5,
              backColor: "black"
          });
      }
      args.header.areas.push({
          left: 0,
          right: 0,
          top:20,
          height: 1,
          backColor: "black"
      });
      args.header.html = "";
  }
};

Note that we have used "Day" group size in both time header rows:

dp.timeHeaders = [
  { groupBy: "Day" },
  { groupBy: "Day", height: 30}
];

We have completely disabled the original HTML:

dp.onBeforeTimeHeaderRender = function(args) {
  if (args.header.level === 1) {

      // ...

      args.header.html = "";
  }
};

And replaced it with custom-positioned elements, drawing a completely new timeline.