CommandButton action triggering despite validation errors - validation

I have a page which contains <input type="text"> fields which have the required="true" attribute set. I also have a save button which submits the form.
Unfortunately, the form submits even if the required="true" field is left empty.
This is my current code:
<s:decorate template="layout/edit.xhtml" id="decAQty">
<ui:define name="label">Actual Qty Received</ui:define>
<h:inputText
value="#{tktReceivingInfoHome.instance.actualReceivedQty}"
required="true" id="txtAQty"
converterMessage="Not a valid Quantity">
<a:ajax event="blur" render="txtAcTotal,decAQty"
listener="#{returnsReceivingManager.setActualTotal}" />
<h:messages id="error" style="display:none" />
</h:inputText>
<a:commandButton id="btnSave"
action="#{returnsReceivingManager.checkQtyDiff}" value="Save"
render="decSQty,decScQty,decRtvQty,addForm,decAQty,decRecdDate,decRecWH,decErrorRMA,decErrorRTV,decReason,decStatusRMA,decStatusRTV,decPriority,decResolution"
oncomplete="#{returnsReceivingManager.rmaInfo.qtyDiff!=0 ? '#{rich:component(\'addPanel\').show();' : 'callSave();'}"
onclick="showProgressBar()" />
<a:jsFunction action="#{returnsReceivingManager.save}"
oncomplete="hideProgressBar()" name="callSave" />
When I click the save button, I can see the message pop up indicating that the value is required, but it then disappears and gives me a message stating that the transaction is failed.
In other words, it appears that the page is being submitted twice. I'd love any suggestions that the community can provide about how to resolve this issue.

At the moment validation is only triggered on leaving the txtAQty field (blur event). That's why you see the error message. What happens next is the click on the save button, which performs rerendering of some fields, but without processing (including validation) of any field. That's why the error disappears.
You should add the process attribute to the commandButton with values listing at least the txtAQty field (but even better also all the other fields which you are rerendering)

Related

Primefaces InputText does not work after validation failed

I have a table and each row has a delete button. After clicking on delete button, a confirm dialog should appear. In this dialog, there is only one required input field and a cancel and delete button. If the filed is filled, everything is ok, but if it will be left blank, the field will be red highlighted with a message under it, that the user should enter a value. At this moment, if I want to enter a value, I can not do it. Only if I close the dialog and click on the delete button again, the dialog comes again with the field still highlighted and I am able to enter a value. Why isn't it possible to enter a value directly after validation?
I have seen several problems here regarding updating an inputText field after validation failed, but I think I have another problem.
xhtml:
<h:form id="dialogForm"> ...
<p:inputText id="comment" value="#{myController.comment}" maxlength="14" required="true" placeholder="please enter a comment"/>
<p:message for="comment"/> ...
<p:commandButton value="#{message.delete}"
action="#{myController.doDelete()}"
process="#form"
update="#form"
oncomplete="if (!args.validationFailed){
PF('dialog').hide();}"/> ...
</h:form>

Composite component with action attribute conditional validation check throws ClassCastException during restore view phase

I have a JSF composite component(Name Panel). In that component I am using customValidator like below:
<h:inputHidden id="nameValidator" value="true">
<f:validator validatorId="NameValidator"
disabled="#{!cc.attrs.nameRequired}" />
<f:attribute name="firstName" value="firstName" />
<f:attribute name="lastName" value="lastName" />
</h:inputHidden>
firstName and lastName are two input text on this JSF form. And nameRequired attribute is being passed from the place where we are placing this composite component.
I am using this composite component like below:
<util:NamePanel viewbean="#{BACKING_BEAN}"
nameDTO="#{BACKING_BEAN.nameDTO}"
nameRequired="#{param['requireValidation']=='1' " />
On my screen I have two buttons. But I want to validate name only press of Save button and want to skip the validation on press of Cancel button. For that I have applied conditional validation.
<h:commandButton value="Cancel"
action="#{BACKING_BEAN.doCancel}">
<f:param name="requireValidation" value="0"></f:param>
</h:commandButton>
<h:commandButton value="Save"
action="#{BACKING_BEAN.doSave}">
<f:param name="requireValidation" value="1"></f:param>
</h:commandButton>
So when I press the Save button. The Name is getting validated by calling that custom validator but after that when the JSF restore view phase try to restore the page after saving data in database it's throwing below error:
Caused by: java.lang.IllegalStateException: Error restoring component: nameValidator
at org.apache.myfaces.view.facelets.DefaultFaceletsStateManagementStrategy.restoreStateFromMap(DefaultFaceletsStateManagementStrategy.java:518)
Caused by: java.lang.ClassCastException: package.NameValidator incompatible with javax.faces.component.StateHolder
at javax.faces.component._DeltaList.restoreState(_DeltaList.java:222)
at javax.faces.component.UIInput.restoreState(UIInput.java:1047)
But when I replaced nameRequired="#{param['requireValidation']=='1'" with nameRequired="true" at the place where I am placing composite component in my form, it worked perfectly fine.
Can't understand the reason of it and not able to find a fix for this issue. Or some other way to achieve this.

Skip validation of a form on re-render with Richfaces

I use Richfaces 3.1.2 and JSF 1.1
I have a textarea with two buttons inside a form : Submit and Update
the button Submit submits the form
One click on the button Update adds some text in the textarea
A validator is used inside the textarea, this validator throws an exception if the textarea only contains the name of the current connected user, for instance if the current connected user is "root" and the textarea contains "root", then an exception should be thrown
The code of the Textarea (by default it contains the name of the current connected user):
<h:panelGroup id="messagePanel">
<h:inputTextarea id="message" label="Update" value="#{beanName.message}">
<f:validator validatorId="messageValidator" />
</h:inputTextarea>
</h:panelGroup>
The submit button :
<h:commandLink id="validerLink" value="Submit" action="accueil"
actionListener="#{beanName.saveInformation}">
<f:param value="#{param.evenementId}" name="evenementId" />
</h:commandLink>
And the update button :
<a4j:commandLink id="inclureRapportLink" value="Update"
actionListener="#{beanName.updateText}" reRender="message">
<f:param name="evenementId" value="#{param.evenementId}" />
</a4j:commandLink>
The problem : If the textarea contains the name of the current connected user, the button Update doesn't update the text because the validator throws an exception.
So what I want to do is to disable the validator, but only if the user clicks on the button Update
I tried to add immediate="true" in the update button, but that didn't worked because apparently immediate="true" and reRender="message" doesn't work together (The bean is updated, but not the front).
I also tried this solution here : Skip validation on re-render and apply only on form submit but that didn't worked either, I got the error Undefined property clientId, and the validator is called even if the required property is set to false.
Can someone help me?

Howto submit JSF ajax field during form submit

I have a problem with a JSF 2 form that contains an ajax field. When I use the mouse to press the submit button of the form while the cursor is still in the ajaxified input field the input value of the field does not get submitted before the action is triggered in the backing bean. Also the attached validator and converter are not triggered.
<h:form id="invoice">
...
<h:inputText value="#{invoiceBean.amount}" required="true" validator="#{invoiceBean.validateAmount}">
<f:converter converterId="CurrencyConverter" />
<f:ajax event="blur" render="#this"/>
</h:inputText>
<h:commandButton action="#{invoiceBean.processInvoice()}" />
</h:form>
I also tried to enhance the command button with <f:ajax /> but the result stayed the same. Other (non-ajax) fields on the same form (not shown in the code snippet above) are submitted correctly. The ajax field is also submitted, converted and validated if I click somwhere else on the page before submitting but not when using the button directly.
Is there anything I am missing to have the field also be submitted on/before form submit?
Regarding the <h:inputText> ajax behaviour: use <f:ajax> with the default event valueChange, which is the default event for all input components. This is indeed equivalent to omitting the event attribute:
<f:ajax render="#this" />
Regarding the <h:commmandButton> component, don't forget to specify the execute attribute of <f:ajax>:
<f:ajax execute="#form" />
otherwise it will default to #this, therefore rendering vane your effort.

Deactivating commandButton functionality if inputText validation fails or ajax call starts

I have the following piece of code inside a form:
<p:panel id="panel" header="lalalala">
<h:panelGrid columns="5">
<h:outputLabel value="Enter name" for="name" />
<p:inputText id="name" value="#{userBean.name}"
required="true" label="name" maxlength="15"
validatorMessage="oops"
requiredMessage="ooopps">
<f:validateRegex
pattern="^somepattern$">
</f:validateRegex>
<p:ajax event="blur" update="inputValidationMessage" />
</p:inputText>
<p:message id="inputValidationMessage" showSummary="false"
for="name" />
<p:watermark for="name" value="eg. John" />
</h:panelGrid>
<p:commandButton id="submitButton" value="Submit" update="panel"
actionListener="#{userBean.save}"
onclick="handleOnclick"
oncomplete="handleAjaxResponse(xhr, status, args)">
</p:commandButton>
<p:messages autoUpdate="true" globalOnly="true" showDetail="true" />
</p:panel>
So the validation messages work well on the inputText element. But the submit button is still making an Ajax request when clicked, even though the input is invalid. I want the Ajax request to be sent iff the inputText is valid.
How do I do that?
Furthermore; there is another case I'd like to deactivate the button. This is the case where inputText is validated and the user clicks the button. The reason for this one is, I don't want the user to mistakenly flood requests. (i.e repeatedly press the submit button)
Currently, the handleOnclick javascript function only shows a modal dialog box saying "wait". Since that dialog is modal, the background is inaccessible. However, that still doesn't prevent the user from pressing it repeatedly because 1 second passes between onclick and modal dialog showing. Furthermore; this approach doesn't prevent submitting invalid data. What can you suggest?
I use JSF2.0 and Primefaces 3.0.
Any help appreciated.
You can use the button's disabled attribute for it. Just set it to true whenever FacesContext#isPostback() returns false (so, it's an initial request), or when it's true (so, a form submit has occurred), then check if FacesContext#isValidationFailed() returns true (so the validation has failed in general).
<p:commandButton ... disabled="#{not facesContext.postback or facesContext.validationFailed}" />
You only need to ensure that you update the button on ajax requests as well, so that it will reappear either enabled or disabled when necessary.
<p:ajax event="blur" update="inputValidationMessage submitButton" />

Resources