Multiple instances of managed bean - jsf

I'm using prime-faces Tabs to display multiple input forms. The problem is, there are times when I need to instantiate 2 of the same form. They both of course use the same Managed Bean which causes the input of the first initialized form to override the other with the same data. I need to be able to put different data in each form and submit both of them collectively. Each form goes into a list and forwarded on for calculation. I've been reading scope scope scope scope but the only scope that works somewhat is "Sessioned". Session only allows one instance of the Managed Bean and places the form data into the list, "Request, View scope" Doesn't place the data into the list respectively nor does it hold the data. The Managed Bean is serializable and in sessioned scope. I've read the other post and they don't work. Any ideas?
Backing Bean
#ManagedBean
#SessionScoped
public class RequestCalculation {
private CalculationRequest calcReq;
private List<ViewTabs> formTabs;
private String id;
private boolean calcButton;
public RequestCalculation() {
calcReq = new CalculationRequest();
formTabs = new ArrayList<ViewTabs>();
calcButton = false;
}
public String loadForm(TcsBase loadForm) {
id = loadForm.getId();
ViewTabs tab = new ViewTabs();
tab.setFormTitle("Form".concat(id));
tab.setFormPage("Form".concat(id).concat(".xhtml"));
formTabs.add(0, tab);
calcReq.getFormCollection().add(0, loadForm);
loadCalcButton();
return "Main";
}
public void loadCalcButton() {
if (formTabs.isEmpty())
isCalcButton();
else {
calcButton = true;
}
}
public void onTabClosed(TabCloseEvent e) {
TabView tabView = (TabView) e.getComponent();
int closingTabIndex = tabView.getChildren().indexOf(e.getTab());
removeForm(closingTabIndex);
formTabs.remove(closingTabIndex);
loadCalcButton();
}
public void removeForm(int index) {
TcsBase formIndex = calcReq.getFormCollection().get(index);
String formId = formIndex.getId();
// Creates a new instance of the selected form
FacesContext fc = FacesContext.getCurrentInstance();
fc.getELContext().getELResolver()
.setValue(fc.getELContext(), null, "form".concat(formId), null);
calcReq.getFormCollection().remove(index);
formTabs.remove(index);
}
public String calculate() {
CalculateService service = new CalculateService();
CalculatorInterface calculateInterface = service.getCalculatePort();
XStream xstream = new XStream(new StaxDriver());
xstream.registerConverter(new JodaTimeConverter());
// Here is where the client request (input) is converted to an Xml
// string before going
// to the Web Service
String xml = xstream.toXML(calcReq);
String request = calculateInterface.calculate(xml);
// Here the response back from the Web Service is converted back from
// Xml to a string
// to be displayed to the user in Xhtml
calcReq = (CalculationRequest) xstream.fromXML(request);
FacesContext fc = FacesContext.getCurrentInstance();
for (int i = 0; i < calcReq.getFormCollection().size(); i++) {
TcsBase newFrm = calcReq.getFormCollection().get(i);
String frmId = newFrm.getId();
fc.getELContext()
.getELResolver()
.setValue(fc.getELContext(), null, "form".concat(frmId),
newFrm);
}
return null;
}
public List<ViewTabs> getFormTabs() {
return formTabs;
}
public void setFormTabs(List<ViewTabs> formTabs) {
this.formTabs = formTabs;
}
public boolean isCalcButton() {
return calcButton;
}
public void setCalcButton(boolean calcButton) {
this.calcButton = calcButton;
}
}
**Html Menu **
<!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:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<head>
</head>
<f:view>
<h:body>
<h:commandLink action="#{requestCalculation.loadForm(formA)}" value="FormA" /> <br/>
<h:commandLink action="#{requestCalculation.loadForm(formB)}" value="FormB" /> <br/><br/><br/>
</h:body>
</f:view>
</html>
Html Main page
<!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:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:c="http://java.sun.com/jsp/jstl/core">
<f:view>
<h:head>
<title> TCS </title>
</h:head>
<h:form >
<p:layout style="min-width:400px;min-height:700px " >
<p:layoutUnit position="north" style="text-align:center">
<p style="text-align:center; font-size:28px">Tax Computation Service</p>
</p:layoutUnit>
<p:layoutUnit header="Menu" position="west" style="min-width:190px; min-height:50px; ">
<p:panelMenu>
<p:submenu label="Forms">
<p:submenu label="Individual Forms">
<p:menuitem>
<ui:include src="Menu.xhtml" />
</p:menuitem>
</p:submenu>
</p:submenu>
</p:panelMenu>
</p:layoutUnit>
<p:layoutUnit position="center" >
<p:tabView onTabShow="focus" widgetVar="tabView">
<p:ajax event="tabClose" listener="#{requestCalculation.onTabClosed}"/>
<c:forEach items="#{requestCalculation.formTabs}" var="listItem">
<p:tab title="#{listItem.formTitle}" closable="true" >
<ui:include src="#{listItem.formPage}" />
</p:tab>
</c:forEach>
</p:tabView>
<p:panelGrid columns="0" >
<p:commandButton value="Calculate" action = "#{requestCalculation.calculate}" ajax="false" rendered="#{requestCalculation.calcButton}" />
</p:panelGrid>
</p:layoutUnit>
</p:layout>
</h:form>
</f:view>
</html>
FormA Html
<!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:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<f:view>
<h:head>
<title> FormA</title>
</h:head>
<h:body>
<p:focus />
<p:panelGrid id="panelGridA" columns="2">
<p:outputLabel value="Form ID: " style="width: 725px" />
<p:outputLabel value="#{formA.id}" />
<p:outputLabel value="4. . . " style="width: 725px" />
<p:inputText id="input1" style="text-align:right" value="#{formA.line4}" converter="bdNullableConverter" onfocus="this.select()"/>
<p:outputLabel value="5. . . . . . . " style="width: 725px" />
<p:inputText style="text-align:right" value="#{formA.line5}" converter="bdNullableConverter" onfocus="this.select()" />
<p:outputLabel value="6. . . . . . . . " style="width: 725px" />
<p:outputLabel value="#{formA.line6}" converter="bdNullableConverter" />
</p:panelGrid>
</h:body>
</f:view>
</html>

Instead of trying to use multiple instances of a managed bean, use ONE managed bean that gives access to multiple instances of a class via e.g. a hashmap or arraylist or whatever you want to use. Just like you would in plain old java programming. You cannot have two variables with the same name:
#ViewScoped
#Named
public class RequestCalculations {
Map<String, RequestCalculation> hm;
#PostConstruct
public init() {
hm = new HashMap<>();
// prepopulate if known upfront
hm.put("1", new RequestCalculation());
hm.put("2", new RequestCalculation());
}
public HashMap<String, RequestCalculation> getCalculations() {
return hm;
}
}
Then use the tabIndex of the tab as the key to the hashmap (or an array list). And in your xhtml do something like
#{requestCalculations.calculations[myTabIndex]}
You might need to pass this on to the include via a include param if you need this IN the include (as I think you do)

If you want to use the multiple instances of manager bean, then you can declare it in faces-config.xml file with different names and use it independently. See example
<managed-bean>
<managed-bean-name>productSearchForm</managed-bean-name>
<managed-bean-class>com.company.package.ProductSearchForm</managed-bean-class>
<managed-bean-scope>view</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>productChildFilter</managed-bean-name>
<managed-bean-class>com.company.package.ProductSearchForm</managed-bean-class>
<managed-bean-scope>view</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>productAttachFilter</managed-bean-name>
<managed-bean-class>com.company.package.ProductSearchForm</managed-bean-class>
<managed-bean-scope>view</managed-bean-scope>
</managed-bean>
Edit for JSF 2.3:
If you are using CDI, then you can inject files with different names
#Inject
#ManagedProperty(value = "#{productSearchForm}")
private ProductSearchForm productSearchForm;
#Inject
#ManagedProperty(value = "#{productCandidateForm}")
private ProductSearchForm productCandidateForm;

Related

Getter method returns null when called from action listener [duplicate]

This question already has answers here:
How to choose the right bean scope?
(2 answers)
Closed 4 years ago.
I have an application with a p:selectOneMenu component. This component is used to determine what category of file is being uploaded so I can do some work to it when the file is uploaded.
I implemented the answer from this post and it seems to call my setter methods correctly for fileType. But once the file is submitted and the handleFileUpload method is called, the fileType getter method returns null.
For example, if I select Foo then I get the output
File type changed to: Foo
But when I hit the upload button I get the output
The file type selected is null
When I expect
The file type selected is Foo
What is causing the get method to return two different results and is there a way to fix this?
main.xhtml
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<meta http-equiv="refresh"
content="#{session.maxInactiveInterval};url=index.xhtml" />
<f:view contentType="text/html">
<h:head>
<title>File Upload</title>
</h:head>
<p:layout fullPage="true">
<p:layoutUnit position="center">
<ui:insert name="pagebody" />
</p:layoutUnit>
</p:layout>
</f:view>
</html>
index.xhtml
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui" template="/templates/main.xhtml">
<ui:define name="pagebody">
<h:body>
<h:form id="uploadform" enctype="multipart/form-data">
<h:panelGrid columns="2" style="margin-bottom:10px" cellpadding="5">
<h:outputText value="File Type:" />
<p:selectOneMenu value="#{uploadBean.fileType}">
<f:selectItem itemLabel="Foo" itemValue="Foo"/>
<f:selectItem itemLabel="Bar" itemValue="Bar"/>
<f:ajax listener="#{uploadBean.changeFileType}" />
</p:selectOneMenu>
</h:panelGrid>
<br />
<p:fileUpload fileUploadListener="#{uploadBean.handleFileUpload}" mode="advanced"/>
</h:form>
</h:body>
</ui:define>
</ui:composition>
UploadBean.java
#RequestScoped
#ManagedBean(name = "uploadBean")
public class UploadBean implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private String fileType = null;
#PostConstruct
public void init() {
}
public void handleFileUpload(FileUploadEvent event){
System.out.println("The file type selected is " + this.getFileType());
}
public String getFileType() {
return fileType;
}
public void setFileType(String fileType) {
this.fileType = fileType;
}
public void changeFileType() {
System.out.println("File type changed to: " + this.getFileType());
}
}
As pointed out by #Kukeltje the issue was that my bean was not properly scoped. Switching from RequestScoped to ViewScoped fixed the issue I was having.

echo parameter with an #Named backing bean to a facelets template client

What should be the return type for getResponse and submit, and are both necessary?
When a guess is entered in either the firstForm or SecondForm, how do I echo that guess to the same webpage?
Either with ajax, and so not reloading the same page
or
loading a new page, guessResults.xhtml, for example, which echo's the guess.
backing bean, NextClient:
package dur.beans;
import dur.jpa.Client;
import dur.jpa.ClientFacadeLocal;
import java.util.concurrent.atomic.AtomicInteger;
import javax.ejb.EJB;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Named;
#Named("nextClient")
#ApplicationScoped
public class NextClient implements NextClientLocal {
#EJB
private ClientFacadeLocal clientFacade;
private AtomicInteger next = new AtomicInteger(1009);
private AtomicInteger guess = new AtomicInteger(0);
private final boolean correct = true;
#Override
public String getNext() {
next.addAndGet(1);
Client client = clientFacade.find(next.intValue());
return client.toString();
}
#Override
public void setGuess(int guessInt) {
guess = new AtomicInteger(guessInt);
}
#Override
public int getGuess() {
return guess.intValue();
}
//not sure what do with these methods
#Override
public String getResponse() {
return "the guess of " + guess.intValue() + " is " + correct;
}
#Override
public String submit() {
return "the guess of " + guess.intValue() + " is " + correct;
}
}
facelets template client, next.xhtml:
<!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:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
>
<h:head></h:head>
<h:body>
This and everything before will be ignored
<ui:composition template="template.xhtml">
<ui:define name="navigation">
<ui:include src="menu.xhtml"/>
</ui:define>
<ui:define name="main">
<h1>next bird</h1>
<p>
#{nextClient.next}
</p>
<p>
<h:panelGroup id="firstPanel">
<h:form id="firstForm">
<h:outputLabel for="input" value="First form input" />
<h:inputText id="input" value="#{nextClient.guess}" required="true" />
<h:commandButton value="Submit form" action="#{nextClient.submit}">
<f:ajax execute="#form" render="#form :secondPanel :secondForm :messages" />
</h:commandButton>
<h:message for="input" />
</h:form>
</h:panelGroup>
<h:panelGroup id="secondPanel">
<h:form id="secondForm">
<h:outputLabel for="input" value="Second form input" />
<h:inputText id="input" value="#{nextClient.guess}" required="true" />
<h:commandButton value="Submit other form" action="#{nextClient.submit}">
<f:ajax execute="#form" render="#form :firstPanel :firstForm :messages" />
</h:commandButton>
<h:message for="input" />
</h:form>
</h:panelGroup>
<h:messages id="messages" globalOnly="true" layout="table" />
</p>
</ui:define>
</ui:composition>
This and everything after will be ignored
</h:body>
</html>
see also:
http://balusc.blogspot.ca/2011/09/communication-in-jsf-20.html#AjaxRenderingOfContentWhichContainsAnotherForm
JSF 2.0 commandButton do nothing
https://javaserverfaces.java.net/nonav/docs/2.0/pdldocs/facelets/h/commandButton.html
http://docs.oracle.com/javaee/7/tutorial/doc/jsf-facelets003.htm
I'm running facelets on Glassfish, using CDI, so am using #Named and not #ManagedBean -- some of the documentation above is more geared for #ManagedBean, but I'm not sure how much that matters.
The goal is one step better than "hello world", "hello world, your guess is " would be a good result. If there's a specific manual, I don't mind a RTFM to that specific documentation. The Oracle docs are probably the best for facelets?
code:
https://github.com/THUFIR/EntAppWeb
This response.xhtml:
<!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:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>response</h:head>
<h:body>
This and everything before will be ignored
<ui:composition template="template.xhtml">
<ui:define name="navigation">
<ui:include src="menu.xhtml"/>
</ui:define>
<ui:define name="main">
<h1>submitted value</h1>
<p>
#{nextClient.guess}
</p>
<h2>for this bird</h2>
<p>
#{nextClient.client}
</p>
</ui:define>
</ui:composition>
This and everything after will be ignored
</h:body>
</html>
to next.xhtml:
<!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:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>next</h:head>
<h:body>
This and everything before will be ignored
<ui:composition template="template.xhtml">
<ui:define name="navigation">
<ui:include src="menu.xhtml"/>
</ui:define>
<ui:define name="main">
<h1>next bird</h1>
<p>
#{nextClient.next}
</p>
<p>
<h:panelGroup id="simpleGroup">
<h:form id="simpleForm">
<h:outputLabel for="input" value="First form input" />
<h:inputText id="input" value="#{nextClient.guess}" required="true" />
<h:commandButton value="submit" action="response">
</h:commandButton>
</h:form>
</h:panelGroup>
</p>
</ui:define>
</ui:composition>
This and everything after will be ignored
</h:body>
</html>
using the backing bean NextClient:
package dur.beans;
import dur.jpa.Client;
import dur.jpa.ClientFacadeLocal;
import java.util.concurrent.atomic.AtomicInteger;
import javax.ejb.EJB;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Named;
#Named("nextClient")
#ApplicationScoped
public class NextClient implements NextClientLocal {
#EJB
private ClientFacadeLocal clientFacade;
private AtomicInteger next = new AtomicInteger(1009);
private AtomicInteger guess = new AtomicInteger(0);
private final boolean correct = true;
private Client client = new Client();
#Override
public String getNext() {
next.addAndGet(1);
client = clientFacade.find(next.intValue());
return client.toString();
}
#Override
public void setGuess(int guessInt) {
guess = new AtomicInteger(guessInt);
}
#Override
public int getGuess() {
return guess.intValue();
}
#Override
public Client getClient() {
return client;
}
#Override
public void setClient(Client client) {
this.client = client;
}
}
outputs the submitted value to the response, along with the bird. It might make more sense to output the result to the same page, but this is sufficient.

Can't get view Scoped bean value on another jsf page?

I am developing a project using JSF. In an opening popup window, i want to show some details about a product but can not get view scoped bean' s value on a datatable.
Can you help me?
Thanks.
Here is my UrunuDenetlemeSayfasi.xhtml code snippet:
<h:commandLink onclick="window.open('UruneGozAt.xhtml',
'Ürün İçeriği', config='width=700, height=400, top=100, left=100,
scrollbars=no, resizable=no');"
action="#{uruneGozAtBean.urunIdsineGoreUrunIcerigiGetir}" value="Ürün İçeriğine Göz At">
<f:param name="urunid" value="#{urun.urunID}" />
</h:commandLink>
Here is UrunuGozAt.xhtml:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:body>
<h:dataTable class="table table-striped"
value="#{uruneGozAtBean.urunIcerik}" var="urun">
<h:column>
<f:facet name="header">
<h:outputText value="barkod no" />
</f:facet>
<h:outputText value="#{urun.barkodNo}" />
</h:column>
</h:dataTable>
</h:body>
</html>
Here is UruneGozAtBean.java
UrunDenetlemeSayfasiBean urunDenetle = new UrunDenetlemeSayfasiBean();
UrunDenetleService urunService = new UrunDenetleService();
private UrunIcerik urunIcerik = new UrunIcerik();
private Long urunIdParametre;
public UrunIcerik getUrunIcerik() {
return urunIcerik;
}
public void setUrunIcerik(UrunIcerik urunIcerik) {
this.urunIcerik = urunIcerik;
}
public Long getUrunIdParametre() {
return urunIdParametre;
}
public void setUrunIdParametre(Long urunIdParametre) {
this.urunIdParametre = urunIdParametre;
}
public void urunIdsineGoreUrunIcerigiGetir() {
setUrunIcerik(urunService.urunIdsineGoreUrunIcerigiGetir(urunIdEldeEt()));
}
public Long urunIdEldeEt(){
FacesContext fc = FacesContext.getCurrentInstance();
setUrunIdParametre(getUrunIdParametre(fc));
return getUrunIdParametre();
}
public Long getUrunIdParametre(FacesContext fc){
Map<String, String> parametre = fc.getExternalContext().getRequestParameterMap();
return Long.valueOf(parametre.get("urunid")).longValue();
}
EDIT:
This is now my current implementation, it returns null.
i am developing a project using JSF. In an opening popup window, i want to show some details about a product but can not get view scoped bean' s value on a datatable.
Can you help me?
Thanks.
Here is my UrunuDenetlemeSayfasi.xhtml code snippet:
<h:commandLink onclick="window.open('UruneGozAt.xhtml','Ürün İçeriği',
config='width=700, height=400, top=100, left=100, scrollbars=no, resizable=no');"
value="Ürün İçeriğine Göz At"> <f:param name="urunId" value="#{urun.urunID}" />
</h:commandLink>
Here is UruneGozAt.xhtml:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<f:metadata>
<f:viewParam name="urunId" value="#{uruneGozAtBean.urunId}"
required="false" />
<f:viewAction action="#{uruneGozAtBean.urunIdsineGoreUrunIcerigiGetir()}" />
</f:metadata>
<h:head>
<title>Ürün İçeriği</title>
<!-- add this always, even if it's empty -->
</h:head>
<h:body>
<h:dataTable class="table table-striped"
value="#{uruneGozAtBean.urunIcerik}" var="urun">
<h:column>
<f:facet name="header">
<h:outputText value="barkod no" />
</f:facet>
<h:outputText value="#{urun.barkodNo}" />
</h:column>
</h:dataTable>
</h:body>
</html>
Here is UruneGozAtBean.java
#ManagedBean
#ViewScoped
public class UruneGozAtBean {
public UrunDenetlemeSayfasiBean urunDenetle = new UrunDenetlemeSayfasiBean();
public UrunDenetleService urunService = new UrunDenetleService();
private ArrayList<UrunIcerik> urunIcerik = new ArrayList<UrunIcerik>();
private Long urunId;
public Long getUrunId() {
return urunId;
}
public void setUrunId(Long urunId) {
this.urunId = urunId;
}
public ArrayList<UrunIcerik> getUrunIcerik() {
return urunIcerik;
}
public void setUrunIcerik(ArrayList<UrunIcerik> urunIcerik) {
this.urunIcerik = urunIcerik;
}
public void urunIdsineGoreUrunIcerigiGetir() {
setUrunIcerik(urunService.urunIdsineGoreUrunIcerigiGetir(urunIdEldeEt()));
System.out.print("aaa");
}
public Long urunIdEldeEt() {
FacesContext fc = FacesContext.getCurrentInstance();
setUrunId(getUrunId(fc));
return getUrunId();
}
public Long getUrunId(FacesContext fc) {
Map<String, String> parametre = fc.getExternalContext().getRequestParameterMap();
return Long.valueOf(parametre.get("urunId")).longValue();
}
}
#ViewScoped beans are alive per view. If you open a popup window from your current view, then you're opening a new view, so even if it uses the same managed bean to display the data, since they're different views, they use different instances of the same class.
In cases like this, you should pass a parameter through query string, then receive it in your view and process it to load the desired data. In this case, your code would be like this (note: make sure you send the parameter with name "urunId"):
UrunuGozAt.xhtml:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<!-- add this always, even if it's empty -->
<f:metadata>
<f:viewParam name="urunId" value="#{uruneGozAtBean.urunId}"
required="false" />
<f:viewAction action="#{uruneGozAtBean.loadData}" />
</f:metadata>
</h:head>
<h:body>
<h:dataTable class="table table-striped"
value="#{uruneGozAtBean.urunIcerik}" var="urun">
<h:column>
<f:facet name="header">
<h:outputText value="barkod no" />
</f:facet>
<h:outputText value="#{urun.barkodNo}" />
</h:column>
</h:dataTable>
</h:body>
</html>
UruneGozAtBean managed bean:
#ViewScoped
#ManagedBean
public class UruneGozAtBean {
//your current fields, getters and setters...
private Long urunId;
//getter and setter for this field...
public void loadData() {
if (urunId != null) {
//load the data for the table...
}
}
}
More info:
What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?
How to choose the right bean scope?
DataTable expects a list to iterate through, but as far as I can see you return an UrunIcerik object.

JSF command button not working within included JSF page

I'm try to build application with Primefaces 4.0 and JSF 2.2.5. I need to load content dynamically in accordance with choosen menu item.
Here is my main 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"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>Hello, world!</title>
</h:head>
<h:body>
<p:layout fullPage="true">
<p:layoutUnit position="west" size="15%">
<h:form>
<p:commandButton value="List1" action="#{backingBean.setCurrentPage('included.xhtml')}"
update=":mypanel_id" process="#this"/><br/>
<p:commandButton value="List2"/>
</h:form>
</p:layoutUnit>
<p:layoutUnit position="center">
<p:panel id="mypanel_id">
<ui:include src="#{backingBean.page}"/>
</p:panel>
<p:messages autoUpdate="true" showDetail="true" showSummary="true"/>
</p:layoutUnit>
</p:layout>
</h:body>
</html>
And this is included 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:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Hello,world</title>
</h:head>
<h:body>
<h:outputText value="Included page"/>
<h:form>
<ui:repeat value="#{backingBean.items}" var="item">
<p:fieldset legend="item" toggleable="true">
<h:outputText value="#{item}"/>
<ui:param name="it" value="#{item}"/>
<p:commandButton value="Click" style="margin-left: 50px;"
actionListener="#{backingBean.actionListener}"/>
</p:fieldset>
</ui:repeat>
<p:commandButton value="Test" action="#{backingBean.actionListener}"/>
</h:form>
</h:body>
</html>
Command buttons not work. Not with action nor with actionListener. What i'm doing wrong? How to build page with conditionally rendered elements, such as command buttons and fieldsets?
P.S. Forget to say, that my bean have request scope.
Updated:
public class BackingBean {
private List<String> items;
private String currentItem;
private String page;
public BackingBean() {
items = new ArrayList<String>();
}
public List<String> getItems() {
if (items.size() == 0) {
this.fillAndUpdate();
}
return items;
}
public void setItems(List<String> items) {
this.items = items;
}
public void fillAndUpdate() {
for (int i = 0; i < 5; i++) {
items.add("Item " + String.valueOf(i));
}
}
public String getPage() {
return page;
}
public void setPage(String page) {
this.page = page;
}
public void setCurrentPage(String page) {
this.page = page;
}
public void actionListener() {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Test"));
}
}
UPDATED
Ok. I found the error (if someone interested). Because my bean has request scope, when i click the button in right panel my view was updated, but list of items was updated too and became empty (request scope). Now i keep selected menu in the session bean, and return that number when view rendered.
try to add ajax="false" in your command buttons

#ViewScope not working with primefaces <p:ajax>

I am not able to get he the selected value from the table withe bean in View scope.
Following code doesn't work but it works when I uses Session or Request scope.
Here's my JSF page:
<!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:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:p="http://primefaces.org/ui">
<f:view>
<h:head>
<title>Sample JSF/Prime Page</title>
</h:head>
<h:body>
<h:form id="primeForm">
<p:panel id="toggle1" header="Panel 1" collapsed="#{prime.toggle1}" footer=" footer Info if required " toggleable="true" closable="true" >
<p:dataTable id="cars" value="#{prime.listModel}" var="data" paginator="true" style="width:500px"
selection="#{prime.selected}" selectionMode="single">
<p:ajax event="rowSelect" listener="#{prime.onRowSelect}" />
<f:facet name="header">
Select a row to display a message
</f:facet>
<p:column headerText="Model">
#{data.number}
</p:column>
<p:column headerText="Model">
#{data.number}
</p:column>
</p:dataTable>
</p:panel>
</h:form>
</h:body>
</f:view>
</html>
Here's my bean:
#ManagedBean
#ViewScoped
public class Prime implements Serializable {
ArrayList<UIData> list = new ArrayList<UIData>();
private UIData selected;
private UIDataModel listModel;
private String testVaue;
private ArrayList<String> tmp = new ArrayList<String>();
private HashMap<String, List<String>> pagesMap = new HashMap<String, List<String>>();
private boolean toggle1 = true;
public Prime() {
for (int k = 1; k < 3; k++) {
UIData model =new UIData(""+k, ""+k);
list.add(model);
}
listModel = new UIDataModel(list);
}
public void onRowSelect(SelectEvent event) {
try{
System.out.println("Sellected Value : "+((UIData)event.getObject()).getNumber());
}catch (Exception e) {
e.printStackTrace();
}
}
// Getters and setters.
}
Add proper rowKey attribute to datatable. Primefaces must have a way to uniquely identify you row. That's why you should set a property which is unique to you dataset. Usually this is database primary key. In your case for example it coul be rowKey=#{data.number}.

Resources