Air Calendar (Full Calendar)

Demo to preview the settings


The Air Calendar Plugin is a bubble plugin based on the FullCalendar.
A highly customizable calendar with several different views based on FullCalendar.
FullCalendar is the most powerful calendar and scheduler used by several companies and projects.
This plugin was developed in response to the several limitations of the default bubble calendar and addresses the three main concerns: Performance, Customization, and Feature set.It is a full-fledged calendar that you can even build your SAAS on ( uses the same library, FullCalendar, that this plugin is based on)
  • multiple views
  • custom views
  • full control of Look and Feel
  • internationalization (Locales and Timezones)
  • high performance
  • on-demand fetching:
  • drag-and-Drop and Resize
  • easy setup
  • drag to select
  • blocked dates/times
  • standard date representation
Image without caption

Key features include

*Multiple views: Weekly, Monthly, Yearly views in timed grids or agenda grids. There are 9 different views by default.
*Custom views: In addition to the default views, you can also create your own views (currently two). For example, you can decide to create a 3-day workday schedule view. There is also an option for the browser to remember the last view the user was on (like google calendar).
*Full control of Look and Feel: The calendar is super customizable and by default provides only the calendar gird allowing you to create your own buttons and layout for navigation. For example, you can place the next and previous buttons anywhere, user buttons or dropdowns (like google calendar) to switch views, etc. There are also several options to set event colors, border colors, calendar background, and text colors, etc.
*Internationalization (Locales and Timezones): The calendar supports different locales (languages) and all the timezones in the world. You can even let your users switch between different timezones dynamically. The calendar provides you with a list of all timezone names (ids) allowing you to create a dropdown with it. Same for locales.
*High performance: This plugin is based on the latest re-write(v4) of the FullCalendar library written completely in plain modern javascript removing all jquery dependencies. Also, the library files have been broken down into several small files instead of one huge file. All these make the calendar very lightweight and loads faster.
*On-demand fetching: Instead of loading all the calendar events at once causing huge delays like in other calendar plugins, Air Calendar allows you to fetch events that are only needed for the current view. The plugin exposes the current view's start and end dates which you can use to restrict the amount of data fetched from your database.
*Drag-and-Drop and Resize: You can easily drag-and-drop events and well resize them. It even has support for dragging events from one calendar to another (currently disabled).
*Easy setup: The calendar gives you full control over how to set up your database and how to connect to it. You can name your database fields whatever you want. You don't have to expose your data API. The plugin triggers events for when an event is added, dragged, resized and you use this to determine when and how you write event data to your database through whatever means you prefer.
*Drag to select: You can enable creating an event by dragging to select a time period. The plugin also has actions that allow you to select/unselect through workflow actions.
*Blocked dates/times: The plugin allows you to block all different kinds of periods. Users will not be able to drag-and-drop or resize events into blocked periods. Blocked periods are created just like normal events so there is no limitation on how to create the blocked periods. You can have blocked day ranges, in combination with single days in combination with single time periods and ranges.
*Standard date representation: The calendar uses the iCalendar standard for storing event dates. That is all end dates are exclusive. This allows you to easily import event data from other calendar systems as well as export your calendar data to other calendar systems. For more information on this see the documentation page.

Release Notes

Version 2.1.3

⚙️released on 09 April 2021
  • 🔥 update: FullCalendar library to latest (5.6.0) version
  • 😍 fix: split into two separate events when a single event is dragged from one date to another
  • 🤩 fix: error when “Enable Resource/Scheduler view” checked
  • 🤩 fix: dragging events only works when debug mode is active
  • 🤩 fix: debugger error "Recursion when evaluating property"
  • 🎉 update: day\month render in x-axis when resourceTimelineWeak and resourceTimelineMonth is selected

How to install

  1. Install the plugin from the plugin store
  1. Add the element, AirCalendar, to your page and resize it to your needs.
  1. At this point, if you preview your page you will see an empty calendar without any events and buttons.
By default when you add an AirCalendar element to a page, only the calendar grid is displayed. To add navigation buttons like Today, Day, Week, Month, Next, Prev, etc, you have to add buttons.

Creating an events table in the database

  1. Go to the Data tab in Bubble.
  1. Create a new Thing. You can give it any name you like, e.g. Appointment.
  1. At minimum AirCalendar requires and an Event start and end date field which is of type date. You can have other optional fields and any other fields you require for your application. Ideally, you should have the three fields in bold.
      • 1. Event start date - date (required)
      • 2.Event end date - date (required)
      • 3.All day - yes/no (optional)
      • 4.Event title - text (optional)
      • 5.Event background color - text (optional)
      • 6.Event border color - text (optional)
      • 7.Event text color - text (optional)
      • 8.Blocked - yes/no (optional)
      • 9.Type - text (optional)
Image without caption

How to add events to the calendar

To improve the speed of loading events into the calendar, Air Calendar fetches events on demand. This means instead of loading all the calendar events when the page loads, Air Calendar allows you to load just the events needed for a view.
To achieve this the Air Calendar exposes the current view and the current view start date and current view end dates. So you can pass these as constraints to the event's Do Search query.
For better performance (faster event load), use the calendar's view start date and view end date states to restrict events to only those needed for the current view.
Image without caption

Changing event type

Field "Type" in our table is a type of event display.
Image without caption
​Possible values:
  • 'auto' - in dayGrid, renders the event as a solid rectangle, if it is all-day or multi-day. If a timed event will render it with a dot. When in other views, will render normally.
  • 'block' (default) - in dayGrid, renders the event as a solid rectangle. When in other views, will render normally:
Image without caption
  • 'list-item' - in dayGrid, renders the event with a dot. When in other views, will render normally:
Image without caption
  • 'background' - Events that appear as background highlights:
'background' events, if it is not a full day, cannot be displayed in the dayGridView
Image without caption
  • 'inverse-background' - Like'background', but fills the reverse space.
Image without caption
  • 'none' - Won’t render the event at all.
Note: Ignore unselect ID field will prevent the current selection from being cleared (due to the unselectAuto option).
This option is useful if you have a “Create an event” form that shows up in response to the user making a selection. When the user clicks on this form, you probably don’t want to the current selection to go away. Thus, you should add a class to your form such as my-form, and set the Ignore unselect ID field to .my-form.
See the related link here: unselectCancel - Docs | FullCalendar

Plugin Actions

AirCalendar provides actions and states that allow you the freedom to design your calendar navigation the way you like. The following actions, triggers, and states are provided.
The following actions are provided.
  1. Go to Next view - Moves the calendar one step forward (by a month or week for example).
  1. Go to Prev view - Moves the calendar one step back (by a month or week for example).
  1. Go to Next year - Moves the calendar forward one year.
  1. Go to Prev year - Moves the calendar back one year.
  1. Go to Today - Moves the calendar to the current day
  1. Go to date - Moves the calendar to the supplied date.

Calendar views

Air Calendar provides 9 different views plus two custom views that you can define yourself. Below are the different views, actions, triggers, and states.

DayGrid view

A DayGrid view is a view with one or more columns, each representing a day. The pre-configured DayGrid views are dayGridDay and dayGridWeek.
dayGridDay: A view with one column listing the available events in the day. By default, it shows one day but you can create a custom view dayGridDay view to show any number of days. e.g. a 3-day dayGridDay. ​
Image without caption
dayGridWeek: A view with two or more columns each representing a day. By default, this will show a one-week view. But you can create a custom dayGridWeek view to show any number of weeks, e.g. a 2-week dayGridWeek.
Image without caption
dayGridMonth: This is a monthly view that displays the current month’s days, and usually a few days of the previous and next months, in a table-like format. There is no custom dayGridMonth view.
Image without caption

TimeGrid view

A TimeGrid view displays one or more horizontal days as well as an axis of time, usually midnight to midnight, on the vertical axis. The two predefined TimeGrid views are the timeGridWeek and timeGridDay views.
timeGridDay: A view that displays horizontal days with a time axis. You can create a custom timeGridDay view with a different number of days. ​
Image without caption
timeGridWeek: A view that displays horizontal days with a time axis. You can create a custom timeGridWeek view with a different number of weeks.​
Image without caption

List view

A list view displays events in a simple vertical list for a specific interval of time.
There are 4 preset list views: listDay, listWeek, listMonth, and listYear.
You can create a custom list view that displays a different number of days, weeks, months, or years.
Image without caption


  1. current view's name: The current view's name as text. Possible values are any one of the available views listed above. e.g. timeGridWeek. Note that this is case-sensitive (meaning the small letters and capital letters should be exactly as listed above)
  1. current view's title : Title text that is displayed at the top of the header (such as “September 2009” or “Sep 7 - 13 2009”).
  1. current view's activeStart date : A Date that is the first visible day. In month-view, this value is often before the 1st day of the month, because most months do not begin on the first day-of-week.
  1. current view's activeEnd date : A Date that is the exclusive last visible day.
  1. current view's currentStart date : A Date is the start of the interval the view is trying to represent. For example, in month view, this will be the first of the month. This value disregards hidden days. You can use this to restrict the number of events the calendar fetches.
  1. current view's currentEnd date :A Date is the exclusive end of the interval the view is trying to represent. For example, in month view, this will be the day after the last day of the month (because it is exclusive). This value disregards hidden days. You can use this to restrict the number of events the calendar fetches.


1. view changes: Triggered when a calendar's view changes.
Note: This will be triggered the first time a calendar page is loaded.


1. change view: Immediately switches the calendar to a different view.
This action can be supplied some properties depending on whether you're picking the view name statically from the available views or getting it dynamically from another element (e.g. a dropdown value).
2. Toggle Weekends : hide or show weekend without reloading calendar

Changing view statically

Static view name: The name of the new view to switch to. Date: If you’d like to navigate to a new date while simultaneously switching to a new view, you can specify a date parameter.
Image without caption

Changing view name dynamically

Get view name dynamically: Check this box if you want to get the name of the view to switch to dynamically. This can be used if you're getting the view name from say a dropdown. This case you will call this action in the dropdown value's change event.
Then you can get the dropdown value as Dynamic view name: The view name to switch two. Can be any one of the supported view names: timeGridDay, timeGridWeek, dayGridDay, dayGridWeek, dayGridMonth,listDay, listWeek, listMonth, listYear , customView1, customView2
Image without caption
Important: view names are case-sensitive. They must be specified exactly as specified above taking note of the lower and upper case.

Exclusive End date - AllDay events

Air Calendar is based on FullCalendar which uses exclusive end dates. Below is an explanation of what this means and how to set things up to work properly.
All end dates are exclusive. For example, if an all-day event ends on a Thursday, the end datewill be 00:00:00 on Friday. An event with the end date of 2018-09-03will appear to span through the 2nd of the month, but will end before the start of the 3rd of the month.
This behavior is more consistent with other API’s and formats, such as iCalendar.
These threads (#1,#2) have a lot of discussion and useful information on why exclusive dates are used for end dates of All day events.
Yes, it might be confusing for users. But remember computers understand things differently from humans.
For example, array indexes stars from 0 but humans count from 1. This means when dealing with arrays the indexes you display to your users will be different from what you use to perform your calculation. as a no-code platform makes life easy for its developer by counting from one but behind the scene, counting starts from 0.
So how do we make sure the users don't get confused?
Store end dates with exclusive times (most apps do this). Whenever you are about to display an all-day end date to the user, always subtract 1 day. Immediately after you accept an all-day end date input from the user, always add 1 before you store it. You can for example use Bubble's conditional to check if the event is an all day event and if yes subtract 1 day using the bubble function +(days): -1
Image without caption
When saving an All Day event, do the opposite by adding 1 day to the end date.

Current event

The current event is a very important state returned by the plugin. Below are details of the value.
  1. current event: This is the current bubble event that has been left-clicked, right-clicked or hovered. Its type is your calendar's event type. For example, if your calendar things are called Appointment, this value will be an Appointment.
Important: The following states/values are for the advanced user, example to help create context menu popup when an event is clicked or disable the default right-click context menu like google calendar. Don't use them if you're not familiar with the concepts. For most users, you shouldn't care about these.
  1. current event id attribute: The HTML ID attribute of the current clicked event. You can use this for showing a context menu popup using some javascript or some plugin.
  1. current event's rightclick pageX: The right-clicked horizontal coordinate (pageX) on an event.
  1. current event's rightclick pageY: The right-clicked vertical coordinate (pageY) on an event.

Event dragging and resizing

Here is described the triggers and actions for reacting to event drags and resize on the calendar.
Air Calendar doesn't automatically save dragged or resized events to the database. If your application allows dragging and resizing an event, you must add a workflow to update the event as explained below.
A unique feature of Air Calendar is that it doesn't automatically write changes in the calendar to the database. This allows you complete control on when and how to update your database.
The calendar provides the following states and events for updating an event in the database when it is modified on the calendar.


  1. modified event: the current event that has just been dragged or resized. It's type is your calendar's event type so you can access all the thing's fields
  1. modified event start: the start date of the modified event. This is a date type.
  1. modified event end : the end date of the modified event. This is a date type.
  1. modified all day: the new All-day field of the modified event. This a yes/no field. Currently, for some technical reasons, you can't drag an event from the All Day field to a timed region and vice versa so you don't need to use this field. You can get the all-day field from the event object itself. This value will become important when we enable the ability to drag events from All day region to time region or vice versa. So for you get the all-day field from the modified event thing itself.


  1. event is modified: This is triggered when an event on the calendar is dragged or resized.

Example workflow for updating an event when modified

  1. In the workflow tab add a new event and select AirCalendar event is modified.
Image without caption
2. Add a make a change to a thing action and in the Thing to change field select AirCalendar's modified event. Then for your event's start and end dates select AirCalendar's modified event start and AirCalendar's modified event end states respectively.
Image without caption

Event selecting

Air Calendar supports dynamic selection. User can click and drag to select a period of time to create an event. Below are the actions, triggers and states associated with selection.
Image without caption
To enable selection check the element property Event and days are selectable . Once enabled the following states, triggers and actions can be used.
Image without caption
When selection is enabled, clicking on a cell triggers the selection is made event as well as the date clicked event. If you don't want your users to click to select but instead click and drag to select, you have to change the element property, Select min distance to a value greater than 0.
Image without caption


  1. selected start date : The start date/time of the current selection. The value is a date.
  1. selected end date : The end date/time of the current selection. The value is a date.
  1. selection all day? : This is a boolean (yes/no) that tells you if the selection occurred in an All Day (yes) cell or a timed cell (no).
selected cells id attribute : This is the HTML element ID attribute of the selected region. You can use this as a reference to show a context menu. NB: This is an advanced property so only use it if you understand what you're doing.


  1. selection is made : Triggered when a selection has been made. Once this event occurs the states defined above are available and can be used in a workflow. For example, you may want to show a popup with the selected dates to create an event in your database.


Air calendar allows you to programmatically select or cancel a selection. This is useful if after the user has selected an area decides to change the start or end time (see a demo at the start of this page). The following actions are provided.
1. Select: Selects a period of time on the calendar. It has the following fields
  • start date - Start date of the selection. The value should be a date.
  • end date - End of the selection. Optional. Default slot value will be used. The value should be a date. This value is exclusive, meaning if you want your last full-day selection to be Thursday, then specify Friday
  • All day - Specify if selection should happen in the All Day slot. Optional. Default is false.
2. Unselect: Cancels the current selection. It doesn't have any fields.​

Event clicking and hovering

Here are described the triggers and actions for clicking on events and dates on the calendar.


See the current event​ states above.


1. event is clicked: Triggered when a calendar event is clicked.
2. date is clicked: Triggered when a calendar date is clicked.
3. calendars's event is right clicked: Triggered when an event is right-clicked. This is useful if you've disabled the default right-click context menu and want to show your own context menu when an event is right-clicked.
4. Blocked Event Clicked: Triggered when a blocked event is clicked.

Timezone feature

Required fields, actions and states


Owner's Timezone - this dropdown contains a list of timezones. The page owner must choose his own time zone so that the time difference between different time zones can be calculated.
Image without caption


Set Timezone - The incoming parameter is the ID (text) of the new time zone. Switches the timezone of the calendar to the selected one.
Image without caption
Reload Events - New action. Hides all events, and then displays again, updating all data (including calculating the time of the event in a new time zone).
Image without caption


timezone offset display seconds - This state stores information about the difference between the time zone of the owner of the calendar and the current time zone of the calendar. It is used to correctly display the event time when editing it, since by default the event is stored in the database in the owner's time zone.
timezone offset save seconds - This state stores information about the difference between the time zone of the owner of the calendar and the current time zone of the calendar. unlike the previous state in the sign, that is, it is the opposite (example: offset display = 120 => offset save = -120). Used for correct saving to the database. Changes the time of the added event from the user's time zone to the owner's time zone

How to use

Image without caption
Image without caption
Image without caption
Image without caption
Image without caption

Resources / Scheduler

Image without caption
Image without caption


Resource type - this field represents an App Type from your Data.
Image without caption
Required is 1 field for the title of the resource
Resource data source - List of your resources from data.
Event resource field - This field is needed for communication resources and events. In this field is saved id of the resource.
Res. id field - field from Data representing resource identifier
Resource title field - field from Data representing resource title. This title will be displayed in calendar
Image without caption
Resource label - Title of resource column​
Image without caption
Res. order field - field for ordering resources. it can be title or ID Order Res. ascending - yes/no. Order resource ascending


modified event's new resource - in this state is stored a new resource of modified event.
selected_resource - in this state is stored resource of a new event created by selection in the calendar.​

Get Events or Resources from API

In order to use a third-party API as events, a number of rules must be followed. The screenshots show examples of correct data from the endpoint. If your endpoint provides all the required fields, you can use it as a data source.
Image without caption
Image without caption


For resources, 2 fields of type text are required


If you are faced with a problem that the calendar does not load and gives errors related to time zones, try to put these lines in the application header.
<script src="//"></script>
Image without caption


Update 19-04-2021: Version - 2.6.0

Added a possibility to change the event display type. Fixed word-wrap in HTML titles. Now users have the possibility to change the view type of an event from four types:
  • block ( it seems to display type in older versions of the calendar),
  • background ( is using for "blocked" events on our demo page),
  • inverse-background (new view type. Like'background',but fills the reverse space)
  • list-item (new view type added in v5 of Fullcalendar and used by default ).
The default view is set to 'block' because this view was used in older versions. Type can be changed in the same way as the title or color of the event.

Update 22-04-2021: Version - 2.7.0

Fixed any issues after updating the library. Added possibility to import events from Google Calendar and possibility to change touch delay for mobile devices.
What was done:
🛠 fixed: colors changed in settings now work 🛠 fixed: information message in the left corner is removed 🛠 fixed: before the update, the color of the circle in the list view was taken by the color of the borders. now, if no border color is assigned to the event, the default color of the event will be used.
➕ added: possibility to import events from google calendar. Instruction on how to get API key and calendar id: ➕ added: possibility to change press delay for mobile devices.

Update 28-04-2021: Version - 2.8.0

HTML is customized to be as close as possible to the design from Seanhoots. Added getUTCFullYear error fix.
What was done:
🛠fixed: getUTCFullYear error when the Remember view checkbox is activated 🛠fixed: calendar design was customized as close as possible to the Seanhoots (old versions) 🛠fixed: removed outer borders from the week view ➕added: Google Calendar events functionality ➕added: the "Today" circle

Update 24-05-2021: - Version 2.12.0

Fixed plugin element settings
What was done:
🛠fixed: day header render
🛠fixed: error when the background color of the event is not changed
🛠fixed: displaying of event content then end time is not set

Update 03-06-2021 - Version 2.14.0

2.14.0: dayGridView rendering fix
What was done:
🛠fixed: dayGridView rendering

Update 09-06-2021 - Version 2.15.0

2.15.0: added timezone support
What was done:
➕ added timezone support. Added a field with the time zone of the page owner for the correct saving of events. It is needed to specify the page owner time zone in this filed in order to use this feature.
Image without caption
The "timezone offset display seconds" and "timezone offset save seconds" states the difference between the owner's time zone and the current calendar time zone.
"Timezone offset display seconds" - used for correct time display.
"Timezone offset save seconds" - used to save time correctly.
Image without caption
Image without caption
IMPORTANT: We strongly recommend making a backup of the database in order to avoid data loss while configuring the updated plugin functionality. It is also necessary to remove and then install the plugin element so that the latest update takes effect and no errors appear. Please be aware that removing the plugin element will impact the previous element settings (fields, checkboxes, etc.). Therefore, before reinstalling the plugin element please make sure you remember all the plugin element settings. :::

Update 12-07-2021: Version - 2.16.0

2.16.0: Added the possibility to use dynamic colors from DB.
➕ added possibility to use dynamic colors in related fields.
Image without caption
The colors in DB should be indicated in HEX format, for example #DB2F1F

Update 13-08-2021: Version - 2.18.0

2.18.0: Fixed: "not ready" error, military time issue, resource sorting. Added: event "blocked event clicked", action "show/hide weekends".
What was done:
🛠fixed: "not ready" error 🛠fixed: military time issue 🛠fixed: resource sorting
➕ added: event "blocked event clicked", ➕ added: action "show/hide weekends".

Update 29-08-21: Version - 2.19.0

2.19.0: Fix in resource ordering
🛠fixed: resource ordering

Update 01-10-21: Version - 2.21.0

2.21.0: Full Calendar updated to 5.9.0
⚒fixed: current timezone display. On the data switch, the hour position is kept. ⚒fixed: part of scripts are transferred to the global header.
➕ updated: Full Calendar library version updated to 5.9.0

Update 04-11-21: Version - 2.22.0​

⚒fixed: error in uploading header.​

Update 02-12-21: Version - 2.23.0​

⚒fixed: display time of "Now Indicator".​

Update 20-01-22: Version - 2.25.0​

➕ Added action to set the max number of displayed events
Image without caption

Update 14-02-22: Version - 2.26.0​

➕ Added posibility to change first day of the week and width of resource column
Image without caption
Image without caption

Update 07-07-22: Version - 2.29.0​

➕ Added possibility to activate displayed weekends separately
🛠️ Fixed displaying of current time indicator.

Update 09-08-22: Version 2.31.0.

🛠️ Removed “Hide time axis” field

Update 18-08-22: Version 2.32.0

➕ Added dynamic change option possibility

Update 28-09-22: Version 2.35.0

➕ Adapted to the new responsive engine

Update 03-10-22: Version 2.36.0

🛠️ Minor fixes

Update 16-10-22: Version 2.38.0

🛠️ Minor fixes

Update 23-10-22: Version 2.39.0

🛠️ Deprecated "eventResize”

Update 20-12-22: Version 2.41.0

🛠️ Fixed "Title has html content" option

Update 10-01-23: Version 2.42.0

🛠️ Minor fixes