3

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?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Javel
  • 41
  • 1
  • 9
  • Two `selectOneMenu` components have same selected value attribute. when oneis changed the second is also changed that is why action listener triggered twice. – erencan Jul 13 '13 at 13:04
  • you can change the scoop of session in `faces-config.xml` file, or switch to JSF2, in JSF2 you would set it as annotations :D –  Jul 13 '13 at 13:07
  • I'm working on the old application , hence it is not possible to use JSF2. I need to stick to JSF1.1 – Javel Jul 13 '13 at 13:19
  • @user2511414 what differs between 1.1. and 2.x in the scope of this question? – erencan Jul 13 '13 at 13:34

1 Answers1

3

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:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thank You very much Balu!! Your answer is 100% clear, to resolve the issue. I will double check my code whether #{mybean.selectedChannel2} changed or not, when first drop down changed[:)I missed this one!!] – Javel Jul 13 '13 at 14:50
  • @Balu-You are correct. #{mybean.selectedChannel2} value is changing when the first drop down get selected. I have fixed that bug, now ValueChangeListener is working fine. Thanks. – Javel Jul 15 '13 at 11:32
  • @Javel - Am also facing the same issue. How did you fix this issue.? What is the solution for this.? – Jai May 03 '19 at 06:24
  • @BalusC - Is there any best solution for this.? – Jai May 03 '19 at 06:24
  • 1
    @Jai: upgrading to JSF 2.x and using instead. – BalusC May 03 '19 at 08:25