Script events
WooCommerce Product Options dispatches a number of JavaScript events on the product page as customers interact with your options. Developers can listen for these events to run custom code, for example when a customer changes an option, when an option is shown or hidden by conditional logic, or when the total price is recalculated.
Note: This is a developer-level article. If you don't know how to use this code then we recommend asking your developer.
How to listen for an event
All events are native DOM events dispatched on the add to cart form of the product (form.cart or more specifically .woocommerce .product form.cart). Most of them carry extra information in the detail property of the event.
const form = document.querySelector( 'form.cart' );
form.addEventListener( 'wpo:field:change', ( event ) => {
const { optionId, type, values } = event.detail;
console.log( `Option ${ optionId } (${ type }) changed to`, values );
} );
Events marked as 'Bubbles' in the tables below can also be caught higher up the page, for example on document. This is useful when the form is added to the page later, such as in a quick view lightbox or a product table. Events that don't bubble must be listened for on the form itself.
Initialization
| Event | Dispatched on | Bubbles | When |
|---|---|---|---|
wpo:ready |
Add to cart form | Yes | Once the options in the form have been initialized. |
Event details:
form- The add to cart form.fields- An array with one entry for each option, describing the state that it starts from. Each entry containselement,optionId,type,values,quantitiesandvisible(see 'Field details' below).
The form also receives the attribute data-wpo-ready="true". If your script might load after the options are initialized, check for this attribute before waiting for the event:
const onReady = ( form ) => {
// Your code here.
};
if ( form.dataset.wpoReady === 'true' ) {
onReady( form );
} else {
form.addEventListener( 'wpo:ready', () => onReady( form ) );
}
Field events
These events are dispatched when a customer interacts with an individual option.
| Event | Dispatched on | Bubbles | When |
|---|---|---|---|
wpo:field:input |
Add to cart form | Yes | While the customer is typing in or selecting an option (the native input event). |
wpo:field:change |
Add to cart form | Yes | When the value of an option changes. This includes its selected choices, the text entered, and the quantity of each choice. |
wpo:field:quantity_change |
Add to cart form | Yes | When the quantity picker of a choice changes. |
wpo:field:validity |
Add to cart form | Yes | When an option becomes valid or invalid, or when its error message changes. |
wpo:visibility:change |
Add to cart form | Yes | When conditional logic shows or hides an option. |
Field details
All the field events contain the following details:
element- The HTML element which wraps the option (.wpo-field).optionId- The ID of the option.type- The option type, e.g.checkbox,radio,dropdown,text,number,file_uploadorproduct.field- An internal object used by the plugin. Its properties depend on the event, so we recommend usingelementandoptionIdinstead.
The wpo:field:input, wpo:field:change and wpo:field:quantity_change events also contain:
values- An array with the current values of the option. This contains the IDs of the selected choices or products, the uploaded files, or the value entered by the customer. It is empty if nothing has been selected or entered.quantities- An object with the value of each quantity picker, using the ID of the choice or product as the key. It is empty if the option has no quantity pickers.
The wpo:field:validity event also contains:
valid-trueif the option is now valid, orfalseif it is invalid.message- The error message for an invalid option. It is empty when the option is valid.
The wpo:visibility:change event also contains:
visible-trueif the option has just been shown, orfalseif it has just been hidden.
Things to know
- From version 3.0.1, the
wpo:field:input,wpo:field:changeandwpo:field:quantity_changeevents are only dispatched when the option has actually changed since the last time the same event was dispatched. - The
wpo:field:validityandwpo:visibility:changeevents are not dispatched while the page is loading. For example, a required option which is empty when the page loads will not dispatch an event until the customer changes it. Use thewpo:readyevent to read the initial state of each option. - If an option has a single quantity picker for all its choices (e.g. radio buttons), the quantity is listed against the selected choice.
Validation events
| Event | Dispatched on | Bubbles | When |
|---|---|---|---|
wpo:formValidityCheck |
Add to cart form | Yes | Every time the plugin checks whether all the options are valid. This happens whenever an option changes, and when the customer clicks the add to cart button. |
wpo:invalidForm |
Add to cart form | Yes | Once while the options are being initialized, if the form is not valid at that point (e.g. because it contains required options). |
Event details for wpo:formValidityCheck:
isValid-trueif all the options are valid.isSubmit-trueif the check was triggered by the customer trying to add the product to the cart, in which case any error messages are displayed.
Event details for wpo:invalidForm:
form- The add to cart form.
Price calculation events
| Event | Dispatched on | Bubbles | When |
|---|---|---|---|
wpo:recalculate |
Add to cart form | No | When the plugin requests a new price calculation, e.g. after an option or quantity picker changes. |
wpo_run_frontend_calculation |
Add to cart form | No | When conditional logic has finished checking an option. This also requests a new price calculation. |
wpo:recalculated |
Add to cart form | No | When a price calculation has finished. |
wpo:priceUpdated |
Add to cart form | No | When the total displayed on the product page has been updated. |
Event details for wpo:recalculated:
form- The add to cart form.optionsPrice- The total price of the selected options. This is not available when the product is displayed using WooCommerce Bulk Variations.totalPrice- The total price of the product, including its options and quantity.
Event details for wpo:priceUpdated:
form- The add to cart form.total- The total price displayed on the product page.
The wpo:recalculate and wpo_run_frontend_calculation events have no reliable details.
Requesting a price calculation
The plugin listens for the wpo:recalculate event as well as dispatching it. If your code changes something which affects the price, you can dispatch this event on the form to update the total:
form.dispatchEvent( new CustomEvent( 'wpo:recalculate' ) );
Layout events
These events are dispatched for option groups which use the Tabs or Numbered steps layout.
| Event | Dispatched on | Bubbles | When |
|---|---|---|---|
wpo:tab:change |
Add to cart form | Yes | When the customer moves to a different tab. |
wpo:step:change |
Add to cart form | Yes | When the customer moves to a different step. |
Event details:
container- The HTML element which wraps the option group (.wpo-layout-tabsor.wpo-layout-steps).panel- The HTML element of the tab or step which is now displayed.index- The position of the tab or step which is now displayed, starting from 0.previousIndex- The position of the tab or step which was displayed before.
WooCommerce Product Table events
These events are dispatched when the options are displayed in a product table created with WooCommerce Product Table.
| Event | Dispatched on | Bubbles | When |
|---|---|---|---|
wpo:wptPriceUpdated |
Add to cart form | Yes | When the price of the options in a table row has been recalculated. |
wpo_form_options_price |
Add to cart form | No | The same, for tables which use the legacy table design. |
Event details:
form- The add to cart form in the table row.optionsPrice- The total price of the selected options.totalPrice- The total price of the product, including its options and quantity.
Example: reacting to conditional logic
This example adds a CSS class to the product page whenever a specific option is displayed:
document.addEventListener( 'wpo:visibility:change', ( event ) => {
const { optionId, visible } = event.detail;
// Replace 123 with the ID of your option.
if ( optionId === 123 ) {
document.body.classList.toggle( 'my-option-visible', visible );
}
} );