Listener is not called by selectOneMenu - jsf

I have a p:selectOneMenu that changing value should run a listener to update the value of another p:selectOneMenu (Type: state -> city). In addition to the items have the item "All" in the first p:selectOneMenu. When you select any item other than the "All" the listener is not called, but when I select the "All" option.
I also realized that the model will not be updated. That is the value of the first p:selectOneMenu is not set in the entity attribute,
The following codes:
First
<p:selectOneMenu id="pesquisaCategoria" style="width:100%;"
value="#{inscricaoFaces.entity.categoriaSelecionada}"
styleClass="input-block-level" converter="#{categoriaConverter}">
<f:selectItem itemLabel="#{msgs['label.dropdown.todos']}"
noSelectionOption="true" itemValue="#{null}" />
<f:selectItems value="#{categoriaFaces.listarTodasCategorias()}"
var="categoria" itemValue="#{categoria}"
itemLabel="#{categoria.descricao}" />
<p:ajax update="pesquisaAreaAtuacao" event="change"
listener="#{inscricaoFaces.atualizarAreasAtuacao}" />
</p:selectOneMenu>
Second
<p:selectOneMenu id="pesquisaAreaAtuacao" style="width:100%;"
value="#{inscricaoFaces.entity.areaAtuacao}"
styleClass="input-block-level" converter="#{areaAtuacaoConverter}">
<f:selectItem itemLabel="#{msgs['label.dropdown.todos']}"
noSelectionOption="true" itemValue="#{null}" />
<f:selectItems value="#{inscricaoFaces.areasAtuacao}" var="area"
itemValue="#{area}" itemLabel="#{area.descricao}" />
</p:selectOneMenu>
Convert
#ManagedBean
#RequestScoped
public class CategoriaConverter implements Converter, Serializable {
/**
*
*/
private static final long serialVersionUID = -1073909086688882110L;
#EJB
private CategoriaService categoriaService;
#Override
public Object getAsObject(FacesContext fc, UIComponent uic, String value) {
if (value != null && value.trim().length() > 0 && !"Todos".equals(value)) {
return categoriaService.consultarPorId(new Categoria(Integer.valueOf(value)));
} else {
return null;
}
}
#Override
public String getAsString(FacesContext fc, UIComponent uic, Object value) {
if(value != null){
return value instanceof Categoria ? String.valueOf(((Categoria) value).getCodigo()) : null;
}else{
return null;
}
}
}

Related

Country State City dropdown in jsf

The city Dropdown populated when the state is selected and State Dropdown populated according Country selection; however, it is not doing this.
Problem is when country selected according country state populated in state dropdwon but after it when i select state from state dropdwon list it does not show populate city dropdwon
actual problem is State value not set in state variable when i select state
Here is the code:
JsfPage
<p:selectOneMenu id="countrydrop" value="#{user.country}" >
<f:ajax id="countryajex" listener="#{user.statesbycontry()}" render="statedrop"/>
<f:selectItem itemLabel="Select Country" itemValue="" noSelectionOption="true" />
<f:selectItems value="#{user.allcontry()}" />
</p:selectOneMenu>
<p:selectOneMenu id="statedrop" value="#{user.ustate}" >
<p:ajax event="change" id="stateajex" listener="#{user.citybystate()}" update="citydrop" />
<f:selectItem itemLabel="Select State" itemValue="" noSelectionOption="true" />
<f:selectItems value="#{user.statelist}"/>
</p:selectOneMenu>
<p:selectOneMenu id="citydrop" value="#{user.city}" >
<f:selectItem itemLabel="Select City" itemValue="" noSelectionOption="true" />
<f:selectItems value="#{user.citylist}" />
</p:selectOneMenu>
jsfManagedBean
String country;
String state;
String city;
List<String> statelist;
List<String> citylist;
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public List<String> getStatelist() {
return statelist;
}
public void setStatelist(List<String> statelist) {
this.statelist = statelist;
}
public List<String> getCitylist() {
return citylist;
}
public void setCitylist(List<String> citylist) {
this.citylist = citylist;
}
public List<String> allcontry(){
return od_user_bean.allcountries();
}
public void statesbycontry(){
//Method tested Working well
statelist = od_user_bean.findstatesbycontries(country);
}
public void citybystate(){
System.out.println("State="+state);
if(state != null)
//Method tested Working well
citylist=od_user_bean.findcitybystate(state);
}

Primefaces remotecommand action called only once

I have
<p:remoteCommand name="updateSelectedTarget" update="partToUpdate" actionListener="#{bean.onSelectedTarget}"/>
bean.java
public void onSelectedTarget() {
System.out.println("here");
}
With this configuration, the action is only fired once. Do I need to use actionListener or action? And is there something to do with the process parameter of remoteCommand?
I just want to add that it was working before. I just changed the updated part below
<h:panelGroup id="partToUpdate" layout="block">
<p:panelGrid rendered="#{bean.selectedTarget == null ? false : true}">
...
<h:selectOneMenu value="#{bean.stuffID}">
...
</h:selectOneMenu>
...
</p:panelGrid>
</h:panelGroup>
Before there was just an ID one the selectOneMenu
<h:selectOneMenu value="#{bean.stuffID}">
and now I have the object
<h:selectOneMenu value="#{bean.stuff}">
the java.lang.ClassCastException comes from the line
<f:selectItem itemLabel="None" itemValue="null" />
Could you verify this
#FacesConverter("user")
public class UserConverter implements Converter{
private List<User> users;
public UserConverter(){
this.users = myController.getAllUsers();
}
public Object getAsObject(FacesContext context, UIComponent component, String value) {
return this.getUser(value);
}
public String getAsString(FacesContext context, UIComponent component, Object value) {
return String.valueOf(((User) value).getId()).toString();
}
public User getUser(String id) {
Iterator<User> iterator = this.users.iterator();
while(iterator.hasNext()) {
User user = iterator.next();
if(user.getId() == Integer.valueOf(id)) {
return user;
}
}
return null;
}
}
I think my converter is good because I use it somewhere else.
Maybe the mistake is how to use it with the h:selectOneMenu
I have this
<h:selectOneMenu value="#{bean.selectedUser}">
<f:selectItem itemLabel="None" itemValue="null" />
<f:selectItems value="#{bean.allusers}" var="user" itemValue="#{user.id}" itemLabel="#{user.name}"/>
<f:converter converterId="user"/>
</h:selectOneMenu>
So to conclude I changed my selectOneMenu to
<h:selectOneMenu value="#{bean.selectedUser}">
<f:selectItem itemLabel="None" itemValue="#{null}" />
<f:selectItems value="#{bean.allusers}" var="user" itemValue="#{user}" itemLabel="#{user.name}"/>
<f:converter converterId="user"/>
</h:selectOneMenu>
And in my converter
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if(!StringUtils.isInteger(value)) {
return null;
}
return this.getUser(value);
}
public String getAsString(FacesContext context, UIComponent component, Object value) {
if(value == null) {
return null;
}
return String.valueOf(((User) value).getId()).toString();
}
With the method below because I am looking for id and getAsObject value returned the label "None"
public static boolean isInteger(String s) {
try {
Integer.parseInt(s);
} catch(NumberFormatException e) {
return false;
}
return true;
}
And problem solved.
Thnks
EDIT
Don't forget to add the equals override method to the User class.
it happens to me many times like this and I find that the problem comes from previous page that call the current one

p:selectOneMenu value still required

In my xhtml page i have two dependant selectOneMenu, with the second one being filled in an ajax call. Here's the jsf code fragment:
<h:panelGrid columns="2" cellpadding="5">
<h:outputLabel value="Dirección:" for="direccion"/>
<p:inputText id="direccion" value="#{datosInstitucion.institucion.direccion}" required="true" label="Dirección"/>
<h:outputLabel value="Departamento:" for="departamento"/>
<p:selectOneMenu id="departamento" value="#{datosInstitucion.idDepartamento}" required="true" label="Departamento">
<f:selectItem itemLabel="Seleccione el departamento" itemValue="#{null}"/>
<c:forEach items="#{datosInstitucion.departamentos}" var="departamento">
<f:selectItem itemLabel="#{departamento.nombre}" itemValue="#{departamento.id}"/>
</c:forEach>
<f:ajax render="municipio" listener="#{datosInstitucion.cargarMunicipios()}"/>
</p:selectOneMenu>
<h:outputLabel value="Municipio:" for="municipio"/>
<p:selectOneMenu id="municipio" value="#{datosInstitucion.idMunicipio}" required="true" label="Municipio">
<f:selectItem itemLabel="Seleccione el municipio" itemValue="#{null}"/>
<c:forEach items="#{datosInstitucion.municipios}" var="municipio">
<f:selectItem itemLabel="#{municipio.nombre}" itemValue="#{municipio.id}"/>
</c:forEach>
</p:selectOneMenu>
</h:panelGrid>
This fragment of code is inside a primefaces wizard component, so when the 'next' button is pressed a validation error is caused for the second selectOneMenu even when there's a value set.
What could be causing this behavior?
Relevant backing bean code:
#ManagedBean(name = "datosInstitucion")
#ViewScoped
public class DatosInstitucion implements Serializable{
#EJB
private Instituciones instituciones;
#EJB
private Parametros parametros;
#Inject
private Mensajes mensajes;
private List<Departamento> departamentos;
private List<Municipio> municipios;
private Map<Integer, Departamento> mapaDepartamentos;
private Integer idDepartamento;
private Integer idMunicipio;
private Institucion institucion;
#PostConstruct
private void inicializar(){
this.mapaDepartamentos = new HashMap<>();
this.departamentos = parametros.consultarDepartamentos();
for(Departamento departamento : departamentos){
this.mapaDepartamentos.put(departamento.getId(), departamento);
}
this.prepararInstitucion();
}
private void prepararInstitucion(){
this.institucion = new Institucion();
this.institucion.setResponsable(new Persona());
}
public Institucion getInstitucion() {
return institucion;
}
public List<Departamento> getDepartamentos(){
return departamentos;
}
public TipoIdentificacion[] getTiposIdentificacion(){
return TipoIdentificacion.deResponsables();
}
public Integer getIdDepartamento() {
return idDepartamento;
}
public void setIdDepartamento(Integer idDepartamento) {
this.idDepartamento = idDepartamento;
}
public Integer getIdMunicipio() {
return idMunicipio;
}
public void setIdMunicipio(Integer idMunicipio) {
this.idMunicipio = idMunicipio;
}
public void cargarMunicipios(){
idMunicipio = null;
if(idDepartamento != null){
this.municipios = mapaDepartamentos.get(idDepartamento).getMunicipios();
}else{
this.municipios = Collections.emptyList();
}
}
public List<Municipio> getMunicipios() {
return municipios;
}
public void confirmar(){
this.instituciones.guardar(institucion);
this.mensajes.exito("La institución ha sido registrada en el sistema");
this.prepararInstitucion();
}
}
This is because you are using JSTL <c:foreach> with JSF. The life cycle of JSTL vs JSF matters. JSTL is executed when the view is being built, while JSF is executed when the view is being rendered. The two do not work in synch with each other. In your case, you need to use <f:selectItems> instead of <c:foreach>
Replace:
<c:forEach items="#{datosInstitucion.municipios}" var="municipio">
<f:selectItem itemLabel="#{municipio.nombre}" itemValue="#{municipio.id}"/>
</c:forEach>
with:
<f:selectItems value="#{datosInstitucion.municipios}"
var="municipio" itemLabel="#{municipio.nombre}"
itemValue="#{municipio.id}"/>
For more reading, I suggest you to read the following answer

p:selectOneRadio converter causing stack heap memory issues

Really odd one...
I have a converter which works when I use a p:SelectOneMenu, but when I switch to a p:SelectOneRadio, I get a major crash with a java heap space errors. The stacktrace seems to be of no use, just a java.lang.OutOfMemeoryError.
This works:
<p:selectOneMenu id="regions" value="#{aDMSBean.selectedRegion}">
<f:selectItem itemLabel="Global" itemValue="#{null}" />
<f:selectItems value="#{aDMSBean.adminRegions}" var="adminRegion" itemLabel="# {adminRegion.regionName}" itemValue="#{adminRegion}" />
<f:converter id="adminRegionConverter" converterId="regionConverter" />
<p:ajax listener="#{aDMSBean.regionSelect}" update="unassignedTasks"></p:ajax>
</p:selectOneMenu>
This crashes and burns:
<p:selectOneRadio id="regions" value="#{aDMSBean.selectedRegion}">
<f:selectItem itemLabel="Global" itemValue="#{null}" />
<f:selectItems value="#{aDMSBean.adminRegions}" var="adminRegion" itemLabel="# {adminRegion.regionName}" itemValue="#{adminRegion}" />
<f:converter id="adminRegionConverter" converterId="regionConverter" />
<p:ajax listener="#{aDMSBean.regionSelect}" update="unassignedTasks"></p:ajax>
</p:selectOneRadio>
I can only assume the converter is OK, as it works with the selectOneMenu.
#FacesConverter("regionConverter")
public class RegionConverter implements Converter {
#Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
Region region = null;
if (value != null && value.length() > 0) {
region = Region.findRegion(new Long(value));
}
return region;
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
String val = "";
if (value != null && value instanceof Region) {
val = ((Region) value).getId().toString();
}
return val;
}
}
Regards
i
In the end it was a recursive #RooToString method being called. I had to examine the data model relationships and add an annotation to #RooToString to avoid the cycle in a few entities
#RooToString(excludeFields = { "adminRegion" })

Disabling items with PrimeFaces SelectOneMenu with custom content / p:column

it seems as if it is not possible to disable items in a SelectOneMenu from PrimeFaces (3.3) when using the custom content (as shown at http://www.primefaces.org/showcase-labs/ui/selectOneMenu.jsf).
The testcase is simple, just take the following:
<h:form>
<p:selectOneMenu value="#{testBean.selected}">
<f:selectItems value="#{testBean.options}" var="t"
itemLabel="#{t.label}" itemValue="#{t}"
itemDisabled="#{t.value % 2 == 0 ? 'true' : 'false'}" />
</p:selectOneMenu>
<p:selectOneMenu value="#{testBean.selected}" var="x">
<f:selectItems value="#{testBean.options}" var="t"
itemLabel="#{t.label}" itemValue="#{t}"
itemDisabled="#{t.value % 2 == 0 ? 'true' : 'false'}" />
<p:column>
#{x.label} -- #{x.label}
</p:column>
</p:selectOneMenu>
</h:form>
and the following Java files:
Bean:
#Named
public class TestBean {
private TestObject selected;
// getter/setter
public List<TestObject> getOptions() {
return Arrays.asList(new TestObject("1"), new TestObject("2")); }
}
Object:
public class TestObject {
private Integer value;
// getter/setter
public TestObject() {}
public TestObject(String s) {
this.setLabel(s);
}
public String getLabel() {return "label: " + value;}
public void setLabel(String l) {this.value = new Integer(l);}
}
The first dropdown works fine, the second one doesn't. Any idea on how to solve that?

Resources