Trigger OmniFaces multi field validation after focus lost - ajax

I need to create a validation on Calendar components - Begin/End. OmniFaces supports multi field validation very well, like here:
<h:panelGrid columns="3">
<h:outputLabel for="startDate" value="Start date" />
<h:inputText id="startDate" value"#{booking.reservation.startDate}" required="true"
requiredMessage="Please enter start date"
converterMessage="Please enter format yyyy-MM-dd">
<f:convertDateTime pattern="yyyy-MM-dd" />
</h:inputText>
<h:message for="startDate" />
<h:outputLabel for="endDate" value="End date" />
<h:inputText id="endDate" value"#{booking.reservation.endDate}" required="true"
requiredMessage="Please enter end date"
converterMessage="Please enter format yyyy-MM-dd">
<f:convertDateTime pattern="yyyy-MM-dd" />
</h:inputText>
<h:panelGroup>
<h:message for="endDate" />
<h:message for="order" />
<o:validateOrder id="order" components="startDate endDate"
message="End date must be after start date" />
</h:panelGroup>
</h:panelGrid>
<h:commandButton value="submit" action="#{booking.submit}">
<f:ajax execute="#form" render="#form" />
</h:commandButton>
But, In this example validation is triggered after manually submit. And I need to validate after focus (of Calendar) is lost. How can I achieve that? Thanks.

The multi field validators from OmniFaces can be referenced in <f:ajax execute>. The "focus lost" event is the blur event. Thus, this should do:
<h:inputText ...>
<f:ajax event="blur" execute="startDate endDate order" render="m_startDate m_endDate m_order" />
</h:inputText>
where m_startDate, etc are the IDs of the <h:message> components like so
<h:message id="m_startDate" for="startDate" />

Related

Force user to select different values in multiple h:selectOneMenu showing same lists

I am relatively new to JSF and Primefaces. I have a page in which I have three selectOneMenu displaying the same set of values from a map. I would like to make sure that the user selects different values for the three drop downs. I have achieved this by writing a custom validator. But the validator works only if I click the submit page. I want to have an ajax call which would show an error message for drop down 2 as soon as the user selects the same value as drop down 1.Also the same case for drop down 3.Here is my code snippet:
user.xhtml
<h:outputLabel for="Question1" value="#{msg['account.question1']}"/>
<h:message styleClass="validation-error" for="Question1"/>
<h:selectOneMenu id="Question1" required="true" value="#{account.question1}" class="smallTxt">
<f:selectItems value="#{controller.questionMap}" />
<f:validator validatorId="com.validator.QuestionsValidator"></f:validator>
</h:selectOneMenu>
<h:outputLabel for="Answer1" value="#{msg['account.answer1']}"/>
<h:message styleClass="validation-error" for="Answer1"/>
<h:inputText id="Answer1" required="true" value="#{account.answer1}" />
<h:outputLabel for="Question2" value="#{msg['account.question2']}"/>
<h:message styleClass="validation-error" for="Question2"/>
<h:selectOneMenu id="Question2" required="true" value="#{account.question2}" class="smallTxt">
<f:selectItems value="#{controller.questionMap}" />
</h:selectOneMenu>
<h:outputLabel for="Answer2" value="#{msg['account.answer2']}"/>
<h:message styleClass="validation-error" for="Answer2"/>
<h:inputText id="Answer2" required="true" value="#{account.answer2}" />
<h:outputLabel for="Question3" value="#{msg['account.question3']}"/>
<h:message styleClass="validation-error" for="Question3"/>
<h:selectOneMenu id="Question3" required="true" value="#{account.question3}" class="smallTxt">
<f:selectItems value="#{controller.questionMap}" />
</h:selectOneMenu>
<h:outputLabel for="Answer3" value="#{msg['account.answer3']}"/>
<h:message styleClass="validation-error" for="Answer3"/>
<h:inputText id="Answer3" required="true" value="#{account.answer3}" />
I am using JSF 2 and Primefaces 5.2.
Thanks in advance
If you want to execute your validator on an AJAX call, you have to add <f:ajax /> to your <h:selectOneMenu>
<h:selectOneMenu id="Question1" required="true" value="#{account.question1}" class="smallTxt">
<f:selectItems value="#{controller.questionMap}" />
<f:validator validatorId="com.validator.QuestionsValidator"></f:validator>
<f:ajax />
</h:selectOneMenu>
Side question: You state, that you use Primefaces 5.2, but you use JSF standard components (<h:selectOneMenu> instead of <p:selectOneMenu>). Is that on purpose?
You can apply listener on selectonemenu.linke this:
<p:selectOneMenu id="country" value="#{dropdownView.country}" style="width:150px">
<p:ajax listener="#{dropdownView.onCountryChange}" update="city" />
<f:selectItem itemLabel="Select Country" itemValue="" noSelectionOption="true" />
<f:selectItems value="#{dropdownView.countries}" />
</p:selectOneMenu>
And then in this oncountrychange() function you will get the values of all the three select items and compare them.

f:ajax validation shows only one message at once

I'm working on JSF form with field validation.
<h:form>
<h:panelGrid id="panel" styleClass="data_table_pricing" columns="3">
<h:outputText value="Title"/>
<h:inputText id="title" value="#{pricingForm.title}" validatorMessage="Value is too big.">
<f:validateLength minimum="0" maximum="40" />
<f:ajax event="change" render="#form"/>
</h:inputText>
<h:message id="title_message" for="title" style="color:red"/>
<!-- // -->
<h:outputText value="First name"/>
<h:inputText id="first_name" value="#{pricingForm.firstName}" validatorMessage="Value is too big.">
<f:validateLength minimum="0" maximum="40" />
<f:ajax event="change" render="#form"/>
</h:inputText>
<h:message id="first_name_message" for="first_name" style="color:red"/>
<!-- // -->
<h:outputText value="Last name"/>
<h:inputText id="last_name" value="#{pricingForm.lastName}" validatorMessage="Value is too big.">
<f:validateLength minimum="0" maximum="40" />
<f:ajax event="change" render="#form"/>
</h:inputText>
<h:message id="last_name_message" for="last_name" style="color:red"/>
<!-- // -->
</h:panelGrid>
<h:commandLink value="reset" class="link" type="reset" style="margin: 20px;">
<f:ajax execute="#form" render="#form"/>
</h:commandLink>
<h:commandLink value="Next" class="link" style="margin: 20px;" actionListener="#{pricingForm.calculatorPage()}">
<f:ajax execute="#form" render="#form"/>
</h:commandLink>
</h:form>
When I insert into several input fields big values I see only one error message. Looks like when the form is rendered the old values are not saved. San you help me to solve this?
This,
<f:ajax event="change" render="#form"/>
means the same as: "when the value of the current input is changed, submit and process only the current input and update the whole form".
So, other inputs aren't processed/validated, and the update basically clears out previous messages.
You likely meant to update only the associated message. E.g. in case of your first input:
<f:ajax render="title_message" />
I only omitted event="change" as that's the default already in <h:inputXxx> components.
See also:
Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes

Primefaces 2 <h:form> and 2<p:message> confusion

My login page has 2 forms, 1 for login itself, and another one to create new users and they are in a tab view(p:tabView), so users will never see both on the page, it would be, one or another.
The problem is that everytime that a valitation fails on login tab, the failure is also shown in the new user tab, and vice-versa.
How to handle this? i tried to set update property in the buttoncommand, but it did not work
see my code below:
<p:tabView id="loginTabView" orientation="right" style="margin-bottom:20px" styleClass="login_fields_panel">
<p:tab title="Acesso" id="acessoTab" >
<h:form>
<h3><h:outputText value="#{bundle.loginHello}" escape="false"/></h3>
<p:messages id="messages_login" showDetail="false" autoUpdate="true" closable="true" showIcon="true"/>
<p:outputLabel for="email" value="#{bundle.label_email}"/>
<p:inputText value="#{loginMB.email}" label="#{bundle.label_email}" id="email" required="true" validatorMessage="#{bundle.emailInvalido}" size="45">
<f:validateRegex pattern="^[\w-\.]+#([\w-]+\.)+[\w-]{2,4}$" for="email" />
</p:inputText>
<br/>
<p:outputLabel for="senha" value="#{bundle.label_password}" />
<p:password value="#{loginMB.password}" id="senha" label="#{bundle.label_password}" required="true" size="45"/>
<br/><br/>
<p:commandButton action="#{loginMB.login}" value="#{bundle.btn_login}" ajax="false" update="messages_login"/>
</h:form>
</p:tab>
<p:tab title="Faça seu cadastro aqui" id="newUserPanel" >
<h:form id="formNewUser">
<h3><h:outputText value="#{bundle.loginHello}" escape="false"/></h3>
<p:messages id="messages_new" showDetail="false" autoUpdate="true" closable="true" showIcon="true" />
<h:panelGrid columns="2" id="matchGrid" cellpadding="1">
<p:outputLabel for="email" value="#{bundle.label_name}: "/>
<p:inputText value="#{loginMB.email}" label="#{bundle.label_name}:" id="name" required="true" validatorMessage="#{bundle.emailInvalido}" size="45" maxlength="100">
</p:inputText>
<p:outputLabel for="email" value="#{bundle.label_email}: "/>
<p:inputText value="#{loginMB.email}" label="#{bundle.label_email}" id="email" required="true" validatorMessage="#{bundle.emailInvalido}" size="45">
<f:validateRegex pattern="^[\w-\.]+#([\w-]+\.)+[\w-]{2,4}$" for="email" />
</p:inputText>
<p:outputLabel for="senha" value="#{bundle.label_password}" />
<p:password value="#{loginMB.password}" id="senha" label="#{bundle.label_password}" required="true" size="45"/>
<p:outputLabel for="senhaConfirmacao" value="#{bundle.label_password_confirmacao}" />
<p:password value="#{loginMB.password}" id="senhaConfirmacao" label="#{bundle.label_password_confirmacao}" required="true" size="45"/>
<p:outputLabel for="birthday" value="#{bundle.label_birthday}" />
<p:calendar id="birthday" value="#{calendarView.date2}" required="true" size="45" pattern="dd/MM/yyyy"/>
</h:panelGrid>
<br/><br/>
<p:commandButton id="btn_create" action="#{loginMB.createUser}" value="#{bundle.btn_criar_usuario}" ajax="true" update="messages_new"/>
</h:form>
</p:tab>
thanks
The described problem with two forms and two message components is actually two-fold:
You're using autoUpdate="true" on those message components. So regardless of what you specify in update attribute, those message components will be auto-updated.
You need to either remove the autoUpdate="true" from the message components, or add ignoreAutoUpdate="true" to the command component.
You're using ajax="false" on the first button. This forces a full page reload. Do note that all ajax-related attribtes such as process and update are ignored in such case.
You need to either re-enable ajax on the first button, or to add redisplay="false" to the second message component.

primefaces watermark disappears after disabling and re enabling a text field using p:ajax

I am using p:ajax of primefaces in a p:selectOneRadio, to disable and re-enable form input text fields. these text fields have watermarks which disappear after disabling and they do not appear even after re-enabling them. I could not figure out the problem. please help. The code chunk where it appears is as bellow
<h:outputText
value="#{msg['elicense.contractorLicenseForm.personal.licenseApplied']}"/>
<p:selectOneRadio id="licenseApplied"
value="#{contractorLicenseBean.licenseApplied}">
<f:selectItem itemLabel="Yes" itemValue="1" />
<f:selectItem itemLabel="No" itemValue="0"/>
<p:ajax update="licensePersonName, relationshipPersonName" />
</p:selectOneRadio>
<h:outputText value="When it is yes, it should skip to supervisor details"/>
<h:outputText
value="#{msg['elicense.contractorLicenseForm.personal.licensePersonName']} "/>
<p:inputText id="licensePersonName"
value="#{contractorLicenseBean.licensePersonName}"
required="true"
label="LicensePersonName"
disabled="#{contractorLicenseBean.licenseApplied=='1'}"/>
<p:watermark for="licensePersonName"
value="Person/firm/company on whose Favour License is Sought "
id="watermark2" />
<h:outputText
value="#{msg['elicense.contractorLicenseForm.personal.relationshipPersonName']} "/>
<p:inputText id="relationshipPersonName"
value="#{contractorLicenseBean.relationshipPersonName}"
required="true"
label="RelationshipPersonName"
disabled="#{contractorLicenseBean.licenseApplied=='1'}" />
<p:watermark for="relationshipPersonName"
value="Relationship of the Applicant "
id="watermark3" />
Use a h:panelGroup around your watermarked components and update that h:panelGroup instead of component.
Primefaces binds the watermark to component through JQuery. If you changes/update the component then events bound to that component will not work, that may be the reason for your Issue.
I used primefaces 5.0, and I encountered as your problem. When I put the p:inputText into p:panelGrid and update the panelGrid. The problem was gone.
<h:form>
<p:messages id="messages" showDetail="true"/>
<p:selectOneRadio id="radio" value="#{watermarkView.radio}">
<f:selectItem itemLabel="Yes" itemValue="1" />
<f:selectItem itemLabel="No" itemValue="0"/>
<p:ajax process="radio" update="panelGridInput" />
</p:selectOneRadio>
<h:panelGrid id="panelGridInput"
columns="3" cellpadding="5"
style="margin-bottom:10px">
<h:outputLabel value="Search: "/>
<p:inputText id="keyword"
value="#{watermarkView.keyword}"
required="true"
label="Keyword"
disabled="#{watermarkView.radio eq '1'}"/>
<p:watermark for="keyword"
value="Search with a keyword"
id="watermark" />
<h:outputLabel value="Search: "/>
<p:inputText id="keyword2"
value="#{watermarkView.keyword2}"
required="true"
label="Keyword"
disabled="#{watermarkView.radio eq '1'}"/>
<p:watermark for="keyword2"
value="Search with a keyword"
id="watermark2" />
</h:panelGrid>
<p:commandButton id="regular"
actionListener="#{watermarkView.search}"
value="Regular"
ajax="false" />
<p:commandButton id="ajax"
actionListener="#{watermarkView.search}"
value="Ajax"
onclick="PrimeFaces.cleanWatermarks();"
oncomplete="PrimeFaces.showWatermarks();"
update="messages" />
</h:form>

JSF Validate on keyup event

i want to implement a validation for a username. The 'normal' way to do it
is something like that:
<h:outputText for="username" value="Username:" />
<p:inputText id="username" value="#{registerService.username}" >
<f:validator binding="#{usernameValidator}" />
</p:inputText>
<p:message for="username" />
<p:commandButton type="submit" value="Submit" action="#{registerService.addUser}" ajax="false" update="panel" validateClient="true" />
But what i now want to do is to validate the username everytime
the user presses a key in the username inputText without pressing
the commandButton.
So each character should trigger the validation and should update
the messages field for username to show the user instantly if the
username is already present in database or not.
How can i do that?
Found:
Ajax Listener
This triggers the validation!
<h:inputText id="foo" value="#{bean.foo}">
<f:ajax event="keyup" execute="#this" render="fooMessage" />
<f:validator validatorId="fooValidator" />
</h:inputText>
<h:message id="fooMessage" for="foo" />

Resources