Reputation: 39622
Is there a quick way to set an HTML text input (<input type=text />
) to only allow numeric keystrokes (plus '.')?
Upvotes: 1125
Views: 2889224
Reputation: 22138
A 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 keyboards, 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 allowed
var 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 id="number" value="-3.1415" placeholder="Type a number" autofocus>
EDIT: I removed my old answer because I think it is antiquated now.
Upvotes: 15
Reputation: 30234
Update: easier solution seems to use beforeinput
event.
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 the input-error
class. Here’s a suggestion:
.input-error{
outline: 1px solid red;
}
Note that you still must do server side validation!
Another caveat is that this will break the undo stack since it sets this.value
directly.
This means that CtrlZ will not work to undo inputs after typing an invalid character.
See the JSFiddle demo for more input filter examples or run the Stack snippet below:
// Restricts input for the given textbox to the given inputFilter.
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 = "";
}
});
});
}
// Install input filters.
setInputFilter(document.getElementById("intTextBox"), function(value) {
return /^-?\d*$/.test(value);
}, "Must be an integer");
setInputFilter(document.getElementById("uintTextBox"), function(value) {
return /^\d*$/.test(value);
}, "Must be an unsigned integer");
setInputFilter(document.getElementById("intLimitTextBox"), function(value) {
return /^\d*$/.test(value) && (value === "" || parseInt(value) <= 500);
}, "Must be between 0 and 500");
setInputFilter(document.getElementById("floatTextBox"), function(value) {
return /^-?\d*[.,]?\d*$/.test(value);
}, "Must be a floating (real) number");
setInputFilter(document.getElementById("currencyTextBox"), function(value) {
return /^-?\d*[.,]?\d{0,2}$/.test(value);
}, "Must be a currency value");
setInputFilter(document.getElementById("latinTextBox"), function(value) {
return /^[a-z]*$/i.test(value);
}, "Must use alphabetic latin characters");
setInputFilter(document.getElementById("hexTextBox"), function(value) {
return /^[0-9a-f]*$/i.test(value);
}, "Must use hexadecimal characters");
.input-error {
outline: 1px solid red;
}
<h2>JavaScript input filter showcase</h2>
<p>Supports Copy+Paste, Drag+Drop, keyboard shortcuts, context menu operations, non-typeable keys, the caret position, different keyboard layouts, and <a href="https://caniuse.com/#feat=input-event" target="_blank">all browsers since IE 9</a>.</p>
<p>There is also a <a href="https://jsfiddle.net/emkey08/tvx5e7q3" target="_blank">jQuery version</a> of this.</p>
<table>
<tr>
<td>Integer</td>
<td><input id="intTextBox"></td>
</tr>
<tr>
<td>Integer >= 0</td>
<td><input id="uintTextBox"></td>
</tr>
<tr>
<td>Integer >= 0 and <= 500</td>
<td><input id="intLimitTextBox"></td>
</tr>
<tr>
<td>Float (use . or , as decimal separator)</td>
<td><input id="floatTextBox"></td>
</tr>
<tr>
<td>Currency (at most two decimal places)</td>
<td><input id="currencyTextBox"></td>
</tr>
<tr>
<td>A-Z only</td>
<td><input id="latinTextBox"></td>
</tr>
<tr>
<td>Hexadecimal</td>
<td><input id="hexTextBox"></td>
</tr>
</table>
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.
HTML5 has a native solution with <input type="number">
(see the specification and documentation). The documentation has a working demo of this input type.
value
property, read the valueAsNumber
property of the input to get the typed value as a number rather than a string.<form>
is recommended because validation is made easier this way; for example, pressing Enter will automatically show an error message if the value is invalid.
checkValidity
method or the requestSubmit
method on the entire form in order to explicitly check the validity.required
attribute in order to disallow an empty input.checkValidity
method or the validity
property on the input element itself in order to explicitly check the validity.reportValidity
to show an error message and use setCustomValidity
to set your own message.This approach fundamentally has a different user experience: you are allowed to input invalid characters and the validation is performed separately. This has the benefit that the undo stack (CtrlZ) won’t break. Note that server-side validation must be performed, regardless, no matter which approach you choose.
But note that browser support varies:
step
, min
and max
attributes.e
and E
into the field. Also see the Q&A Why does the HTML input with type="number"
allow the letter e
to be entered in the field?.document.querySelector("form").addEventListener("submit", (event) => {
event.preventDefault();
console.log(`Submit!
Number is ${event.target.elements.number.valueAsNumber},
integer is ${event.target.elements.integer.valueAsNumber},
form data is ${JSON.stringify(Object.fromEntries(new FormData(event.target).entries()))}.`);
})
label {
display: block;
}
<form>
<fieldset>
<legend>Get a feel for the UX here:</legend>
<label>Enter any number: <input name="number" type="number" step="any" required></label>
<label>Enter any integer: <input name="integer" type="number" step="1" required></label>
<label>Submit: <input name="submitter" type="submit"></label>
</fieldset>
</form>
Upvotes: 1362
Reputation: 393
Look at this answer, hope you could not find any bug. Only numeric input
$(document).on('keydown','input[name^=qtyInvItem_]',function(event){
var element = this;
var val = this.value;
var decimalAllowed = 2;
if(positiveNumber(event,element,val,decimalAllowed) === false){return false;};
});
function positiveNumber(event,element,value,allowedDecimalDigits){
const selectionStart = element.selectionStart;
const key = event.key;
var allowedKeys = [".","0","1","2","3","4","5","6","7","8","9","ArrowUp","ArrowDown","ArrowLeft","ArrowRight","Home","End","Backspace","Delete","Tab","PageUp","PageDown"];
var numberKeys = ["0","1","2","3","4","5","6","7","8","9"];
// prevent double decimal point
if(key === "." && value.includes(".")){return false;};
// allow allowedKeys
if(allowedKeys.includes(key) === false){return false;};
var decimalsPart = value.split(".");
let part2 = decimalsPart[1]; // get digits after decimal point
//allow number increase on left side of decimal point and prevent more digits entry on the right side of decimal point
if(value.indexOf(".") !== -1 && selectionStart > value.indexOf(".") && part2.length === allowedDecimalDigits && numberKeys.includes(key)){
return false;
}
}
Upvotes: 0
Reputation: 21
function isNumeric(event) {
const keyCode = event.keyCode || event.which;
const keyValue = String.fromCharCode(keyCode);
// Allow numeric keys, backspace, delete, and decimal point
const numericRegex = /[0-9]|\.|Backspace|Delete/;
if (!numericRegex.test(keyValue)) {
event.preventDefault();
return false;
}
}
<input type="text" id="numericInput" onkeydown="return isNumeric(event)" />
Upvotes: 0
Reputation: 61
If you want to suggest to the device (maybe a mobile phone) between alpha or numeric you can use
<input type="number">
Upvotes: 12
Reputation: 305
I've used type=tel
to be able to limit the number of digits and to allow only digits, I've used the following code:
HTML
<input type="tel" class="form-control number-only" name="Extension" id="Extension" required maxlength="4" minlength="4" placeholder="4 Digits"/>
JQuery
$('.number-only').on('input', (e) => {
e.target.value = e.target.value.replace(/[^\d]/g, '');
});
Upvotes: 1
Reputation: 22941
Here is a simple one which allows for exactly one decimal, but no more. The input event uses regex to replace text on the fly based on the two patterns:
<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
.
Upvotes: 282
Reputation: 41
$('#input-field').keypress(e => !String.fromCharCode(e.which).match(/\D/g));
Upvotes: -1
Reputation: 846
For ReactJS:
<input
onKeyPress={(event) => {
if (!/[0-9]/.test(event.key)) {
event.preventDefault();
}
}}
/>
Upvotes: 1
Reputation:
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();
},
Upvotes: 1
Reputation: 11
use this regex /\D*/g
const phoneHandler = (event: React.ChangeEvent<HTMLInputElement>) =>{
setPhone(event.target.value.replaceAll(/\D*/g, ''));};
Upvotes: 0
Reputation: 1423
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" id="edit1" value="0" size="5" maxlength="5" />
Upvotes: 60
Reputation: 41823
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();
}
}
Upvotes: 328
Reputation: 1174
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) )">
Upvotes: 175
Reputation: 621
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.
Upvotes: 0
Reputation: 1217
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;
}
Upvotes: -1
Reputation: 131
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;
Upvotes: 3
Reputation: 19555
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">
Upvotes: 0
Reputation: 1
// 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)
Upvotes: 16
Reputation: 604
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')
Upvotes: 2
Reputation: 302
I might have another (simple) workaround for this...
Since String.fromCharCode(key) returns weird things upon QWERTY keyboard (numerical keypad returns code as g for 1, and 1 for & character ..
I've realized catching the final value on keyup within the input to reset it to an arbitrary value is a simpler, lightweight & bugproof method (could also be done via some regex ... to keep decimals and so on ... don't have to filter other Ctrl, Home, Del, and Enter events...)
Usage with jq :
<input class='pn'>
<script>
function pn(el){nb=el.value;if(isNaN(nb) || nb<1)el.value=1;}
jQuery('.pn').keyup(function(){pn(this);});
</script>
Onkeyup attribute:
<input onkeyup='positiveNumericInput(this)'>
<script>function positiveNumericInput(el){nb=el.value;if(isNaN(nb) || nb<1)el.value=1;}</script>
Upvotes: 2
Reputation: 559
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, ""));
}
Upvotes: 5
Reputation: 1507
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()
}
}
Upvotes: 0
Reputation: 1017
There is much simplier solution no one mentioned before:
inputmode="numeric"
read more: https://css-tricks.com/finger-friendly-numerical-inputs-with-inputmode/
Upvotes: 2
Reputation: 720
<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;
}
Upvotes: 2
Reputation: 28094
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;"
Upvotes: 2
Reputation: 2033
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.
Upvotes: 1
Reputation: 31
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">
Upvotes: 3
Reputation: 153
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)));
}
Upvotes: -3
Reputation: 85
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.
Upvotes: 3