Question

I'm using MyFaces 1.1. I have two <h:selectOneMenu>s dropdowns which each point to same valueChangeListener method.

<h:selectOneMenu id="d1" value="#{mybean.selectedChannel1}" 
    onchange="submit()" valueChangeListener="#{myform.channelValuechange}">
    <f:selectItems value="#{mybean.channelList}"/>
</h:selectOneMenu>

<h:selectOneMenu id="d2" value="#{mybean.selectedChannel2}"
    onchange="submit()" valueChangeListener="#{myform.channelValuechange}">
    <f:selectItems value="#{mybean.channelList}"/>
</h:selectOneMenu>

When I change the first dropdown, then the value change listener method get fired correctly. In the method, I'm obtaining the ID of the current component as sourceId via ValueChangeEvent argument and then comparing it as follows:

if (sourceId.equals("d1")) {
    // ...
} else if (sourceId.equals("d2")) {
    // ...
}

However, my concrete problem is that d2 block is also called when d1 is changed.

I tried the one and other and figured that the following helped to solve the problem:

if (!event.getPhaseId().equals(PhaseId.INVOKE_APPLICATION)) {
      event.setPhaseId(PhaseId.INVOKE_APPLICATION);
      event.queue();
}

However, I don't feel like that it's the best solution. How is this caused and how can I solve it without using the above code?

Was it helpful?

Solution

With onchange="submit()" you're basically submitting the entire form when the current input element is changed, not only the currently changed input! In contrary to what many starters incorrectly think, there is no means of any input-specific JavaScript/Ajax magic here. As you're submitting the entire form, it would trigger the processing of all input components.

The valueChangeListener is always invoked when the submitted value of the input component does not equals() the initial model value as in the backing bean. Given that in your case both menus hit the value change listener when you change only the first one, that can only mean that the default select item value of the second menu does not equals() the initial model value in the backing bean.

You need to make sure that #{mybean.selectedChannel2} of the second menu has by default exactly the same value as the first item of #{mybean.channelList} of the second menu's list. This way the value change listener won't be invoked for the second menu when you change the first menu.

See also:

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top