HTML text input allow only numeric input
Sebastian Wright
Is there a quick way to set an HTML text input (<input type=text />) to only allow numeric keystrokes (plus '.')?
73 Answers
123 NextNote: This is an updated answer. Comments below refer to an old version which messed around with keycodes.
JavaScript
Try it yourself on JSFiddle.
You can filter the input values of a text <input> with the following setInputFilter function (supports Copy+Paste, Drag+Drop, keyboard shortcuts, context menu operations, non-typeable keys, the caret position, different keyboard layouts, validity error message, and all browsers since IE 9):
// Restricts input for the given textbox to the given inputFilter function.
function setInputFilter(textbox, inputFilter, errMsg) { ["input", "keydown", "keyup", "mousedown", "mouseup", "select", "contextmenu", "drop", "focusout"].forEach(function(event) { textbox.addEventListener(event, function(e) { if (inputFilter(this.value)) { // Accepted value if (["keydown","mousedown","focusout"].indexOf(e.type) >= 0){ this.classList.remove("input-error"); this.setCustomValidity(""); } this.oldValue = this.value; this.oldSelectionStart = this.selectionStart; this.oldSelectionEnd = this.selectionEnd; } else if (this.hasOwnProperty("oldValue")) { // Rejected value - restore the previous one this.classList.add("input-error"); this.setCustomValidity(errMsg); this.reportValidity(); this.value = this.oldValue; this.setSelectionRange(this.oldSelectionStart, this.oldSelectionEnd); } else { // Rejected value - nothing to restore this.value = ""; } }); });
}You can now use the setInputFilter function to install an input filter:
setInputFilter(document.getElementById("myTextBox"), function(value) { return /^\d*\.?\d*$/.test(value); // Allow digits and '.' only, using a RegExp
}, "Only digits and '.' are allowed");Apply your preferred style to input-error class. Here's a suggestion:
.input-error{ outline: 1px solid red;
}See the JSFiddle demo for more input filter examples. Also note that you still must do server side validation!
TypeScript
Here is a TypeScript version of this.
function setInputFilter(textbox: Element, inputFilter: (value: string) => boolean, errMsg: string): void { ["input", "keydown", "keyup", "mousedown", "mouseup", "select", "contextmenu", "drop", "focusout"].forEach(function(event) { textbox.addEventListener(event, function(this: (HTMLInputElement | HTMLTextAreaElement) & {oldValue: string; oldSelectionStart: number | null, oldSelectionEnd: number | null}) { if (inputFilter(this.value)) { this.oldValue = this.value; this.oldSelectionStart = this.selectionStart; this.oldSelectionEnd = this.selectionEnd; } else if (Object.prototype.hasOwnProperty.call(this, 'oldValue')) { this.value = this.oldValue; if (this.oldSelectionStart !== null && this.oldSelectionEnd !== null) { this.setSelectionRange(this.oldSelectionStart, this.oldSelectionEnd); } } else { this.value = ""; } }); });
}jQuery
There is also a jQuery version of this. See this answer.
HTML 5
HTML 5 has a native solution with <input type="number"> (see the specification), but note that browser support varies:
- Most browsers will only validate the input when submitting the form, and not when typing.
- Most mobile browsers don't support the
step,minandmaxattributes. - Chrome (version 71.0.3578.98) still allows the user to enter the characters
eandEinto the field. Also see this question. - Firefox (version 64.0) and Edge (EdgeHTML version 17.17134) still allow the user to enter any text into the field.
Try it yourself on w3schools.com.
36Use this DOM
<input type='text' onkeypress='validate(event)' />And this script
function validate(evt) { var theEvent = evt || window.event; // Handle paste if (theEvent.type === 'paste') { key = event.clipboardData.getData('text/plain'); } else { // Handle key press var key = theEvent.keyCode || theEvent.which; key = String.fromCharCode(key); } var regex = /[0-9]|\./; if( !regex.test(key) ) { theEvent.returnValue = false; if(theEvent.preventDefault) theEvent.preventDefault(); }
} 24 Here is a simple one which allows for exactly one decimal, but no more:
<input type="text" oninput="this.value = this.value.replace(/[^0-9.]/g, '').replace(/(\..*?)\..*/g, '$1');" />As someone commented below, the solution above does not handle leading zeros. If your particular use case requires that these are not allowed you can add to the pattern above like so:
<input type="text" oninput="this.value = this.value.replace(/[^0-9.]/g, '').replace(/(\..*?)\..*/g, '$1').replace(/^0[^.]/, '0');" />That will allow 0.123 or .123 but not 0123 or 00.123.
I've searched long and hard for a good answer to this, and we desperately need <input type="number", but short of that, these 2 are the most concise ways I could come up with:
<input type="text" onkeyup="this.value=this.value.replace(/[^\d]/,'')">If you dislike the non-accepted character showing for a split-second before being erased, the method below is my solution. Note the numerous additional conditions, this is to avoid disabling all sorts of navigation and hotkeys. If anyone knows how to compactify this, let us know!
<input type="text"
onkeydown="return ( event.ctrlKey || event.altKey || (47<event.keyCode && event.keyCode<58 && event.shiftKey==false) || (95<event.keyCode && event.keyCode<106) || (event.keyCode==8) || (event.keyCode==9) || (event.keyCode>34 && event.keyCode<40) || (event.keyCode==46) )"> 13 Most answers here all have the weakness of using key- events.
Many of the answers would limit your ability to do text selection with keyboard macros, copy+paste and more unwanted behavior, others seem to depend on specific jQuery plugins, which is killing flies with machineguns.
This simple solution seems to work best for me cross platform, regardless of input mechanism (keystroke, copy+paste, rightclick copy+paste, speech-to-text etc.). All text selection keyboard macros would still work, and it would even limit ones ability to set a non-numeric value by script.
function forceNumeric(){ var $input = $(this); $input.val($input.val().replace(/[^\d]+/g,''));
}
$('body').on('propertychange input', 'input[type="number"]', forceNumeric); 16 HTML5 has <input type=number>, which sounds right for you. Currently, only Opera supports it natively, but there is a project that has a JavaScript implementation.
And one more example, which works great for me:
function validateNumber(event) { var key = window.event ? event.keyCode : event.which; if (event.keyCode === 8 || event.keyCode === 46) { return true; } else if ( key < 48 || key > 57 ) { return false; } else { return true; }
};Also attach to keypress event
$(document).ready(function(){ $('[id^=edit]').keypress(validateNumber);
});And HTML:
<input type="input" value="0" size="5" maxlength="5" /> 12 HTML5 supports regexes, so you could use this:
<input pattern="[0-9.]+" type="text">Warning: Some browsers don't support this yet.
7I opted to use a combination of the two answers mentioned here i.e.
<input type="number" />
and
function isNumberKey(evt){ var charCode = (evt.which) ? evt.which : evt.keyCode return !(charCode > 31 && (charCode < 48 || charCode > 57));
}<input type="text" onkeypress="return isNumberKey(event);">
JavaScript
function validateNumber(evt) { var e = evt || window.event; var key = e.keyCode || e.which; if (!e.shiftKey && !e.altKey && !e.ctrlKey && // numbers key >= 48 && key <= 57 || // Numeric keypad key >= 96 && key <= 105 || // Backspace and Tab and Enter key == 8 || key == 9 || key == 13 || // Home and End key == 35 || key == 36 || // left and right arrows key == 37 || key == 39 || // Del and Ins key == 46 || key == 45) { // input is VALID } else { // input is INVALID e.returnValue = false; if (e.preventDefault) e.preventDefault(); }
}additional you could add comma, period and minus (,.-)
// comma, period and minus, . on keypad key == 190 || key == 188 || key == 109 || key == 110 ||HTML
<input type="text" onkeydown="validateNumber(event);"/ > 4 2 solutions:
Use a form validator (for example with jQuery validation plugin)
Do a check during the onblur (i.e. when the user leaves the field) event of the input field, with the regular expression:
<script type="text/javascript">
function testField(field) { var regExpr = new RegExp("^\d*\.?\d*$"); if (!regExpr.test(field.value)) { // Case of error field.value = ""; }
}
</script>
<input type="text" ... onblur="testField(this);"/> 4 // In a JavaScript function (can use HTML or PHP).
function isNumberKey(evt){ var charCode = (evt.which) ? evt.which : evt.keyCode; if (charCode > 31 && (charCode < 48 || charCode > 57)) return false; return true;
}In your form input:
<input type=text name=form_number size=20 maxlength=12 onkeypress='return isNumberKey(event)'>With input max. (These above allows for a 12-digit number)
3A safer approach is checking the value of the input, instead of hijacking keypresses and trying to filter keyCodes.
This way the user is free to use keyboard arrows, modifier keys, backspace, delete, use non standard keyboars, use mouse to paste, use drag and drop text, even use accessibility inputs.
The below script allows positive and negative numbers
1
10
100.0
100.01
-1
-1.0
-10.00
1.0.0 //not allowedvar input = document.getElementById('number');
input.onkeyup = input.onchange = enforceFloat;
//enforce that only a float can be inputed
function enforceFloat() { var valid = /^\-?\d+\.\d*$|^\-?[\d]*$/; var number = /\-\d+\.\d*|\-[\d]*|[\d]+\.[\d]*|[\d]+/; if (!valid.test(this.value)) { var n = this.value.match(number); this.value = n ? n[0] : ''; }
}<input value="-3.1415" placeholder="Type a number" autofocus>EDIT: I removed my old answer because I think it is antiquated now.
1You can use pattern for this:
<input pattern="[0-9.]+" type="number">Here you can see the complete mobile website interface tips.
2Please find below mentioned solution. In this user can be able to enter only numeric value, Also user can not be able to copy, paste, drag and drop in input.
Allowed Characters
0,1,2,3,4,5,6,7,8,9Not allowed Characters and Characters through events
- Alphabetic value
- Special characters
- Copy
- Paste
- Drag
- Drop
$(document).ready(function() { $('#number').bind("cut copy paste drag drop", function(e) { e.preventDefault(); });
});
function isNumberKey(evt) { var charCode = (evt.which) ? evt.which : evt.keyCode; if (charCode > 31 && (charCode < 48 || charCode > 57)) return false; return true;
}<link href="" rel="stylesheet"/>
<script src=""></script>
<input type="text" name="number" onkeypress="return isNumberKey(event)" placeholder="Enter Numeric value only">Let me know if it not works.
1One more example where you can add only numbers in the input field, can not letters
<input type="text" name="phone" placeholder="PHONE" spellcheck="false" oninput="this.value = this.value.replace(/[^0-9.]/g, '').replace(/(\..*)\./g, '$1');"> If you want to suggest to the device (maybe a mobile phone) between alpha or numeric you can use <input type="number">.
A short and sweet implementation using jQuery and replace() instead of looking at event.keyCode or event.which:
$('input.numeric').live('keyup', function(e) { $(this).val($(this).val().replace(/[^0-9]/g, ''));
});Only small side effect that the typed letter appears momentarily and CTRL/CMD + A seems to behave a bit strange.
just use type="number" now this attribute supporting in most of the browsers
<input type="number" maxlength="3" ng-bind="first"> 1 A easy way to resolve this problem is implementing a jQuery function to validate with regex the charaters typed in the textbox for example:
Your html code:
<input type="text">And the js function using jQuery
$(function() { $('.integerInput').on('input', function() { this.value = this.value .replace(/[^\d]/g, '');// numbers and decimals only });
});$(function() { $('.integerInput').on('input', function() { this.value = this.value .replace(/[^\d]/g, '');// numbers and decimals only }); });<script src="" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous">
</script>
<input type="text"/> input type="number" is an HTML5 attribute.
In the other case this will help you:
function isNumberKey(evt){ var charCode = (evt.which) ? evt.which : evt.keyCode if (charCode > 31 && (charCode < 48 || charCode > 57)) return false; return true;
}
<input type="number" name="somecode" onkeypress="return isNumberKey(event)"/> 1 JavaScript code:
function validate(evt)
{ if(evt.keyCode!=8) { var theEvent = evt || window.event; var key = theEvent.keyCode || theEvent.which; key = String.fromCharCode(key); var regex = /[0-9]|\./; if (!regex.test(key)) { theEvent.returnValue = false; if (theEvent.preventDefault) theEvent.preventDefault(); } } }HTML code:
<input type='text' name='price' value='0' onkeypress='validate(event)'/>works perfectly because the backspace keycode is 8 and a regex expression doesn't let it, so it's an easy way to bypass the bug :)
Just an other variant with jQuery using
$(".numeric").keypress(function() { return (/\d/.test(String.fromCharCode(event.which) ))
}); I saw some great answers however I like them as small and as simple as possible, so maybe someone will benefit from it. I would use javascript Number() and isNaN functionality like this:
if(isNaN(Number(str))) { // ... Exception it is NOT a number
} else { // ... Do something you have a number
}Hope this helps.
4You can also compare input value (which is treated as string by default) to itself forced as numeric, like:
if(event.target.value == event.target.value * 1) { // returns true if input value is numeric string
}However, you need to bind that to event like keyup etc.
0<input name="amount" type="text" value="Only number in here"/>
<script> $('input[name=amount]').keyup(function(){ $(this).val($(this).val().replace(/[^\d]/,'')); });
</script> My solution for a better user experience:
HTML
<input type="tel">jQuery
$('[type=tel]').on('change', function(e) { $(e.target).val($(e.target).val().replace(/[^\d\.]/g, ''))
})
$('[type=tel]').on('keypress', function(e) { keys = ['0','1','2','3','4','5','6','7','8','9','.'] return keys.indexOf(event.key) > -1
})Details:
First of all, input types:
number shows up/down arrows shrinking the actual input space, I find them ugly and are only useful if the number represents a quantity (things like phones, area codes, IDs... don't need them)tel provides similar browser validations of number without arrows
Using [number / tel] also helps showing numeric keyboard on mobile devices.
For the JS validation I ended up needing 2 functions, one for the normal user input (keypress) and the other for a copy+paste fix (change), other combinations would give me a terrible user experience.
I use the more reliable KeyboardEvent.key instead of the now deprecated KeyboardEvent.charCode
And depending of your browser support you can consider using Array.prototype.includes() instead of the poorly named Array.prototype.indexOf() (for true / false results)
0Use this DOM:
<input type = "text" onkeydown = "validate(event)"/>And this script:
validate = function(evt)
{ if ([8, 46, 37, 39, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 35, 36].indexOf(evt.keyCode || evt.which) == -1) { evt.returnValue = false; if(evt.preventDefault){evt.preventDefault();} }
}...OR this script, without indexOf, using two for's...
validate = function(evt)
{ var CharValidate = new Array("08", "046", "039", "948", "235"); var number_pressed = false; for (i = 0; i < 5; i++) { for (Ncount = 0; Ncount < parseInt(CharValidate[i].substring(0, 1)) + 1; Ncount++) { if ((evt.keyCode || evt.which) == parseInt(CharValidate[i].substring(1, CharValidate[i].lenght)) + Ncount) { number_pressed = true; } } } if (number_pressed == false) { evt.returnValue = false; if(evt.preventDefault){evt.preventDefault();} }
}I used the onkeydown attribute instead of onkeypress, because the onkeydown attribute is checked before onkeypress attribute. The problem would be in the Google Chrome browser.
With the attribute "onkeypress", TAB would be uncontrollable with "preventDefault" on google chrome, however, with the attribute "onkeydown", TAB becomes controllable!
ASCII Code for TAB => 9
The first script have less code than the second, however, the array of ASCII characters must have all the keys.
The second script is much bigger than the first, but the array does not need all keys. The first digit in each position of the array is the number of times each position will be read. For each reading, will be incremented 1 to the next one. For example:
NCount = 0
48 + NCount = 48
NCount + +
48 + NCount = 49
NCount + +
...
48 + NCount = 57
In the case of numerical keys are only 10 (0 - 9), but if they were 1 million it would not make sense to create an array with all these keys.
ASCII codes:
- 8 ==> (Backspace);
- 46 => (Delete);
- 37 => (left arrow);
- 39 => (right arrow);
- 48 - 57 => (numbers);
- 36 => (home);
- 35 => (end);
This is an improved function:
function validateNumber(evt) { var theEvent = evt || window.event; var key = theEvent.keyCode || theEvent.which; if ((key < 48 || key > 57) && !(key == 8 || key == 9 || key == 13 || key == 37 || key == 39 || key == 46) ){ theEvent.returnValue = false; if (theEvent.preventDefault) theEvent.preventDefault(); }
} Here is my simple solution for React users only, I couldn't find a better solution and made my own. 3 steps.
First, create a state.
const [tagInputVal, setTagInputVal] = useState("");Then, use the state as input value (value={tagInputVal}) and pass the event to the onChange handler.
<input type="text" placeholder="Add a tag" value={tagInputVal} onChange={(e) => onChangeTagInput(e)}></input>Then, set the value of the event inside onChange handler.
function onChangeTagInput(e) { setTagInputVal(e.target.value.replace(/[^\d.]/ig, ""));
} 1
123 Next