# Countdown events

> The DOM events the AndOr countdown dispatches, with payload fields and a listener example, plus its data attributes and states.

Source: https://backtrackhq.com/docs/widgets/countdown/events/

This page is for theme developers. The countdown host,
`<andor-countdown>`, dispatches three DOM events with
`widgetType: "countdown"`. The one you will use most is the change
event when the sale ends.

All events are `CustomEvent`s that bubble, so you can listen on
`document`.

## Events

| Event | Dispatched on | When |
|---|---|---|
| `andor:widget:mount` | the host | The first time the events script sees the timer |
| `andor:widget:unmount` | the host and `document` | The first check after the timer left the page |
| `andor:display:change` | the host | The timer's state changed since the last check |

Rules worth knowing:

- **A ticking countdown sends no events.** The time text is not part of
  the state, so each tick is deduped away.
- **No event on first paint.** The first check sends
  `andor:widget:mount` and stores the state silently.
- **Up to one second late.** The timer hides at the exact moment the
  sale ends. The `andor:display:change` event can arrive up to one
  second later.

## Payloads

`andor:widget:mount` and `andor:widget:unmount`:

| Field | Value for this widget |
|---|---|
| `resource.widgetType` | `"countdown"` |
| `resource.widgetId` | The block id (`data-andor-widget-id`) |
| `resource.productId` | The numeric product id, or `null` |

`andor:display:change` has the same three fields, plus
`resource.previous` and `resource.current`. Each is a state object
(`previous` can be `null`):

| State field | Value for this widget |
|---|---|
| `discountId` | `data-andor-discount-id` |
| `kind` | Always `null` (the timer has no `data-andor-kind`) |
| `mode` | Always `null` (the timer has no `data-andor-mode`) |
| `visible` | `true` while the timer shows |
| `endsAt` | `data-andor-ends`, ISO 8601. `null` means this variant has no timer |
| `priceCents` | `null` |
| `originalCents` | `null` |

## Examples

Do something when the countdown reaches zero:

```js
document.addEventListener("andor:display:change", (event) => {
  const { widgetType, previous, current } = event.detail.resource;
  if (widgetType !== "countdown") return;
  if (previous?.visible && !current.visible) {
    console.log("sale ended at", previous.endsAt);
  }
});
```

To recheck all timers after you change the page with Ajax, call
`AndOrWidgets.refresh()`. See
[JavaScript API](https://backtrackhq.com/docs/developers/javascript-api/).

## Data attributes and states

| Attribute or class | On | Meaning |
|---|---|---|
| `data-andor-skeleton` | host | not printed yet |
| `hidden` | host | the sale ended, or none for this variant |

For the attributes every widget shares, like `data-andor-state` and
`data-andor-progress`, see
[Data attributes and states](https://backtrackhq.com/docs/developers/data-attributes/).
