JSF command button not working within included JSF page - jsf

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

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.

Javax ViewExpiredException thrown upon POST

I try to understand why I get a javax ViewExpiredException on my simple webapp - but I don't seem to understand what is causing the view to expire.
This is the register.jsf:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:b="http://bootsfaces.net/ui"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
template="pageTemplate.xhtml">
<ui:define name="content">
<b:panel title="Registrierung" look="primary">
<h:form>
<h:panelGrid>
<h:outputText value="Name:"/>
<b:inputText value="#{registerController.user.name}" placeholder="Robina Kuh"/>
<h:outputText value="E-Mail:"/>
<b:inputText value="#{registerController.user.email}" placeholder="robina.kuh#oc.com" size="32">
<f:facet name="prepend">
<h:outputText value="#" />
</f:facet>
</b:inputText>
<b:commandButton value="Registrieren" icon="envelope" action="#{registerController.registerUser}"/>
</h:panelGrid>
</h:form>
</b:panel>
</ui:define>
</ui:composition>
The template:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:b="http://bootsfaces.net/ui"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>Lunch</title>
</h:head>
<h:body style="padding: 60px;">
<ui:include src="topMenu.xhtml" />
<ui:insert name="content">
<b:container>
<b:jumbotron>
<h1>Da ist wohl etwas schiefgelaufen... Sorry!</h1>
</b:jumbotron>
</b:container>
</ui:insert>
</h:body>
</html>
This is the controller:
#Named("registerController")
#SessionScoped
public class RegisterController implements Serializable {
#Inject
private UserManager userManager;
private User user;
private Logger logger = Logger.getLogger(RegisterController.class);
public RegisterController() {
logger.debug("Created RegisterController");
user = new User();
if(user != null)
logger.debug("Name: " + user.getName()
+"\nEmail: " + user.getEmail());
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String registerUser() {
logger.debug("registerUser called"
+ "\n Name: " + user.getName()
+"\nEmail: " + user.getEmail());
userManager.addUser(user);
logger.debug("registerUser end");
return "benutzer.jsf";
}
}
It even is not entering the action method of my commandButton when I try to debug it (I am using the Bootsfaces Framework but I don't think this has anything to do with that Framework).
Setting the save state to client works but I would like to understand what is the problem? From what I am understanding of JSF this should work without pushing the state to the client side.
Am I missing something fundamental?
I deployed the webapp to a widlfly 9 server.
It was a bug in the used wildfly version - just used the new widlfly 10 final release and it is working as it should.

Multiple instances of managed bean

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;

Primefaces: open a dialog when an element in a pie chart is clicked

I'm trying to figure out how to open a dialog box when an element in a pie chart is clicked. I'm new to Primefaces, so most of what I've found in searches are more complex examples than what I'm trying to accomplish. The dialog box is opened using the Dialog Framework. I've been able to open the dialog via a command button no problem, so I'm pretty sure the problem isn't with the dialog itself.
Here's the initial 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:ui="http://java.sun.com/jsf/facelets"
>
<body>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:s="http://jboss.com/products/seam/taglib"
xmlns:p="http://primefaces.org/ui"
xmlns:pm="http://primefaces.org/mobile"
>
<p:panel header="Dashboard" toggleable="true">
<h:form>
<p:growl id="growl" showDetail="true" />
<h:panelGrid columns="2">
<p:chart type="pie" model="#{dashboardPieChart.pieModel1}" style="width:350px; height:200px" >
<p:ajax event="itemSelect" listener="#{dashboardPieChart.itemSelect}"/>
</p:chart>
</h:panelGrid>
<h:outputText id="out" value="#{dashboardPieChart.seriesText}" />
</h:form>
</p:panel>
<script type="text/javascript">
PrimeFaces.info ('Info message');
PrimeFaces.debug('Debug message');
PrimeFaces.warn ('Warning message');
PrimeFaces.error('Error message');
</script>
</ui:composition>
</body>
</html>
And the backing bean:
package com.company.project.model;
import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import org.primefaces.context.RequestContext;
import org.primefaces.event.ItemSelectEvent;
import org.primefaces.model.chart.PieChartModel;
#ManagedBean
#ViewScoped
public class DashboardPieChart implements Serializable {
private static final long serialVersionUID = -9056199453379512637L;
private PieChartModel pieModel1;
private String seriesText;
/*
public DashboardPieChart()
{
init();
}
*/
#PostConstruct
public void init() {
System.out.println("DashboardPieChart - inside init()");
createPieModels();
}
public PieChartModel getPieModel1() {
return pieModel1;
}
private void createPieModels() {
createPieModel1();
}
private void createPieModel1() {
pieModel1 = new PieChartModel();
pieModel1.set("Proposals in Progress", 12);
pieModel1.set("Proposals Completed", 15);
pieModel1.setTitle("Proposals");
pieModel1.setLegendPosition("w");
pieModel1.setDiameter(100);
}
public void itemSelect(ItemSelectEvent event) {
String msgText = "Item Index: " + event.getItemIndex() + ", Series Index:" + event.getSeriesIndex();
System.out.println (msgText);
this.seriesText = msgText;
RequestContext.getCurrentInstance().openDialog("pieChartDrillDownDialog");
}
public String getSeriesText() {
return seriesText;
}
public void setSeriesText(String seriesText) {
this.seriesText = seriesText;
}
}
and this is the dialog I'm trying to open:
<!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:p="http://primefaces.org/ui"
xmlns:pm="http://primefaces.org/mobile"
>
<h:head>
<title>Proposal Status Detail</title>
</h:head>
<h:body>
<h:form>
<p:chart type="pie" model="#{dashboardPieChartDrillDown.pieModel}" style="width:350px; height:200px" >
</p:chart>
</h:form>
</h:body>
</html>
I was able to make it work using remoteCommand:
XHTML:
<p:remoteCommand name="fnc" actionListener="#{playgroundController.showDialog()}"/>
<p:chart type="pie" model="#{playgroundController.pieModel1}" style="width:400px;height:300px">
<p:ajax event="itemSelect" listener="#{playgroundController.itemSelect}" oncomplete="fnc()" />
</p:chart>
BEAN:
public void showDialog() {
RequestContext.getCurrentInstance().openDialog("pieChartDrillDownDialog");
}
public void itemSelect(ItemSelectEvent event) {
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Item selected",
"Item Index: " + event.getItemIndex() + ", Series Index:" + event.getSeriesIndex());
FacesContext.getCurrentInstance().addMessage(null, msg);
}

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.

Resources