How to hide validatorMessage when field is empty - jsf

Please help how to hide validatorMessage when user clearing the field:
<div class="item">
<p:outputLabel for="firstName" value="#{msgs['customerForm.firstName']}"/>
<p:inputText id="firstName" value="#{customerBean.customer.firstName}"
requiredMessage="#{msgs['Error.firstName.mandatory']}"
validatorMessage="#{msgs['Error.firstName.wrongFormat']}"required="true">
<f:validateRegex pattern="^([a-zA-Z]+[a-zA-Z\s\-]*){1,255}$" />
</p:inputText>
<p:message id="m_firstName" for="firstName" display="text"/>
</div>

You defined your field having two validations:
* required value validator
* regular expression validator
Both validators have equivalent priority, and both are run against your field value. And both of these validators see empty value as a problem, and your framework, unable to determine which of these two equivalent-looking failures is the "actual" failure, displays both.
To "fix" it, you should allow empty values to pass your regex, like this:
<f:validateRegex pattern="^([a-zA-Z]+[a-zA-Z\s\-]*){0,255}$" />
Notice that I changed number qualifier to allow 0-255 characters instead of 1-255 characters like before.
That should allow two of your validators cover different cases of invalid values, like you intended.

You can update the error messages if you put this in the input element. It will validate the input on every keyup event though.
<f:ajax execute="#this" event="keyup" render="m_firstName" />

Related

Validation of a b:modal form is not working

I am trying to validate a modal form ( JSF/Bootsfaces ) and prevent it from being saved if the inputtext is not correct. For some reason I ignore it is not working, here is the JSF code:
<b:modal id="creation"
title="#{msgs['page.manageFlights.addingNew']}"
styleClass="formValidationModalClass"
closeOnEscape="false"
backdrop="false"
closable="false">
<b:form id="createModal">
<b:selectOneMenu
value="#{flightBean.currentFlight.journey}"
label="#{msgs['page.manageFlights.findAllJourneys']}"
required="true"
requiredMessage="Please select a journey"
large-screen="full-width">
<f:selectItems value="#{journeyBean.findAllJourneys()}" var="journey" itemValue="#{journey}" itemLabel="#{journey.departureLocation} -> #{journey.arrivalLocation}" />
</b:selectOneMenu>
<b:dateTimePicker
value="#{flightBean.currentFlight.departureDate}"
label="#{msgs['page.manageFlights.departureDate']}"
required="true"
requiredMessage="Please enter a date and time"
large-screen="full-width">
</b:dateTimePicker>
<b:dateTimePicker
value="#{flightBean.currentFlight.arrivalDate}"
label="#{msgs['page.manageFlights.arrivalDate']}"
required="true"
requiredMessage="Please enter a date and time"
large-screen="full-width">
</b:dateTimePicker>
<b:inputText value="#{flightBean.currentFlight.numberOfBusinessClassSeats}"
label="#{msgs['page.manageFlights.numberOfBusinessClassSeats']}"
required="true"
requiredMessage="The number of seats must be positive"
large-screen="full-width">
<f:validateLongRange minimum = "1" maximum = "2000" />
</b:inputText>
<b:inputText
value="#{flightBean.currentFlight.numberOfEconomyClassSeats}"
label="#{msgs['page.manageFlights.numberOfEconomyClassSeats']}"
required="true"
requiredMessage="Please enter a number"
validatorMessage="The number of seats must be positive"
large-screen="full-width">
</b:inputText>
<br/>
<b:row>
<b:column>
<b:commandButton
largeScreen="half"
value="#{msgs['cancel.button']}"
dismiss="modal"
action="#{flightBean.resetCurrentFlight()}"
oncomplete="$('#creation').modal('hide')"
/>
<b:commandButton
largeScreen="half"
dismiss="modal"
update="#(#dataTable)"
value="#{msgs['save.button']}" look="success"
action="#{flightBean.addFlight(flightBean.currentFlight)}"
oncomplete="if(!validationFailed) { $('#creation').modal('hide')};">
</b:commandButton>
</b:column>
</b:row>
<b:fetchBeanInfos/>
<b:messages/>
</b:form>
</b:modal>
I am trying to check if the number of business class seats is positive.
As you can see I added fetchbeaninfos, validateLongRange and oncomplete.
<b:fetchBeanInfos> and validationFailed only work after an AJAX request. You need to send the input to the server, have it validated there, and only when the response is sent back to the client, validationFailed is updated.
My suggestion is to use simple JavaScript to show the error message and to disable the button.
However, if you prefer to use server-side validation, here's what to do:
Add an empty validateInput() method to your bean. It doesn't need any implementation; it just has to be there so it can be called by an JSF AJAX call.
Add an id to <b:fetchBeanInfos>.
Add an AJAX change listener to each input field. Depending on the type of the input field, you may need a different listener (onblur, onchange, etc.), but the general idea is like so:
<b:inputText
onblur="ajax:flightBean.validateInput()"
update="**:fetchBeansId"
value="..."
label="..."
required="true"
requiredMessage="..."
validatorMessage="...">
</b:inputText>
<b:fetchBeanInfos id="fetchBeansId"/>
The **:idbit helps you if your JSF page has multiple "namespaces", such as forms, modals, data tables, and tabs. These namespaces add a prefix to the id, and **:id allows you to find the id no matter what the prefix is.

Primefaces Diagram - Generating IDs for DOM Elements

I'm trying to create a <p:diagram> with elements which contain input fields, but the problem is that for each added element, the name and ID are the same for each input field.
What I've tried to do to give each field a unique id is adding a bean-generated ID for each element, but this just gets omitted in the final code. Here's my EL/xhtml:
<p:diagram value="#{Controller.model}" style="height:600px;width:1500px" styleClass="ui-widget-content" var="lrvEl" scrollable="true">
<f:facet name="element">
<div onmouseleave="nodeOnMouseOut(this)" onclick="nodeOnClick(this)">
<h:outputText value="#{lrvEl.title}" style="display:block;margin-top:1em;width:100%;height:10px;padding-left:4px"/>
<h:outputText value="#{lrvEl.description}" style="display:block;margin-top:1em;width:100%;height:10px;padding-left:4px"/>
<h:inputText id="inputEpValue_#{lrvEl.id}" name="inputEpValue_#{lrvEl.id}" onchange="setScoreVal('#{lrvEl.id}', this)" rendered="#{lrvEl.isScore()}" style="display:block;margin-top:1em;height:10px;padding-left:4px">
</h:inputText>
</div>
</f:facet>
<p:ajax event="connect" listener="#{Controller.onConnect}" />
<p:ajax event="disconnect" listener="#{Controller.onDisconnect}" />
<p:ajax event="connectionChange" listener="#{Controller.onConnectionChange}" />
</p:diagram>
The important bit here is the <h:inputText id='inputEpValue_#{lrvEl.id}' ... > - this comes out on the page as the following:
editor:LRVContent:overlayForm_lm:inputEpValue
as if the value wasn't set, however, as you can see in the onchange field I use the same constellation. This gets rendered as onchange="setScoreVal('ep:2', this)" so that works.
Can I not dynamically set IDs for elements in this fashion? Is there another way?
Edit:
The actual Reason I want to do this is that, if I have more than one input with the same generated ID, the focus(/cursor) will automatically jump into the last generated input field when I click on any one of them, meaning I won't be able to actually change the value of any of those fields.

How to reset <f:ajax> disabled attribute

given the following code:
<h:inputText id="minRate" value="#{bakingController.minRate}">
<f:convertNumber type="currency" pattern="#{msg.currencyPattern}" maxFractionDigits="0"/>
<f:ajax event="keyup" listener="#{bankingController.listProviders()}" execute="minRate" render="minRate btn-submit" disabled="#{facesContext.validationFailed}"/>
</h:inputText>
i would like to disable the ajax-listener if the validation is failed for the first keyup-event, e.g. user enters some non-digits. but when i clear the input field or enter a valid number then, it won't get reactivated, although the parent field is re-rendered. how can i solve that?
may you answers help.
there was a thinking flaw -.-
i have to validate with javascript if the input matches the appropriate format. then the listener will only be called, if the javascript-function returns true. so the disabled attribute is not needed.
<h:inputText id="minRate" value="#{bakingController.minRate}" onkeyup="return $.isNumeric(this.value)">
<f:convertNumber type="currency" pattern="#{msg.currencyPattern}" maxFractionDigits="0"/>
<f:ajax event="keyup" listener="#{bankingController.listProviders()}"
execute="minRate" render="minRate btn-submit"/>
</h:inputText>

Skip validation when a specific button is clicked and set specific values

I have a form with several fields and there is a block with two required fields and a search button.
What i want is when i click on search button i want to ignore the form validations and that the two fields values to be set in the bean, but this doesnt happen.
How should I apply the values?
EDIT: I have more required fields in the view, that in this case i want ignore.
<p:inputMask id="field1" mask="9999" styleClass="marginLeft input smaller"
requiredMessage="#{label.msg_requiredFields}"
required="true" value="#{cc.attrs.cena.field.cp4Offline}"/>
<p:inputMask id="field2" mask="999"
requiredMessage="#{label.msg_requiredFields}"
required="true" styleClass="input smallest"
value="#{cc.attrs.cena.field.cp3Offline}"/>
<p:commandButton id="pesquisarId" styleClass="marginLeft" icon="ui-icon-search"
actionListener="#{pesquisarMorada.pesquisar(cc.attrs.cena)}"
update="resultPesquisaPanelId" process="#this field1 field2" immediate="true"/>
Remove immediate="true" from <p:commandButton />.
From this article:
... When immediate is set to true on an Command component, the action is invoked in the Apply Request Values phase ...
... so your model values will not be updated at all.

JSF Number Validation

Is there any inbuilt number validator tag in JSF that checks whether an input entered in h:inputext field is a number?
The first question was answered. Edited to explain the next problem:
<h:inputText id="maxrecs" value="#{simpleBean.numRecords}" required="false" maxlength="4" >
<f:convertNumber longOnly="true"/>
</h:inputText>
Backing Bean
private long numRecords = null;
If I use String or Integer object in the backing bean , value is not being set. Now when I use primitive int, 0 is being printed on the screen. I would like the screen to be empty.
You can use f:convertNumber (use the integerOnly attribute).
You can get more information here.
You can use:
<f:validateLongRange minimum="20" maximum="1000" />
Where minimum is the smallest number allowed and maximum is the largest.
Look here for more details
JSF Number validation for inputtext
mention f:converterNumber component in between h inputText component and mention the attributes integerOnly and type.
<h:inputText id="textMobileId" label="Mobile" styleClass="controlfont" value="#{UserRegistrationBean.textMobile}">
<f:convertNumber integerOnly="true" type="number" />
</h:inputText>
If you enter abcd in Mobile textbox at the time when you click on commandbutton it automatically shows an error like
Mobile: 'abcd' is not a number.
i8taken solution converts number into long without validation message (at least in my case: JSF2 / global messages per page). For proper validation message you can
1. check value in action method in bean;
or
2. use converter attribute for inputText:
<h:inputText id="maxrecs" value="#{simpleBean.numRecords}" maxlength="4" converter="javax.faces.Integer" />
You can simply use the passthrough, so first add this library
xmlns:pt="http://xmlns.jcp.org/jsf/passthrough"
and after use this
<h:inputText id="numberId" pt:type="number" />

Resources