BUG - Wix editor MultiStateBox element triggering onChange event handler executing twice.
OVERVIEW
I have a multiStateBox element where I’m trying to conditionally navigate between states. The problem I’m experiencing is that the element’s onChange event handler is being triggered twice, and the targeted next state ID isn’t always equal to the one I set programmatically, but seemingly equal to the next adjacent state.
For example, if I have state IDs [1,2,3], starting at state 1 and setting my state to 3, my logs show the first transition as 1 → 3 (as desired), but then the second (undesired) transition as 3 → sometimes 2 or 3; either way, this second transition (i.e., onChange event) is a bug.
Sometimes I’ve noticed in my logs that despite all of my helper methods correctly listing state ID 3 is the next state, the onChange event handler shows state 2 as the receiving state. And the order of state transitions has been inconsistent, ranging from 1 → 3 then 3 → 2 in one playthrough, to 1 → 3 then 3 → 3 (as shown in the screenshot) in another playthrough.
CODE SNIPPET
In the following code snippet:
- I have an
onNextButtonClickevent handler manually attached in the editor UI to the next button on each state; my logs show it only executing once (as desired). - I also have
findNextPageIdhelper method that conditionally determines the next state from the current state; again my logs show it working correctly and only executing once. - Once more, I have a
changePagehelper method that triggers the state change; this too works correctly and only executes once. - But as you’ll see in the screenshot, the
onChangeevent handler is being triggered twice.
const PAGE = {
AGREEMENT: 'agreement',
LOCATION: 'location',
SERVICES: 'services',
MOWING: 'mowing'
}
class StateManager {
constructor() {
log('New state manager.')
this.currentPageId = PAGE.AGREEMENT
this.pages = [
{ id: PAGE.AGREEMENT, active: true },
{ id: PAGE.LOCATION, active: false },
{ id: PAGE.SERVICES, active: true },
{ id: PAGE.MOWING, active: false }
]
this.SERVICES = [
{
_id: PAGE.MOWING,
label: 'Cutting My Grass',
image: 'https://example.svg'
}
]
}
changePage(newPageId) {
log(`Changing page to ${newPageId}`)
$w(`#statebox1`).changeState(newPageId)
}
findNextPageId() {
log('findNextPageId:')
const currentPageIndex = this.pages.findIndex(
(page) => page.id === this.currentPageId
)
const nextPageIndex = this.pages.findIndex(
(page, index) => page.active && index > currentPageIndex
)
const nextPageId =
nextPageIndex !== -1 ? this.pages[nextPageIndex].id : null
log({ nextPageIndex, nextPageId })
return nextPageId
}
}
const stateManager = new StateManager()
export function onNextButtonClick(_) {
log('onNextButtonClick:')
let nextPageId = stateManager.findNextPageId()
if (!nextPageId) {
throw new Error(`Next page not found from: ${stateManager.currentPageId}`)
}
stateManager.changePage(nextPageId)
}
$w('#statebox1').onChange((event) => {
const previousPageId = stateManager.currentPageId
const newPageId = event.target.currentState.id
log({
msg: `State changing from ${previousPageId} to ${newPageId}`,
event,
states: event.target.states,
currentState: event.target.currentState
})
stateManager.currentPageId = newPageId
})
Note: Whether I attach the onChange event handler through the UI or programmatically, the bug remains.
SCREENSHOT:
In the following screenshot, you can see nothing is executing more than once, except the onChange event handler.
CONCLUSION
Please help me understand and mitigate the onChange event handler from executing twice.






