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 using an HTTP request

See also the React Scheduler Component Tutorial which shows how to start using the React Scheduler component in your application.

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.

Static Callout Content Defined as HTML

react scheduler bubble callout static html

The easiest approach is to define the callout content using the 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: "2022-10-02T00:00:00",
    end: "2022-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.schedulerRef = React.createRef();

    this.state = {
      timeHeaders: [{groupBy:"Month"},{groupBy:"Day",format:"d"}],
      scale: "Day",
      days: 31,
      startDate: "2022-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: "2022-10-02T00:00:00",
          end: "2022-10-05T00:00:00",
          resource: "B",
          bubbleHtml: "Static 'Event 1' details specified using event <b>data object</b>."
        },
        {
          id: 2,
          text: "Event 2",
          start: "2022-10-03T00:00:00",
          end: "2022-10-10T00:00:00",
          resource: "D",
          barColor: "#38761d",
          barBackColor: "#93c47d"
        },
      ]
    });

  }

  get scheduler() {
    return this.schedulerRef.current.control;
  }

  render() {
    return (
      <div>
        <DayPilotScheduler
          {...this.state}
          ref={this.schedulerRef}
        />
      </div>
    );
  }
}

export default Scheduler;

Dynamic Callout Loaded from the Server Side

react scheduler bubble callout dynamic html

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) {
      const 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 snippet uses DayPilot.Http.get() to load the data:

bubble: new DayPilot.Bubble({
  onLoad: async (args) => {
    args.async = true;

    const {data} = await DayPilot.Http.get(`/bubble/${args.source.data.id}`);
    args.html = 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.schedulerRef = React.createRef();

    this.state = {
      timeHeaders: [{groupBy:"Month"},{groupBy:"Day",format:"d"}],
      scale: "Day",
      days: 31,
      startDate: "2022-10-01",
      bubble: new DayPilot.Bubble({
        onLoad: async (args) => {
          args.async = true;

          const {data} = await DayPilot.Http.get(`/bubble/${args.source.data.id}`);
          args.html = 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: "2022-10-02T00:00:00",
          end: "2022-10-05T00:00:00",
          resource: "B",
          bubbleHtml: "Static 'Event 1' details specified using event <b>data object</b>."
        },
        {
          id: 2,
          text: "Event 2",
          start: "2022-10-03T00:00:00",
          end: "2022-10-10T00:00:00",
          resource: "D",
          barColor: "#38761d",
          barBackColor: "#93c47d"
        },
      ]
    });

  }

  get scheduler() {
    return this.schedulerRef.current.control;
  }

  render() {
    return (
      <div>
        <DayPilotScheduler
          {...this.state}
          ref={this.schedulerRef}
        />
      </div>
    );
  }

}

export default Scheduler;

Callout Defined using React JSX Component

react scheduler bubble callout jsx component

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 the onBeforeDomAdd event handler. Simply set the JSX to args.element property.

bubble: new DayPilot.Bubble({
  onBeforeDomAdd: (args) => {
      const 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.schedulerRef = React.createRef();

    this.state = {
      timeHeaders: [{groupBy:"Month"},{groupBy:"Day",format:"d"}],
      scale: "Day",
      days: 31,
      startDate: "2022-10-01",
      bubble: new DayPilot.Bubble({
        onBeforeDomAdd: (args) => {
            const 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: "2022-10-02T00:00:00",
          end: "2022-10-05T00:00:00",
          resource: "B",
          bubbleHtml: "Static 'Event 1' details specified using event <b>data object</b>."
        },
        {
          id: 2,
          text: "Event 2",
          start: "2022-10-03T00:00:00",
          end: "2022-10-10T00:00:00",
          resource: "D",
          barColor: "#38761d",
          barBackColor: "#93c47d"
        },
      ]
    });

  }

  get scheduler() {
    return this.schedulerRef.current.control;
  }

  render() {
    return (
      <div>
        <DayPilotScheduler
          {...this.state}
          ref={this.schedulerRef}
        />
      </div>
    );
  }

}

export default Scheduler;