50

How to allow only numbers in textbox in reactjs using regular expression only?

Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
Soumya Behera
  • 2,325
  • 4
  • 15
  • 25

17 Answers17

118

Basic idea is:

Use controlled component (use value and onChange property of input field), and inside onChange handle check whether the entered value is proper number or not. Update the state only when entered value is a valid number.

For that use this regex: /^[0-9\b]+$/;

onChange handler will be:

onChange(e){
    const re = /^[0-9\b]+$/;

    // if value is not blank, then test the regex

    if (e.target.value === '' || re.test(e.target.value)) {
       this.setState({value: e.target.value})
    }
}

Working example:

class App extends React.Component{
   constructor(){
      super();
      this.state = {value: ''};
      this.onChange = this.onChange.bind(this)
   }
   
   onChange(e){
      const re = /^[0-9\b]+$/;
      if (e.target.value === '' || re.test(e.target.value)) {
         this.setState({value: e.target.value})
      }
   }
   
   render(){
     return <input value={this.state.value} onChange={this.onChange}/>
   }
}

ReactDOM.render(<App/>,document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id='app'/>
Mayank Shukla
  • 100,735
  • 18
  • 158
  • 142
  • What's the purpose of `\b` in the regular expression `/^[0-9\b]+$/`? – Axel Meier Apr 23 '19 at 09:53
  • To anwser Axel's question for anyone else wondering: `\b \B word, not-word boundary` – dmikester1 Apr 14 '20 at 16:33
  • How to add a max length check on it as well? – Emma Apr 02 '21 at 08:12
  • @MayankShukla `re.test(e.target.value)` would have been suffice, you need not check for empty – Vivek Bani Jun 11 '21 at 08:53
  • This is the only that worked. Others don't support backspace. – Omar Dulaimi Mar 06 '22 at 14:36
  • 1
    An update to the original answer, it gives NaN for the empty string. To avoid that change the onChange function as such, ```onChange(e){ const re = /^[0-9\b]+$/; if (e.target.value === '') { this.setState(0) } if ( re.test(e.target.value)) { this.setState({value: e.target.value}) } }``` – tontus Jul 24 '22 at 05:12
  • @Emma you can use html maxLength prop/attribute to limit the max length of the input textbox – BoyePanthera Jan 28 '23 at 22:24
26

The answer provided by Mayank Shukla is correct, no doubt about it.


But instead of it, you can just use the default html property type="number".

No need to use regex in this case as <input type="number" value={this.state.value} onChange={this.onChange}/> will accept only numbers.

abhishake
  • 763
  • 9
  • 16
  • What about older browsers? – Dinǝsh Gupta Sep 12 '18 at 13:22
  • No worries. All the browser supports it since it is the default HTML property and implemented a very long ago. – abhishake Jan 11 '19 at 11:10
  • I remember that type number gave me some issues on some old android browser, honestly too long ago to remember which. Anyway, I would go for a regex... just in case – gianni Mar 22 '19 at 09:04
  • 7
    It still allow some special characters like 'e', '.', '-' etc – Sobin Augustine Dec 27 '21 at 17:52
  • Inputs of type="number" have potential usability issues: Allowing certain non-numeric characters ('e', '+', '-', '.') and silently discarding others The functionality of scrolling to increment/decrement the number can cause accidental and hard-to-notice changes and more - see this article by the GOV.UK Design System team for a more detailed explanation. https://mui.com/material-ui/react-text-field/ – leo valeriano Jun 20 '23 at 21:53
17

A simple solution, using hooks:

const [age, setAge] = useState();

const handleChange = (e) => {
  const value = e.target.value.replace(/\D/g, "");
  setAge(value);
};

return (
  <div>
    <input value={age} onChange={handleChange} />
  </div>
);

Example: https://codesandbox.io/s/adoring-minsky-9sqvv

Ricardo Canelas
  • 2,280
  • 26
  • 21
3

Even though you said regular expression only this is high up in Google without specifying regular expression (as that's not stated in the title) so I thought I'd add another simple way, not using regular expressions. And given the test results linked below it'd seem silly to use regular expressions for simple use cases.

I found this on another post that I can no longer find. I believe it was referred to as the self-equals check... Not entirely sure how it works. But it's at least 20 times faster than Regex in Chrome (from the test results).

isNumeric(number) {
  if (+number === +number) { // if is a number
      return true;
  }

  return false;
}

Benchmarking self-equals vs regex vs NaN

There are revisions to this test at the bottom of the page, number 5 is the one that corresponds to the post I found that had this simple solution, I'm unsure how the other revisions differ.

I use it for my positive number only textboxes like this:

isValidQuantityInput() {
  const value = +this.state.quantityInputText; // convert to number
  if (value !== +value || value < 0) { // if fails validity check
    return false;
  }

  return true;
}

I don't bind the value of the input to the data as that causes weird usability issues such as not being able to clear the field without highlighting etc... quantityInputText holds the input text, then I validate it and if it is valid I set my data to it's value.

Gibrahh
  • 173
  • 2
  • 7
3

The simplest and far from complicated way according to www.w3schools.com :

onHandleChangeNumeric = e => {
 let valu = e.target.value;

 if (!Number(valu)) {
 return;
 }

 this.setState({ [e.target.name]: valu });
};

On render input :

<input
   type="text"
   className="form-control"
   name="someName"
   value={this.state.someName}
   onChange={this.onHandleChangeNumeric}
    />

Important : Do not make type="number", it won't work.

Sulung Nugroho
  • 1,605
  • 19
  • 14
  • This helped me when using the new Hooks. Only had to change ``` this.setState({e.target.name]: valu });``` for ``` onChange(e.target.value)``` and using ```onChange={e=>onHandleChangeNumeric(e)} ``` in the ```input``` component. – programandoconro Dec 09 '19 at 13:42
2

<input/> component is having pattern props, on this props we can use this regex: /^[0-9\b]+$/ directly.;

<input type="text" pattern="^[0-9\b]+$" />

// or if you want to include ".", then the following pattern will work fine.
<input type="text" pattern="^[0-9]*[.,]?[0-9]*$" />
Web dozens
  • 168
  • 1
  • 2
  • 8
  • Doesn't seem to work as it should. After a page refresh, it allows to type in letters, and only after I hit backspace and delete the letters I just typed, it starts to work and from now on prevents letters and allows only numbers: my regex ^[0-9]*$ – realPro Jun 12 '22 at 22:34
1

I know you've asked for regular expression.
But here is a solution without regex if anyone wants.


  const handlePincode = (e) => {
    !isNaN(e.nativeEvent?.data) && setPincode(e.currentTarget.value);
  };

  return (
    <div className="App">
      <input type="text" value={pincode} onChange={handlePincode} />
    </div>
  );

The event.nativeEvent.data gives me the currently typed value, I can just validate that and set the event.currentTarget.value or just return it.

Ishwar Rimal
  • 1,071
  • 11
  • 19
1
I think simplest answer is to replace non digit number with '' 
onChange of <input>

//FUNCTION HANDLER
const handleChange = event => {
  const result = event.target.value.replace(/\D/g, '');
  setValue(result);

};

//HTML ELEMENT 
<input value={value} onChange={handleChange}/>
0
countDecimals(value) {
  return value % 1 ? value.toString().split(".")[1].length : 0;
};

handleOnChangeAmount(id, e) {
  let count = this.countDecimals(e.target.value);
  if (count === 3) {
    e.preventDefault();
  }
}
adiga
  • 34,372
  • 9
  • 61
  • 83
Bhairavi
  • 11
  • 1
0

The most convenient solution for checking that the string in a textbox is a numeric is Gibrahh's solution, but to avoid self-comparison, you should make the comparison in the following way:

typeof x === 'number' && isNaN(x)

Where x is the numeric string coming from the textbox input.

So if you using create-react-app for development, the ESLint won't yell at you. See https://eslint.org/docs/rules/no-self-compare.

avivsab
  • 21
  • 4
0

import React, { useState } from "react";

const SingleCart = () => {
    const [num, setNum] = useState();

    const handleChange = (event) => {
        const value = event.target.value.replace(/\+|-/gi, "");

        if (value.length) {
      const number = parseInt(value);
      setNum(number);
    }
  };
  return (
    <div>
      <input value={num} onChange={handleChange} />
    </div>
  );
};
 
 ReactDOM.render(<SingleCart/>,document.getElementById('app'))
0

simply solution from me, you just create the following function

const NumericOnly= (e) => { //angka only
     const reg = /^[0-9\b]+$/
     let preval=e.target.value
     if (e.target.value === '' || reg.test(e.target.value)) return true
     else e.target.value = preval.substring(0,(preval.length-1))
}

and implement it to your form

<input 
type="text"
className="form-control"
name="kodepos"
onChange={NumericOnly}
/>

No need setState or useState!

It would be great if you put the function into helper and put it in various forms wherever you need

Djono A
  • 1
  • 2
0

`

import React, { useState } from 'react';

export default function Demo() {
const [contact, setcontact] = useState('');

const handleContact = (e) => {
         if(e.target.value>='0' && e.target.value<='9' ) setcontact(e.target.value);
    }
    
     return (
      <div>
        <form>
          <div className="form-group">
            <label>Contact No.</label>
              <input type="text" className="form-control" id="contact" onChange={handleContact} value={contact} placeholder="Contact No." required="required"  />
           </div>
        </form>
      </div>
     )
}

`Here is a simple method to implement the condition of entering only numeric values in the input field of type 'text' in the function-based component of ReactJs. I personally implemented this in many places and it definitely works.

Cheers!!

0

you can use this solution and enter only numbers in inputs that has type="text" see my code in reactJs ClassComponent

<input
    type="text"
    name={this.props.name}
    onChange={(e) => {
        if (!isNaN(e.target.value)) {
            this.props.change(value_)
            this.setState({ value_: Number(e.target.value)})
        }
    }}
    value={Number(this.state.value_) || Number(this.props.value)}
    autoComplete="off"
/>

this code : if (!isNaN(e.target.value)) helps you that users only enter numbers and does not accept other characters

The isNaN() function determines whether a value is NaN or not. "NaN" is meaning: 'Not a Number'

see document about this function

fatemeh kazemi
  • 516
  • 6
  • 10
0

If you only want to accept numbers from the user but also want the user to delete characters as well in the input field (which they should be able to do) you just need to make your input a controlled component and add onChange handler in the input field like this :-

<input type="text" placeholder="your_placeholder" value={your_state_value} onChange={(e) => {if(/^[0-9]+$/.test(e.target.value) || e.nativeEvent.inputType == "deleteContentBackward" || e.nativeEvent.inputType == "deleteContentForward"){changeState(e.target.value)}))}}} />

where changeState is your state update function.

Singh_Avi
  • 1
  • 1
0

Here's a one liner. If your input is type='number' don't use that, make sure to remove it.

export function formatOnlyNumbers(value:string){ 
  return (Number.isInteger(+value)) ? value : value.slice(0,-1);
}

then

use it like this:

<input 
  type="text"
  className="form-control"
  name="minimum rate"
  onChange={formatOnlyNumbers}
/>
RJA
  • 129
  • 1
  • 7
0

You can simply replace all characters to "" other than digits

const [userInput, setUserInput] = useState("");
const handleInput = (e) => {
    const formattedNumber = formatNumber(e.target.value);
    setUserInput(formattedNumber);
  };

const formatNumber = (value) => {
    return value.replace(/[^\d]/g, "")
}

<input onChange={(e) => handleInput(e)} value={userInput} />
Meisam Mofidi
  • 161
  • 1
  • 6