Essentially the problem is how to control the list of items in a second <p:selectOneMenu/< from the selection made in the first menu. The question comes up frequently enough that I decided to write up a demo application.
The application was developed using NetBeans 7.1.2 and PrimeFaces 3.2 originally. It has been updated to use PrimeFaces 3.3.1 which is the most current at the time of writing. I validated it on GlassFish 3.1.2.
The Apache Maven project can be downloaded from here: primefaces-ajax-selectone.zip
This demo wants the user to pick a state, and then a city. A key problem is not just the update, but not displaying city values if a state is not selected. Also erasing the selected city, if the state has changed.
index.xhtml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | <? xml version = '1.0' encoding = 'UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> > < h:head > < title >PrimeFaces AJAX Enabled SelectOneMenu</ title > </ h:head > < h:body > < h:form > < p:panel header = "Address" > < h:panelGrid columns = "4" > < h:outputLabel value = "State:" for = "states" /> < p:selectOneMenu id = "states" value = "#{dataBean.selectedState}" valueChangeListener = "#{dataBean.stateChangeListener}" style = "width: 150px;" > < f:selectItem itemLabel = "" itemValue = "" /> < f:selectItems value = "#{dataBean.states}" /> < p:ajax event = "change" update = "cities, cs" /> </ p:selectOneMenu > < h:outputLabel value = "City:" for = "cities" /> < p:selectOneMenu id = "cities" value = "#{dataBean.selectedCity}" style = "width: 150px;" > < f:selectItem itemLabel = "" itemValue = "" /> < f:selectItems value = "#{dataBean.cities}" /> < p:ajax event = "change" update = "cs" /> </ p:selectOneMenu > </ h:panelGrid > < p > < h:outputText id = "cs" value = "#{dataBean.selectedCity} #{dataBean.selectedCity ne null ? ',': '' } #{dataBean.selectedState}" /> </ p > </ p:panel > </ h:form > </ h:body > </ html > |
DataBean.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | package com.bluelotussoftware.example.jsf; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.PostConstruct; import javax.faces.bean.ManagedBean; import javax.faces.bean.ViewScoped; import javax.faces.event.ValueChangeEvent; import javax.faces.model.SelectItem; /** * Page Backing bean for example application. * * @author John Yeary * @version 1.0 */ @ManagedBean @ViewScoped public class DataBean implements Serializable { private static final long serialVersionUID = -1776353555799643520L; private List<selectitem> states; private Map<String, List<selectitem>> cities; private String selectedState; private String selectedCity; /** * Default Constructor. */ public DataBean() { states = new ArrayList<selectitem>(); cities = new HashMap<String, List<selectitem>>(); } /** * Initializes data. */ @PostConstruct private void initialize() { states.add( new SelectItem( "Maine" )); states.add( new SelectItem( "South Carolina" )); states.add( new SelectItem( "Illinois" )); List<selectitem> mcities = new ArrayList<selectitem>(); mcities.add( new SelectItem( "Augusta" )); mcities.add( new SelectItem( "Bangor" )); mcities.add( new SelectItem( "Bath" )); mcities.add( new SelectItem( "Brunswick" )); mcities.add( new SelectItem( "Castine" )); mcities.add( new SelectItem( "Ellsworth" )); mcities.add( new SelectItem( "Portland" )); mcities.add( new SelectItem( "Woolwich" )); cities.put( "Maine" , mcities); List<selectitem> scities = new ArrayList<selectitem>(); scities.add( new SelectItem( "Charleston" )); scities.add( new SelectItem( "Clemson" )); scities.add( new SelectItem( "Columbia" )); scities.add( new SelectItem( "Greenville" )); scities.add( new SelectItem( "Simpsonville" )); cities.put( "South Carolina" , scities); List<selectitem> icities = new ArrayList<selectitem>(); icities.add( new SelectItem( "Argonne" )); icities.add( new SelectItem( "Batavia" )); icities.add( new SelectItem( "Chicago" )); icities.add( new SelectItem( "Evanston" )); cities.put( "Illinois" , icities); } /** * Gets the selected city. * * @return selected city. */ public String getSelectedCity() { return selectedCity; } /** * Sets the selected city. * * @param selectedCity city to be set. */ public void setSelectedCity(String selectedCity) { this .selectedCity = selectedCity; } /** * Gets selected state. * * @return selected state. */ public String getSelectedState() { return selectedState; } /** * Sets the selected state. * * @param selectedState state to be set. */ public void setSelectedState(String selectedState) { this .selectedState = selectedState; } /** * Gets a {@code List<selectitem>} for populating state names. * * @return a list of state names. */ public List<selectitem> getStates() { return states; } /** * Gets a {@code List<selectitem>} of cities based on the selected state. * * @return a list of cities based on selected state, or an empty list if no * state is selected. */ public List<selectitem> getCities() { if (selectedState != null ) { return cities.get(selectedState); } else { return new ArrayList<selectitem>(); } } /** * This listener cleans up the city value if a new state is selected. * * @param event a change event when the value of the state changes. */ public void stateChangeListener(ValueChangeEvent event) { if (event.getNewValue() != selectedState) { selectedCity = null ; } } } |
5 comments :
Hello,
I got:
java.lang.NullPointerException
at com.bluelotussoftware.example.jsf.DataBean.stateChangeListener(DataBean.java:159)
I run on glassfish 3.1.2 Do you know maybe reason?
Thank you
Interestingly... the exception is being caused by the valueChangeListener="#{dataBean.stateChangeListener(event)}". If you remove the (event), it will start working.
Thank you:)
thank you soo much man your code helped me a lot _/\_
Post a Comment