6

I have created a currency input React component to allow the user to enter numeric values. I made the input type to "number". This only works in Chrome (user can still enter non-numeric values in Firefox).

CurrencyInput Component:

import React from "react";
import { Form } from "semantic-ui-react";

interface ICurrencyInputProps {
  onChange(value: any): void;
  checkRange?: boolean;
  min: number;
  max: number;
  validationMessage: string;
  cssClasses?: string;
}

export class CurrencyInput extends React.Component<ICurrencyInputProps> {
  state = {
    showInvalidError: false,
    value: null
  };
  render() {
    return (
      <>
        <Form.Input
          icon="pound"
          iconPosition="left"
          placeholder="Whole pounds"
          className={this.props.cssClasses}
          type="text"
          error={this.state.showInvalidError}
          onChange={(event: any) => {
            let value = null;
            if (event.target.value) value = parseInt(event.target.value);

            this.setState({ value: value });
            this.props.onChange(value);
          }}         
        />      
      </>
    );
  }
}

export default CurrencyInput;

Usage:

<CurrencyInput
    cssClasses="has_tooltip"
    checkRange={true}
    onChange={(data: any) => {
              this.setState({
               premium: data
                        });
                      }}
    min={TargetPremiumRange.MIN}
    max={TargetPremiumRange.MAX}
    validationMessage="Validation message"/>

I want to prevent the user from entering any non-numeric value. How can I achieve this?

Joshua
  • 2,275
  • 7
  • 41
  • 57

2 Answers2

5
<Input
onKeyPress={(event) => {
        if (!/[0-9]/.test(event.key)) {
          event.preventDefault();
        }
      }}
/>
simo
  • 23,342
  • 38
  • 121
  • 218
  • Please explain your code and also state why your solution should be preferred over the other answers. – BDL Sep 17 '21 at 08:36
  • I've tried other solutions on StackOverflow by far this is the only answer that works for me. Thank you. – PA55ION May 12 '22 at 20:32
4

You can change the error state in your onChange in <Form.Input>. Something like:

onChange={(event: any) => {
    let value = null;
    if (event.target.value) {
        value = parseInt(event.target.value, 10);

        // Test for valid number
        if (isNaN(value)) {
            setState({showInvalidError: true});
        } else {
            this.setState({ value: value });
            this.props.onChange(value);
        }
    }       
}  
Ed Lucas
  • 5,955
  • 4
  • 30
  • 42
  • Thanks. But the user still will be able to enter non numeric values? – Joshua Feb 04 '20 at 20:53
  • 1
    Yes, but if the value is incorrect, it will not change the value saved in the state, your error state will be displayed, and the user will be allowed to correct it. You could check on each `keydown()` and prevent anything from a number being typed, but that doesn't solve for the case where someone just pastes in a value. `onchange()` should cover that. – Ed Lucas Feb 04 '20 at 20:55