Overview

This tutorial explores different ways of displaying event details in the React Scheduler component.

  • The built-in Bubble component displays a callout on hover
  • You can define the Bubble content using HTML, JSX component or load the details from the server
  • The project includes a trial version of DayPilot Pro for JavaScript (see also 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.

Static Callout Content Defined as HTML

react-scheduler-bubble-callout-static-html.png

The easiest approach is to define the callout content using bubbleHtml property of the event data object. The default bubble object will detect the bubbleHtml value and use it to display the callout on hover.

events: [
  {
    id: 1,
    text: "Event 1",
    start: "2019-10-02T00:00:00",
    end: "2019-10-05T00:00:00",
    resource: "B",
    bubbleHtml: "Static 'Event 1' details specified using event <b>data object</b>."
  },
  // ...
]

Scheduler.js

import React, {Component} from 'react';
import {DayPilot, DayPilotScheduler} from "daypilot-pro-react";

class Scheduler extends Component {

  constructor(props) {
    super(props);

    this.state = {
      timeHeaders: [{groupBy:"Month"},{groupBy:"Day",format:"d"}],
      scale: "Day",
      days: 31,
      startDate: "2019-10-01",
    };
  }

  componentDidMount() {

    // load resource and event data
    this.setState({
      resources: [
        {name: "Resource A", id: "A"},
        {name: "Resource B", id: "B"},
        {name: "Resource C", id: "C"},
        {name: "Resource D", id: "D"},
        {name: "Resource E", id: "E"},
        {name: "Resource F", id: "F"},
        {name: "Resource G", id: "G"}
      ],
      events: [
        {
          id: 1,
          text: "Event 1",
          start: "2019-10-02T00:00:00",
          end: "2019-10-05T00:00:00",
          resource: "B",
          bubbleHtml: "Static 'Event 1' details specified using event <b>data object</b>."
        },
        {
          id: 2,
          text: "Event 2",
          start: "2019-10-03T00:00:00",
          end: "2019-10-10T00:00:00",
          resource: "D",
          barColor: "#38761d",
          barBackColor: "#93c47d"
        },
      ]
    });

  }

  render() {
    var {...config} = this.state;
    return (
      <div>
        <DayPilotScheduler
          {...config}
          ref={component => {
            this.scheduler = component && component.control;
          }}
        />
      </div>
    );
  }
}

export default Scheduler;

Dynamic Callout Loaded from the Server Side

react-scheduler-bubble-callout-dynamic-html.png

The bubble content can also be defined dynamically using DayPilot.Bubble.onLoad event handler. This is a good idea if the HTML can be easily generated from the event data on the client side. It will save bandwidth as the bubbleHtml value doesn't have to be sent for each event from the server side.

You can generate the HTML when the bubble is activated:

bubble: new DayPilot.Bubble({
  onLoad: function(args) {
    if (!args.html) {
      var e = args.source;
      args.html = "Dynamic bubble HTML:<br/>" + e.data.text;
    }
  },
}),

In some cases, you might want to load additional data from the server side. In that case, it's necessary to switch the loading to asynchronous mode using args.async in onLoad.

As soon as the data is available, you can use it to set args.html and call args.loaded() to notify the bubble object that the HTML has been provided. This snipper uses DayPilot.Http.ajax() to load the data:

bubble: new DayPilot.Bubble({
  onLoad: function(args) {
    args.async = true;
    DayPilot.Http.ajax({
      url: "/bubble/" + args.source.data.id,
      success: function(ajaxArgs) {
        args.html = ajaxArgs.data;
        args.loaded();
      }
    }).
  },
}),

Scheduler.js

import React, {Component} from 'react';
import {DayPilot, DayPilotScheduler} from "daypilot-pro-react";

class Scheduler extends Component {

  constructor(props) {
    super(props);

    this.state = {
      timeHeaders: [{groupBy:"Month"},{groupBy:"Day",format:"d"}],
      scale: "Day",
      days: 31,
      startDate: "2019-10-01",
      bubble: new DayPilot.Bubble({
        onLoad: function(args) {
          args.async = true;
          DayPilot.Http.ajax({
            url: "/bubble/" + args.source.data.id,
            success: function(ajaxArgs) {
              args.html = ajaxArgs.data;
              args.loaded();
            }
          }).
        },
      }),
    };
  }

  componentDidMount() {

    // load resource and event data
    this.setState({
      resources: [
        {name: "Resource A", id: "A"},
        {name: "Resource B", id: "B"},
        {name: "Resource C", id: "C"},
        {name: "Resource D", id: "D"},
        {name: "Resource E", id: "E"},
        {name: "Resource F", id: "F"},
        {name: "Resource G", id: "G"}
      ],
      events: [
        {
          id: 1,
          text: "Event 1",
          start: "2019-10-02T00:00:00",
          end: "2019-10-05T00:00:00",
          resource: "B",
          bubbleHtml: "Static 'Event 1' details specified using event <b>data object</b>."
        },
        {
          id: 2,
          text: "Event 2",
          start: "2019-10-03T00:00:00",
          end: "2019-10-10T00:00:00",
          resource: "D",
          barColor: "#38761d",
          barBackColor: "#93c47d"
        },
      ]
    });

  }

  render() {
    var {...config} = this.state;
    return (
      <div>
        <DayPilotScheduler
          {...config}
          ref={component => {
            this.scheduler = component && component.control;
          }}
        />
      </div>
    );
  }
}

export default Scheduler;

Callout Defined using React JSX Component

react-scheduler-bubble-callout-jsx-component.png

It may be inconvenient to create the bubble content by manually creating the HTML string. Fortunately, the callout content can be defined using React JSX.

This needs to be done in onBeforeDomAdd event handler. Simply set the JSX to args.element property.

bubble: new DayPilot.Bubble({
  onBeforeDomAdd: function(args) {
      let e = args.source;
      args.element = <div>JSX callout for Scheduler event:<br/> {e.data.text}</div>;
  }
}),

Scheduler.js

import React, {Component} from 'react';
import {DayPilot, DayPilotScheduler} from "daypilot-pro-react";

class Scheduler extends Component {

  constructor(props) {
    super(props);

    this.state = {
      timeHeaders: [{groupBy:"Month"},{groupBy:"Day",format:"d"}],
      scale: "Day",
      days: 31,
      startDate: "2019-10-01",
      bubble: new DayPilot.Bubble({
        onBeforeDomAdd: function(args) {
            let e = args.source;
            args.element = <div>JSX callout for Scheduler event:<br/> {e.data.text}</div>;
        }
      }),
    };
  }

  componentDidMount() {

    // load resource and event data
    this.setState({
      resources: [
        {name: "Resource A", id: "A"},
        {name: "Resource B", id: "B"},
        {name: "Resource C", id: "C"},
        {name: "Resource D", id: "D"},
        {name: "Resource E", id: "E"},
        {name: "Resource F", id: "F"},
        {name: "Resource G", id: "G"}
      ],
      events: [
        {
          id: 1,
          text: "Event 1",
          start: "2019-10-02T00:00:00",
          end: "2019-10-05T00:00:00",
          resource: "B",
          bubbleHtml: "Static 'Event 1' details specified using event <b>data object</b>."
        },
        {
          id: 2,
          text: "Event 2",
          start: "2019-10-03T00:00:00",
          end: "2019-10-10T00:00:00",
          resource: "D",
          barColor: "#38761d",
          barBackColor: "#93c47d"
        },
      ]
    });

  }

  render() {
    var {...config} = this.state;
    return (
      <div>
        <DayPilotScheduler
          {...config}
          ref={component => {
            this.scheduler = component && component.control;
          }}
        />
      </div>
    );
  }
}

export default Scheduler;