Extensibility options through custom scripts
Custom event hooks enables implementation partners and consultants to extend the behavior of Rhythm for Commerce widgets without modifying product code. You can use custom event hooks to validate, modify, or cancel widget interactions by registering JavaScript event listeners.
Custom event hooks are available on these widgets:
- Mini Cart
- Shopping Cart
- Product List
- Product Details
- Order Checkout
- Return Merchandise Authorization
- Item Attribute
About custom event hooks
Custom event hooks use the browser-native CustomEvent API. Events are dispatched on the window object and can be received with standard window.addEventListener calls.
Events use this naming convention: {widgetPrefix}:{category}:{action}
- Blocking events
- Blocking events occur before the system performs an action. A listener can call event.preventDefault() to cancel the action. When the action is cancelled, the widget resets to its previous visual state.
- Non-blocking events
- Non-blocking events occur after the system performs an action. These events are informational. Calling event.preventDefault() on a non-blocking event has no effect.
Enabling custom event hooks
Custom events are disabled by default. To enable events, define the RhythmExtensibilityConfig object on the window before the widget initializes.
No events fire unless explicitly enabled. When no configuration is defined, widget behavior is identical to a standard installation.
Specifying the configuration
For the steps on adding a custom script to a page, see Infor Rhythm Portal Administration Library (Cloud) .
window.RhythmExtensibilityConfig = {
enabledEvents: ['miniCart:panel:beforeOpen', 'shoppingCart:orderline:*']
};
Using wildcard patterns
You can use wildcard patterns to enable multiple events.
| Pattern | Description |
|---|---|
| miniCart:panel:beforeOpen | Enables only the specified event |
| miniCart:* | Enables all Mini Cart events |
| shoppingCart:orderline:* | Enables all Shopping Cart orderline events |
| * | Enables all events across all widgets |
Listening to events
To listen to a custom event, use window.addEventListener with the event name.
All event data is available in event.detail.data.
window.addEventListener('miniCart:cart:afterUpdate', function(event) {
var data = event.detail.data;
// data.totalQuantity
// data.totalPrice
// data.orderLines
});
Cancelling an action
To cancel a blocking event, call event.preventDefault() in the listener.
When a blocking event is cancelled: - The underlying action does not execute. - The widget resets to its previous visual state. Buttons are re-enabled and spinners are hidden.
window.addEventListener('shoppingCart:orderline:beforeDelete', function(event) {
var itemNumber = event.detail.data.itemNumber;
if (isCriticalItem(itemNumber)) {
event.preventDefault();
}
});
If multiple listeners are registered for the same blocking event, any single listener calling event.preventDefault() cancels the action.
Modifying event data
For blocking events, you can modify properties of event.detail.data to change the values used by the subsequent action.
window.addEventListener('shoppingCart:template:beforeSave', function(event) {
var timestamp = new Date().toISOString().slice(0, 10);
event.detail.data.templateName = event.detail.data.templateName + ' (' + timestamp + ')';
});
In this example, the listener appends the current date to the template name before it is saved. The modified value is used in the save request.
Error handling
The extensibility framework guarantees fault isolation. If a listener throws an error, the error is caught and logged as a console warning. The widget action proceeds normally.
A faulty listener cannot crash the widget or prevent the user from completing their task.
Mini cart widget events
This table shows the custom events available on the Mini Cart widget:
| Event name | Type | Payload |
|---|---|---|
| miniCart:panel:beforeOpen | Blocking | isMobile |
| miniCart:panel:afterOpen | Non-blocking | isMobile |
| miniCart:checkout:beforeNavigate | Blocking | targetUrl |
| miniCart:orderline:beforeQuantityUpdate | Blocking | orderlineId, itemNumber, quantity, unitPrice, unit |
| miniCart:orderline:afterQuantityUpdate | Non-blocking | orderlineId, itemNumber, quantity, unitPrice, unit |
| miniCart:orderline:quantityUpdateError | Non-blocking | orderlineId, itemNumber, quantity, unitPrice, unit, error |
| miniCart:orderline:beforeDelete | Blocking | orderlineId, itemNumber, quantity, unitPrice, unit |
| miniCart:orderline:afterDelete | Non-blocking | orderlineId, itemNumber, quantity, unitPrice, unit |
| miniCart:unavailable:beforeRemove | Blocking | itemNumber |
| miniCart:unavailable:afterRemove | Non-blocking | itemNumber |
| miniCart:unavailable:beforeRemoveAll | Blocking | unavailableItems |
| miniCart:unavailable:afterRemoveAll | Non-blocking | unavailableItems |
| miniCart:matrix:beforeOpen | Blocking | itemNumber |
| miniCart:transfer:beforeSubmit | Blocking | protocol, orderId |
| miniCart:transfer:afterSubmit | Non-blocking | protocol, orderId |
| miniCart:cart:afterFetch | Non-blocking | totalQuantity, totalPrice, orderLines |
| miniCart:cart:afterUpdate | Non-blocking | totalQuantity, totalPrice, orderLines |