
The Scheduler component can display a callout/tooltip with additional information on event hover. This is useful when the event box is too small to display all important information.
The callout is implemented using the Bubble component. The DayPilot.Bubble object lets you define the appearance and behavior of the tooltip, such as the popup delay, animation, CSS theme. You can also use it to load the content on demand.
The bubble can also be used to display details for Scheduler cells, row headers, links, and event groups.
JavaScript Scheduler
In the JavaScript Scheduler component, you can configure the event bubble using the bubble property.
The Scheduler uses a default DayPilot.Bubble instance as the value of the bubble property. That means you don't have to define the bubble unless you want to override the default behavior.
Static Bubble HTML
You can define the bubble content using the bubbleHtml property of the event data object.
<div id="dp"></div>
<script>
const dp = new DayPilot.Scheduler("dp");
dp.events.list = [
{
start: "2022-03-25T00:00:00",
end: "2022-03-25T12:00:00",
id: "123",
resource: "A",
text: "Event",
bubbleHtml: "Testing bubble HTML"
}
];
// ...
dp.init();
</script>You can also define the HTML using the onBeforeEventRender event handler:
<div id="dp"></div>
<script>
const dp = new DayPilot.Scheduler("dp");
dp.events.list = [
{
start: "2022-03-25T00:00:00",
end: "2022-03-25T12:00:00",
id: "123",
resource: "A",
text: "Event"
}
];
dp.onBeforeEventRender = function(args) {
args.data.bubbleHtml = "Additional information for: " + DayPilot.Util.escapeHtml(args.data.text);
};
// ...
dp.init();
</script>Dynamic Bubble HTML
It is possible to create the bubble content on-demand, right before the bubble is displayed.
You can define the HTML content using the onLoad event handler of the DayPilot.Bubble object.
The
args.htmlproperty will be initialized with the static bubble HTML (if any) and you can override it as needed.By default, the args.html is resolved synchronously, right after the onLoad handler is fired. In order to load the HTML from the server, you can switch to an asynchronous mode.
The following example loads the Scheduler event bubble content dynamically from the server using an HTTP call.
// The endpoint returns trusted/sanitized HTML in {html: "..."}.
dp.bubble = new DayPilot.Bubble({
onLoad: async args => {
args.async = true;
try {
const {data} = await DayPilot.Http.get("/getBubble/" + encodeURIComponent(args.source.id()));
args.html = data.html;
} catch { args.html = "Could not load event details."; }
finally { args.loaded(); }
}
});
API: bubble.
The hover bubble below displays the event name and start date. Its onLoad callback escapes the name before combining it with HTML.
The framework examples use DayPilot Pro. For installation, see the Angular, React or Vue Scheduler guide.
Angular
Assign the bubble instance to config.bubble. Angular event templates customize the event box; this example supplies bubble content through args.html.
import {Component} from "@angular/core";
import {DayPilot, DayPilotModule} from "daypilot-pro-angular";
@Component({
selector: "app-scheduler-example",
standalone: true,
imports: [DayPilotModule],
template: `
<daypilot-scheduler [config]="config"></daypilot-scheduler>
`
})
export class SchedulerExampleComponent {
config: DayPilot.SchedulerConfig = {
startDate: "2026-11-01",
days: 30,
scale: "Day",
timeHeaders: [{groupBy: "Month"}, {groupBy: "Day", format: "d"}],
resources: [{id: "A", name: "Room A"}, {id: "B", name: "Room B"}],
events: [{id: 1, text: "Planning", resource: "A", start: "2026-11-03", end: "2026-11-06"}, {id: 2, text: "Delivery", resource: "B", start: "2026-11-08", end: "2026-11-11"}],
bubble: new DayPilot.Bubble({onLoad: args => { args.html = DayPilot.Util.escapeHtml(args.source.text()) + "<br>" + args.source.start().toString("d MMM yyyy"); }})
};
}

Angular Scheduler: Dynamic ToolTip
React
Pass the
DayPilot.Bubbleinstance as thebubbleprop. The callback returns an HTML string, so its text does not go through JSX escaping.import React from "react"; import {DayPilot, DayPilotScheduler} from "daypilot-pro-react"; export default function SchedulerExample() { return <div> <DayPilotScheduler startDate={"2026-11-01"} days={30} scale={"Day"} timeHeaders={[{groupBy: "Month"}, {groupBy: "Day", format: "d"}]} resources={[{id: "A", name: "Room A"}, {id: "B", name: "Room B"}]} events={[{id: 1, text: "Planning", resource: "A", start: "2026-11-03", end: "2026-11-06"}, {id: 2, text: "Delivery", resource: "B", start: "2026-11-08", end: "2026-11-11"}]} bubble={new DayPilot.Bubble({onLoad: args => { args.html = DayPilot.Util.escapeHtml(args.source.text()) + "<br>" + args.source.start().toString("d MMM yyyy"); }})} /> </div>; }
React Scheduler: Rendering JSX Component in Bubble
Vue
Create the bubble in
<script setup>and bind:bubble. The HTML is produced by the bubble callback rather than a Vue slot.<script setup> import {DayPilot, DayPilotScheduler} from "daypilot-pro-vue"; const startDate = "2026-11-01"; const days = 30; const scale = "Day"; const timeHeaders = [{groupBy: "Month"}, {groupBy: "Day", format: "d"}]; const resources = [{id: "A", name: "Room A"}, {id: "B", name: "Room B"}]; const events = [{id: 1, text: "Planning", resource: "A", start: "2026-11-03", end: "2026-11-06"}, {id: 2, text: "Delivery", resource: "B", start: "2026-11-08", end: "2026-11-11"}]; const bubble = new DayPilot.Bubble({onLoad: args => { args.html = DayPilot.Util.escapeHtml(args.source.text()) + "<br>" + args.source.start().toString("d MMM yyyy"); }}); </script> <template> <div> <DayPilotScheduler :startDate="startDate" :days="days" :scale="scale" :timeHeaders="timeHeaders" :resources="resources" :events="events" :bubble="bubble" /> </div> </template>ASP.NET WebForms
<DayPilot:DayPilotScheduler runat="server" id="DayPilotScheduler1" ... BubbleID = "DayPilotBubble1" /> <DayPilot:DayPilotBubble ID="DayPilotBubble1" runat="server" />Static bubble HTML
Static bubble HTML can be defined using e.BubbleHtml in BeforeEventRender event handler.
It's possible to specify the Bubble HTML content statically in BeforeEventRender event (and prevent dynamic AJAX call on popup). See also event customization.
protected void DayPilotScheduler1_BeforeEventRender(object sender, BeforeEventRenderEventArgs e) { e.BubbleHtml = (string) e.DataItem["detail"]; }Dynamic bubble HTML
If there is no static bubble HTML defined the bubble control will ask for it using RenderEventBubble event of the DayPilotBubble object.
.aspx
<DayPilot:DayPilotBubble ID="DayPilotBubble1" runat="server" OnRenderEventBubble="DayPilotBubble1_RenderEventBubble" />.aspx.cs
protected void DayPilotBubble1_RenderEventBubble(object sender, RenderEventBubbleEventArgs e) { e.InnerHTML = "<b>Event details</b><br />Here is the right place to show details about the event with ID: " + e.Value + ". This text is loaded dynamically from the server."; }ASP.NET MVC
The bubble object must be declared before it is used (Html.DayPilotBubble helper must be above the Html.DayPilotScheduler helper).
@Html.DayPilotBubble("bubble", new DayPilotBubbleConfig {}) @Html.DayPilotScheduler("dps", new DayPilotSchedulerConfig { BackendUrl = ResolveUrl("~/Scheduler/Backend"), EventBubble = "bubble", ... })Static Bubble HTML
Static bubble HTML can be defined in OnBeforeEventRender:
protected override void OnBeforeEventRender(BeforeEventRenderArgs e) { e.BubbleHtml = (string) e.DataItem["detail"]; }Dynamic Bubble HTML
If no static bubble HTML is specified, OnEventBubble event will be invoked (on DayPilotScheduler object).
protected override void OnEventBubble(EventBubbleArgs e) { e.BubbleHtml = "Event details for id: " + e.Id; }Availability
Availability of this feature in DayPilot editions:
Product Lite Pro DayPilot for JavaScript DayPilot for ASP.NET WebForms DayPilot for ASP.NET MVC DayPilot for Java
DayPilot