Visualforce: apex:inputText - restrict input to numbers only

One way you could make this work is HTML5-ifying your Visualforce page and use <apex:input type="number" /> instead of apex:inputText.

Otherwise, you could implement some javascript validation or send it back to your controller and do the validation in Apex.

Note: To HTML5-ify your page, the easiest way is using the page element with the docType attribute <apex:page docType="html-5.0">.

See: http://blogs.developerforce.com/developer-relations/2011/12/visualforce-html5-mobile.html


This can be done easily with Javascript and here's an example from a project I had to do in the past.

Javascript

function inputLimiter(e,allow) {
            var AllowableCharacters = '';

            if (allow == 'Letters'){AllowableCharacters=' ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';}
            if (allow == 'Numbers'){AllowableCharacters='1234567890';}
            if (allow == 'NameCharacters'){AllowableCharacters=' ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-.\'';}
            if (allow == 'NameCharactersAndNumbers'){AllowableCharacters='1234567890 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-\'';}
            if (allow == 'Currency'){AllowableCharacters='1234567890.';}

            var k = document.all?parseInt(e.keyCode): parseInt(e.which);
            if (k!=13 && k!=8 && k!=0){
                if ((e.ctrlKey==false) && (e.altKey==false)) {
                return (AllowableCharacters.indexOf(String.fromCharCode(k))!=-1);
                } else {
                return true;
                }
            } else {
                return true;
            }
        } 

Standard Apex Tag using method:

<apex:inputField value="{!opportunity.MyCustomField}" onkeypress="return inputLimiter(event,'Numbers');" />

While the Javascript approach gives immediate feedback to the user (as well as the HTML-5 approach) and is hence a superior solution, there may be times when you want to do validation of apex:inputText on your controller. Should you opt for that route:

  • Bind the apex:inputText value to a controller variable of type String.
  • Note that a null value as seen by the user (no data entered in field) will be seen by the VF controller variable as a String of length=0 - not a value=null (this took me the longest time to realize)
  • Do your validation logic in the controller, using String methods or try{cast to Decimal/Integer} catch{..}.
  • Issue error messages as per normal

Note that if you bind your apex:inputText value to a controller variable of type Integer or Decimal, SFDC will do the conversion for you and, if not a number, will report an error at the top of the page: Value 'abc' cannot be converted from Text to Number. But, null values in the box (that is, no data entered) will be converted by SFDC to your controller variable as 0, not null - which can create feedback confusion to the user.