We have 2 plain input fields (h:inputText) each using bean-validation in a JSF 2.3 page.
If the first input field fails validation, the value entered into the second input field should be cleared.
JSF:
<h:body>
<h:form>
<!-- If either field fails then the other should be cleared -->
<h:outputLabel value="Enter text that must be lowercase"/>
<h:inputText value="#{myBean.mandatoryLowercase}" required="true" />
<h:outputLabel value="Enter a decimal"/>
<h:inputText value="#{myBean.mandatoryDecimal}" required="true"/>
<h:commandButton action="#{myController.doSomething}" value="Submit"/>
</h:form>
</h:body>
MyBean.java
#SessionScoped
#Named
public class MyBean implements Serializable{
#NotNull
#Pattern(regexp="(?=.*[a-z]).+")
private String mandatoryField;
#Digits(integer=6, fraction=2, message = "Must be a decimal")
private BigDecimal someOtherField;
public String getMandatoryLowercase() {
return mandatoryField;
}
public void setMandatoryLowercase(String mandatoryLowercase) {
this.mandatoryField = mandatoryLowercase;
}
public BigDecimal getMandatoryDecimal() {
return someOtherField;
}
public void setMandatoryDecimal(BigDecimal mandatoryDecimal) {
this.someOtherField = mandatoryDecimal;
}
}
What is the correct way to clear mandatoryDecimal if mandatoryLowercase is invalid?
One solution might be to use a custom validator which is aware of all the components and then possibly clear the values that way, but that seems to join the fields together semantically when in reality they should be separate.
Ideally a <f:viewAction> with the RENDER_RESPONSE phase would be ideal as I feel it logically makes sense. However viewActions are not able to execute at that phase.
Thanks for the help.
Ed
Related
I am building a JSF application. I defined the GUI and did the select statements query the database using select.
Now I must do the insert statements, but I don't know how to read the value of a JSF input component like <h:inputText> and send it to my bean which performs the insert.
Should <h:inputText> value be mapped through faces-config.xml, so I can have it in my Java code?
You need to put all <h:inputXxx>/<h:selectXxx> components in a <h:form> and bind their value attribute to a bean property via an EL expression like #{bean.property}, backed by a getter/setter pair. When properly set, JSF will automatically set the values in the bean when the form is submitted via a <h:commandXxx> component in the very same form. You can specify a bean action method in action attribute of the <h:commandXxx> component via an EL expression like #{bean.action}, which points to the bare method action(). All submitted values are available right away there the usual Java way.
Given this JSF form example with one input field and one select field:
<h:form>
<h:inputText value="#{bean.text}" required="true" />
<h:selectOneMenu value="#{bean.choice}" required="true">
<f:selectItem itemValue="#{null}" />
<f:selectItem itemValue="One" />
<f:selectItem itemValue="Two" />
<f:selectItem itemValue="Three" />
</h:selectOneMenu>
<h:commandButton value="submit" action="#{bean.submit}" />
<h:messages />
<h:outputText value="#{bean.result}" />
</h:form>
The following bean prints the submitted values to the stdout, proving that JSF has already set the values long before the moment you access it in the action method.
package com.example;
import javax.inject.Named;
import javax.enterprice.context.RequestScoped;
#Named // Use #javax.faces.bean.ManagedBean on outdated environments.
#RequestScoped // Use #javax.faces.bean.RequestScoped on outdated environments.
public class Bean {
private String text;
private String choice;
private String result;
public void submit() {
result = "Submitted values: " + text + ", " + choice;
System.out.println(result);
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getChoice() {
return choice;
}
public void setChoice(String choice) {
this.choice = choice;
}
public String getResult() {
return result;
}
}
That's all. Turning the regular form into an ajax form is a matter of nesting a <f:ajax> in the command component as below.
<h:commandButton value="submit" action="#{bean.submit}">
<f:ajax execute="#form" render="#form" />
</h:commandButton>
You can find another example and valuable links at bottom of our JSF wiki page.
Do note that whatever you intend to do with the submitted values is beyond the responsibility of JSF. For example, manipulating it, passing into another class, saving it in database, etc. None of this all is related to JSF. It has as being a HTML form based framework already done its job of providing you the submitted values in flavor of usable Java variables. The remainder is up to you.
To investigate the next step, you should at this point just be doing as if you've already a bunch of prepared / hardcoded variables instead of a whole JSF based user interface. For example, in order save to the values in a database, people usually use a business service layer framework like EJB which in turn uses a persistence layer framework like JPA. Some people even use "plain vanilla" JDBC for that. For more links to concrete examples, start here: JSF Controller, Service and DAO.
I am building a JSF application. I defined the GUI and did the select statements query the database using select.
Now I must do the insert statements, but I don't know how to read the value of a JSF input component like <h:inputText> and send it to my bean which performs the insert.
Should <h:inputText> value be mapped through faces-config.xml, so I can have it in my Java code?
You need to put all <h:inputXxx>/<h:selectXxx> components in a <h:form> and bind their value attribute to a bean property via an EL expression like #{bean.property}, backed by a getter/setter pair. When properly set, JSF will automatically set the values in the bean when the form is submitted via a <h:commandXxx> component in the very same form. You can specify a bean action method in action attribute of the <h:commandXxx> component via an EL expression like #{bean.action}, which points to the bare method action(). All submitted values are available right away there the usual Java way.
Given this JSF form example with one input field and one select field:
<h:form>
<h:inputText value="#{bean.text}" required="true" />
<h:selectOneMenu value="#{bean.choice}" required="true">
<f:selectItem itemValue="#{null}" />
<f:selectItem itemValue="One" />
<f:selectItem itemValue="Two" />
<f:selectItem itemValue="Three" />
</h:selectOneMenu>
<h:commandButton value="submit" action="#{bean.submit}" />
<h:messages />
<h:outputText value="#{bean.result}" />
</h:form>
The following bean prints the submitted values to the stdout, proving that JSF has already set the values long before the moment you access it in the action method.
package com.example;
import javax.inject.Named;
import javax.enterprice.context.RequestScoped;
#Named // Use #javax.faces.bean.ManagedBean on outdated environments.
#RequestScoped // Use #javax.faces.bean.RequestScoped on outdated environments.
public class Bean {
private String text;
private String choice;
private String result;
public void submit() {
result = "Submitted values: " + text + ", " + choice;
System.out.println(result);
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getChoice() {
return choice;
}
public void setChoice(String choice) {
this.choice = choice;
}
public String getResult() {
return result;
}
}
That's all. Turning the regular form into an ajax form is a matter of nesting a <f:ajax> in the command component as below.
<h:commandButton value="submit" action="#{bean.submit}">
<f:ajax execute="#form" render="#form" />
</h:commandButton>
You can find another example and valuable links at bottom of our JSF wiki page.
Do note that whatever you intend to do with the submitted values is beyond the responsibility of JSF. For example, manipulating it, passing into another class, saving it in database, etc. None of this all is related to JSF. It has as being a HTML form based framework already done its job of providing you the submitted values in flavor of usable Java variables. The remainder is up to you.
To investigate the next step, you should at this point just be doing as if you've already a bunch of prepared / hardcoded variables instead of a whole JSF based user interface. For example, in order save to the values in a database, people usually use a business service layer framework like EJB which in turn uses a persistence layer framework like JPA. Some people even use "plain vanilla" JDBC for that. For more links to concrete examples, start here: JSF Controller, Service and DAO.
I try learn JSF and faced with problem.
I did use Servlet 2.5, JDK 1.6 and JSF 2.0.6 (com.sun.faces version from pom file).
I have a simple JSF page that has a <h:inputText/> tag for interaction with user
I expect what user fill this h:inputText then click on h:commandButton and on server side i will get backing bean with updated value.
But in my case lifecycle of JSF breaks on process validations, move to render
response and show to user "Parser error!" message
I.e. for simple h:inputText without any validator and converter i receive error message from server side about parsing of h:inputText value.
After some time i figured out what i can create my own converter which will not modify object, just pass String through himself.
I did add my realization of converter to <h:inputText/> and this work.
Question:
In all examples in books and other tutorials nobody used custom converter for <h:inputText/> if inputText is representation of String value of backing bean.
Why all of this tutorials and examples not working for me without custom converter? Where my mistake?
Source codes:
index.xhtml without converter, not worked for me:
<h:form id="UserForm">
<h:outputText value="Insert your first name:" />
<h:inputText id="userNameID" required="true" value="#{userBean.firstName}">
<f:validateLength minimum="5" maximum="25" />
</h:inputText>
<h:message showSummary="true" showDetail="false" for="userNameID" />
<h:commandButton id="submit" action="/view/validator/response?faces-redirect=true"
value="Submit" />
</h:form>
UserBean.java:
#ManagedBean(name = "userBean")
#SessionScoped
public class UserBean implements Serializable {
private String firstName;
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
}
MyConverter.java - dummy converter
#FacesConverter(value = "myConverter")
public class MyConverter implements Converter {
#Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
return value;
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
return value.toString();
}
}
index.xhtml with converter, worked as expected:
<h:form id="UserForm">
<h:outputText value="Insert your first name:" />
<h:inputText id="userNameID" required="true" value="#{userBean.firstName}" converter="myConverter">
<f:validateLength minimum="5" maximum="25" />
</h:inputText>
<h:message showSummary="true" showDetail="false" for="userNameID" />
<h:commandButton id="submit" action="/view/validator/response?faces-redirect=true"
value="Submit" />
</h:form>
The cause of the problem is not visible in the code posted so far, but the key symptom "it fails with a message coming from a so far unidentified converter while it succeeds with an explicit converter" suggests that you've elsewhere in the same project a #FacesConverter(forClass=String.class) which would run automatically on every single String property which doesn't have another converter explicitly specified.
First, I show my code:
XHTML page:
<h:body>
<h:form id="ffffffffff">
<p:inputText value="#{prueba.dato}" >
<p:ajax event="keyup" process="#this" />
</p:inputText>
</h:form>
</h:body>
Bean:
#ManagedBean
#ViewScoped
public class Prueba implements Serializable {
private String dato = "ASSSS";
public String getDato() {
return dato;
}
public void setDato(String dato) {
this.dato = dato;
System.out.println("DAAAAAA: " + dato);
}
public void listener() {
System.out.println("LISTENEEEEEEEEEEEEEEEEEEEEEEEEEE");
}
}
Converter
#FacesConverter
public class SnaCarreraConverter extends SelectItemsConverter {
//CODE
}
My problem, setDato is always getting a null value. But when I modify the converter to this:
#FacesConverter(forClass=SnaCarrera.class)
adding forClass resolve my problem, I don't know why this happens. Is The inputText trying to find a Converter without add the converter property?
First of all, the SelectItemsConverter is for <f:selectItems>. The <p:inputText> is not a <f:selectItems>. So the SelectItemsConverter is useless for the <p:inputText>. See also its documentation and showcase.
Second, it's normal to give the Converter implementation an ID or a "for-class" in order to use it. Otherwise you can't refer it in the <x:inputSomething converter> attribute, or in the <f:converter> tag, or you can't auto-associate it with a certain class. This requirement is totally unrelated to the SelectItemsConverter. It's just required by standard JSF spec.
I am building a JSF application. I defined the GUI and did the select statements query the database using select.
Now I must do the insert statements, but I don't know how to read the value of a JSF input component like <h:inputText> and send it to my bean which performs the insert.
Should <h:inputText> value be mapped through faces-config.xml, so I can have it in my Java code?
You need to put all <h:inputXxx>/<h:selectXxx> components in a <h:form> and bind their value attribute to a bean property via an EL expression like #{bean.property}, backed by a getter/setter pair. When properly set, JSF will automatically set the values in the bean when the form is submitted via a <h:commandXxx> component in the very same form. You can specify a bean action method in action attribute of the <h:commandXxx> component via an EL expression like #{bean.action}, which points to the bare method action(). All submitted values are available right away there the usual Java way.
Given this JSF form example with one input field and one select field:
<h:form>
<h:inputText value="#{bean.text}" required="true" />
<h:selectOneMenu value="#{bean.choice}" required="true">
<f:selectItem itemValue="#{null}" />
<f:selectItem itemValue="One" />
<f:selectItem itemValue="Two" />
<f:selectItem itemValue="Three" />
</h:selectOneMenu>
<h:commandButton value="submit" action="#{bean.submit}" />
<h:messages />
<h:outputText value="#{bean.result}" />
</h:form>
The following bean prints the submitted values to the stdout, proving that JSF has already set the values long before the moment you access it in the action method.
package com.example;
import javax.inject.Named;
import javax.enterprice.context.RequestScoped;
#Named // Use #javax.faces.bean.ManagedBean on outdated environments.
#RequestScoped // Use #javax.faces.bean.RequestScoped on outdated environments.
public class Bean {
private String text;
private String choice;
private String result;
public void submit() {
result = "Submitted values: " + text + ", " + choice;
System.out.println(result);
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getChoice() {
return choice;
}
public void setChoice(String choice) {
this.choice = choice;
}
public String getResult() {
return result;
}
}
That's all. Turning the regular form into an ajax form is a matter of nesting a <f:ajax> in the command component as below.
<h:commandButton value="submit" action="#{bean.submit}">
<f:ajax execute="#form" render="#form" />
</h:commandButton>
You can find another example and valuable links at bottom of our JSF wiki page.
Do note that whatever you intend to do with the submitted values is beyond the responsibility of JSF. For example, manipulating it, passing into another class, saving it in database, etc. None of this all is related to JSF. It has as being a HTML form based framework already done its job of providing you the submitted values in flavor of usable Java variables. The remainder is up to you.
To investigate the next step, you should at this point just be doing as if you've already a bunch of prepared / hardcoded variables instead of a whole JSF based user interface. For example, in order save to the values in a database, people usually use a business service layer framework like EJB which in turn uses a persistence layer framework like JPA. Some people even use "plain vanilla" JDBC for that. For more links to concrete examples, start here: JSF Controller, Service and DAO.