Check for validation errors in part of a form in JSF - jsf

I'm building a Seam application, which is basically a huge form divided into different parts, or modules. I need a way to figure out when a module is "complete", meaning all validation for the fields in that module passes. I then need to do something in the view, setting a css-class or whatever.
Something like:
<a:region id="region1">
<s:div styleClass="#{invalid ? 'errors' : ''}">
<h:inputText required="true" id="input1" />
<h:inputText required="true" id="input2" />
<h:commandButton value="Save this section" reRender="region1" />
</s:div>
</a:region>
I figured I had two options:
Using some sort of view-logic (like #{invalid} for a single field)
Using a method in the bean, where I get all components for the module programmatically, and check them for validation errors.
However, I can't find any way to do any of them. Any ideas if this is even possible?
We're using JSF 1.2 with Seam.
Thanks.

You can use UIInput#isValid() to check if a validation error has occurred on the particular input component.
<s:div styleClass="#{!input1.valid or !input2.valid ? 'errors' : ''}">
<h:inputText binding="#{input1}" required="true" id="input1" />
<h:inputText binding="#{input2}" required="true" id="input2" />
<h:commandButton value="Save this section" reRender="region1" />
</s:div>

Related

SelectOneMenu required when a certain button is pressed

I have created form and I want to show previous existing items on a table while a new one is creating. I'd like to show matching items as form is filling up. But when I try to filter the list without having the form completed, the validation messages appear and the table doesn't get updated.
Don't know if it's possible, but what I want to do something like this:
<h:form id="form">
<h:outputText value="Name: "/>
<p:inputText value="#{itemsBean.name}" id="name" required="true"/>
<br/>
<h:outputText value="Description: "/>
<p:inputText value="#{itemsBean.description}" id="description" required="true"/>
<p:commandButton value="Save" update="form" actionListener="#{itemsBean.save}"/> //validate and save
<p:commandButton value="Filter" update="form" actionListener="#{itemsBean.updateItemsList}"/> //don't validate, and update the table.
<p:dataTable id="list" value="#{itemsBean.itemsList}" var="item">
<p:column>
<h:outputText value="#{item.name}"/>
</p:column>
<p:column>
<h:outputText value="#{item.description}"/>
</p:column>
</p:dataTable>
</h:form>
I'm very new to JSF.
I understand that you want to filter based on the name input field. The <p:commandButton> sends by default an ajax request and has a process attribute wherein you can specify which components you'd like to process during the submit. In your particular case, you should then process only the name input field and the current button (so that its action will be invoked).
<p:commandButton process="#this name" ... />
The process attribute can take a space separated collection of (relative) client IDs of the components, wherein #this refers to the current component. It defaults in case of <p:commandButton> to #form (which covers all input fields of the current form and the pressed button), that's why they were all been validated in your initial attempt. In the above example, all other input fields won't be processed (and thus also not validated).
If you however intend to skip the required validation for all fields whenever the button in question is been pressed, so that you can eventually process multiple fields which doesn't necessarily need to be all filled in, then you need to make the required="true" a conditional instead which checks if the button is been pressed or not. For example, let it evaluate true only when the save button has been pressed:
<p:inputText ... required="#{not empty param[save.clientId]}" />
...
<p:inputText ... required="#{not empty param[save.clientId]}" />
...
<p:commandButton binding="#{save}" value="Save" ... />
This way it won't be validated as required="true" when a different button is pressed. The trick in the above example is that the name of the pressed button (which is essentially the client ID) is been sent as request parameter and that you could just check its presence in the request parameter map.
See also:
Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes
I Have tested this with non-ajax submits:
<p:inputText ... required="#{not empty param.includeInSave1}" />
...
<p:inputText ... required="true" />
...
<p:commandButton value="Save1" ajax="false">
<f:param name="includeInSave1" value="true" />
</p:commandButton>
<p:commandButton value="Save2" ajax="false" />
The first input is required validated only on Save1 button submit.
Additionally to the BalusC answer (very useful and complete) I want to add that when you use a <h:commandButton /> it will validate (required, custom validations) all the fields in the <h:form /> where the command button is located, therefore when you need to use more than one command button you could consider that it is a good practice to use different <h:form /> to different responsibilities to avoid unexpected behavior in submit actions of the command buttons.
It is well explained in a BalusC answer: Multiple h:form in a JSF Page
If your form has validations and you do not update the <h:form /> or you do not show messages, you could get a headache thinking that the <h:commandButton /> is not firing your action, but likely is a validation problem that has not been shown.
Change your filter commandbutton like this to ignore validation:
<p:commandButton value="Filter" update="list" actionListener="#{itemsBean.updateItemsList}" process="#this"/>
EDIT:
The related post on SO, I think this will solve your issue too
JSF 2.0: How to skip JSR-303 bean validation?

Primefaces dialog doesn't update when is open [duplicate]

I have created form and I want to show previous existing items on a table while a new one is creating. I'd like to show matching items as form is filling up. But when I try to filter the list without having the form completed, the validation messages appear and the table doesn't get updated.
Don't know if it's possible, but what I want to do something like this:
<h:form id="form">
<h:outputText value="Name: "/>
<p:inputText value="#{itemsBean.name}" id="name" required="true"/>
<br/>
<h:outputText value="Description: "/>
<p:inputText value="#{itemsBean.description}" id="description" required="true"/>
<p:commandButton value="Save" update="form" actionListener="#{itemsBean.save}"/> //validate and save
<p:commandButton value="Filter" update="form" actionListener="#{itemsBean.updateItemsList}"/> //don't validate, and update the table.
<p:dataTable id="list" value="#{itemsBean.itemsList}" var="item">
<p:column>
<h:outputText value="#{item.name}"/>
</p:column>
<p:column>
<h:outputText value="#{item.description}"/>
</p:column>
</p:dataTable>
</h:form>
I'm very new to JSF.
I understand that you want to filter based on the name input field. The <p:commandButton> sends by default an ajax request and has a process attribute wherein you can specify which components you'd like to process during the submit. In your particular case, you should then process only the name input field and the current button (so that its action will be invoked).
<p:commandButton process="#this name" ... />
The process attribute can take a space separated collection of (relative) client IDs of the components, wherein #this refers to the current component. It defaults in case of <p:commandButton> to #form (which covers all input fields of the current form and the pressed button), that's why they were all been validated in your initial attempt. In the above example, all other input fields won't be processed (and thus also not validated).
If you however intend to skip the required validation for all fields whenever the button in question is been pressed, so that you can eventually process multiple fields which doesn't necessarily need to be all filled in, then you need to make the required="true" a conditional instead which checks if the button is been pressed or not. For example, let it evaluate true only when the save button has been pressed:
<p:inputText ... required="#{not empty param[save.clientId]}" />
...
<p:inputText ... required="#{not empty param[save.clientId]}" />
...
<p:commandButton binding="#{save}" value="Save" ... />
This way it won't be validated as required="true" when a different button is pressed. The trick in the above example is that the name of the pressed button (which is essentially the client ID) is been sent as request parameter and that you could just check its presence in the request parameter map.
See also:
Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes
I Have tested this with non-ajax submits:
<p:inputText ... required="#{not empty param.includeInSave1}" />
...
<p:inputText ... required="true" />
...
<p:commandButton value="Save1" ajax="false">
<f:param name="includeInSave1" value="true" />
</p:commandButton>
<p:commandButton value="Save2" ajax="false" />
The first input is required validated only on Save1 button submit.
Additionally to the BalusC answer (very useful and complete) I want to add that when you use a <h:commandButton /> it will validate (required, custom validations) all the fields in the <h:form /> where the command button is located, therefore when you need to use more than one command button you could consider that it is a good practice to use different <h:form /> to different responsibilities to avoid unexpected behavior in submit actions of the command buttons.
It is well explained in a BalusC answer: Multiple h:form in a JSF Page
If your form has validations and you do not update the <h:form /> or you do not show messages, you could get a headache thinking that the <h:commandButton /> is not firing your action, but likely is a validation problem that has not been shown.
Change your filter commandbutton like this to ignore validation:
<p:commandButton value="Filter" update="list" actionListener="#{itemsBean.updateItemsList}" process="#this"/>
EDIT:
The related post on SO, I think this will solve your issue too
JSF 2.0: How to skip JSR-303 bean validation?

Implementing a return navigation in JSF

I am looking for a JSF coding practice that will allow one page to link to another that, when it completes, will return to the original page. So I have a page viewDoc.xhtml that has this:
<f:metadata>
<f:viewParam name="id" value="#{viewDoc.id}" />
</f:metadata>
( bunch of stuff to show the document indicated by "id" )
<p:button value="Edit Name/Title"
outcome="editnametitle">
<f:param name="id" value="#{param.id}" />
</p:button>
Then I have a page editnametitle.xhtml that has this:
<h:form>
(input fields and stuff)
<p:commandButton value="Save Changes"
action="#{editNameTitle.doSave()}"
/>
<p:commandButton value="Cancel"
action="#{editNameTitle.doCancel()}"
immediate="true"
/>
</h:form>
So how do I implement the backing bean methods doSave() and doCancel() such that when they finish they navigate back to viewDoc.xhtml with the id parameter of the document included?
I haven't found any guidance for a solution and I haven't been happy with any approach I have thought of so far. I have thought of something like adding to the p:button the return path like:
<p:button value="Edit Name/Title"
outcome="editnametitle">
<f:param name="id" value="#{param.id}" />
<f:param name="returnoutcome" value="viewDoc" />
</p:button>
Is this the right approach? Or is there some JSF facility that does this that I missed?
Yes, that's basically it if those requests are idempotent.
One possible improvement is that you can dynamically obtain the current view ID as below:
<f:param name="returnoutcome" value="#{view.viewId}" />
This allows abstracting away it in a reusable custom tag.
Personally I'd use parameter name "from" too as that's more short.

In JSF is there a way to add a passThroughAttribute to a component based on a condition or parameter?

I have an "inputSecret" component and I need to enable both HTML native non null validation, as well as JSF validation. Or to switch both of them off based on a parameter.
As a start, I have the xmlns:h="http://xmlns.jcp.org/jsf/html and xmlns:f="http://xmlns.jcp.org/jsf/core namespaces imported
This code
<h:inputSecret required="#{passwordRequired}" >
</h:inputSecret>
will enable JSF validation if the passwordRequired parameter is 'true'. And I thought the "required" attrib would also translate into the final HTML to enable native HTML validation, but it does not. So then I used the passThroughAttribute to have the "required" attribute down into the HTML rendered component.
<h:inputSecret required="#{passwordRequired}" >
<f:passThroughAttribute name="required" value="#{passwordRequired}" />
</h:inputSecret>
One problem is that the value of the passThroughAttribute does not really matter, I can set it to "required", "true", "false" or even empty string, the HTML native validation will just occur if I type in the passThroughAttribute tag as described above (again, regardless of value).
This would be fine for the use case I initially had, but there is also a situation in which the use case does not require the user to change the password, so I would like to be able to conditionally add that "required" attrib as a "passThroughAttribute" tag in the JSF code.
Something ala
<h:inputSecret required="#{passwordRequired}" >
<if:condition value="#{passwordRequired}">
<f:passThroughAttribute name="required" value="true" />
</if>
</h:inputSecret>
For an UI component I would use the "render" attribute, but this is not the case. I simply want to be able to switch the inclusion of the "passthroughAttribute" on or off based on my parameter. I know it sounds like JSTL and "c:if" but that doesn't always work so I need something else.
Does anyone know of a method for me to accomplish what I need without some horrible hacks?
Use JSTL <c:if>:
<!-- xmlns:c="http://java.sun.com/jsp/jstl/core" -->
<h:inputSecret required="#{passwordRequired}" >
<c:if test="#{passwordRequired}">
<f:passThroughAttribute name="required" value="true" />
</c:if>
</h:inputSecret>
As alternative, you could duplicate the code with a rendered condition:
<h:inputSecret required="#{passwordRequired}" rendered="#{passwordRequired}">
<f:passThroughAttribute name="required" value="#{passwordRequired}" />
</h:inputSecret>
<h:inputSecret required="#{passwordRequired}" rendered="#{!passwordRequired}"/>

Single JSF form on a page approach vs several forms?

Does it makes sense to merge these several hidden forms on a single page into just one single big form?
To submit a particular set of parameters belonging to a particular form process attribute could be used to submit all elements required to be processed.
What are the pro/cons of this single form approach over using several forms?
<span class="hiddenForms">
<h:form>
<h:inputHidden id="selctdChnlType_in" value="#{channelCntlr.type}"/>
<h:inputHidden id="selctdChnlId_in" value="#{channelCntlr.channelId}"/>
<p:remoteCommand name="updateChnlDataPanel" process="#form" actionListener="#{channelCntlr.init()}" update=":channelHeader, :channelDataPanel, :channelSideColumn"/>
</h:form>
<h:form>
<h:inputHidden id="selctdLOBId_in" value="#{lobCntlr.targetLOBId}"/>
<p:remoteCommand name="updateLOBPanel" process="selctdLOBId_in, #this" actionListener="#{lobCntlr.retrieveCurrentLOB()}" update=":lobFullContentPanel" />
</h:form>
<h:form id="lobAction_form" >
<h:inputText id="targetLOBId_in" value="#{lobCntlr.targetLOBId}"/>
<h:inputText id="targetResponseId_in" value="#{lobCntlr.targetResponseOrCommmentId}"/>
<h:inputText id="targetAction_in" value="#{lobCntlr.targetAction}"/>
<p:remoteCommand name="doLOBAction" process="targetLOBId_in, targetAction_in, targetResponseId_in,#this" actionListener="#{lobCntlr.doLOBAction()}"/>
<h:inputText id="targetTopics" value="#{lobCntlr.list}" converter="listConverter"/>
<p:remoteCommand name="suggestAsHotLOB" process="targetLOBId_in, targetTopics, #this" actionListener="#{lobCntlr.addForTryAsHotLOB()}"/>
</h:form>
<h:form id="comment_form" >
<h:inputText id="targetLOBId_in" value="#{lobCntlr.targetLOBId}"/>
<h:inputText id="targetCommentOrResponseId_in" value="#{lobCntlr.targetResponseOrCommmentId}"/>
<h:inputText id="comment_in" value="#{lobCntlr.text_input}" required="true">
<f:validateLength minimum="15" maximum="1000"/>
</h:inputText>
<h:inputText id="previousCommenters_in" value="#{lobCntlr.list}" converter="listConverter"/>
<p:remoteCommand name="addComment" process="#form" actionListener="#{lobCntlr.addUserComment()}" oncomplete="addCommentToPage(args);" />
<p:remoteCommand name="deleteComment" process="targetLOBId_in, targetCommentOrResponseId_in, #this" actionListener="#{lobCntlr.removeUserComment()}" oncomplete="removeFromPage(args);" />
</h:form>
<h:form id="recosForm">
<h:inputText id="startFromRecos_in" value="#{recmdnsCntlr.startFromIndex}"/>
<p:remoteCommand name="fetchAllRecos" actionListener="#{recmdnsCntlr.retrieveAllRecmmndns()}" process="startFromRecos_in,howManyRecos_in,isLocalStorAvailble_in,#this" />
<p:remoteCommand name="fetchFollowiesList" actionListener="#{recmdnsCntlr.fetchAllFollowiesList()}" process="#this" oncomplete="storeFollowiesList(args)"/>
</h:form>
<span id="editsForm" style="display:none">
<form action="javascript:void(0);" class="edits_submitter" >
<p:inputTextarea styleClass="editedText"/>
<input type="submit" value="Save edits"/>
<a class="cancel-edit" href="javascript:void(0)">Cancel</a>
</form>
</span>
</span>
A major con to the single, monolithic JSF form control is the sheer volume of data that is (needlessly) sent to the server for processing. Using your existing code. Consider the following. If all the controls in <h:form id="lobAction_form" > and <h:form id="comment_form" > were in a single form, you'd have
<h:inputText id="targetLOBId_in" value="#{lobCntlr.targetLOBId}"/>
<h:inputText id="targetResponseId_in" value="#{lobCntlr.targetResponseOrCommmentId}"/>
<h:inputText id="targetAction_in" value="#{lobCntlr.targetAction}"/>
<p:remoteCommand name="doLOBAction" process="targetLOBId_in, targetAction_in, targetResponseId_in,#this" actionListener="#{lobCntlr.doLOBAction()}"/>
<h:inputText id="targetTopics" value="#{lobCntlr.list}" converter="listConverter"/>
<p:remoteCommand name="suggestAsHotLOB" process="targetLOBId_in, targetTopics, #this" actionListener="#{lobCntlr.addForTryAsHotLOB()}"/>
<h:inputText id="targetLOBId_in" value="#{lobCntlr.targetLOBId}"/>
<h:inputText id="targetCommentOrResponseId_in" value="#{lobCntlr.targetResponseOrCommmentId}"/>
<h:inputText id="comment_in" value="#{lobCntlr.text_input}" required="true">
<f:validateLength minimum="15" maximum="1000"/>
</h:inputText>
<h:inputText id="previousCommenters_in" value="#{lobCntlr.list}" converter="listConverter"/>
<p:remoteCommand name="addComment" process="#form" actionListener="#{lobCntlr.addUserComment()}" oncomplete="addCommentToPage(args);" />
<p:remoteCommand name="deleteComment" process="targetLOBId_in, targetCommentOrResponseId_in, #this" actionListener="#{lobCntlr.removeUserComment()}" oncomplete="removeFromPage(args);" />
</h:form>
For every command action that you initiate in that form, possibly to process 1 input text component, you'd always be sending all 13 components in there to the server anyway. Wasteful and unnecessary. You'll have high volume of client-server communications for small operations and sometimes slow response times. Depending on whatever JSF framework you're using, you might be able to get creative with this situation, selectively processing components and what not, but that is just needless and painful. Clean separation of concerns also comes into play in the presentation layer.
Then there is the problem of validation. More often than not, you will have selected components in a single form that are marked as required and have nothing to do with the rest of the components within that form. You'll most likely be unable to selectively process those components without affecting all the other components on that form.
I see you're using primefaces. You could consider the use of Wizard component. With this component there is a single form with more sections in different tabs. The validation is done in Ajax mode when you go from one tab to the next one. As the partial validation is done with Ajax, only the fields of the tab you are validating, are processed and sent to the server.
It is also useful to split long forms in more readable and user friendly sections.

Resources