# Availability Rules

The Availability Rules element is an interactive display of your availability rules.

*(Interactive UI element — see the HTML version for the live demo)*

### Example initialization
```html
<div id="cronofy-availability-rules"></div>
<script src="https://elements.cronofy.com/js/CronofyElements.v1.67.6.js"></script>
<script>
    CronofyElements.AvailabilityRules({
        element_token: "ELEMENT_TOKEN",
        target_id: "cronofy-availability-rules",
        availability_rule_id: "work_hours",
        config: {
          start_time: "08:00",
          end_time: "18:00",
          duration: 60
        },
        styles: {
            colors: {
                available: "green",
                unavailable: "red"
            },
            prefix: "custom-name"
        },
        tzid: "Etc/UTC"
    });
</script>
```

### Element permissions
`managed_availability` is required when generating the [Element Token](/developers/ui-elements/authentication/index.md).

### Element options
##### `element_token` *(required)*

The [Element Token](/developers/ui-elements/authentication/index.md) the
Availability Rules will use to communicate with Cronofy.

*Not required if the Element is activated in demo mode.*

##### `target_id` *(required)*

The ID of the DOM node the Element will be loaded in to.

##### `availability_rule_id` *(optional)*

The String that uniquely identifies the [Availability Rule](/developers/api/scheduling/availability-rules/upsert-availability-rule/index.md).

If the rule exists in the system, the existing rule will be loaded and displayed in the UI Element's grid. If this is the first request for a given ID (meaning that the rule does not already exist in the system), then the [`availability_rule_not_found` notification](#availability-rule-not-found) will trigger and the UI Element will populate the grid with a default availability period. The new rule is not added to the system until the "save new rules" button is clicked.

Defaults to `default`.

> **INFO:** If the `availablility_rule_id` does not exist in the system, a `404` response will be returned. This is normal behaviour.

##### `tzid` *(optional)*

The timezone the Availability Rule will be saved with. Must be a known time zone
identifier from the [IANA Time Zone Database](https://www.iana.org/time-zones).

If the provided [`availability_rule_id`](#param-availability_rule_id) matches a rule in the system, then that rule's `tzid` will take precedence.

If no `tzid` is provided (and the rule does not already exist in the system), then the Element will detect the system time zone from the user's browser. If an invalid `tzid` is provided, then the Element will use the system time zone from the user's browser and trigger a [`warn` notification](/developers/ui-elements/index.md).

##### `data_center` *(optional)*

Designates the Cronofy data center the Element will communicate with.

Defaults to `us`.

##### `config.start_time` *(optional)*

Hide any available slots before this time. Defaults to `08:00`.

##### `config.end_time` *(optional)*

Hide any available slots after this time. Defaults to `18:00`.

##### `config.duration` *(optional)*

The length of time of each option in minutes. Valid values are `15`, `30`, and
`60`.

Defaults to `60`.

> **SECONDARY:** **Note:** if there is a mismatch between the `config.duration` and the start/end times of a rule returned by the API, the element will inclusively round the available periods. For example, if the `available_period` is returned as `09:15` to `11:45` but the `config.duration` is set to `30`, the displayed available period will be `09:30` to `11:30`.

This scenario could occur if a rule has been created or updated through API directly (without using the UI Element).

If the rule is saved (by actively clicking the "Save new rules" button) then the rule will be saved with the displayed available periods (effectively "cropping" the period to match the provided `config.duration`). If the rule is not saved, the rule will be unchanged.

##### `config.logs` *(optional)*

Set the level of logging you want to appear in the console:

- `info`: show verbose logging (recommended for development use only).

- `warn`: (default) only log errors and warnings.

- `error`: only log errors.

- `none`: suppress all console output from the Element.

##### `config.week_start_day` *(optional)*

Day of the week that the view will start on. For example, setting `config.week_start_day: &quot;tuesday&quot;` will display the UI Element's week-grid as `Tue | Wed | Thu | Fri | Sat | Sun | Mon`

Defaults to `sunday`.

Valid options are:

- `sunday`

- `monday`

- `tuesday`

- `wednesday`

- `thursday`

- `friday`

- `saturday`

##### `config.default_weekly_periods` *(optional)*

If no Availability Rule exists, the element will initially load with a default set of periods pre-selected. This option allows you to set the default.

`default_weekly_periods` is an array of objects that take three values.

```json
"default_weekly_periods": [
  {
      "day": "monday",
      "start_time": "09:00",
      "end_time": "17:00"
  },
  {
      "day": "tuesday",
      "start_time": "09:00",
      "end_time": "17:00"
  },
  {
      "day": "wednesday",
      "start_time": "09:00",
      "end_time": "13:00"
  }
]
```

`day`: a string of the day of the week.
`start_time`: a valid time string in the format `HH;mm`.
`end_time`: a valid time string in the format: `HH:mm`.

If no default is set, it will fallback to a default of 09:00 - 17:00, Mon - Fri.

##### `config.auto_create_rules` *(optional)*

Boolean to activate auto-create-rules-mode. Defaults to `false`. If `auto_create_rules` is set to `true` the element will automatically save a new availability rule, using default values, if the rule doesn't already exist. You can set a custom default value by using the [`config.default_weekly_periods`](#param-config.default_weekly_periods).

##### `config.keyboard_support` *(optional)*

Enables basic keyboard support in the Availability Rules element.

Valid options are:

- `basic`

The supported key commands are as follows:

- `Tab` / `Shift` + `Tab` to navigate through the slots. If the slot selection is active and you tab into a new days column, the selection will clear and reset.

- `Spacebar` to start the slot selection. Thereafter tabbing through the slots will select the slots that are tabbed over. If `Spacebar` is pressed again before confirming your selection, the selection will clear and start again on the currently focused slot.

- `Enter` to confirm the selected slots be added/removed to the rule.

- `Esc` to clear and reset the selection.

##### `locale` *(optional)*

The Availability Rules element supports localization (e.g. `locale: &quot;fr&quot;` to load in French). Defaults to browser language setting.

Supported locales (languages) for the UI Elements are:

- `ar` Arabic

- `cs` Czech

- `cy` Welsh

- `de` German

- `en` US English (default)

- `es` Spanish

- `fr` French

- `fr-CA` Canadian French

- `he` Hebrew

- `it` Italian

- `ja` Japanese

- `nl` Dutch

- `pl` Polish

- `pt-BR` Brazilian Portuguese

- `ru` Russian

- `sv` Swedish

- `tr` Turkish

- `zh-CN` Simplified Chinese

##### `config.tz_list` *(optional)*

The element includes a timezone dropdown that allows the user to view the available days and times in a timezone of their choice.

This config option allows you to set an array of timezones you want to appear in the timezone dropdown:

```js
"tz_list": [
    "America/Sao_Paulo",
    "Etc/UTC",
    "Pacific/Fakaofo",
    "Europe/London",
],
```

The list must be made up of known time zone
identifiers from the [IANA Time Zone Database](https://www.iana.org/time-zones). Setting this option will entirely override the default list, so ensure you include all the timezones you need.

##### `callback` *(optional)*

The function to be called when an action has occurred within the Element. Receives an object in the format:

```json
{
    "notification": {
        "type": "notification_type"
    }
}
```

The object will always include a `notification` object with a `type` attribute to allow you to determine how to handle it. Your application should ignore notifications it does not understand as new ones may be added in future.

###### availability_rule_saved
Sent by the Element when a new rule has been successfully saved.

```json
{
    "notification": {
        "type": "availability_rule_saved"
    },
    "availability_rule": {
        "availability_rule_id": "default",
        "tzid": "Europe/London",
        "weekly_periods": [
            {"day": "monday", "start_time": "09:00", "end_time": "17:00"},
            {"day": "tuesday", "start_time": "09:00", "end_time": "17:00"}
        ],
        "calendar_ids": ["A_CALENDAR_ID"]
    }
}
```

###### availability_rule_edited
Sent by the Element when a new rule has been edited within the UI. This notification is fired following changes to either the available periods grid or the "selected calendars" list. Note: the changes to the rule have *not* been saved at the point that this notification is fired.

```json
{
    "notification": {
        "type": "availability_rule_edited",
    },
    "availability_rule": {
        "availability_rule_id": "default",
        "tzid": "Europe/London",
        "weekly_periods": [
            {"day": "monday", "start_time": "09:00", "end_time": "17:00"},
            {"day": "tuesday", "start_time": "09:00", "end_time": "17:00"}
        ],
        "calendar_ids": ["A_CALENDAR_ID"]
    }
}
```

###### availability_rule_not_found
Sent by the Element on the first request for a given `availability_rule_id`, meaning that the rule does not already exist in the system.

```json
{
    "notification": {
        "type": "availability_rule_not_found",
        "message": "Availability rule ID does not already exist. Using default values."
    }
}
```

##### `translations` *(optional)*

To override either a locale or a particular string, pass in a translations object here. The Availability Rules element uses the `availability_rules` translation "context".

[Read more about customizing translations](/developers/ui-elements/customization/index.md)

##### `demo` *(optional)*

Boolean to activate demo-mode. Defaults to `false`. If `demo` is set to `true` the element will return mock data (and not make any API calls).

##### `styles` *(optional)*

An object that controls the pre-packaged element styles.

##### `styles.colors` *(optional)*

Use these options to set the colors for various parts of the Element without the
need to add your own custom CSS. Each color option accepts either a valid HEX
code (e.g. `available: &quot;#FF0000&quot;`) or a browser-safe color name (e.g. `available: &quot;tomato&quot;`)

- `hairline` - gridlines. Defaults to `#D8D8D8`

- `primary` - button background color. Defaults to `#15B3D6`

- `available` - available slot background color. Defaults to `#E2FAC8`

- `availableHover` - available slot when hovered. Defaults to `available` darkened by 10%

- `availableActive` - available slot when active. Defaults to `available` darkened by 20%

- `unavailable` - unavailable slot background color. Defaults to `#FFFFFF`

- `unavailableHover` - unavailable slot when hovered. Defaults to `unavailable` darkened by 10%

- `unavailableActive` - unavailable slot when active. Defaults to `unavailable` darkened by 20%

##### `styles.prefix` *(optional)*

Customizable elements are given a prefixed class name using this value. For
example, if the `prefix` was set as `Foo`, the class name on a slot element
would be `Foo__slot`.

Defaults to `AvailabilityRules`.

### Styling
Cronofy UI Elements come with built-in CSS that control their layout (as well as
adding a generic theme with placeholder colors and spacing). You can specify any
style rule you like in your own stylesheet.

To be sure to avoid specificity issues with CSS, make sure any custom selectors
you add are preceded by `.PREFIX`. For example, if your prefix is `ABC`, you
would target the button styles with this selector:

```css
.ABC .ABC__button {
    /* your button styles go here */
}
```

#### Element classes
`PREFIX` default is `AvailabilityRules`.

- `{PREFIX}__calendars`

- `{PREFIX}__calendars__title`

- `{PREFIX}__calendars__selector`

- `{PREFIX}__calendars__calendar`

- `{PREFIX}__calendars__add-button`

- `{PREFIX}__calendars__add-button-icon`

- `{PREFIX}__calendars__add-button-icon--path`

- `{PREFIX}__calendars__remove-button`

- `{PREFIX}__calendars__remove-button-icon`

- `{PREFIX}__calendars__modal`

- `{PREFIX}__calendars__modal-close`

- `{PREFIX}__calendars__modal-close-icon`

- `{PREFIX}__calendars__modal-list`

- `{PREFIX}__calendars__modal-list-item`

- `{PREFIX}__calendars__modal-item-details`

- `{PREFIX}__calendars__modal-item-title`

- `{PREFIX}__calendars__modal-item-subtitle`

- `{PREFIX}__confirmation`

- `{PREFIX}__checkbox`

- `{PREFIX}__checkbox--checked`

- `{PREFIX}__checkbox--unchecked`

- `{PREFIX}__checkbox-tickmark`

- `{PREFIX}__error`

- `{PREFIX}__error-icon`

- `{PREFIX}__error-text`

- `{PREFIX}__example`

- `{PREFIX}__example--available`

- `{PREFIX}__example--unavailable`

- `{PREFIX}__footer`

- `{PREFIX}__footer-spacer`

- `{PREFIX}__grid`

- `{PREFIX}__grid-border`

- `{PREFIX}__label--day`

- `{PREFIX}__label--time`

- `{PREFIX}__label-column`

- `{PREFIX}__label-row`

- `{PREFIX}__legend`

- `{PREFIX}__legend-item`

- `{PREFIX}__legend-label`

- `{PREFIX}__loading-wrapper`

- `{PREFIX}__slot`

- `{PREFIX}__slot--available`

- `{PREFIX}__slot--unavailable`

- `{PREFIX}__slot--dragging`

- `{PREFIX}__slot-button`

- `{PREFIX}__slot-tooltip`

- `{PREFIX}__slot-tooltip-background`

- `{PREFIX}__slot-tooltip-label`

- `{PREFIX}__slot-background`

- `{PREFIX}__slot-background--available`

- `{PREFIX}__slot-background--unavailable`

- `{PREFIX}__slots-background-column`

- `{PREFIX}__slots-background-columns`

- `{PREFIX}__slots-column`

- `{PREFIX}__slots-columns`

- `{PREFIX}__status-icon-wrapper`

- `{PREFIX}__status-icon`

- `{PREFIX}__submit`

- `{PREFIX}__submit-inner`

- `{PREFIX}__tick-mark`

- `{PREFIX}__tick-mark-wrapper`

- `{PREFIX}__time-select`

- `{PREFIX}__time-select__close-button`

- `{PREFIX}__time-select__close-button-icon`

- `{PREFIX}__time-select__label`

- `{PREFIX}__time-select__row`

- `{PREFIX}__time-select__select`

- `{PREFIX}__time-select__select-wrapper`

- `{PREFIX}__time-select__trigger`

- `{PREFIX}__time-select__trigger-icon`

- `{PREFIX}__timezone`

- `{PREFIX}__wrapper`

### Element methods
##### `refresh()`

From time to time you may wish to reload the AvailabilityRules UI Element on the page. You can do this with the `AvailabilityRules.refresh()` method:

```js
// Load AvailabilityRules Element:
const AvailabilityRules = CronofyElements.AvailabilityRules(optionsObject);

// Refresh the AvailabilityRules Element:
AvailabilityRules.refresh();
```

> **WARNING:** Being able to refresh a UI Element is useful in cases where your availability may have changed behind the scenes. UI Elements gather their availability data when they are first loaded, so unless they are refreshed they will not be aware of any changes to availability.

##### `update()`

Should you need to update the `options` for any Element, you can reload them with the `.update()` method (this requires you to have saved your Element instance to a variable beforehand):

```js
// Load AvailabilityRules Element:
const AvailabilityRules = CronofyElements.AvailabilityRules(optionsObject);

// Update the AvailabilityRules Element with new options:
AvailabilityRules.update(newOptions);
```

When updating, you do not need to redeclare *all* the options; you just need to add the ones you want to update.

**Note:** the `AvailabilityRules.update()` method must be called with an options object, otherwise a [warning-level log notification](/developers/ui-elements/index.md) will be fired.



---
[Read in HTML](/developers/ui-elements/availability-rules/)