All products

Calendar Operation

Let you admins see and manage model entries... directly on a calendar.

The Whole Fruit Manifesto

This package provides a dead-simple way to add a "Calendar" view to your Backpack CRUDs. Save many hours of time integrating FullCalendar, and benfit from the experience and best practices of the Backpack core team. Here are the key features:

Calendar View

  • Easily access a calendar representation of your CRUD entries by switching to the "Calendar" view.


  • Add calendar events when selecting a date or a date range.
  • Access event options like preview, edit, delete, when clicking on it.
  • Easily add more options to the event menu, to allow users to perform user-driven actions.


  • Seamlessly integrates with existing Backpack CRUDs, adding calendar functionality without significant code changes.
    You don't need to change your crud field names, you can simply map them to the calendar fields.


Calendar Operation for Backpack

Online demo:


  1. Install the package via Composer
composer require backpack/calendar-operation
  1. Add the operation to your EntityCrudController, by adding the CalendarOperation trait to your EntityCrudController. This will also add the Calendar button toggle to your List view:
class EntityCrudController extends CrudController
    use \Backpack\CRUD\app\Http\Controllers\Operations\ListOperation;
+   use \Backpack\CalendarOperation\CalendarOperation;
  1. Configure your calendar operation. These are the default settings for the calendar operation, use only if you want to change them.
public function setupCalendarOperation()
    // Set the initial view
    CRUD::setOperationSetting('initial-view', 'dayGridMonth');

    // Set the available views
    CRUD::setOperationSetting('views', ['dayGridMonth', 'timeGridWeek', 'timeGridDay']);

    // Are the calendar events editable?
    CRUD::setOperationSetting('editable', true);

    // Set the calendar default colors
    CRUD::setOperationSetting('background_color', '#3788d8');
    CRUD::setOperationSetting('text_color', '#ffffff');

    // CalendarOperation will inject a javascript into your create and 
    // update views to handle the date fields as we do on our demo.
    CRUD::setOperationSetting('with-javascript-widget', true);

Calendar operation uses the fields title, start, end, background_color, and text_color to display the events on the calendar. You don't need to follow this naming convention, you can map your fields to the calendar fields. Here is an example of how you'd map your fields to the calendar fields if you're using different names:

// in the EntityCrudController ...
protected function getCalendarFieldsMap(): array
    // Map your fields to the calendar fields.
    return [
        'title' => 'title',
        'start' => 'start',
        'end' => 'end',
        'background_color' => 'background_color',
        'text_color' => 'text_color',
        'all_day' => 'all_day',

    // you only need to map the fields that you use and are different:
    return [
        'title' => 'event_name',
        'start' => 'start_date',

If you're just creating the migrations for a new CRUD, we recommend you to use use following settings in order to avoid mapping the fields:

Schema::create('calendar', function (Blueprint $table) {
    $table->dateTime('end')->nullable(); // optional
    $table->string('background_color')->nullable(); // optional
    $table->string('text_color')->nullable(); // optional
    // ...


Edit calendar javascript options

Backpack sets some "opinionated" defaults for the calendar, but you can change them by calling setOperationSetting('javascript-configuration') on setupCalendarOperation().

public function setupCalendarOperation()
    CRUD::setOperationSetting('javascript-configuration', [
        // ... FullCalendar options
        'dayMaxEvents' => false, // by default backpack uses 5

Add/Remove menu items to the calendar event menu

Backpack ships with 3 default buttons stored inside the calendar.line-buttons setting. These are the default buttons:

  • Preview - redirects the user to the event show page
  • Edit - redirects the user to the event edit page
  • Delete - call the delete event endpoint

The access to those actions are the same as for the CRUD operations, so you can use the same access attribute to control the visibility of the buttons.

public function setupCalendarOperation()
    // if user is not admin, don't show any of the event buttons
        CRUD::denyAccess(['delete', 'update', 'show'])

    // to remove the default buttons, you can just clear the setting array:
    CRUD::setOperationSetting('line-buttons', []);

    // ... now add your custom buttons

If you want to add custom menu items to the calendar event menu, you can do so by calling addCalendarLineButton() on setupCalendarOperation().

    action: 'email',
    label: 'Send Email',
    group: 'send'
    url: fn($event) => backpack_url('send-email', ['email' => $event->email]), // $event is the model instance

As you can see, you can add a url to the button, and it will be used as the href attribute of the button. Using a closure we ensure that you have the $event instance available to build the URL.

access atribute in buttons also support a closure:

    access: fn($event) => backpack_user()->hasRole('admin'), // only show button for admins

Configure event colors

Apart from saving the event colors directly on the database, you can also use a closure to determine the color based on the event properties.

public function setupCalendarOperation()
CRUD::setOperationSetting('background_color', fn($event) => $event->active ? 'green' : 'red');

// same principle applies to text color
CRUD::setOperationSetting('text_color', fn($event) => $event->active ? 'white' : 'black');

Using Javascript to handle the menu items

Every time you click on a menu item, a menuClick event will be dispatched in Javascript, with the action and properties of the button. You can listen to this event and do whatever you want with it.

    action: 'alert',
    label: 'Javascript Event',
    group: 'alert',
    properties: [
        'message' => 'Alert message!',
document.getElementById('calendar').addEventListener('menuClick', e => {
  let { action, event, properties } = e.detail;
  if (action === "alert") alert(`Event ${} — ${properties.message}`);

This will trigger an alert with the message "Event 1 — Alert message!".


Please see the changelog file.


This is a first-party Backpack addon. If you're having any problems with it, please open a discussion in our community forum.


This is a closed-source package. For bug reports, feature requests and improvement proposals, please open a discussion in our community forum.


If you discover any security related issues, please email [email protected] instead of using the issue tracker.



This project was released under EULA, so you can install it on top of any Backpack & Laravel project. Please see the license file for more information.

Package Access

You don't currently have access to this package. To gain access, go ahead and purchase it. You'll get:

Next 12 months
  • download or install using Composer;
  • all updates (major, minor and patch);
After 12 months
  • can still access all versions and updates you paid;
  • can still install using Composer;
  • no new versions or updates;
Buy for 99 EUR 49 EUR