Switcher Component
Available in Hyva_Enterprise
since 1.0.7
In an attempt to both simplify and unify the various action switchers available to customers throughout Adobe Commerce,
the Hyva_Enterprise
module now contains an abstract implementation that aims to make adding, editing, and removing
actions from these action lists as easy as possible. The purpose of this document is to provide an overview of how the
component works and highlight an example implementation from our own codebase.
For reference, the switcher component template can be found in Hyva_Enterprise::form/actions/switcher.phtml
and the
various code snippets included in this document come directly from our Magento_NegotiableQuote
compatibility module.
Reference
In short; a switcher is simply a container for a set of actions and is responsible for orchestrating both the rendering and invocation of their business logic. In order to be presented as part of a switcher, an action must register itself with that switcher - providing a callback function to execute when the action is selected by the customer.
Switcher Layout XML
You can use layout XML to add a new action switcher component. No special block class is required - simply assign the
Hyva_Enterprise::form/actions/switcher.phtml
template and provide the necessary arguments.
<block name="quote_items.mass_actions.switcher"
template="Hyva_Enterprise::form/actions/switcher.phtml">
<arguments>
<argument name="switcher_name" xsi:type="string">quoteItems</argument>
<argument name="target_element_id" xsi:type="string">form-quote-items-update</argument>
<argument name="item_selector" xsi:type="string">input[type="checkbox"][name^="quote-item-"]:checked</argument>
</arguments>
</block>
Arguments
Arguments marked with an asterisk (*
) are required.
switcher_name *
The name of your action switcher. This value is used to help differentiate this switcher from others on the same page. The value of this argument is used to:
- Prefix the component name
- Prefix the components
x-ref
directive - Define a switcher-specific event listener
target_element_id
The id
of the element associated with the switcher. This is typically going to be a <form>
but can be anything
containing a set of elements you're interested in performing actions with.
item_selector
A query selector that can be applied to the target element in order to fetch the subset of elements your actions will be interested in.
label
The value of this argument is output as a label above the switcher and is parsed by the translation function.
Actions Layout XML
Layout XML is also used to add, edit, and remove the various actions housed within the switcher. Each action block must be assigned a template which houses the logic to invoke when applying the associated action.
<block name="quote_items.mass_actions.switcher"
template="Hyva_Enterprise::form/actions/switcher.phtml">
<arguments>...</arguments>
<block name="quote_items.mass_actions.remove"
template="Hyva_MagentoNegotiableQuote::quote/item/actions/mass/remove.phtml">
<arguments>
<argument name="action_name" xsi:type="string">removeItems</argument>
</arguments>
</block>
</block>
Arguments
Arguments marked with an asterisk (*
) are required.
action_name *
The name of your action. The value of this argument is used to both register and execute the action callback function.
Registration
There are two ways for an action to register itself with a switcher - either directly as a child of the switcher or indirectly through the dispatching of a JavaScript event. When registering an action you must provide its name and a callback function. The callback function will automatically receive the following data:
targetElement
- The HTML element associated with the ID provided by the switcher
<block>
starget_element_id
layout argument
- The HTML element associated with the ID provided by the switcher
items
- The subset of HTML elements obtained by the switcher
<block>
sitem_selector
layout argument i.e.targetElement.querySelectorAll(item_selector)
- The subset of HTML elements obtained by the switcher
Self-Registering Children
Because actions added as children of the switcher automatically inherit its properties and functions, they can be
registered using the registerAction(name, callback)
function by defining themselves as their own Alpine component and
using the x-init
directive to perform this registration.
<div x-data="actionComponentFoo"
x-init="init">
<?= $escaper->escapeHtml(__('Foo')); ?>
</div>
<script>
'use strict';
function actionComponentFoo()
{
return {
init()
{
this.registerAction('foo', (targetElement, items) => {
...
});
},
}
}
</script>
External Registration
Each switcher has an event listener that can be used in order to register an action. This event name follows the pattern
register-{{switcher_name}}-action
where {{switcher_name}}
is the value of the switcher <block>
s layout XML
argument of the same name.
Info
Because HTML attributes do not support camelCasing, the event name will always be lowercase regardless of the
capitalisation used in the switcher_name
argument e.g. fooSwitcher
becomes fooswitcher
.
window.dispatchEvent(new CustomEvent(
'register-fooswitcher-action',
{
detail: {
name: 'foo',
callback: (targetElement, items) => { ... },
},
}
));
Execution
Similarly to action registration, there are also two ways for an actions callback function to be executed by the switcher. Executing self-registered actions is taken care of automatically by a click handler attached to the containing element of each action in the switcher.
External Execution
Each switcher has an event listener that can be used in order to execute an action, provided it has previously been
registered. This event name follows the pattern execute-{{switcher_name}}-action
where {{switcher_name}}
is the
value of the switcher <block>
s layout XML argument of the same name.
Info
Because HTML attributes do not support camelCasing, the event name will always be lowercase regardless of the
capitalisation used in the switcher_name
argument e.g. fooSwitcher
becomes fooswitcher
.
window.dispatchEvent(new CustomEvent(
'execute-fooswitcher-action',
{
detail: {
name: 'foo',
},
}
));
Modals
Modals are commonly displayed in response to selecting an action, often to surface an error message or warning, so, for
the convenience of developers implementing actions, the switcher component is
merged with the hyva.modal()
view utility
to ensure it is available to them by default.
Removing Actions
Because actions are added as children of the switcher via layout XML, removing an action from a
switcher can be done using the remove
directive.