# Editing > Create and edit events in dash-mui-scheduler — the edit dialog, event creation config, and read-only calendars or events. --- .. llms_copy::Editing .. toc:: ### Editing events `dms.EventCalendar` is interactive out of the box. With no callback at all, a user can create, drag, resize, and delete events — Dash's own `setProps` round-trip persists each change into the `events` prop. The component treats `events` as **both input and output**: on every create, move, resize, or delete it writes the *full new array* back. Dates inside `events` are always **ISO strings** (e.g. `"2024-01-15T10:00:00"` for wall time, or a trailing `Z` for UTC) — never Python `datetime` objects. Add a callback only when you want to *observe* what changed: read `events` for the new state, or read `lastAction` — an output-only dict shaped `{type, event, event_timestamp}` where `type` is one of `create`, `update`, `delete`, `move`, `resize`, or `change`. ### The edit dialog Clicking an existing event opens the built-in edit dialog where the title, time, color, and description can be changed; saving writes the updated event back into `events`. Interacting with an empty slot starts event creation (see below). You do not wire any of this up yourself — it is part of the component. .. admonition::Beta :color: blue The MUI X Scheduler is in beta. The edit dialog's exact fields and styling may change in future releases. The Dash data boundary described here (`events` in/out, `lastAction`, ISO strings) is stable. ### Configuring event creation The `eventCreation` prop controls how new events are drawn: - `eventCreation=True` (default) — creation is enabled with the default gesture. - `eventCreation=False` — creation is **disabled** entirely; users can still move or resize existing events (unless those are locked too). - `eventCreation={"interaction": "double-click", "duration": 45}` — an object where `interaction` is `"click"` or `"double-click"`, and `duration` is the new event's length in **minutes**. In the example below, double-clicking an empty slot creates a 45-minute event. The `lastAction` output is echoed underneath so you can see each change. .. exec::docs.editing.event_creation ```python # File: docs/editing/event_creation.py from dash import Input, Output, callback import dash_mantine_components as dmc import dash_mui_scheduler as dms # Dates are ISO strings (wall time, no "Z"). The component writes the # full new array back to `events` on every create / move / resize / delete. events = [ { "id": "kickoff", "title": "Project kickoff", "start": "2024-01-15T10:00:00", "end": "2024-01-15T11:30:00", "color": "indigo", }, { "id": "review", "title": "Design review", "start": "2024-01-17T14:00:00", "end": "2024-01-17T15:00:00", "color": "teal", }, ] component = dmc.Stack( [ dmc.Text( "Double-click an empty slot to create a 45-minute event. " "Existing events stay draggable and resizable.", size="sm", c="dimmed", ), dms.EventCalendar( id="editing-creation-cal", events=events, # interaction: 'click' | 'double-click'; duration is in minutes. eventCreation={"interaction": "double-click", "duration": 45}, defaultVisibleDate="2024-01-15", defaultView="week", height=600, ), dmc.Code(id="editing-creation-action", block=True), ], gap="sm", ) @callback( Output("editing-creation-action", "children"), Input("editing-creation-cal", "lastAction"), ) def show_action(last_action): if not last_action: return "No action yet — double-click an empty slot to create an event." event = last_action.get("event") or {} return f"{last_action.get('type')}: {event.get('title', '(none)')}" ``` ### Read-only: whole calendar vs. one event Locking works at two levels: - **Globally** — `readOnly=True` on the calendar disables all creating, moving, resizing, and deleting. The calendar becomes a pure display. - **Per event** — add `"readOnly": True` to a single event dict to freeze just that event while the rest of the calendar stays editable. The example shows both: a fully read-only calendar on the left, and an editable calendar on the right where only the red all-hands event is locked. .. exec::docs.editing.editing_readonly ```python # File: docs/editing/editing_readonly.py import dash_mantine_components as dmc import dash_mui_scheduler as dms # Even with readOnly=False, one event is locked via its own `readOnly` key. events = [ { "id": "standup", "title": "Daily standup", "start": "2024-01-15T09:00:00", "end": "2024-01-15T09:30:00", "color": "blue", }, { "id": "frozen", "title": "Locked: company all-hands (readOnly)", "start": "2024-01-16T13:00:00", "end": "2024-01-16T14:00:00", "color": "red", "readOnly": True, }, { "id": "demo", "title": "Sprint demo", "start": "2024-01-18T11:00:00", "end": "2024-01-18T12:00:00", "color": "green", }, ] component = dmc.Stack( [ dmc.Text( "Left: a fully read-only calendar (readOnly=True) — no create, move, " "resize, or delete. Right: an editable calendar where only the red " "all-hands event is locked via its per-event readOnly key.", size="sm", c="dimmed", ), dmc.SimpleGrid( cols={"base": 1, "md": 2}, spacing="md", children=[ dms.EventCalendar( id="editing-readonly-cal", events=events, readOnly=True, defaultVisibleDate="2024-01-15", defaultView="week", height=580, ), dms.EventCalendar( id="editing-perevent-cal", events=events, defaultVisibleDate="2024-01-15", defaultView="week", height=580, ), ], ), ], gap="sm", ) ``` .. admonition::Disabling creation only :color: green To keep events editable but stop new ones from being drawn, set `eventCreation=False` rather than `readOnly=True`. `readOnly` locks everything; `eventCreation=False` locks creation alone. ### EventCalendar props .. kwargs::dash_mui_scheduler.EventCalendar --- *Source: /editing*