Is there a quick way to set an HTML text input (<input type=text />) to only allow numeric keystrokes (plus '.')?
Is there a quick way to set an HTML text input (<input type=text />) to only allow numeric keystrokes (plus '.')?
Note: This is an updated answer. Comments below refer to an old version which messed around with keycodes.
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!
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 = "";
}
});
});
}
There is also a jQuery version of this. See this answer.
HTML 5 has a native solution with <input type="number"> (see the specification), but note that browser support varies:
step, min and max attributes.e and E into the field. Also see this question.Try it yourself on w3schools.com.
Use 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();
}
}
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.
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);"/>
just use type="number" now this attribute supporting in most of the browsers
<input type="number" maxlength="3" ng-bind="first">
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 class="integerInput" 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="https://code.jquery.com/jquery-2.2.4.min.js"
integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="
crossorigin="anonymous">
</script>
<input type="text" class="integerInput"/>
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.
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 id="tag-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, ""));
}
You can replace the Shurok function with:
$(".numeric").keypress(function() {
return (/[0123456789,.]/.test(String.fromCharCode(Event.which) ))
});
Here's a nice simple solution that I like to use:
function numeric_only (event, input) {
if ((event.which < 32) || (event.which > 126)) return true;
return jQuery.isNumeric ($(input).val () + String.fromCharCode (event.which));
}// numeric_only;
<input type="text" onkeypress="return numeric_only (event, this);" />
Explanation:
Using "event.which" - first determine if it's a printable character. If it isn't then allow it (for things like delete and backspace). Otherwise, concatinate the character to the end of the string and test it using the jQuery "isNumeric" function. This takes all of the tedium away from testing each individual character and also works for cut / paste scenarios.
If you want to get really cute then you can create a new HTML input type. Let's call it "numeric" so that you can have the tag:
<input type="numeric" />
which will only allow numeric characters. Just add the following "document.ready" command:
$(document).ready (function () {
$("input[type=numeric]").keypress (function (event) {
if ((event.which < 32) || (event.which > 126)) return true;
return jQuery.isNumeric ($(this).val () + String.fromCharCode (event.which));
});// numeric.keypress;
});// document.ready;
HTML doesn't care what type name you use - if it doesn't recognize it then it will use a textbox by default, so you can do this. Your editor may complain but, hey, that's its problem. No doubt puritans will freak out, but it works, is easy and so far it's been pretty robust for me.
UPDATE
Here's a better way: it takes text selection into account and uses native javascript:
verify (event) {
let value = event.target.value;
let new_value = `${value.substring (0, event.target.selectionStart)}${event.key}${value.substring (event.target.selectionEnd)}`;
if ((event.code < 32) || (event.code > 126)) return true;
if (isNaN (parseInt (new_value))) return false;
return true;
}// verify;
this also work for persian and arabic number :)
setNumericInput: function (event) {
var key = window.event ? event.keyCode : event.which
if (event.keyCode === 8 ||
(key >= 48 && key <= 57) ||
(key >= 1776 && key <= 1785)) {
return true
} else {
event.preventDefault()
}
}
If you are trying on angular this might help
To get the input as number (with a decimal point) then
<input [(ngModel)]="data" oninput="this.value = this.value.replace(/[^0-9.]/g, '').replace(/(\..*)\./g, '$1');">
Now this will not update the value in model correctly to explicitly change the value of model too add this
<input [(ngModel)]="data" oninput="this.value = this.value.replace(/[^0-9.]/g, '').replace(/(\..*)\./g, '$1');" (change)="data = $event.target.value">
The change event will fire after the value in the model has been updated so it can be used with reactive forms as well.
You may try using the '''onkeydown''' event and cancel the event (event.preventDefault or something like that) when it's not one of the allowed keys.
You can attach to the key down event and then filter keys according to what you need, for example:
<input id="FIELD_ID" name="FIELD_ID" onkeypress="return validateNUM(event,this);" type="text">
And the actual JavaScript handler would be:
function validateNUM(e,field)
{
var key = getKeyEvent(e)
if (specialKey(key)) return true;
if ((key >= 48 && key <= 57) || (key == 46)){
if (key != 46)
return true;
else{
if (field.value.search(/\./) == -1 && field.value.length > 0)
return true;
else
return false;
}
}
function getKeyEvent(e){
var keynum
var keychar
var numcheck
if(window.event) // IE
keynum = e.keyCode
else if(e.which) // Netscape/Firefox/Opera
keynum = e.which
return keynum;
}
Remember the regional differences (Euros use periods and commas in the reverse way as Americans), plus the minus sign (or the convention of wrapping a number in parentheses to indicate negative), plus exponential notation (I'm reaching on that one).
I finished using this function:
onkeypress="if(event.which < 48 || event.which > 57 ) if(event.which != 8) return false;"
This works well in IE and Chrome, I don´t know why it´s not work well in firefox too, this function block the tab key in Firefox.
For the tab key works fine in firefox add this:
onkeypress="if(event.which < 48 || event.which > 57 ) if(event.which != 8) if(event.keyCode != 9) return false;"
var userName = document.querySelector('#numberField');
userName.addEventListener('input', restrictNumber);
function restrictNumber (e) {
var newValue = this.value.replace(new RegExp(/[^\d]/,'ig'), "");
this.value = newValue;
}
<input type="text" id="numberField">
<input type="tel"
onkeypress="return onlyNumberKey(event)">
in script tag
function onlyNumberKey(evt) {
// Only ASCII charactar in that range allowed
var ASCIICode = (evt.which) ? evt.which : evt.keyCode
if (ASCIICode > 31 && (ASCIICode < 48 || ASCIICode > 57))
return false;
return true;
}
There is much simplier solution no one mentioned before:
inputmode="numeric"
read more: https://css-tricks.com/finger-friendly-numerical-inputs-with-inputmode/
Got a pretty nice solution. Removes leading zeros, sets the max number of natural and decimal places, handles copy-paste, makes sure that it is a numeric value.
this.value = this.value
.replace(/\b0+/g, '')
.replace(/[^0-9.]/g, '')
.replace(/(\..*?)\..*/g, '$1')
.replace(/([0-9]{0,6}(\.[0-9]{0,2})?).*/g, '$1')
Last replace sets the length of decimal and natural places. Just replace tokens with your preferred values.
.replace(/([0-9]{0,<max_natural>}(\.[0-9]{0,<max_decimal>})?).*/g, '$1')
Here is a very short solution that doesn't use the deprecated keyCode or which, doesn't block any non input keys, and uses pure javascript. (Tested in Chromium 70.0.3533, Firefox 62.0, and Edge 42.17134.1.0)
HTML:
<input type="text" onkeypress="validate(event)">
JS:
function validate(ev) {
if (!ev) {
ev = window.event;
}
if (!ev.ctrlKey && ev.key.length === 1 && (isNaN(+ev.key) || ev.key === " ")) {
return ev.preventDefault();
}
}
I couldn't find a clear answer, that doesn't loop over the whole string every time, so here:
document.querySelectorAll("input").forEach(input => {
input.addEventListener("input", e => {
if (isNaN(Number(input.value[input.value.length-1])) && input.value[input.value.length-1] != '.') {
input.value = input.value.slice(0, -1);
}
})
});
No regex, this goes over the last character every time you type and slices it if it's not a number or period.
Execute this function on any keystroke and it will not allow anything except plus, a hyphen, and parenthesis.
Hypothetical Eg: +234-(123)1231231 will work but not letters
Replace (/^[0-9+()-]*$/.test(char)) with (/^[0-9]*$/.test(char)) to allow only numerics at keystroke.
isNumber(e) {
let char = String.fromCharCode(e.keyCode);
if (/^[0-9+()-]*$/.test(char)) return true;
else e.preventDefault();
},
Thanks guys this really help me!
I found the perfert one really useful for database.
function numonly(root){
var reet = root.value;
var arr1=reet.length;
var ruut = reet.charAt(arr1-1);
if (reet.length > 0){
var regex = /[0-9]|\./;
if (!ruut.match(regex)){
var reet = reet.slice(0, -1);
$(root).val(reet);
}
}
}
Then add the eventhandler:
onkeyup="numonly(this);"
I realize an old post but i thought this could help someone. Recently I had to limit a text box to just 5 decimal places. In my case ALSO the users input had to be less than 0.1
<input type="text" value="" maxlength=7 style="width:50px" id="fmargin" class="formText" name="textfield" onkeyup="return doCheck('#fmargin',event);">
Here is the doCheck function
function doCheck(id,evt)
{
var temp=parseFloat($(id).val());
if (isNaN(temp))
temp='0.0';
if (temp==0)
temp='0.0';
$(id).val(temp);
}
Here is the same function except to force integer input
function doCheck(id,evt)
{
var temp=parseInt($(id).val());
if (isNaN(temp))
temp='0';
$(id).val(temp);
}
hope that helps someone
Regular expressions and the match function can work well for this situation. For instance, I used the following to validate 4 input boxes that served as coordinates on a graph. It works reasonably well.
function validateInput() {
if (jQuery('#x1').val().toString().match(/^[-]?[0-9]+[\.]?[0-9]*$/) == null ||
jQuery('#x2').val().toString().match(/^[-]?[0-9]+[\.]?[0-9]*$/) == null ||
jQuery('#y1').val().toString().match(/^[-]?[0-9]+[\.]?[0-9]*$/) == null ||
jQuery('#y2').val().toString().match(/^[-]?[0-9]+[\.]?[0-9]*$/) == null) {
alert("A number must be entered for each coordinate, even if that number is 0. Please try again.");
location.reload();
}
}
Some of the answers above use outdated content, like the use of which.
To check if the pressed key is a number you use a keyup eventListener to read the value of event.key. Then simply prevent the typing of the character if it's not a number. You can whitelist additional keys. Example, allow the user to navigate backward or forwards in the input field with the arrows, or to hit backspace and delete the typed-in numbers.
validate (event) {
const isNumber = isFinite(event.key)
const whitelist = ['Backspace','Delete','ArrowDown','ArrowUp','ArrowRight','ArrowLeft']
const whitelistKey = whitelist.includes(event.key)
if (!isNumber && !whitelistKey) {
event.preventDefault()
}
}
Here is an Object-Oriented re-implementation of emkey08's JavaScript Wiki answer which uses an EventListener object implementation. (See: MDN web docs EventListener)
In a way, it prevents duplicating anonymous event handler function declarations for each filtered input element, while still allowing it through an optional call-back.
/**
* Base input {@see Element} {@see EventListener} filter abstract class
*
* @implements EventListener
*/
class AbstractInputFilter {
/**
* Attach the input filter to the input {@see Element}
*
* @param inputElement The input {@see Element} to filter
* @param isValid - The callback that determines if the input is valid.
* @throws Error
*/
constructor(inputElement, isValid = null) {
// Abstract class
if (this.constructor === AbstractInputFilter) {
throw new Error("Object of Abstract Class cannot be created");
}
if (typeof isValid === "function") {
this.isValid = isValid;
}
for (const event of ["input", "keydown", "keyup",
"mousedown", "mouseup", "select", "contextmenu", "drop"]) {
inputElement.addEventListener(event, this);
}
}
/**
* Checks the value is valid
*
* @callback isValid default call-back that will throw
* an {Error} if not implemented by extending this
* {AbstractInputFilter} class.
*
* @param value The value to check
* @returns {boolean}
* @throws Error
*/
isValid(value) {
throw new Error('must be implemented by callback!');
}
/**
* Handles the {@see event} dispatched by
* the {@see EventTarget} object from the input {@see Element}
* to filter its contant while it is being filled.
*
* @param event the {@see event} dispatched by
* the {@see EventTarget} input {@see Element}
* @override
*/
handleEvent(event) {
const inputElement = event.currentTarget;
if (this.isValid(inputElement.value)) {
inputElement.oldValue = inputElement.value;
inputElement.oldSelectionStart = inputElement.selectionStart;
inputElement.oldSelectionEnd = inputElement.selectionEnd;
} else if (inputElement.hasOwnProperty("oldValue")) {
inputElement.value = inputElement.oldValue;
inputElement.setSelectionRange(
inputElement.oldSelectionStart, inputElement.oldSelectionEnd);
} else {
this.value = "";
}
}
}
/**
* Generic Input element {@see EventListener} filter
*
* @extends AbstractInputFilter
* It needs the {@see AbstractInputFilter~isValid} callback
* to determine if the input is valid.
*/
class InputFilter extends AbstractInputFilter {}
/**
* Unsigned Integer Input element {@see EventListener} filter
* @extends AbstractInputFilter
*/
class UIntInputFilter extends AbstractInputFilter {
isValid(value) {
return /^\d*$/.test(value);
}
}
/**
* Unsigned Float Input element {@see EventListener} filter
* @extends AbstractInputFilter
*/
class UFloatInputFilter extends AbstractInputFilter {
isValid(value) {
return /^\d*\.?\d*$/.test(value);
}
}
// Filter with pre-made InputFilters (re-use the filter)
new UIntInputFilter(document.getElementById("UInt"));
new UFloatInputFilter(document.getElementById("UFloat"));
// Filter with custom callback filter anonymous function
new InputFilter(document.getElementById("AlNum"), function(value) {
return /^\w*$/.test(value);
});
<label>Unsigned integer: </label><input id="UInt"><br/>
<label>Unsigned float: </label><input id="UFloat"><br/>
<label>AlphaNumeric (no special characters): </label><input id="AlNum">
input type="tel" works well on mobile devices, so you want to keep that.
Just use the following code (JQuery):
$("input[type=tel]").keydown(function (event) {
return (event.which >= 48 && event.which <= 57) || //0 TO 9
event.which === 8 || event.which == 46; //BACKSPACE/DELETE
});
And your input will be:
<input type="tel" />
And you can add whatever you like to the input field, id, and dont need to bind any other listeneres.
use this regex /\D*/g
const phoneHandler = (event: React.ChangeEvent<HTMLInputElement>) =>{
setPhone(event.target.value.replaceAll(/\D*/g, ''));};
For ReactJS:
<input
onKeyPress={(event) => {
if (!/[0-9]/.test(event.key)) {
event.preventDefault();
}
}}
/>
$('#input-field').keypress(e => !String.fromCharCode(e.which).match(/\D/g));
I have seen many questions that answer this with javascript, but the best answer is to use the type="number" and remove the spin button with css, most of the reason why this is needed is that the spin button doesn't emit the change event when used.
Solution:
HTML
<input type="number" class="input-class">
CSS
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
/* Firefox */
input[type=number] {
-moz-appearance: textfield;
}
Below function will check for every input char if it is number.
numeric: value => {
let numset = new Set(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']);
console.log(numset.has(value.substring(value.length - 1, value.length)));
}