JSF, Primefaces - Invoking Application Code Even When Validation Failed - The Koch Family
The Koch Family The Koch Family

Latest news

جاري التحميل ...

JSF, Primefaces - Invoking Application Code Even When Validation Failed


A use case

I have a form which has requirements as follow:
- There are some mandatory fields.
- Validation is triggered when changing value on each field.
- A button "Next" is enable only when all fields are entered. It turns to disabled if any field is empty.

My first approach

I defined a variable "isDisableNext" at a backend bean "Controller" for dynamically disabling/enabling the "Next" button by performing event "onValueChange", but, it had a problem:
<h:form id="personForm">
<p:outputLabel value="First Name" for="firstName"/>
<p:inputText id="firstName" value="#{person.firstName}"
required="true">
<p:ajax event="change" listener="#{controller.onValueChange}" update="nextButton"/>
</p:inputText>

<p:outputLabel value="Last Name" for="lastName"/>
<p:inputText id="lastName" value="#{person.lastName}"
required="true">
<p:ajax event="change" listener="#{controller.onValueChange}" update="nextButton"/>
</p:inputText>

<p:commandButton id="nextButton" actionListener="#{controller.onNext}" update="personForm" disabled="#{controller.isDisabledNext}"/>
</h:form>
Due to JSF lifecyle, the application code of Ajax "onValueChange" (at phase Invoke Application) is never invoked when validation failed. How could we update the value "isDisableNext"?
src: http://docs.oracle.com/javaee/5/tutorial/doc/bnaqq.html

My new approach: I don't try to update the backend bean at phase Invoke Application anymore but use custom validator

What is it? And, why is it possible?
- At phase Process Validation, it always calls my application code even when validation failed
- I handle enabling/disabling the button with JSF component tree instead of a backend bean.

The previous implementation turns to the following:
- Don't use required="true" because it won't invoke customer validators when a field's submitted value is empty. Then I need to add the "*" manually with "span class="ui-outputlabel-rfi".
- Use custom validator with "f:validator"
- Pass component button "Next" with "f:attribute" and "binding"
<h:form id="personForm">
<p:outputLabel value="First Name" for="firstName">
<span class="ui-outputlabel-rfi">*</span>
</p:outputLabel>
<p:inputText id="firstName" value="#{person.firstName}">
<p:ajax event="change" listener="#{controller.onValueChange}" update="nextButton"/>
<f:validator validatorId="requiredFieldValidator"/>
<f:attribute name="nextButton" value="#{nextButton}"/>
</p:inputText>

<p:outputLabel value="Last Name" for="lastName">
<span class="ui-outputlabel-rfi">*</span>
</p:outputLabel>
<p:inputText id="lastName" value="#{person.lastName}">
<p:ajax event="change" listener="#{controller.onValueChange}" update="nextButton"/>
    <f:validator validatorId="requiredFieldValidator"/>
<f:attribute name="nextButton" value="#{nextButton}"/>
</p:inputText>

<p:commandButton id="nextButton" actionListener="#{controller.onNext}" update="personForm" binding="#{nextButton}"/>
</h:form>
The custom validator looks like:
@FacesValidator(value = "requiredFieldValidator")
public class RequiredFieldValidator implements Validator{

public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
CommandButton nextButtonUi = (CommandButton) component.getAttributes().get("nextButton");
Map<String, String> requestParameterMap = context.getExternalContext().getRequestParameterMap();
String firstName = requestParameterMap.get(getClientId("firstName"));
String lastName = requestParameterMap.get(getClientId("lastName"));
if(StringUtils.isEmpty(firstName) || StringUtils.isEmpty(lastName)) {
nextButtonUi.setDisabled(true);
}else {
nextButtonUi.setDisabled(false);
}

RequestContext.getCurrentInstance().update(getClientId("nextButton"));
}

}
How is your approach? Leave your comment down below!

Comments



If you like the content of our blog, we hope to stay in constant communication, just enter your email to subscribe to the blog's express mail to receive new blog updates, and you can send a message by clicking on the button next ...

إتصل بنا

About the site

author The Koch Family <<  Welcome! I'm so glad that you stopped by Your Modern Family blog. Together, we will talk about raising kids, organizing the home and saving money! and Tips & tricks and more…

< Learn more ←

Blog stats

Sparkline 2513183

All Copyrights Reserved

The Koch Family

2020