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.
Related
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.
I am trying to implement simple page navigation. So whenever I click on login button it should simply redirect me to welcome page and show welcome message.
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
<title>External Resources</title>
</h:head>
<h:body>
<ui:composition template="/WEB-INF/templates/template.xhtml">
<ui:define name="css">
<h:outputStylesheet library="css" name="index.css"/>
</ui:define>
<ui:define name="content">
<h1>Welcome to Login Page</h1>
<h:form id="login-form" prependId="false">
<h:panelGrid columns="5">
<h:outputLabel for="username" value="Username"/>
<h:inputText id="username" value="#{loginBean.user.username}" />
<h:outputLabel for="password" value="Password"/>
<h:inputSecret id="password" value="#{loginBean.user.password}" />
<h:commandButton value="Login" id="cmdButton"
action="#{loginBean.goToWelcome()}"/>
</h:panelGrid>
</h:form>
</ui:define>
</ui:composition>
</h:body>
</html>
this is my login bean which contains a goToWelcome method which returns string.
LoginBean.java
#SessionScoped
#ManagedBean
public class LoginBean implements Serializable{
private User user;
public LoginBean(){
}
#PostConstruct
public void init(){
user= new User();
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String goToWelcome(){
return "/pages/welcome?faces-redirect=true";
}
}
the error says:-
Unable to find matching navigation case with from-view-id
'/index.xhtml' for action '#{loginBean.goToWelcome()}' with outcome
'/pages/welcome?faces-redirect=true'
There are many ways to return a page!
The very simple one : return a page like this for example in your backingBean:
return "DesiredPage.xhtml";
That page must be in WebPages folder.
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.
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;
JSF validation are not working When i submit ,I under the myfaces(2.1.10) and mojarra(2.1.21) has tried, as same results.here is my code.Theoretically not execute onSubmit() and display error messages in m_name.But in fact is execute onSubmit() and not display error message.
template.xhtml
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:rich="http://richfaces.org/rich">
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="Cache-Control" content="no-cache" />
<title>Title</title>
</h:head>
<h:body>
<ui:insert name="body"></ui:insert>
</h:body>
</html>
template client file templatevalidation.xhtml
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
template="/template.xhtml">
<ui:define name="body">
<h:form>
<div>
<h:inputText id="name" value="#{templateBean.name}">
<f:validateRequired />
<f:validateLength minimum="5" />
</h:inputText>
<h:message id="m_name" for="name" />
</div>
<div>
<h:commandButton action="#{templateBean.onSubmit}" value="submit">
<f:ajax execute="name" render="m_name" />
</h:commandButton>
</div>
</h:form>
</ui:define>
</ui:composition>
here is my bean TemplateBean.class
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ManagedBean
#ViewScoped
public class TemplateBean implements Serializable{
private static final long serialVersionUID = 9009393522101806766L;
private String name;
public void onSubmit(){
System.out.println("Name: " + name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
You need to update your <h:message> component after the AJAX call to show the error message using the render attribute in your <f:ajax> tag:
<h:message id="nameMsg" for="name" />
<h:commandButton action="#{templateBean.onSubmit}" value="submit">
<f:ajax execute="name" render="nameMsg" />
</h:commandButton>
Must use hibernate-validation
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.0.0.Final</version>
</dependency>