calendar active areas event

Active areas are interactive regions within calendar events that extend event functionality and provide visual cues to users. They can be customized with HTML and styles and can trigger various actions, such as opening context menus or displaying additional information.

Active areas are also supported in the open-source DayPilot Lite for JavaScript.

Creating Active Areas

You can use the onBeforeEventRender event handler to define one or more active areas for each event.

Example:

onBeforeEventRender: (args) => {
  args.data.areas = [
    {
      // ... active area properties
      onClick: (args) => {
        // ... custom action
      },
      width: 15,
      height: 15,
      top: 3,
      right: 3,
      cssClass: "custom_area_class",
      visibility: "Hover",
    },
  ];
},

Built-In Actions

Active areas can be associated with built-in actions. The available built-in actions include:

  1. Drag handle for moving the event: The active area can be used as a drag handle, allowing users to move the event within the calendar or scheduler by dragging and dropping it.

  2. Drag handle for resizing the event: The active area can be configured as a drag handle for resizing the event using drag and drop. Users can adjust either the start or end time of the event by dragging the respective active area.

  3. Display a context menu: The active area can be used to trigger a context menu, providing users with a list of context-specific actions or options.

  4. Show a bubble (callout) on hover: The active area can display a bubble (or callout) when the user hovers over it. This bubble can provide additional details about the event.

To configure these built-in actions, use the action property for an active area. The action property can have the following values: "Move", "ResizeStart", "ResizeEnd", "ContextMenu", and "Bubble".

See also event drag handles to see how to turn off the default drag handles.

Example:

onBeforeEventRender: (args) => {
  args.data.areas = [
    {
      action: "Move",
      left: 3,
      height: 15,
      top: 3,
      right: 3,
      cssClass: "event_action_move",
    },
    // ... other active area properties
  ];
},

Custom Actions

Custom actions can be implemented by utilizing the onClick event handler for active areas. The onClick event handler is provided with an args object, which contains the related DayPilot.Event object in the args.source property. This enables you to create custom actions tailored to your specific needs and requirements.

Here's an example of how to implement a custom action using the onClick event handler:

onBeforeEventRender: (args) => {
  args.data.areas = [
    {
      onClick: (args) => {
        // Custom action implementation
        const event = args.source;
        // Perform operations on the event object
      },
      // ... other active area properties
    },
  ];
},

The onClick event handler will also be fired for active areas with action is specified.

By default, the click event bubbles to the underlying event. To prevent that, use action: "None".

Icons in Active Areas

Icons can be added to active areas to provide visual cues and enhance the user experience. DayPilot supports three different methods for specifying icons in active areas: using the icon, symbol, or image property.

Font Icons

The icon property can be used to specify an icon using CSS classes, such as those provided by popular icon libraries like Font Awesome. To use the icon property, simply provide the appropriate CSS classes as a string.

Example:

icon: "fas fa-trash",

SVG Symbols

The symbol property allows you to specify an SVG icon by referencing the id of the SVG symbol element. This is useful when you want to use custom SVG icons in your active areas.

Example:

symbol: "#svg-custom-icon",

You can also use a SVG symbol from an external file.

Example:

symbol: "daypilot.svg#bubble",

Images

The image property enables you to specify an icon by providing a URL to an image file. This can be a local file or a remote image hosted on a server.

Example:

image: "https://example.com/path/to/icon.png",

By using any of these methods, you can customize the appearance of your active areas with icons that suit your application's design and functionality.

Position

The active area position can be defined using CSS-like properties:

  • top

  • bottom

  • left

  • right

  • width

  • height

In JavaScript, the vertical position specifier can be replaced with start and end property which accept DayPilot.Date values.

Visibility

The visibility property determines when the active areas are displayed within a DayPilot event. By default, if no visibility property is specified, the active area will always be visible. The property supports three different values:

  1. "Visible": The active area is always visible, regardless of user interaction. It will be displayed as a static part of the event.

  2. "Hover": The active area is visible only when the user hovers over the event with their mouse cursor. This can be useful for displaying contextual actions or information when the user shows interest in a specific event.

  3. "TouchVisible": The active area is visible on hover for desktop devices and always visible on touch devices. This provides a user experience that is adaptive to the type of device being used. On desktop devices, the active area becomes visible when the user hovers over the event with their mouse cursor. On touch devices, the active area is always visible, allowing users to interact with it easily.

To set the visibility property for an active area, include it in the area definition:

onBeforeEventRender: (args) => {
  args.data.areas = [
    {
      // ... other active area properties
      visibility: "Hover",
    },
  ];
},

Examples

Delete Icon as SVG Symbol

This example demonstrates how to display an SVG symbol in an active area. The active area will show an SVG icon representing a delete action. When the icon is clicked, the associated event is removed from the calendar.

To achieve this, we use the symbol property to define the SVG symbol for the active area.

onBeforeEventRender: (args) => {
  args.data.areas = [
    {
      onClick: (args) => {
        calendar.events.remove(args.source);
      },
      width: 15,
      height: 15,
      top: 3,
      right: 3,
      symbol: "#svg-delete-icon",
    },
  ];
},

In this example, we create an active area with the symbol property set to the value "svg-delete-icon". The SVG symbol with the ID "svg-delete-icon" should be defined in the HTML document, for example:

<svg style="display:none;">
  <symbol id="svg-delete-icon" viewBox="0 0 24 24">
    <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z"/>
  </symbol>
</svg>

The SVG symbol will be scaled automatically to fill the active area.

Using Font Awesome Icons in Active Areas

This example demonstrates how to use a Font Awesome icon in an active area. By including the Font Awesome library and setting the icon property to the appropriate CSS class, the active area will display the delete icon from Font Awesome. When the icon is clicked, the associated event will be removed from the calendar.

onBeforeEventRender: (args) => {
  args.data.areas = [
    {
      onClick: (args) => {
        calendar.events.remove(args.source);
      },
      width: 15,
      height: 15,
      top: 3,
      right: 3,
      icon: "fas fa-trash-alt",
    },
  ];
},

Using an Edit Icon to Open a Modal Dialog for Editing Event Details

This example demonstrates how to display an edit icon in an active area, which opens a DayPilot.Modal for editing event details when clicked. The modal dialog contains a form with fields for start time, end time, and text.

onBeforeEventRender: (args) => {
  args.data.areas = [
    {
      onClick: async (args) => {
        const form = [
          {name: "Start", id: "start", type: "datetime"},
          {name: "End", id: "end", type: "datetime"},
          {name: "Text", id: "text"},
        ];

        const data = {
          text: args.source.data.text,
          start: args.source.data.start,
          end: args.source.data.end,
        };

        const modal = await DayPilot.Modal.form(form, data);

        if (!modal.canceled) {
          const result = modal.result;
          calendar.events.update({...args.source.data, ...result});
        }
      },
      width: 15,
      height: 15,
      top: 3,
      right: 20,
      icon: "fas fa-edit",
    },
  ];
},

JavaScript

In JavaScript, the active areas can be defined using the onBeforeEventRender event handler. Use the areas property of the DayPilot.Event.data object that is accessible as args.data:

const calendar = new DayPilot.Calendar("dp", {
  onBeforeEventRender: (args) => {
    args.data.areas = [
      {
        onClick: (args) => {
          dp.events.remove(args.source);
        },
        width: 15,
        height: 15,
        top: 3,
        right: 3,
        cssClass: "event_action_delete",
      },
      {
        action: "ContextMenu",
        width: 15,
        height: 15,
        top: 3,
        right: 20,
        cssClass: "event_action_menu",
      },
    ];
  },
  // ...
});
calendar.init();

The example styles ("event_action_delete", "event_action_menu") are defined in demo/themes/areas.css stylesheet.

Demo

Tutorial

Angular Calendar

This example shows how to implement active areas in the Angular Calendar component. In this example, two active areas are created for each event:

  1. A delete icon, which removes the event when clicked.

  2. A context menu icon, which shows a context menu when clicked.

To achieve this, we create an Angular component for the DayPilot Calendar and define the onBeforeEventRender event handler within the calendarConfig object.

import { Component, ViewChild } from '@angular/core';
import { DayPilot, DayPilotCalendarComponent } from 'daypilot-pro-angular';

@Component({
  selector: 'app-calendar',
  template: `
    <div>
      <daypilot-calendar [config]="calendarConfig" #calendarRef></daypilot-calendar>
    </div>
  `,
})
export class CalendarComponent {
  @ViewChild("calendarRef")
  calendarRef!: DayPilotCalendarComponent;

  calendarConfig: DayPilot.CalendarConfig = {
    onBeforeEventRender: (args) => {
      args.data.areas = [
        {
          onClick: (args) => {
            this.calendarRef.control.events.remove(args.source);
          },
          width: 15,
          height: 15,
          top: 3,
          right: 3,
          cssClass: "event_action_delete",
        },
        {
          action: "ContextMenu",
          width: 15,
          height: 15,
          top: 3,
          right: 20,
          cssClass: "event_action_menu",
        },
      ];
    },
    // ...
  };
}

ASP.NET WebForms

The default visibility in ASP.NET WebForms is Hover.

Example

protected void DayPilotCalendar1_BeforeEventRender(object sender, BeforeEventRenderEventArgs e)
{
  e.CssClass = "calendar_white_event_withheader";

  e.Areas.Add(new Area().Right(3).Top(3).Width(15).Height(15).CssClass("event_action_delete").JavaScript("dpc1.eventDeleteCallBack(e);"));
  e.Areas.Add(new Area().Right(20).Top(3).Width(15).Height(15).CssClass("event_action_menu").JavaScript("dpc1.bubble.showEvent(e, true);"));
  e.Areas.Add(new Area().Left(0).Bottom(5).Right(0).Height(5).CssClass("event_action_bottomdrag").ResizeEnd());
  e.Areas.Add(new Area().Left(15).Top(1).Right(46).Height(11).CssClass("event_action_move").Move());
}

The example styles ("event_action_delete", "event_action_menu", "event_action_bottomdrag", "event_action_move") are defined in Themes/areas.css stylesheet.

Demo

ASP.NET MVC

protected override void OnBeforeEventRender(BeforeEventRenderArgs e)
{
  e.CssClass = "calendar_white_event_withheader";

  e.Areas.Add(new Area().Right(3).Top(3).Width(15).Height(15).CssClass("event_action_delete").JavaScript("dpc_areas.eventDeleteCallBack(e);"));
  e.Areas.Add(new Area().Right(20).Top(3).Width(15).Height(15).CssClass("event_action_menu").JavaScript("dpc_areas.bubble.showEvent(e, true);"));
  e.Areas.Add(new Area().Left(0).Bottom(5).Right(0).Height(5).CssClass("event_action_bottomdrag").ResizeEnd());
  e.Areas.Add(new Area().Left(15).Top(1).Right(46).Height(11).CssClass("event_action_move").Move());
}

The example styles ("event_action_delete", "event_action_menu", "event_action_bottomdrag", "event_action_move") are defined in Themes/areas.css stylesheet.

Demo