Handle JSF validation errors in presentation layer avoiding h:message - validation

Is there a way to let JSF do validations for my inputs but let me control how to display the validation errors? I want to avoid using h:message
I find it making my code too messy when I write a h:message component below every input components inside forms needing validation support. Since there are several forms on the page using h:messages is not an option as that would show the error messages of other forms as well. So I want to handle the error messages sent after validation to the presentation layer & do the errors presentation task myself using JS/Jquery. So how do I handle errors thrown by JSF validation service?

Just conditionally render the <h:messages> based on UIForm#isSubmitted().
<h:form binding="#{form1}">
<h:messages rendered="#{form1.submitted}" />
...
</h:form>
<h:form binding="#{form2}">
<h:messages rendered="#{form2.submitted}" />
...
</h:form>
<h:form binding="#{form3}">
<h:messages rendered="#{form3.submitted}" />
...
</h:form>
Or just bring in some ajax magic and update the current form only instead of the entire view.
<h:form>
<h:messages />
...
<h:commandButton ...><f:ajax execute="#form" render="#form" /></h:commandButton>
</h:form>
<h:form>
<h:messages />
...
<h:commandButton ...><f:ajax execute="#form" render="#form" /></h:commandButton>
</h:form>
<h:form>
<h:messages />
...
<h:commandButton ...><f:ajax execute="#form" render="#form" /></h:commandButton>
</h:form>
So I want to handle the error messages sent after validation to the presentation layer & do the errors presentation task myself using JS/Jquery.
Create a custom component or renderer which replaces the <h:messages>.

Related

JSF won't load everything at the same time

In my JSF application if I refresh the page everything get's rendered exceted the primeface graphicimages and jsf <f:ajax /> isn't working. If I wait 5 seconds the ajax calls are working again and graphicimages are getting loaded.
Another example is when I upload an image. The image get procced, uploaded and the site get's refreshed. After this the image is displayed, but ajax calls won't work after a few seconds after.
The app runs on a JBoss 7.1 with JSF 2.1
Is this a problem with slow hardware or something else. I would be happy with any hints because I don't really know where to look for a solution.
Example:
<p:selectOneRadio id="options" value="#{gameWriter.uploadCover}">
<f:selectItem itemLabel="ja" itemValue="true"/>
<f:selectItem itemLabel="nein" itemValue="false"/>
<f:ajax/>
</p:selectOneRadio>
When you define the f:ajax, try to give the UI components you want to execute and update. Also give the event. If you want process the whole form and update the whole page, you can use #form and #all in the f:ajax.
An example with #form and #all with f:ajax is as follows.
<h:form>
<p:selectOneMenu id="cmb" value="#{investigationItemController.current}" >
<f:selectItem itemLabel="Please select an item" />
<f:selectItems value="#{investigationItemController.items}" var="ii" itemLabel="#{ii.name}" itemValue="#{ii}" />
<f:ajax event="change" execute="#form" render="#all"/>
</p:selectOneMenu>
<h:outputLabel id="lbl" value="#{investigationItemController.current}" />
</h:form>
An example with primefaces ajax command is as follows.
<h:form>
<p:selectOneMenu id="cmb" value="#{investigationItemController.current}" >
<f:selectItem itemLabel="Please select an item" />
<f:selectItems value="#{investigationItemController.items}" var="ii" itemLabel="#{ii.name}" itemValue="#{ii}" />
<p:ajax event="change" process="cmb" update="lbl"/>
</p:selectOneMenu>
<h:outputLabel id="lbl" value="#{investigationItemController.current}" />
</h:form>
We can add more than one or for one UI Component if we want to execute the logic for more than one event.
Events for standard JSF UI component can be taken after removing the 'on' from the list of attributes of the UI component starting with 'on'. For example if JSF UI support onChange as an attribute you can use event="change".
For primefaces UI components, the possible events are listed under Primefaces documentation.
It is essential to correctly select the event in order for a successful ajax response.

JSF 2, ajax input field behaves differently in firefox 10 and ie9

When cursor is in input "test" and user press enter-key in a simplified form like
<h:form>
<h:inputText id="test" value="#{myModel.someValue}" >
<f:ajax event="blur" execute="#this" listener="#{myBean.calculateStuff}" render="myText"/>
</h:inputText>
<h:outputText id="myText" value="#{myModel.myText}" />
<h:commandButton value="send" action="#{myBean.calculatedNextPage} ">
</h:form>
firefox invokes 1 submit, ie invokes submit and partial-request.
Is this behaviour ok? From application side it is nuisance, because there is prevention/detection for multiple request on client/server side.
We don't know the page outcome beforehand if some field's validation/conversion has failed and we might not get updated "myText" rendered on both browsers. Enter-key check to prevent from submitting is not desirable and "blur" is good in normal cases. Any suggestions how to get both browser working the same way?
This behaviour is indeed not desired. But MSIE as whole browser at its own also not. That's what you have to deal with as being a web developer. Firefox/Chrome/Safari/etc correctly skip the blur event when the submit event has occurred.
If your sole purpose is to convert/validate someValue, then you should be doing that inside a normal converter and/or validator, not inside an ajax listener method.
<h:inputText id="test" value="#{myModel.someValue}">
<f:converter converterId="someValueConverter" />
<f:validator validatorId="someValueValidator" />
<f:ajax event="blur" execute="#this" listener="#{myBean.calculateStuff}" render="myText"/>
</h:inputText>
This way you can just safely ignore "unnecessary" ajax requests.
But if you really have a hard head in, you can in your particular example always add an onsubmit handler to skip the onblur.
<h:form id="form" onsubmit="document.getElementById('form:test').onblur=null">

Ajax, conditional rendering and backing beans

I am trying to display a page where the user, by the appropriate selection using a radio button, sees either a textbox or a combo box. This is relatively easy and I managed to do that by the following code:
<h:selectOneRadio id="selection" value="#{inputMethod.choice}">
<f:selectItem itemValue="#{inputMethod.TEXT}" itemLabel="textbox"/>
<f:selectItem itemValue="#{inputMethod.COMBO}" itemLabel="combobox" />
<f:ajax event="click" execute="#this" render="#form" />
</h:selectOneRadio>
<h:panelGroup id="Textbox" rendered="#{inputMethod.choice==inputMethod.TEXT}">
<h:outputLabel>Textbox:</h:outputLabel>
<h:inputText value="#{myBean.somevalue}" />
</h:panelGroup>
<h:panelGroup id="Combobox" rendered="#{inputMethod.choice==inputMethod.COMBO}">
<h:outputLabel Combobox:/>
<h:selectManyListbox id="CommunityListbox" value="#{myBean.choices}">
<f:selectItems value="#{myBean.selections}" var="u" itemValue="#{u.id}" itemLabel="#{u.name}"/>
</h:selectManyListbox>
</h:panelGroup>
The problem I have is that the setter for the combo box is never called.
In fact, the setter is only called for the component that is rendered by default (in this case whenever inputMethod.choice==inputMethod.TEXT). If I remove the conditional rendering, all setters are called as one would expect.
Any ideas or answers will be greatly appreciated!
PS: I am using jsf2.0, Glassfish 3.1, Netbeans 7.0 (in case this is of any importance)
You need to ensure that #{inputMethod.choice} evaluates exactly the same during the request of processing the form submit as it did during the request of displaying the form. Easiest is to put the bean in the view scope or to move the initialization logic into the (post)constructor of the request scoped bean.

JSF form post with AJAX

I want the following form to use AJAX. So the comments are shown after clicking the command button and without reloading the page. What needs to be changed, using Java Server Faces 2.0?
Functionality: This form provides an inputText to define a topic. After pressing the commandButton, it is searched for comments regarding this topic. Comments are shown in a dataTable, if there are any. Otherwise Empty is shown.
<h:form id="myForm">
<h:outputLabel value="Topic:" for="topic" />
<h:inputText id="topic" value="#{commentManager.topic}" />
<h:commandButton value="read" action="#{commentManager.findByTopic}" />
<h:panelGroup rendered="#{empty commentManager.comments}">
<h:outputText value="Empty" />
</h:panelGroup>
<h:dataTable
id="comments"
value="#{commentManager.comments}"
var="comment"
rendered="#{not empty commentManager.comments}"
>
<h:column>
<h:outputText value="#{comment.content}"/>
</h:column>
</h:dataTable>
</h:form>
You need to tell the command button to use Ajax instead. It's as simple as nesting a <f:ajax> tag inside it. You need to instruct it to submit the whole form by execute="#form" and to render the element with ID comments by render="comments".
<h:commandButton value="read" action="#{commentManager.findByTopic}">
<f:ajax execute="#form" render="comments" />
</h:commandButton>
Don't forget to ensure that you've a <h:head> instead of a <head> in the master template so that the necessary JSF ajax JavaScripts will be auto-included.
<h:head>
...
</h:head>
Also, the element with ID comments needs to be already rendered to the client side by JSF in order to be able to be updated (re-rendered) by JavaScript/Ajax again. So best is to put the <h:dataTable> in a <h:panelGroup> with that ID.
<h:panelGroup id="comments">
<h:dataTable rendered="#{not empty commentManager.comments}">
...
</h:dataTable>
</h:panelGroup>
See also:
Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes
How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar"
You need to modify your button:
<h:commandButton value="read" action="#{commentManager.findByTopic}">
<f:ajax render="comments" />
</h:commandButton>
This means, when the button is clicked, the action is executed, and the dataTable will be rendered and updated. This only works if the backing bean is at least view-scoped.

Trigger JSF validation using ajax after focus lost

How do you trigger validation on an input component when the component loses focus using ajax instead of waiting for the form to be manually submitted?
Put a <f:ajax event="blur"> in the UIInput component which re-renders a <h:message> associated with the component in question.
<h:inputText id="foo" value="#{bean.foo}" required="true">
<f:ajax event="blur" render="fooMessage" />
</h:inputText>
<h:message id="fooMessage" />
See also JSF 2.0 tutorial with Eclipse and Tomcat - the view and finetuning validation
Try this code:
<h:inputText value="#{bean.value}" valueChangeListener="#{bean.validateValue}">
<f:ajax event="blur" render="valueError"/>
</h:inputText>
<h:outputText id="valueError" value="#{bean.valueErrorMessage}" style="color: red;" />
If the user changes the value in your input component you can validate it with your valueChangeListener. If the user then moves to another input component the ouputText component will be rendered. There you can display a message if the validation failed.

Resources