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
onNextButtonClick
event 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
findNextPageId
helper 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
changePage
helper method that triggers the state change; this too works correctly and only executes once. - But as you’ll see in the screenshot, the
onChange
event 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.