Twistleton
Twistleton

Reputation: 2935

How validate number fields with validateRegex in a JSF-Page?

In a managed bean I have a property of the type int.

@ManagedBean
@SessionScoped
public class Nacharbeit implements Serializable {

private int number;

In the JSF page I try to validate this property for 6 digits numeric input only

               <h:inputText id="number"
                         label="Auftragsnummer"
                         value="#{myController.nacharbeit.number}"
                         required="true">
                <f:validateRegex pattern="(^[1-9]{6}$)" />
            </h:inputText>

On runtime I get an exception:

javax.servlet.ServletException: java.lang.Integer cannot be cast to java.lang.String

java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String

Is the regex wrong? Or are the ValidateRegex only for Strings?

Upvotes: 10

Views: 29275

Answers (4)

Jasper de Vries
Jasper de Vries

Reputation: 20188

If you are using PrimeFaces, I suggest to simply use the p:inputNumber component. This allows you to set minValue and maxValue. Way more convenient.

See the documentation for more details.

Upvotes: 0

We needed to validate number fields with validateRegex

Here's how we did it

    public class CustomNumberConverter extends NumberConverter {

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        if (StringUtils.isEmpty(value) || StringUtils.isBlank(value)) {
            return null;
        }

        //needed to raise an error when the number comes with trailing letters 
        if (!value.matches("^[\\d,\\.\\s]+$")) {
            throw new ConverterException("");
        }
        return super.getAsObject(context, component, value);
    }
}

Then register the custom converter, don't forget to add the parameters supported by the base converter

<converter>
    <converter-id>project.converter.customnumberconverter</converter-id>
    <converter-class>com.web.project.converters.CustomNumberConverter</converter-class>
    <property>
        <property-name>pattern</property-name>
        <property-class>java.lang.String</property-class>
    </property>
    <property>
        <property-name>maxIntegerDigits</property-name>
        <property-class>java.lang.Integer</property-class>
    </property>
    <property>
        <property-name>minFractionDigits</property-name>
        <property-class>java.lang.Integer</property-class>
    </property>
</converter>

<tag>
    <tag-name>customConvertNumber</tag-name>
    <converter>
        <converter-id>project.converter.customnumberconverter</converter-id>
    </converter>
</tag>

Finally in the view use the custom converter

<p:inputText
    value="#{controller.inputValue}"
    maxlength="35"
>
    <f:validateDoubleRange minimum="0" maximum="9999999999" />
    <s:customConvertNumber pattern="0.00" maxFractionDigits="2" minFractionDigits="2" />
</p:inputText>

inputValue used in the controller is a String, in order to overcome the COERCE_ZERO issue (primefaces version 3.2)

Upvotes: 1

Ajay
Ajay

Reputation: 730

You can achieve this without regex also

To validate int values:

<h:form id="user-form">  
    <h:outputLabel for="name">Provide Amount to Withdraw  </h:outputLabel><br/>  
    <h:inputText id="age" value="#{user.amount}" validatorMessage="You can Withdraw only between $100 and $5000">  
    <f:validateLongRange minimum="100" maximum="5000" />  
    </h:inputText><br/>  
    <h:commandButton value="OK" action="response.xhtml"></h:commandButton>  
</h:form> 

To validate float values:

<h:form id="user-form">  
    <h:outputLabel for="amount">Enter Amount </h:outputLabel>  
    <h:inputText id="name-id" value="#{user.amount}" validatorMessage="Please enter amount between 1000.50 and 5000.99">  
    <f:validateDoubleRange minimum="1000.50" maximum="5000.99"/>  
    </h:inputText><br/><br/>  
    <h:commandButton value="Submit" action="response.xhtml"></h:commandButton>
</h:form>  

Upvotes: 1

BalusC
BalusC

Reputation: 1108732

The <f:validateRegex> is intented to be used on String properties only. But you've there an int property for which JSF would already convert the submitted String value to Integer before validation. This explains the exception you're seeing.

But as you're already using an int property, you would already get a conversion error when you enter non-digits. The conversion error message is by the way configureable by converterMessage attribute. So you don't need to use regex at all.

As to the concrete functional requirement, you seem to want to validate the min/max length. For that you should be using <f:validateLength> instead. Use this in combination with the maxlength attribute so that the enduser won't be able to enter more than 6 characters anyway.

<h:inputText value="#{bean.number}" maxlength="6">
    <f:validateLength minimum="6" maximum="6" />
</h:inputText>

You can configure the validation error message by the validatorMessage by the way. So, all with all it could look like this:

<h:inputText value="#{bean.number}" maxlength="6"
    converterMessage="Please enter digits only."
    validatorMessage="Please enter 6 digits.">
    <f:validateLength minimum="6" maximum="6" />
</h:inputText>

Upvotes: 26

Related Questions