My JSF Books/Videos My JSF Tutorials OmniFaces/JSF PPTs
JSF 2.3 Tutorial
JSF Caching Tutorial
JSF Navigation Tutorial
JSF Scopes Tutorial
JSF Page Author Beginner's Guide
OmniFaces 2.3 Tutorial Examples
OmniFaces 2.2 Tutorial Examples
JSF Events Tutorial
OmniFaces Callbacks Usages
JSF State Tutorial
JSF and Design Patterns
JSF 2.3 New Features (2.3-m04)
Introduction to OmniFaces
25+ Reasons to use OmniFaces in JSF
OmniFaces Validators
OmniFaces Converters
JSF Design Patterns
Mastering OmniFaces
Reusable and less-verbose JSF code

My JSF Resources ...

Java EE Guardian
Member of JCG Program
Member MVB DZone
Blog curated on ZEEF
OmniFaces is an utility library for JSF, including PrimeFaces, RichFaces, ICEfaces ...

[OmniFaces Utilities] - Find the right JSF OmniFaces 2 utilities methods/functions

Search on blog

Petition by Java EE Guardians

Twitter

miercuri, 25 februarie 2015

JSF ValueChangeListener Use Cases

"The valueChangeListener will only be invoked when the form is submitted and the submitted value is different from the initial value" - BalusC

In this post, you can see several use cases for valueChangeListener attribute and ValueChangeListener interface:

·         use the valueChangeListener attribute to point a bean’s method directly when a radio is selected
<h:form>
 <h:selectOneRadio value="#{playerBean.player}" onchange="submit()" valueChangeListener="#{playerBean.playerChangeValueMethod}">
  <f:selectItems value="#{playerBean.players}" />
 </h:selectOneRadio>           
</h:form>

·         use the valueChangeListener attribute to point a bean’s method directly when a boolean checkbox is clicked
<h:form>          
 <h:selectBooleanCheckbox value="#{playerBean.player}" onclick="submit()" valueChangeListener="#{playerBean.playerChangeValueMethod}"/>    
</h:form>

·         use the valueChangeListener attribute to point a bean’s method directly when an item is selected
<h:form>
 <h:selectOneMenu value="#{playerBean.player}" onchange="submit()" valueChangeListener="#{playerBean.playerChangeValueMethod}">
  <f:selectItems value="#{playerBean.players}" />
 </h:selectOneMenu>           
</h:form>

·         use the valueChangeListener attribute to point a bean’s method directly at every key press - not practical, but it works as inspiration source (<f:ajax listener="..."/> is better is this case)
<h:form>
 <h:inputText value="#{playerBean.player}" onkeyup="submit()" valueChangeListener="#{playerBean.playerChangeValueMethod}"/>           
</h:form>

For these three use cases, the PlayerBean is:

@Named
@SessionScoped
public class PlayerBean implements Serializable {

 private List<String> players = new ArrayList<>();
 private String player;

 public PlayerBean() {
  players.add("Rafael Nadal");
  players.add("Novak Djokovic");
  players.add("Roger Federer");
  players.add("Andy Murray");
  players.add("David Ferrer");
 }

 public void playerChangeValueMethod(ValueChangeEvent e) {
  System.out.println("PlayerBean: [PLAYER CHANGE]" + "  " + e.getOldValue() + " IN " + e.getNewValue());
 }
  
 public List<String> getPlayers() {
  return players;
 }

 public void setPlayers(List<String> players) {
  this.players = players;
 }

 public String getPlayer() {
  return player;
 }

 public void setPlayer(String player) {
  this.player = player;
 }
}

·         use the ValueChangeListener interface instead of valueChangeListener attribute

<h:form>
 <h:selectOneMenu value="#{playerBean.player}" onchange="submit()">
  <f:valueChangeListener type="beans.PlayerChangeValueListener" />
  <f:selectItems value="#{playerBean.players}" />
 </h:selectOneMenu>           
</h:form>

The PlayerChangeValueListener is:

public class PlayerChangeValueListener implements ValueChangeListener {

 @Override
 public void processValueChange(ValueChangeEvent event) throws AbortProcessingException {
  System.out.println("PlayerChangeValueListener: [PLAYER CHANGE]" + "  " + event.getOldValue() + " IN " + event.getNewValue());
 }
}

Note You can use both, <f:valueChangeListener> and valueChangeListener attribute, but you have to be aware that the bean's method will be invoked first.

In some situations, you will prefer <f:ajax listener="..."/> instead of <f:valueChangeListener> or valueChangeListener. Per example, we have adapted the example with <h:selectOneMenu>, as below:

<h:form>
 <h:selectOneMenu id="myPlayersId" value="#{playerBean.player}">               
  <f:selectItems value="#{playerBean.players}" />
  <f:ajax execute="@form"  render=":selectedPlayerId" listener="#{playerBean.playerChangeValueMethod}" />
 </h:selectOneMenu>           
</h:form>

In this case, you have to add the below method in PlayerBean. This time, you will not have access to the old value, so maybe is not a good idea to replace the valueChangeListener with <f:ajax listener="..."/>. Do you need the old value ? This is the question!

public void playerChangeValueMethod(AjaxBehaviorEvent e) {
 System.out.println("PlayerBean: [PLAYER CHANGE]" + "  " + player);
}

But, in case that we need to invoke a method at every key press in a text box (see example above), is more proper to use <f:ajax listener="..."/>. Well, in this case, you can "calculate" the old value as a substring of current value:

<h:form>
 <h:inputText value="#{playerBean.player}">           
  <f:ajax event="keyup" execute="@form" render=":selectedPlayerId" listener="#{playerBean.playerChangeValueMethod}" />
 </h:inputText>
</h:form>

So, you can choose correctly between these two approaches only if you know the differences and the similarities between valueChangeListener and <f:ajax listener="..."/>. Well, BalusC provide a great answer on StackOverflow, so don't miss it! Moreover, the StackOverflow archive is also plenty with useful information.

Let's have a quick and handy guide about ValueChangeListener:
·         Don't forget to attach a onevent="submit()" JavaScript to the input component. Novices usually forget this golden rule, and no event will be fired.
·         The bean's method must have an argument of type ValueChangeEvent.
·         The ValueChangeListener will only be called when the form is submitted (this is why we need, onevent="submit()"), not when the value of the input is changed. Moreover, the submitted value should be different from the initial value.
·         The ValueChangeListener allows us to manipulate in bean the old value (event.getOldValue()) and the new value (event.getNewValue()). When you don't need the old value maybe the <f:ajax listener="..."/> will be a better choice.

Complete code on GitHub.

Niciun comentariu :

Trimiteți un comentariu

JSF BOOKS COLLECTION

Postări populare

OmniFaces/JSF Fans

Follow by Email

Visitors Starting 4 September 2015

Locations of Site Visitors