9

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

15
  • 1
    Please share Input component's code. Commented Feb 8, 2018 at 17:41
  • its a huge form component @Prakashsharma. What could be the problem? Commented Feb 8, 2018 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 Commented Feb 8, 2018 at 17:48
  • 2
    @DadyByte Nothing seems wrong with the above logic. I think there is something wrong with Input component itself. Commented Feb 8, 2018 at 17:48
  • Maybe you are missing a e.preventDefault() in case the if condition does not pass. Commented Feb 8, 2018 at 17:51

8 Answers 8

8

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();
        }
    }}
/>
Sign up to request clarification or add additional context in comments.

2 Comments

Although its a clever stateless method it prevents user from copy pasting its value to the input
Alternative of using onKeyPress, which is marked as deprecated is using onKeyDown.
6

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.

2 Comments

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..
To fix that, replace "if (!Number(valu)) {...}" with "if (!Number(valu)&& valu.length > 0) {..}"
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 }
    ));
};

Comments

2

HTML 5 has a native solution:

<input type="number">

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

1 Comment

But I can still type "-".
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"
 />

Comments

1

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

Comments

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);
    });
  }
}

Comments

0

Another solution is to set the onInput property in the <Input/> component. This allows typing only numbers and provides the advantage of using properties like minLength and maxLength to restrict the length of the possible input values.

<Input
    value={this.state.matchPercentage}
    onInput={(e) => {
        // Only allow numbers
        e.currentTarget.value = e.currentTarget.value.replace(
            /^[0-9]+$/,
            "",
        );
    }}
    style={{ width: 100, marginLeft: 10 }}
/>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.