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" />
Related
I want to pass data to back bean through ajax call on command button click.
I have a form with couple of input text fields where each field is having ajax blur event.
Every thing is working fine in happy flow except in the flowing scenario.
Ajax blur event is invoking when i directly clicking on submit which is suppose to be happen before submit click, hence i should make another click on submit button to invoke ajax call to save my form.
Here is the code.
Input text fields:
<p:inputText id="txt_name"
value="#{partnerVO.partnerName}"
required="true" maxlength="30"
rendered="#{!partnerVO.isReadOnly}">
<p:keyFilter regEx="/[A-Za-z0-9#.,&- ]/i"
for="txt_name" preventPaste="false" />
<p:ajax update="txt_name" event="blur" />
</p:inputText>
<p:inputText id="txt_assigned"
value="#{partnerVO.assignedName}"
required="true" maxlength="30"
rendered="#{!partnerVO.isReadOnly}">
<p:keyFilter regEx="/[A-Za-z0-9#.,&- ]/i"
for="txt_assigned" preventPaste="false" />
<p:ajax update="txt_assigned" event="blur" />
</p:inputText>
Command Button:
<p:commandButton id="btn_save"
title="Save"
value="#{lbl['tpdetails.remove.additional.address']}"
update="#form" process="#this"
action="#{partnerDetailsController.save}">
</p:commandButton>
I'm using JSF 2.2
Please provide some suggestions to overcome this strange behavior.
Note: omitted form related code here.
Render works fine during initial load of the page, but once the form has been submitted and some component failed a validation re-render does not trigger, the panel does not show and hide anymore and page must be refreshed again. I'm still new with jsf.
Sample Code
<p:selectOneRadio id="accommodationOptions" value="#{travelRequestMBean.accommodationOptions}">
<f:selectItem itemLabel="#{field['accord3Radio2']}" itemValue="2" />
<f:selectItem itemLabel="#{field['accord3Radio1']}" itemValue="1" />
<f:ajax render="panelMoreAccommodation2"/>
</p:selectOneRadio>
<p:panel id="panelMoreAccommodation2" widgetVar="panelMoreAccommodation2"
visible="#{travelRequestMBean.accommodationOptions == 1}" closable="true" toggleable="true">
<p:graphicImage url="/images/hotel-noun_project_4398.svg" alt="#{field['accord3Label2']}" height="24px" />
<h:outputText value="#{field['accord3Label2']}" />
</p:panel>
Also I have tried the other variant of this using a boolean attribute in the backing bean with an ajax event on the selectoneradio, result was still the same and panel does not do anything.
I can't see where you validate your inputs. But take a look at http://www.primefaces.org/showcase/ui/csv/basic.xhtml with the combination of
update=":panelMoreAccommodation2"
And instead of visible use render.
Finally having some tweaks, the problem was this attribute on the target panel
closable="true"
After removing this attribute the ajax update worked again even after a submit with a failed validation.
This question already has an answer here:
How to skip validation when a specific button is clicked?
(1 answer)
Closed 7 years ago.
In a form, I have some inputText with two commandButton, one to accept and one to cancel.
How can I disable validation for the cancel button only?
<h:form id="detailsForm">
<p:inputText id="editUsername" value="#{userController.editUser.usrUsername}" />
<p:inputText id="editFirstName" value="#{userController.editUser.usrFirstName}" />
<p:inputText id="editLastName" value="#{userController.editUser.usrLastName}" />
<p:commandButton value="Accept" update=":detailsForm" actionListener="#{userController.onDetailsEditAccept}" />
<p:commandButton value="Cancel" update=":detailsForm" actionListener="#{userController.onDetailsEditCancel}" />
</h:form>
I already tried inserting required="false" on fields but it didn't work.
I also tried inserting <f:validateBean disabled="true" /> on fields and it didn't work.
Use the attribute immediate="true" in your cancel commandButton. This will skip the entire processing of the form, tough, by skipping the Apply Request Values, Process Validations and Update Model Values phases.
<p:commandButton value="Cancel" update=":detailsForm" actionListener="#{userController.onDetailsEditCancel}" immediate="true"/>
Use the attribute process="#this" in the Cancel button. This will prevent the whole form being submitted.
Or you can use p:button instead (however this doesn't have the actionListener attribute). See this other Q/A
if You don't want to submit the form. You should use just the <p:button>. the <p:commandButton> submits the form.
<p:button value="delete All"
action="#{reloadBean.purge}" update="#form"/>
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">
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.