Recurrence
Build recurring events in dash-mui-scheduler with EventCalendarPremium using RRULE strings, RRULE objects and exception dates.
---
.. llms_copy::Recurrence
.. toc::
Recurrence (Premium)
Recurring events are a Premium feature. Use dms.EventCalendarPremium instead of dms.EventCalendar — it is identical to the Community calendar but adds a recurrence engine, a Recurrence tab in the edit dialog, and two new per-event keys: rrule and exDates.
.. admonition::Premium :color: yellow
EventCalendarPremium requires a MUI X Premium license key. Pass it via licenseKey=os.environ.get("MUI_X_LICENSE_KEY", ""). Without a valid key the calendar still renders and is fully interactive, but a MUI watermark is shown over it. That is expected — supply a real key to remove it.
The data boundary is unchanged from the Community calendar. events is a list of plain dicts and is both input and output: the component writes the full array back on every create, move, resize or delete. Dates are ISO strings (for example "2024-01-15T10:00:00" for wall time, or a trailing Z for UTC), never Python datetime objects. Recurring series are stored as a *single* event dict carrying an rrule; the calendar expands it into occurrences for display only.
Recurrence as an RRULE string
The simplest form sets event["rrule"] to an RFC-5545 RRULE string. The event below repeats every week on Monday, Wednesday and Friday:
``text FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,WE,FR ``
FREQ is one of DAILY, WEEKLY, MONTHLY, YEARLY. BYDAY codes are MO TU WE TH FR SA SU (for monthly rules you may prefix an ordinal, e.g. 2TU = second Tuesday, -1FR = last Friday). You can also add COUNT, UNTIL (an ISO string), BYMONTHDAY (1–31) and BYMONTH (1–12).
.. exec::docs.recurrence.recurrence_string
```python
File: docs/recurrence/recurrence_string.py
import os
from dash import Input, Output, callback import dash_mantine_components as dmc import dash_mui_scheduler as dms
Premium events may carry an rrule. The RRULE string form follows RFC-5545:
this event recurs every week on Monday, Wednesday and Friday at 10:00.
events = [ { "id": "standup", "title": "Team Standup", "start": "2024-01-15T10:00:00", "end": "2024-01-15T10:30:00", "color": "blue", "rrule": "FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,WE,FR", }, { "id": "review", "title": "Sprint Review", "start": "2024-01-19T15:00:00", "end": "2024-01-19T16:00:00", "color": "purple", }, ]
component = dmc.Stack( [ dms.EventCalendarPremium( id="recurrence-string-cal", licenseKey=os.environ.get("MUI_X_LICENSE_KEY", ""), events=events, defaultView="week", defaultVisibleDate="2024-01-15", height=600, ), dmc.Text("Last action:", fw=600, size="sm"), dmc.Code(id="recurrence-string-action", block=True), ], gap="sm", )
@callback( Output("recurrence-string-action", "children"), Input("recurrence-string-cal", "lastAction"), ) def show_action(last_action): if not last_action: return "No action yet — drag, create, resize or delete an occurrence." return f"{last_action.get('type')} @ {last_action.get('event_timestamp')}" ```
Recurrence as an object + exception dates
Instead of a string, rrule may be an object. This is convenient when you are building the rule programmatically:
``python {"freq": "WEEKLY", "interval": 1, "byDay": ["MO", "WE", "FR"], "count": 10} ``
The keys mirror the RRULE parts: freq, interval, byDay, byMonthDay, byMonth, count and until. To remove individual occurrences from a series without breaking the rule, add exDates — a list of ISO strings naming the start times to skip:
``python "exDates": ["2024-01-17T08:00:00", "2024-01-19T08:00:00"] ``
The example below recurs every weekday for ten occurrences, with two dates excluded. Note that even though the calendar shows many occurrences, the events output still contains a single definition dict.
.. exec::docs.recurrence.recurrence_object
```python
File: docs/recurrence/recurrence_object.py
import os
from dash import Input, Output, callback import dash_mantine_components as dmc import dash_mui_scheduler as dms
rrule may also be an object instead of a string. Here the event recurs
every weekday morning for a total of 10 occurrences, but two specific
dates are removed from the series via exDates (ISO strings).
events = [ { "id": "yoga", "title": "Morning Yoga", "start": "2024-01-15T08:00:00", "end": "2024-01-15T08:45:00", "color": "green", "rrule": { "freq": "WEEKLY", "interval": 1, "byDay": ["MO", "TU", "WE", "TH", "FR"], "count": 10, }, "exDates": [ "2024-01-17T08:00:00", "2024-01-19T08:00:00", ], }, ]
component = dmc.Stack( [ dms.EventCalendarPremium( id="recurrence-object-cal", licenseKey=os.environ.get("MUI_X_LICENSE_KEY", ""), events=events, defaultView="week", defaultVisibleDate="2024-01-15", height=600, ), dmc.Text("Occurrence count in events output:", fw=600, size="sm"), dmc.Code(id="recurrence-object-count", block=True), ], gap="sm", )
@callback( Output("recurrence-object-count", "children"), Input("recurrence-object-cal", "events"), ) def show_count(events_out): # The component writes the full event array back on every edit. The # recurring definition stays a single dict with rrule/exDates; # the UI expands it into occurrences for display only. return f"{len(events_out or [])} stored event definition(s)" ```
Reading edits back
As with the Community calendar, you do not need a callback for the calendar to be interactive — drags, creates and deletes round-trip through Dash on their own. Add a callback only to *display* outputs. The lastAction output is {type, event, event_timestamp}, where type is one of create, update, delete, move, resize or change. The first example above wires lastAction into a code block so you can watch edits as they happen.
EventCalendarPremium props
EventCalendarPremium accepts every EventCalendar prop plus licenseKey, and its events may include rrule and exDates.
.. kwargs::dash_mui_scheduler.EventCalendarPremium
---
*Source: /recurrence*
Note for AI agents: This is the static, prerendered view of an interactive Dash application served because we detected a non-JS user agent. Full prose docs:
- /recurrence/llms.txt — LLM-friendly documentation
- /sitemap.xml
- /robots.txt