3

Reading this answer I came up with this code but did not work. What am I missing?

function App() {
  const [value, setValue] = useState();

  function onChange(e) {
    const re = /^[0-9\b]+$/;
    if (e.target.value === "" || re.test(e.target.value)) {
      setValue(e.target.value);
    }
  }

  return <input value={value} onChange={onChange} />;
}

render(<App />, document.getElementById("root"));
eduardo preuss
  • 63
  • 1
  • 1
  • 6

4 Answers4

2

Here's the updated answer according to this post

You can use the attributes type="number" and pattern="^-?[0-9]\d*\.?\d*$", so modify your input element like this:

/* Chrome, Safari, Edge, Opera */

input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}


/* Firefox */

input[type=number] {
  -moz-appearance: textfield;
}
<input type="number" pattern="^-?[0-9]\d*\.?\d*$" />

source: w3shools

P.S. Or you can skip the type=number part and the additional CSS and just use the pattern.

EvaBat
  • 842
  • 9
  • 18
  • even with `min="0" step="1"` I can still type stuff like plus sign, letter e, dots... – eduardo preuss Apr 22 '20 at 16:53
  • @eduardopreuss I meant to use them combined with `type=number`. Anyway, I have updated my answer after a quick search, please check above. – EvaBat Apr 22 '20 at 17:21
  • @eduardopreuss It may be late for answering this, but in your particular case, you can use `validity.valid` to check whether the input value is in defined range or not. You can use it like `oninput="validity.valid||(value='');"`. – SMAKSS Jan 06 '21 at 04:37
2

One way would be to use type="number" just like the answers above.

Or you could use a pattern and just enhance you implementation a bit:

function App() {
  const [value, setValue] = useState();

  function onChange(e) {
    if (!e.target.validity.patternMismatch) {
      setValue(e.target.value);
    }
  }

  return <input value={value || ''} pattern="^[0-9]*$" onChange={onChange} />;
}

render(<App />, document.getElementById("root"));
Osama Rashid
  • 1,000
  • 8
  • 9
0

Try This. this worked for me. You should add the attribute pattern and in the onChange you should check the condition.


  const[data, setName] = useState({
    phone:""
  });


function setValue(e){
  if(e.target.validity.valid){
    setName({...data,phone:e.target.value});
  }
  
}

  return (
    <form>
      <label>Numbers Only</label>
      <input name="phone" type ="text" pattern="[0-9]*" value={data.phone} onChange={setValue} />
      <input type="submit" />
    </form> 
  );
Kanishka
  • 115
  • 2
  • 8
0

A simpler way is to convert whatever is written to its numerical characters only. You can convert the value when you use it as a parameter for the setValue call.

function onChange(e) {
    setValue(e.target.value.split(/\D/).join(''))
}

This will remove all non-numerical characters from user string and prevent user from changing the state. It also works well with copy-paste values since it removes all non-numerical character occurences.

gsan
  • 549
  • 1
  • 4
  • 14