Julius A
Julius A

Reputation: 39622

HTML text input allow only numeric input

Is there a quick way to set an HTML text input (<input type=text />) to only allow numeric keystrokes (plus '.')?

Upvotes: 1125

Views: 2889224

Answers (30)

Vitim.us
Vitim.us

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

Ian G
Ian G

Reputation: 30234

JavaScript

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.

Demo

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 &gt;= 0</td>
    <td><input id="uintTextBox"></td>
  </tr>
  <tr>
    <td>Integer &gt;= 0 and &lt;= 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>

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.

HTML5

HTML5 has a native solution with <input type="number"> (see the specification and documentation). The documentation has a working demo of this input type.

  • Instead of reading the value property, read the valueAsNumber property of the input to get the typed value as a number rather than a string.
  • Usage inside a <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.
    • You can use the checkValidity method or the requestSubmit method on the entire form in order to explicitly check the validity.
    • Note that you might need to use the required attribute in order to disallow an empty input.
  • You can use the checkValidity method or the validity property on the input element itself in order to explicitly check the validity.
  • You can use 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:

Demo

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

Hafsul Maru
Hafsul Maru

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

AJESHOFFICIAL
AJESHOFFICIAL

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

Steven
Steven

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

Nasser X
Nasser X

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

You Old Fool
You Old Fool

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:

  1. Remove anything that's not a digit or a dot
  2. Remove any second instance of a dot

<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

Rawfin
Rawfin

Reputation: 41

Here's my one-line solution!

$('#input-field').keypress(e => !String.fromCharCode(e.which).match(/\D/g));

Upvotes: -1

Bambier
Bambier

Reputation: 846

For ReactJS:

<input
    onKeyPress={(event) => {
        if (!/[0-9]/.test(event.key)) {
            event.preventDefault();
        }
    }}
/>

Upvotes: 1

user17534350
user17534350

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

Ant1p0w
Ant1p0w

Reputation: 11

use this regex /\D*/g

const phoneHandler = (event: React.ChangeEvent<HTMLInputElement>) =>{
setPhone(event.target.value.replaceAll(/\D*/g, ''));};

Upvotes: 0

Vasyl
Vasyl

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" />

Here is a jsFiddle example

Upvotes: 60

geowa4
geowa4

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

user235859
user235859

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

Vinnie Amir
Vinnie Amir

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

Onyilimba
Onyilimba

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

Rex the Strange
Rex the Strange

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

L&#233;a Gris
L&#233;a Gris

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

Rizal Aditya
Rizal Aditya

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

Pawel
Pawel

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

Jack
Jack

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

Mehedi
Mehedi

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

Thomas Van Holder
Thomas Van Holder

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

Atombit
Atombit

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

Ali Raza
Ali Raza

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

Edson Cezar
Edson Cezar

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

benhatsor
benhatsor

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

Abdul Khalik
Abdul Khalik

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

sau0409
sau0409

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

Chirag Jain
Chirag Jain

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

Related Questions