How to restrict apex:inputText
to take number values only?
-
Are you interested in doing this client-side e.g. not allowing non-numbers to be entered at all or just validating at the server-side?– Keith CApr 2, 2014 at 13:36
-
Ideally I would like to do it in client-side– justasdApr 3, 2014 at 8:18
5 Answers
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
-
3... but be aware that e.g. IE8 and IE9 (and other browser versions) don't support this - see caniuse.com/#feat=input-number.– Keith CApr 2, 2014 at 14:36
-
1I get below error when try to add attribute type = "Number"... Error: Expected input type 'text', got 'number' for String data type .– RajeevFeb 14, 2017 at 11:07
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.
It bugged me too especially that apex:input does not take decimals.
Here is a solution that consumes any other chars than numbers and the dot ' . ' (while typing).
(I found another one with jQuery attaching the 'keyup' event to a specific class, but that one did not work for me. However the idea comes from there).
<script>
function decimalOnly(e){
e.value = e.value.replace(/[^0-9\.]/g,'');
if(e.value.split('.').length>2) e.value = e.value.replace(/\.+$/,"");
};
</script>
<apex:inputText value="{!aDecimalVariable}" onkeyup="decimalOnly(this);" />
One option of doing this, us by using jQuery and Digital Bush’s Masked Input Plugin. In code that would look like this:
<apex:includeScript value="{!$Resource.jquery}"/>
<apex:includeScript value="{!$Resource.jMaskedInput}"/>
<apex:outputLabel for="dbl" value="Double" />
<apex:inputText id="dbl" styleClass="dbl-mask"/>
<script>
$(document).ready(function() {
// Attach masks to correct input fields
$(".dbl-mask").mask("999 999 999.99");
});
</script>
This is explained by Wes Nolte in one of his blog posts here.