Skip to main content
Documentation/Developers/Element Studio/Actions
Developers

Actions

Actions are JavaScript snippets that run in the builder, in response to something the
user does to your element. They exist for elements whose preview needs help: a slider that
has to be re-initialised when a slide is added, a script that measures its container, a
library that needs tearing down before its node is removed.

Nothing here affects the front end. Front-end JavaScript belongs in
Dependencies.

The seven events

The Actions pane in Element Studio, with one of the seven events selected

The tab lists them as accordions, each with a count of how many actions you've added:

Event Fires when
on created element An instance of your element is added to the page
on mounted element An instance is mounted in the canvas — after its dependencies and server-side render have loaded
on activated element The user selects the element
on property change Any of the element's control values changes
on moved element The element is moved in the tree
on before deleting element Immediately before it's removed. Your last chance to clean up
on after deleted element After it has been removed

on property change and on mounted element carry nearly all real use. The first
re-syncs a JavaScript widget with the user's new settings; the second initialises it once
the DOM and any server-rendered markup exist.

Writing one

An action is a script plus two optional settings.

The script goes through the same two passes as an inline dependency. First it's rendered as
Twig against the element's current property values, so you can read controls directly:

const swiper = window.mySwipers['120'];
if (swiper) {
  swiper.params.slidesPerView = {{ content.slider.slides_per_view|json_encode }};
  swiper.update();
}

Then %%NAME%% placeholders are substituted. Four are available:

Placeholder Value
120 The element instance's node id
.bde-themeless-template-content-area-4881530-120 A CSS selector matching this instance
%%PARENTID%% The parent node's id
%%PARENT_SELECTOR%% A selector matching the parent

%%PARENTID%% and %%PARENT_SELECTOR%% are only populated for the delete events, where
the element itself is on its way out and the parent is what you still have.

As in dependencies, run every interpolated control value through |json_encode. It's the
same hazard: a control value dropped raw into a JavaScript literal breaks on the first
apostrophe anyone types.

The script is injected into the canvas document and re-run each time the event fires, so
write it to be safe to run repeatedly — check whether your instance already exists rather
than assuming a clean slate.

Dependencies and runForAllChildren

Each action can name dependencies, which Oxygen ensures are loaded in the canvas before
the script runs. That covers the case where a dependency group is conditional and its
condition has only just become true — the action would otherwise run against a library that
isn't there yet.

Run for all children propagates the action down the tree: the parent's action also fires
for events on any element nested inside it. This is how a container-shaped element stays in
sync when its children change — a tabs element re-measuring after a panel is edited, a
slider re-initialising when a slide is added. Without it, the parent hears nothing about its
children.

When you don't need actions

Most elements need none at all. Before adding one, check whether a simpler mechanism does
the job:

  • The element just renders differently — that's HTML and CSS; the
    builder re-renders Twig as the user types, with no help from you.
  • Server-rendered output is stale — that's the SSR list on
    Property Paths, not an action.
  • A library needs initialising on the front end — that's an inline script on
    Dependencies.

Actions are for the gap those leave: a stateful JavaScript object living in the builder
canvas that has to be told when something changed.