Coming Up for Air

A ValueChangeListener Question and Answer

At the lunch session of the OKC JUG today, a question was asked about the difference between the valueChangeListener attribute and <f:valueChangeListener/>. That is,

<h:selectOneMenu id="optionMenu" value="#{optionBean.selectedOption}"
    valueChangeListener="#{optionBean.optionChanged}" onchange="submit()">
  <f:selectItems value="#{optionBean.optionList}" />
</h:selectOneMenu>

and

<h:selectOneMenu id="optionMenu" value="#{optionBean.selectedOption}" onchange="submit()">
  <f:selectItems value="#{optionBean.optionList}" />
  <f:valueChangeListener type="com.mycompany.MyValueChangeListenerImpl" />
</h:selectOneMenu>

The question was, which is “better?” There was also a question if the latter form automatically handled the JS on the parent component. I will now attempt to answer those questions. :)

The former form takes a MethodExpression (#{optionBean.optionChanged}) that points to a method that satisfies the following method signature:

public void valueChangeListener(ValueChangeEvent e)


The latter form points to a class that implements the ValueChangeListener interface:

public class MyValueChangeListener implements ValueChangeListener  {
    void processValueChange(ValueChangeEvent event) throws AbortProcessingException {
        //...
    }
}

You can also use “binding” with the component:

<f:valueChangeListener type="com.mycompany.MyValueChangeListenerImpl"
    binding="#{optionBean.valueChangeListener}"/>

In OptionBean, you would have a method like this:

public ValueChangeListener getValueChangeListener() {
    return new MyValueChangeListener();
}

If the binding returns null, and the type is specified, then a ValueChangeListener of the specified type is created and set on the binding (i.e., setValueChangeListener(ValueChangeListener vcl) would be called). If the binding is non-null, though, the type is ignored.

Note that both methods require that the user manually add the JS to the component. I can think of a couple of reasons why this is done, though they may not be the official reasons. While it could be done (maybe), care would have to be taken to determine into which event to hook. Some form elements might take onchange, while others take onblur. In the event of <h:inputText>, for example, does the user want to fire this onchange or onblur? Most likely onblur, but should the framework assume that and cause problems for the user? Probably not. Another reason, which is, to me, more significant, is that JSF doesn’t know when the listener should fire. Should it fire as soon as the field is left? What if there are several VCLs that the user wants to fire at the same time? Or perhaps the VCL is there to change server state when the user submits the form rather than changing UI state. There’s no way to tell for sure, so the onus for controlling the timing of the event falls on the page author, and rightly so, I think.

There’s a lot there, so I help it helps more than confuses. If it DOES confuse, feel free to ask for clarification.

Technorati Tags: ,

Popularity: 75% [?]

4 Comments to A ValueChangeListener Question and Answer

  1. February 19, 2008   #

    Comment on :
    “There’s no way to tell for sure, so the onus for controlling the timing of the event falls on the page author, and rightly so, I think.”

    Using JSF before,i found my self having to check for the current phase, and if it is not the Update Model phase, i had to re-queue the event to execute in the Update Model Phase (almost every time) , so my question is, when isn’t value change listener execution defaulted to Update Model Phase in JSF ??

  2. February 20, 2008   #

    Typo:
    “so my question is, when isn’t value change listener execution defaulted to Update Model Phase in JSF ??”

    I meant: Why isn’t value change listener execution defaulted to Update Model Phase in JSF ??

  3. February 22, 2008   #

    I really enjoyed this JUG topic. Myself coming from a Struts Framework environment to JSF/Facelets, I had to endure a learning curve. The more comfortable I become, the more that I like JSF/Facelets.
    This dialog and example code has helped me under stand how the “binding” with the component works.

    I’m still confused on which is “best”, but for now I will continue using the method attribute approach until an issue arises that would behoove creating a class that implements ValueChangeListener.

    Sorry about my lack of communication skills, when I get nervous, I start speaking Gar-bonics. Anyone that has worked me knows what I mean! :razz:

    Great JUG, guys!