Supplying parameters through p:remoteCommand to a Spring bean - spring

The following XHTML sets a selected value in <p:selectOneMenu> to a request scoped bean through <p:remoteCommand>.
<h:form id="languageForm" prependId="true">
<pe:blockUI target=":body" widgetVar="blockBodyUIWidget">
<h:panelGrid columns="2">
<h:graphicImage library="default" name="images/ajax-loader1.gif" class="block-ui-image"/>
<h:outputText value="#{messages['blockui.panel.message']}" class="block-ui-text"/>
</h:panelGrid>
</pe:blockUI>
<p:selectOneMenu id="languages" value="#{localeBean.language}" onchange="changeLanguage([{name:'language', value:this.value}]);">
<f:selectItem itemValue="en" itemLabel="#{messages['languages.english']}" />
<f:selectItem itemValue="hi" itemLabel="#{messages['languages.hindi']}" />
</p:selectOneMenu>
<p:remoteCommand name="changeLanguage" process="#this" update="#none" onstart="PF('blockBodyUIWidget').block();" oncomplete="PF('blockBodyUIWidget').unblock();" action="#{intermediateLocaleBean.localeAction}"/>
</h:form>
The corresponding JSF managed bean:
#ManagedBean
#RequestScoped
public final class IntermediateLocaleBean
{
#ManagedProperty("#{param.language}")
private String language;
#ManagedProperty("#{localeBean}")
private LocaleBean localeBean; //Injecting another session scoped bean here.
public IntermediateLocaleBean() {}
public void setLanguage(String language) {
this.language = language;
}
public void setLocaleBean(LocaleBean localeBean) {
this.localeBean = localeBean;
}
public String localeAction()
{
localeBean.setLocale(language.equals("hi")?new Locale(language, "IN"):new Locale(language));
return FacesContext.getCurrentInstance().getViewRoot().getViewId() + "?faces-redirect=true";
}
}
The language property is initialized to the selected language in <p:selectOneMenu>. This is all done as it is a JSF managed bean.
What if, the bean is maintained by Spring like as follows?
#Controller
#Scope("request")
public final class IntermediateLocaleBean
{
//Do something to initialize the property - language.
//#ManagedProperty would not work as this bean is managed by Spring.
//It is not initialized to the selected language in <p:selectOneMenu>.
//It is null.
private String language;
//The session scoped bean is injected using the #Autowired annotation as follows.
#Autowired
private final transient LocaleBean localeBean=null;
public IntermediateLocaleBean() {}
public void setLanguage(String language) {
this.language = language;
}
public String localeAction()
{
localeBean.setLocale(language.equals("hi")?new Locale(language, "IN"):new Locale(language));
return FacesContext.getCurrentInstance().getViewRoot().getViewId() + "?faces-redirect=true";
}
}
How to initialize the language property to the selected language in <p:selectOneMenu> in this bean?

Traditionally, the parameter value of language - a request parameter, could be made available using
FacesContext context = FacesContext.getCurrentInstance();
String language = context.getExternalContext().getRequestParameterMap().get("language");
like the following,
#Controller
#Scope("request")
public final class IntermediateLocaleBean
{
#Autowired
private final transient LocaleBean localeBean=null;
public IntermediateLocaleBean() {}
public void setLanguage(String language) {
this.language = language;
}
public String localeAction()
{
String language = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("language");
localeBean.setLocale(language.equals("hi")?new Locale(language, "IN"):new Locale(language));
return FacesContext.getCurrentInstance().getViewRoot().getViewId() + "?faces-redirect=true";
}
}
But I personally dislike exposing the entire request using FacesContext unless it is absolutely necessary.
There is an org.springframework.beans.factory.annotation.Value annotation in Spring that can be used with the Spring expression language to obtain request parameters as follows.
#Controller
#Scope("request")
public final class IntermediateLocaleBean
{
#Value("#{request.getParameter('language')}") //Exposing the value of language.
private String language;
#Autowired
private final transient LocaleBean localeBean=null;
public IntermediateLocaleBean() {}
public void setLanguage(String language) {
this.language = language;
}
public String localeAction()
{
localeBean.setLocale(language.equals("hi")?new Locale(language, "IN"):new Locale(language));
return FacesContext.getCurrentInstance().getViewRoot().getViewId() + "?faces-redirect=true";
}
}
The value of language supplied by <p:remoteCommand> as a request parameter is now available in this bean using the #Value annotation (the getter method for language is not required in my case).
Please suggest or add another answer, if something else is available!

Related

How enforce a p:inputText value to be set through p:ajax if the JSR 303 validation constraint is violated?

I have a Java Web 7 project in which I want to write JSF component values directly on an entity instance managed in a backing bean on every p:ajax event. That works fine as long as I add a JSR 303 validation constraint, like #Size(min=5) on one of the entity properties. The value is not longer set on the property with the constraint as long as the constraint is violated. The setter isn't called according to NetBeans debugger; the other property works just fine which leads me to believe that I've isolated the problem. I would like to perform validation when I want and thus get and invalid value set if I want. How to acchieve that?
In my minimal reproducible example I have the entity MyEntity (JPA and JSR 303 annotations)
#Entity
public class MyEntity implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue
private Long id;
#Size(min = 5)
private String property1;
private String property2;
public MyEntity() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getProperty1() {
return property1;
}
public void setProperty1(String property1) {
this.property1 = property1;
}
public String getProperty2() {
return property2;
}
public void setProperty2(String property2) {
this.property2 = property2;
}
}
a JSF page
<?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">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<h:form>
<p:inputText value="#{myManagedBean.myEntity.property1}">
<p:ajax/>
</p:inputText>
<p:inputTextarea value="#{myManagedBean.myEntity.property2}">
<p:ajax/>
</p:inputTextarea>
<p:commandButton value="Save">
<p:ajax listener="#{myManagedBean.onSaveButtonClicked}"/>
</p:commandButton>
</h:form>
</h:body>
</html>
and a backing bean
#ManagedBean
#SessionScoped
public class MyManagedBean {
private String value;
private String textAreaValue;
private MyEntity myEntity = new MyEntity();
public MyManagedBean() {
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getTextAreaValue() {
return textAreaValue;
}
public MyEntity getMyEntity() {
return myEntity;
}
public void setMyEntity(MyEntity myEntity) {
this.myEntity = myEntity;
}
public void setTextAreaValue(String textAreaValue) {
this.textAreaValue = textAreaValue;
}
public void onSaveButtonClicked(AjaxBehaviorEvent event) {
System.out.println("value: "+value);
System.out.println("textAreaValue: "+textAreaValue);
System.out.println("myEntity: "+myEntity);
}
}
The example can be found at https://github.com/krichter722/jsf-skip-entity-validation. I'm using Primefaces 6.0.
It is working as it is supposed to work. If the validation fails the setter shouldn't be called. If you want you can disable bean validations with this:
<f:validateBean disabled="true"/>

Can I call multiple methods from <p:ajax event=select listner=method1, metho2>?

Can I call multiple methods from the ajax event select in listener?
<p:tree value="#{ddTreeBean.root}" var="node" dynamic="true"
selectionMode="single" selection="#{ddTreeBean.selectedNode}">
<p:ajax event="select" listener="#{data2.refresh}"
update=":pchartId,:panelId">
</p:ajax>
<p:treeNode type="node" expandedIcon="folder-open"
collapsedIcon="folder-collapsed">
<h:outputText value="#{node.name}" />
</p:treeNode>
<p:treeNode type="leaf" icon="document-node">
<h:outputText value="#{node.name}" />
</p:treeNode>
</p:tree>
on a select I need to bind my listener to two methods?
Is that allowed?
I have a tree and when I make a selection, I need to update (trigger) two components (two other back beans).
Does listener attribute take two parameters (two method names)?
THanks.
Myclass1 class {
method1();
}
Myclass2 class {
method2();
}
If you want to call a method of one ManagedBean from another, you have to Inject the other ManagedBean.
#ManagedBean
public class MyBean1{
public void methodAbc(){
...
}
}
Inject in to
#ManagedBean
public class MyBean2{
#ManagedProperty(value = "#{myBean1}")
private MyBean1 mybean1;
//SETTER GETTER for mybean1
public void myAction(){
mybean1.methodAbc();
}
}
Compatible ManagedBean Injection scoped are given in following table(courtesy of Core Java Server Faces Book):
OR You can dynalically resolve EL expression in your Action method itself as follows.
public void myAction(){
FacesContext fctx = FacesContext.getCurrentInstance();
MyBean1 mybean1 = fctx.getApplication().evaluateExpressionGet(fctx , "#{myBean1}", MyBean1.class);
mybean1.methodAbc();
}
Since you are using Primefaces there is one more way to do this, using p:remoteCommand :
<p:ajax event="select" listener="#{data2.refresh}"
update=":pchartId,:panelId"
oncomplete="callRemote2()"/>
<p:remoteCommand name="callRemote" partialSubmit="true" process="#this"
action="#{yourmanagedbean.method2}" />
No, it doesn't. You can have a single method where you call the two or more methods you need to execute:
<p:ajax event="select" listener="#{someMB.multipleMethods}" update=":pchartId,:panelId" />
And in Java side
#ManagedBean
#ViewScoped
public class SomeMB {
public void method1() { /* */ }
public void method2() { /* */ }
public void multipleMethods() {
method1();
method2();
}
}
If you need to use several managed beans, an option is to inject one into the other:
#ManagedBean
#SessionScoped
public class AnotherMB {
public void method2() { /* */ }
}
#ManagedBean
#ViewScoped
public class SomeMB {
#ManagedProperty("#{anotherMB}")
AnotherMB anotherMB;
//provide a setter
public void setAnotherMB(AnotherMB anotherMB) {
this.anotherMB = anotherMB;
}
public void method1() { /* */ }
public void multipleMethods() {
method1();
anotherMB.method2();
}
}

Ajax event does not fire on JSF page when an item is selected (update)

I am learning JavaEE and I am playing around with ajax call with jsf and managedbean. I am trying to display the text as soon as i change the value from the drop down list. I see many people have the same problem on stackoverflow and i try to follow answers that are marked as accepted but I still can't make it work. Can someone please tell me where my error is?
Here is the jsf code:
<h:form>
<h:selectOneMenu id="productlist" value="#{productRepoMB.selectedProduct}">
<f:selectItems value="#{productRepoMB.productList}" var="product" itemValue="#{product.productID}" />
<f:ajax event="valueChange"
render="result"
listener="#{productRepoMB.selectMenuListener}" />
</h:selectOneMenu>
text changed: <h:outputText id="result" value="#{productRepoMB.text}" />
</h:form>
Here is managed bean code, Products list is populated from a database:
#Named
#RequestScoped
public class ProductRepoMB implements Serializable {
#EJB
private ProductsRepo productRepo;
private Products selectedProduct;
private List<Products> productList;
private String text="init text"; //use for testing ajax call
public ProductRepoMB() {
}
public Products getSelectedProduct() {
return selectedProduct;
}
public List<Products> getProductList() {
productList = productRepo.findAll();
return productList;
}
//The following code are used to testing ajax only!
public void selectMenuListener(AjaxBehaviorEvent e) {
setText("changed!");
}
public String getText() {
return text;
}
public void setText(String text){
this.text = text;
}
}

Primefaces how to get POJO from selectOneMenu

My question is how to get value from selection in 'selectOneMenu' component. I use POJO not String type. I try to display the name property of selected object in inputText. I use commandButton to refresh value in inputText as in code below. But the problem is that nothing appears in inputText. I'm not sure there is need to use converter but I tried and it also hasn't worked.
here is my .jsp file:
<p:selectOneMenu value="#{appointentBean.selectedSpecialization}">
<f:selectItems value="#{appointentBean.specializationResult}" var="i" itemValue="#{i}" itemLabel="#{i.name}"/>
</p:selectOneMenu>
<p:commandButton value="Szukaj" >
<p:ajax update="textid" />
</p:commandButton>
<p:inputText id="textid" value="#{appointentBean.selectedSpecialization.name}" />
appointmentBean:
#ManagedBean
#ViewScoped
#SessionScoped
public class appointentBean
{
private ArrayList<Specialization> specializationResult;
private Specialization selectedSpecialization;
public ArrayList<Specialization> getSpecializationResult()
{
//Here retrievie objects list from database and it works
return specializationResult;
}
public void setSpecializationResult(ArrayList<Specialization> result) {
this.specializationResult = result;
}
public Specialization getSelectedSpecialization() {
return selectedSpecialization;
}
public void setSelectedSpecialization(Specialization selectedSpecialization) {
this.selectedSpecialization = selectedSpecialization;
}
}
Specialization.java:
#Entity
#Table(name="Specializations")
public class Specialization
{
#Id
#GeneratedValue
private int specialization_id;
#Column(name="name")
private String name;
public int getSpecialization_id() {
return specialization_id;
}
public void setSpecialization_id(int specialization_id) {
this.specialization_id = specialization_id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
What is more. If I do not make selection on the list NullPointerExcetion appears. But when I make choice i doesn't. So the object is set after selection.
Give a name to your Managed Bean like this
1. #ManagedBean(name ="appointentBean")
2. It should be in Session Scoped or View Scoped not in Both
Your code works perfectly on my End. I did changes to
ArrayList<Specialization> getSpecializationResult() like this:
public ArrayList<Specialization> getSpecializationResult()
{
//Here retrievie objects list from database and it works
specializationResult = new ArrayList<Specialization>();
Specialization specialize= new Specialization();
specialize.setName("Vinayak");
specialize.setSpecialization_id(1);
specializationResult.add(specialize);
return specializationResult;
}
It worked . So, make the necessary changes and let us know.
EDIT 2
Whenever we Deal with POJO's at that time we have to deal with Converter.
Why Custom Converter is the question is what you want to ask now. Refer Custom Converter
These are the steps to create Custom Converter
1. Create a converter class by implementing javax.faces.convert.Converter interface.
2. Override both getAsObject() and getAsString() methods.
3. Assign an unique converter ID with #FacesConverter annotation present in javax.annotation.
First of all I have created a POJOConverter class for your Specialization class
package primefaces1;
import java.util.ArrayList;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import javax.faces.convert.FacesConverter;
#FacesConverter(forClass=Specialization.class)
public class PojoConverter implements Converter{
public static List<Specialization> specilizationObject;
static {
specilizationObject = new ArrayList<Specialization>();
specilizationObject.add(new Specialization("Vinayak", 10));
specilizationObject.add(new Specialization("Pingale", 9));
}
public Object getAsObject(FacesContext facesContext, UIComponent
component, String submittedValue) {
if (submittedValue.trim().equals("")) {
return null;
} else {
try {
for (Specialization p : specilizationObject) {
if (p.getName().equals(submittedValue)) {
return p;
}
}
} catch(NumberFormatException exception) {
throw new ConverterException(new
FacesMessage(FacesMessage.SEVERITY_ERROR, "Conversion
Error", "Not a valid Specialization"));
}
}
return null;
}
public String getAsString(FacesContext facesContext, UIComponent
component, Object value) {
if (value == null || value.equals("")) {
return "";
} else {
return String.valueOf(((Specialization) value).getName());
}
}
}
Following changes has been made to your managed Bean class. To overcome the NUll Pointer Exception
package primefaces1;
import java.util.ArrayList;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean(name = "appointentBean")
#SessionScoped
public class appointentBean {
private ArrayList<Specialization> specializationResult;
private Specialization selectedSpecialization ;
#PostConstruct
public void init() {
selectedSpecialization = new Specialization();
selectedSpecialization.setName(new String());
selectedSpecialization.setSpecialization_id(0);
}
public appointentBean() {
specializationResult= (ArrayList<Specialization>)
PojoConverter.specilizationObject;
}
public ArrayList<Specialization> getSpecializationResult() {
// Here retrievie objects list from database
//and it works
return specializationResult;
}
public void setSpecializationResult(ArrayList<Specialization> result) {
this.specializationResult = result;
}
public Specialization getSelectedSpecialization() {
if (this.selectedSpecialization != null)
System.out.println("getSelectedSpecialization----"
+ this.selectedSpecialization.getName());
return this.selectedSpecialization;
}
public void setSelectedSpecialization(Specialization
selectedSpecialization) {
this.selectedSpecialization = selectedSpecialization;
}
}
I have made some minute changes to your xhtml for showing values.
<h:body>
<h:form id="me">
<p:selectOneMenu value="#{appointentBean.selectedSpecialization}" >
<f:selectItem itemLabel="Select One" itemValue=""></f:selectItem>
<f:selectItems value="#{appointentBean.specializationResult}"
var="result" itemValue="#{result}" itemLabel="#{result.name}" />
</p:selectOneMenu>
<p:commandButton value="Szukaj" update="me:textid">
</p:commandButton>
<h:outputText value="NAME: "></h:outputText>
<h:outputText id="textid" value="#{appointentBean.selectedSpecialization.name}" rendered="#{not empty appointentBean.selectedSpecialization}"/>
</h:form>
</h:body>
I find myself in the same situation that user2374573, SelectOneMenu, was populated correctly using a custom converter, but the selected item was null. The proposed solution is a variation of the custom converter, but it doesn't solve the problem (at least for me). The value selecting does not arrive as explained in the Primefaces documentation, this occurs because SelectOneMenu operates with String and not with Pojos. After studying In the end I have opted for an intermediate solution.
Instead of having a variable of type pojo to store the value, I use just having a String that stores the id of the element as follows.
This solution has been useful for the SelectOneMenu and also for loading the Targer in the DualList used in the Primefaces Picklist. It is not an ideal solution, but it saves the problem.
Java View
public class PickListView implements Serializable {
private static final long serialVersionUID = 1L;
private List<CviConcesione> listaConcesion;
private CviConcesione concesionSeleccionada;
private String concesionSeleccionadaS;
#Autowired
private ConcesionesBO concesionesBO;
#PostConstruct
public void init() {
}
public List<CviConcesione> getListaConcesion() {
if (null != listaConcesion && !listaConcesion.isEmpty()) {
return listaConcesion;
} else {
listaConcesion = new ArrayList<CviConcesione>();
listaConcesion = concesionesBO.consultaTodasConcesiones();
return listaConcesion;
}
}
public void setListaConcesion(List<CviConcesione> listaConcesion) {
this.listaConcesion = listaConcesion;
}
public ConcesionesBO getConcesionesBO() {
return concesionesBO;
}
public void setConcesionesBO(ConcesionesBO concesionesBO) {
this.concesionesBO = concesionesBO;
}
public CviConcesione getConcesionSeleccionada() {
return concesionSeleccionada;
}
public void setConcesionSeleccionada(CviConcesione concesionSeleccionada) {
this.concesionSeleccionada = concesionSeleccionada;
}
public String getConcesionSeleccionadaS() {
return concesionSeleccionadaS;
}
public void setConcesionSeleccionadaS(String concesionSeleccionadaS) {
this.concesionSeleccionadaS = concesionSeleccionadaS;
}
}
Html Code for select one menu
<p:selectOneMenu
id="concesionR"
value="#{pickListView.concesionSeleccionadaS}"
style="width:125px"
dynamic="true"
converter="#{concesionConverter}">
<f:selectItem itemLabel="Seleccione" itemValue="" />
<f:selectItems value="#{pickListView.listaConcesion}"
var="concesion"
itemLabel="#{concesion.conCodigo} - #{concesion.conDescripcion}"
itemValue="#{concesion.conCodigo}"
ajax = "true"
/>
<p:ajax update="lineaR" process="#form" />
</p:selectOneMenu>
a
Class converter
#FacesConverter("concesionConverter")
public class ConcesionesConverter implements Converter {
public Object getAsObject(FacesContext fc, UIComponent uic, String value) {
if(value != null && value.trim().length() > 0) {
try {
PickListView service = (PickListView) fc.getExternalContext().getApplicationMap().get("pickListView");
return service.getListaConcesion().get(Integer.parseInt(value));
} catch(NumberFormatException e) {
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Conversion Error", "Not a valid theme."));
}
}
else {
return null;
}
}
public String getAsString(FacesContext fc, UIComponent uic, Object object) {
if(object != null) {
return String.valueOf(((CviConcesione) object).getConId());
}
else {
return null;
}
}
}
This solution does not manage to bring the pojo, but lets you know that it has been selected, showing pojo values.

JSF 2.1 SelectOneMenu toggling automatically to init values

I have 2 SelectOneMenu as follows in the index.xhtml. The menu1 essentially chooses a language(sp or en) and menu2 displays the possible serial numbers(0 to 3). I have the init constructor(post constructor) which initialises the default values on the two Menus. However for some strange reason, if I select a serial number other than the default serial number for the language other than the default language, somehow the language gets reset to init default :(
<?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">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>My page</title>
</h:head>
<h:body>
<div>
<h4>Change Existing Description</h4>
</div>
<h:form id="myForm">
<h:panelGrid columns="4">
<h:outputLabel value="Language:" />
<h:selectOneMenu value="#{myBean.language}">
<f:selectItems value="#{myBean.languages}" />
<f:ajax listener="#{myBean.doUpdate}" render ="myForm" />
</h:selectOneMenu>
<h:outputLabel value="SerialID:" />
<h:selectOneMenu value="#{myBean.serialID}">
<f:selectItems value="#{myBean.serialIDs}" />
<f:ajax listener="#{myBean.doUpdate}" render ="myForm" />
</h:selectOneMenu>
</h:panelGrid>
</h:form>
</h:body>
</html>
Here is my Bean code. Where is the problem?? please advise!
package bean;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.Stateful;
import javax.enterprise.context.RequestScoped;
import javax.faces.bean.ManagedBean;
#ManagedBean(name = "myBean")
//#Stateless
#Stateful
#RequestScoped
public class MyBean {
public static final int PERMISSIONS = 2;
private List<String> languages;
private String language;
private int serialID;
private List<Integer> serialIDs;
/**
* init() method for initializing the bean. Is called after constuction.
*/
#PostConstruct
private void init() {
//public MyBean () {
languages = getAllLanguages();
language = "en"; //defaultLanguage
serialID = 3;
serialIDs = getSerialIDsFromOverview();
}
public List<String> getLanguages() {
System.out.println("getLanguages, language " +language);
return languages;
}
public int getPERMISSIONS() {
return PERMISSIONS;
}
public String getLanguage() {
System.out.println("getLanguage " +language);
return language;
}
public void setLanguage(String language) {
System.out.println("setLanguage " +language);
this.language = language;
}
public int getSerialID() {
System.out.println("getSerialID " +serialID);
return serialID;
}
public void setSerialID(int serialID) {
System.out.println("setSerialID " +serialID);
this.serialID = serialID;
}
public List<Integer> getSerialIDs() {
System.out.println("getSerialIDs language = "+language );
return serialIDs;
}
public List<String> getAllLanguages() {
List<String> results = new ArrayList<String>();
results.add("sp");
results.add("en");
if(results != null){
System.out.println("getting all languages");
}
return results;
}
public void doUpdate() {
System.out.println("doUpdate language " +language);
System.out.println("doUpdate serialID " +serialID);
}
/**
* Returns a list of all serialIDs present in the overview.
* #return
*/
private List<Integer> getSerialIDsFromOverview() {
List<Integer> results = new ArrayList<Integer>();
results.add(0);
results.add(1);
results.add(2);
results.add(3);
return results;
}
}
UPDATES:
After taking suggestions from cubbuk, I sat down and corrected my code with #ViewScoped annotation and making the bean implement Serializable. THIS WORKS. However, the next thing I had to do was include an #EJB annotation to call a stateless bean which calls the Entity manager to fetch the serialIDs from a database instead of "hardcoding" it. That is when I encounter the problem: Not serializable exception "java.io.NotSerializableException: bean.__EJB31_Generated__. How do I solve this? When I made myBean back to RequestScope and remove Serializable, I could run the code without problems however there the toggling of the menu to init values :(
By the way I check this post: #EJB in #ViewScoped managed bean causes java.io.NotSerializableException and set my STATE SAVING METHOD to server but that gives me "empy response from server" pop up message :(
Please help!
Since you are using #RequestScoped bean as your backing bean after each request your init method is getting called and your values are getting reset. To avoid that you need to use #ViewScoped bean as your backing bean. I updated your bean accordingly note that your backing bean now implements Serializable interface. This is needed as this bean will be stored in your servlet and it needs to be flushed to disk if the content can not be hold in the memory. For learning the details of #ViewScoped beans please check the following post:
http://balusc.blogspot.com/2010/06/benefits-and-pitfalls-of-viewscoped.html
Apart from these, for naming conventions I renamed your getAllLanguages and getSerialIDsFromOverview methods to initAllLanguages and initSerialIds as methods starting with get and set can be confusing because they are mostly used for getters and setters.
Lastly when you use f:ajax command by default the UIInput the ajax command is bind to is rendered and executed. Since you don't refresh the h:selectOneMenu menus according to the values of each other you don't need to render the whole form. The following will be enough for this case:
<h:form id="myForm">
<h:panelGrid columns="4">
<h:outputLabel value="Language:" />
<h:selectOneMenu value="#{myBean.language}">
<f:selectItems value="#{myBean.languages}" />
<f:ajax listener="#{myBean.doUpdate}"/>
</h:selectOneMenu>
<h:outputLabel value="SerialID:" />
<h:selectOneMenu value="#{myBean.serialID}">
<f:selectItems value="#{myBean.serialIDs}" />
<f:ajax listener="#{myBean.doUpdate}"/>
</h:selectOneMenu>
</h:panelGrid>
</h:form>
#ManagedBean
#ViewScoped
public class MyBean implements Serializable
{
public static final int PERMISSIONS = 2;
private List<String> languages;
private String language;
private int serialID;
private List<Integer> serialIDs;
/**
* init() method for initializing the bean. Is called after constuction.
*/
#PostConstruct
protected void init()
{
//public MyBean () {
System.out.println("lang: " + language);
System.out.println("serialId: " + serialID);
System.out.println("init is called");
initAllLanguages();
initSerialIds();
language = "en"; //defaultLanguage
serialID = 3;
}
public List<String> getLanguages()
{
return languages;
}
public int getPERMISSIONS()
{
return PERMISSIONS;
}
public String getLanguage()
{
return language;
}
public void setLanguage(String language)
{
this.language = language;
}
public int getSerialID()
{
return serialID;
}
public void setSerialID(int serialID)
{
this.serialID = serialID;
}
public List<Integer> getSerialIDs()
{
return serialIDs;
}
private void initAllLanguages()
{
languages = new ArrayList<String>();
languages.add("sp");
languages.add("en");
}
public void doUpdate()
{
System.out.println("doUpdate language " + language);
System.out.println("doUpdate serialID " + serialID);
}
/**
* Returns a list of all serialIDs present in the overview.
*
* #return
*/
private void initSerialIds()
{
serialIDs = new ArrayList<Integer>();
serialIDs.add(0);
serialIDs.add(1);
serialIDs.add(2);
serialIDs.add(3);
}
}
Cheers

Resources