Coming Up for Air

A ValueChangeListener Question and Answer

Tuesday, February 19, 2008 |

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,

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

and

1
2
3
4
<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:

1
public void valueChangeListener(ValueChangeEvent e);

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

1
2
3
4
5
public class MyValueChangeListener implements ValueChangeListener  {
    void processValueChange(ValueChangeEvent event) throws AbortProcessingException {
        //...
    }
}

You can also use "binding" with the component:

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

In OptionBean, you would have a method like this:

1
2
3
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.

Search

    Quotes

    Sample quote

    Quote source

    About

    My name is Jason Lee. I am a software developer living in the middle of Oklahoma. I’ve been a professional developer since 1997, using a variety of languages, including Java, Javascript, PHP, Python, Delphi, and even a bit of C#. I currently work for Red Hat on the WildFly/EAP team, where, among other things, I maintain integrations for some MicroProfile specs, OpenTelemetry, Micrometer, Jakarta Faces, and Bean Validation. (Full resume here. LinkedIn profile)

    I am the president of the Oklahoma City JUG, and an occasional speaker at the JUG and a variety of technical conferences.

    On the personal side, I’m active in my church, and enjoy bass guitar, running, fishing, and a variety of martial arts. I’m also married to a beautiful woman, and have two boys, who, thankfully, look like their mother.

    My Links

    Publications