---
title: Calendar Control
aliases: [CalendarControl, calendar, weekly view, daily view, drag-and-drop calendar]
sources: [sources/sessions/2026-04-21-calendar-control-deep-dive.md]
last_updated: 2026-04-21
status: draft
---

# Calendar Control

The modeler provides a **native CalendarControl** — a first-class UI element with built-in weekly/daily views, drag-and-drop reschedule, resize, sidebar drop, and context menu support. It is not a custom component.

## CalendarControl XML

```xml
<CalendarControl name="WeeklyCalendar"
    dataSource="ProcessContext::VisitList.items[]"
    dateFromAttribute="plannedStartDate"
    dateThruAttribute="plannedEndDate"
    timeFromAttribute="plannedStartTime"
    timeThruAttribute="plannedEndTime"
    allDayAttribute="allDay"
    backgroundColorAttribute="color"
    firstLine="visitName"
    secondLine="customerName">
  <Bindings>
    <Binding target="DateRangeStartDate" binding="ProcessContext::CurrentDate" bindingMode="ONE_WAY" />
  </Bindings>
  <Settings />
  <Items name="Items" itemPattern="CalendarItems">
    <!-- Item bindings, ContextMenu go here -->
  </Items>
  <Events>
    <!-- Calendar events go here -->
  </Events>
</CalendarControl>
```

| Attribute                                 | Purpose                                                          |
| ----------------------------------------- | ---------------------------------------------------------------- |
| `dataSource`                              | LO providing calendar items — **must include `.items[]` suffix** |
| `dateFromAttribute` / `dateThruAttribute` | LI property names for start/end dates                            |
| `timeFromAttribute` / `timeThruAttribute` | LI property names for start/end times                            |
| `allDayAttribute`                         | LI property name for all-day flag (DomBool)                      |
| `backgroundColorAttribute`                | LI property name for item color (DomRgbColor)                    |
| `firstLine` / `secondLine`                | LI property names for display text                               |

### Build-Critical: Child Element Order

The CalendarControl child elements must appear in this **exact order** — the schema enforces it:

```
CalendarControl
  ├── Bindings     (required — at minimum DateRangeStartDate)
  ├── Settings     (required — can be empty: <Settings />)
  ├── Items        (required — name="Items" itemPattern="CalendarItems")
  └── Events       (required — calendar event handlers)
```

`<Settings />` is required even when empty. Omitting it or placing `<Items>` before `<Bindings>` causes build error `00000001`.

### Build-Critical: DateRangeStartDate Must Be Initialized

The `Bindings` section must include a `DateRangeStartDate` binding that resolves to a valid date at render time. If the bound ProcessContext variable is null, the FullCalendar component crashes at runtime with:

```
Uncaught TypeError: Cannot read properties of null (reading 'getUTCFullYear')
    at GregorianCalendarSystem.getMarkerYear
    at DateEnv.startOfWeek
```

**Fix:** Initialize the date variable in EntryActions before the VIEW action:

```xml
<EntryActions>
  <!-- REQUIRED: CalendarControl crashes if DateRangeStartDate is null -->
  <Action name="InitStartDate" actionType="LOGIC" call="Utils.createAnsiDateToday">
    <Return name="ProcessContext::CurrentWeeklyViewStartDate" />
  </Action>
</EntryActions>
```

If the calendar is opened from another process that passes a date, use `Utils.identity` to copy the input parameter instead:

```xml
<Action name="InitStartDate" actionType="LOGIC" call="Utils.identity">
  <Parameters>
    <Input name="view" value="ProcessContext::inputDate" />
  </Parameters>
  <Return name="ProcessContext::CurrentWeeklyViewStartDate" />
</Action>
```

## Events

### Drag-and-Drop Events

```xml
<!-- Drag item to new date/time slot -->
<CalendarItemMoveEvent event="itemMove">
  <Params>
    <Param name="pKey" value=".pKey" />
    <Param name="plannedStartDate" value=".plannedStartDate" />
    <Param name="plannedEndDate" value=".plannedEndDate" />
    <Param name="plannedStartTime" value=".plannedStartTime" />
    <Param name="plannedEndTime" value=".plannedEndTime" />
  </Params>
</CalendarItemMoveEvent>

<!-- Resize item duration by dragging edges -->
<CalendarItemResizeEvent event="itemResize">
  <Params>
    <Param name="pKey" value=".pKey" />
    <Param name="plannedStartDate" value=".plannedStartDate" />
    <Param name="plannedEndDate" value=".plannedEndDate" />
    <Param name="plannedStartTime" value=".plannedStartTime" />
    <Param name="plannedEndTime" value=".plannedEndTime" />
  </Params>
</CalendarItemResizeEvent>

<!-- Drop from sidebar onto calendar -->
<CalendarDropEvent event="itemDropped">
  <Params>
    <Param name="pKey" value=".pKey" />
    <Param name="jobListPKey" value=".jobListPKey" />
    <Param name="customerPKey" value=".customerPKey" />
  </Params>
</CalendarDropEvent>
```

### Interaction Events

```xml
<!-- Long press on item -->
<CalendarLongTapEvent event="longTap">
  <Params><Param name="pKey" value=".pKey" /></Params>
</CalendarLongTapEvent>

<!-- Item tap/select -->
<ItemSelectedEvent event="itemSelected">
  <Params><Param name="pKey" value=".pKey" /></Params>
</ItemSelectedEvent>

<!-- Context menu -->
<ContextOpeningEvent event="contextMenuOpening">
  <Params>
    <Param name="pKey" value=".pKey" />
    <Param name="visitStatus" value=".status" />
  </Params>
</ContextOpeningEvent>
<ContextSelectedEvent event="contextMenuItemSelected">
  <Params><Param name="pKey" value=".pKey" /></Params>
</ContextSelectedEvent>

<!-- Overlapping items popup -->
<CalendarItemOverlappingOpeningEvent event="overlappingOpening" />

<!-- Date range navigation (week/month change) -->
<CalendarDateRangeChangedEvent event="dateRangeChanged" />
```

## Item Bindings

```xml
<Items>
  <Bindings>
    <Binding target="StartDate" type="Date" binding=".plannedStartDate" />
    <Binding target="Name" type="Text" binding=".visitName" />
    <Binding target="StatusLabel" type="Label" binding=".statusText" />
    <Binding target="Icon" type="Image" binding=".statusIcon" />
    <Binding target="Amount" type="Decimal" formatV2="10.2" binding=".amount" />
  </Bindings>
</Items>
```

Supported binding types: `Date`, `Text`, `Label`, `Image`, `Decimal`.

## Settings

Calendar instances accept per-view settings via a settings LO:

```xml
<Settings dataSource="ProcessContext::CalendarSettings"
          keyAttribute="key" valueAttribute="value" />
```

## Silent Reschedule Pattern

When a user drags an item on the calendar, the process typically calls a reschedule sub-process with a `Silent` parameter:

| Value      | Behavior                                             |
| ---------- | ---------------------------------------------------- |
| `Silent=1` | Immediate reschedule, no UI — used for drag-and-drop |
| `Silent=2` | Show wizard for validation                           |
| (default)  | Full rescheduling wizard                             |

Example from Visit Calendar:

```
TransitionTo → Visit::RescheduleProcess with Silent=1, pKey, plannedStartDate, plannedEndDate, plannedStartTime, plannedEndTime
```

## User Settings

Calendar behavior is configurable per-user via `BoUserSettings`:

| Setting                          | Type    | Purpose                         |
| -------------------------------- | ------- | ------------------------------- |
| `clbCalendarInitialViewMobility` | enum    | Initial view: Weekly or Daily   |
| `clbCalendarInitialTime`         | DomTime | Scroll-to time on open          |
| `clbCalendarDefaultCallStatus`   | enum    | Default status for new items    |
| `clbAgendaDisplayTimeMobility`   | DomBool | Show time labels                |
| `clbShowCalendarWeekMobility`    | DomBool | Show ISO week number            |
| `displayWeekend`                 | DomBool | Show Sat/Sun columns            |
| `clbDisplayTrafficInMapMobility` | DomBool | Traffic layer (when map paired) |
| `clbDisplayRouteInMapMobility`   | DomBool | Route layer (when map paired)   |

Settings retrieval: `src/User/BO/BoUser/Mv1/BoUser.GetCallCalendarSettings.bl.js`

## Existing Implementations

### Visit Calendar (`src/Visit/PR/Visit_Calendar/`)

Weekly view with drag-to-reschedule + Daily view with swipe navigation and Google Map integration. Context menus for Execute, Abandon, Complete, Re-Schedule, Info, Navigate.

Key BL methods on LoVisit:

-   `getVisitsByDate(currentDateStart, currentDateEnd, dateFunction, filterVisits)` — filter by date range and status
-   `getCalendarTitle(currentDate, displayCalendarWeek)` — weekly header with ISO week
-   `getDailyViewTitle(currentDate)` — localized date for daily header

### Call Agenda (`src/Call/PR/Call_Agenda/`)

Most feature-rich implementation. Weekly calendar with:

-   **Drag-and-drop**: itemMove, itemResize, itemDropped
-   **Sidebar planning**: Job Lists, Managed Customers, Trip Lists — drag from sidebar onto calendar
-   **Automatic planning**: system-assisted call scheduling
-   **Multi-user**: user selection for team management
-   **CRUD**: create new calls directly from calendar menu

### Promotion Store Calendar (`src/Analytics and Reporting/`)

Uses a UI Plugin (C3JS/D3JS) for custom timeline visualization — distinct from the standard CalendarControl.

## Date Handling Utilities

| Function                                     | Purpose               |
| -------------------------------------------- | --------------------- |
| `Utils.convertAnsiDate2Date(ansiDateString)` | ANSI → JS Date        |
| `Utils.convertDate2Ansi(dateObj)`            | JS Date → ANSI string |
| `Utils.getCalendarWeekISO(date)`             | ISO week number       |

## ListItem Properties for Calendar Items

The LI backing the calendar must include:

| Property              | Type        | Purpose                   |
| --------------------- | ----------- | ------------------------- |
| `plannedStartDate`    | DomDate     | Event start date          |
| `plannedEndDate`      | DomDate     | Event end date            |
| `plannedStartTime`    | DomTime     | Event start time          |
| `plannedEndTime`      | DomTime     | Event end time            |
| `allDay`              | DomBool     | All-day flag              |
| `color`               | DomRgbColor | Background color          |
| Display text property | DomText     | e.g., `visitName`, `name` |

## Snippet Location

`contractSnippets/YourModule Section/PR/PR_Process_&_UI/_snippets/UI/Calendar/`

## Cross-References

-   [[user-interface]] — CalendarControl is a sibling to GroupedList, CockpitList
-   [[processes]] — Calendar events route to Process DECISION/LOGIC actions
-   [[list-objects]] — Calendar dataSource is an LO; items are LIs
-   [[business-logic]] — Date methods, reschedule logic, settings retrieval
-   [[offline-sync]] — Calendar items sync via standard STATE flag patterns
