7

I know type=number works but that is not what i want. my HTML:

<FormItem style={{ display: "inline-block" }}>
    {getFieldDecorator('matchPercentage', {
        initialValue: this.state.matchPercentage
     })( 
        <Input type="number" value={this.state.matchPercentage} onChange={this.handlePercentMatch} style={{ width: 100, marginLeft: 10 }} />
     )}
</FormItem>

my Function:

handlePercentMatch = (e) => {
    const isInteger = /^[0-9]+$/;
    if (e.target.value === '' || isInteger.test(e.target.value)) {
      this.setState({ matchPercentage: e.target.value })
    }
  }

My isInteger.test() is working meaning I am able to get only integers in matchPercentage in state. But the problem is It is not reflecting in GUI. I am still able to type alphabets even though they are not being set into state.

I know type="number" works but that is not what i want. I want to validate using react as i want control decimals and upto how many digits and non negative

I have added my code here https://codepen.io/DadyByte/pen/xYgLvy?editors=1010

I found the root cause. If you use FormItem you will be allowed to type no matter what. If I use Input outside FormItem my code is working. What can I do to prevent it

DadyByte
  • 894
  • 6
  • 18
  • 30
  • 1
    Please share `Input` component's code. – Prakash Sharma Feb 08 '18 at 17:41
  • its a huge form component @Prakashsharma. What could be the problem? – DadyByte Feb 08 '18 at 17:43
  • 1
    @DadyByte just make sure, inside Input component you defined `value={this.props.value}` on `input` element, if you define that it will work, otherwise it will allow user to add any value. Check [**this answer**](https://stackoverflow.com/questions/43067719/how-to-allow-only-numbers-in-textbox-in-reactjs) – Mayank Shukla Feb 08 '18 at 17:48
  • 2
    @DadyByte Nothing seems wrong with the above logic. I think there is something wrong with `Input ` component itself. – Prakash Sharma Feb 08 '18 at 17:48
  • Maybe you are missing a `e.preventDefault()` in case the _if_ condition does not pass. – keul Feb 08 '18 at 17:51
  • @LucaFabbri `e.preventDefault()` is not working – DadyByte Feb 08 '18 at 18:02
  • can you show some code from the `Input` component? I don't think you are passing value into the html `` component since you are getting non-controlled behavior – Eric Hasselbring Feb 08 '18 at 18:15
  • If you don't want to paste all of the input component, maybe just put it in a codepen? – Max Millington Feb 08 '18 at 18:15
  • @EricHasselbring Input is an Antd Component. click here to know its api docs: https://ant.design/components/input/. I tried replacing Input with input still the same output. – DadyByte Feb 08 '18 at 18:23
  • you should use their InputNumber seems like they have a lot of already implemented features you are using – Eric Hasselbring Feb 08 '18 at 18:41
  • @EricHasselbring I am currently using that only but InputNumber also allows you to type alphabets and validates on `onBlur()` function. What I really Want is not allow the typing of alphabets – DadyByte Feb 08 '18 at 18:47
  • @MaxMillington I dont know how to add antd library support in codepen – DadyByte Feb 08 '18 at 18:47
  • @DadyByte Your code is working check: https://codesandbox.io/s/ly2j4nnzkz – Prakash Sharma Feb 08 '18 at 18:59
  • @Prakashsharma The problem is in FormItem. Check my code in Code Pen attached in problem statement – DadyByte Feb 09 '18 at 10:48
  • @LucaFabbri Check my code snippet in codepen for problem in detail – DadyByte Feb 09 '18 at 10:49

7 Answers7

6

Ant Design has an InputNumber Component. You could use something like this

import {InputNumber} from 'antd';

Usage

<InputNumber placeholder="Age (Max Age :100,  Min Age:1)" size={'large'} min={1} max={100} onChange={this.handleAgeChange} />

Then your handleAgeChange Functionality could look like

 handleAgeChange = (value) => {
    this.setState((prevState) => (
         { ...prevState, age:value }
    ));
};
herlarby
  • 111
  • 2
  • 4
6

Just use the code below and it would just accept the numbers, also it works for ant design Input component.

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

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

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

Sulung Nugroho
  • 1,605
  • 19
  • 14
  • it's simple ..but once user filled out, they won't be able to delete/backspace the last number. They'll be left with single number in the field.. – KMC Aug 29 '20 at 04:31
  • To fix that, replace "if (!Number(valu)) {...}" with "if (!Number(valu)&& valu.length > 0) {..}" – KMC Aug 29 '20 at 04:59
2

I assume you use that for telephone number input.

So here is the input you can use.

<input
   placeholder="Telephone Number"
   onChange={ (e) => {
     const telNo = e.target.value;
     const re = /^[0-9\b]+$/;
     if (telNo === '' || re.test(telNo)) {
       this.setState({ telNo: e.target.value });
     }
   }
   value={ this.state.telNo }
   type="tel"
 />
Hadnazzar
  • 1,517
  • 19
  • 21
1

HTML 5 has a native solution:

<input type="number">

This is assuming your Input component is using the HTML5 <input /> tag

Max Millington
  • 4,378
  • 4
  • 27
  • 34
0

Well, it's quite simple just pass type = number to your input field<input value={this.state.matchPercentage} onChange={this.handlePercentMatch} type="number">

Muneeb
  • 1,469
  • 16
  • 24
0
Hi @DadyByte,

Set the pattern attribute to prevent the user from entering non-integer values in the input field.

<input type="text" pattern="\d*" value={this.state.matchPercentage} onChange={this.handlePercentMatch} style={{ width: 100, marginLeft: 10 }} />

The expression \d* matches any number of digits (0 or more). This will allow only integer values to be entered into the input field.

Alternatively, you could also use /^[0-9]+$/.

handlePercentMatch = (e) => {
  const isInteger = /^[0-9]+$/;
  if (e.target.value === '' || isInteger.test(e.target.value)) {
    this.setState({ matchPercentage: e.target.value }, () => {
      e.target.setSelectionRange(e.target.value.length, e.target.value.length);
    });
  }
}
DSDmark
  • 1,045
  • 5
  • 11
  • 25