Iggee Xy
Iggee Xy

Reputation: 93

React controlled <type='number'> input allows typing in letter?

I am writing an app that contains a controlled input that has the type 'number'. I can still type letters in the input field, but the e.target.value just gets emptied. Does anyone know how I can disable the typing of letters? Namely, if a user types in a letter, the input field will simply not register but still keeps the numbers previously typed in.

Here is my code:

export class AddNewRecipe extends React.Component {
    constructor(props){
        super(props);
        this.state={prepField:{numeral:""}};

        this.handleInput = this.handleInput.bind(this)}

   handleInput(e){
      e.preventDefault();   
      if(e.target.className =='prepNumber')
      {   
          console.log(e.target.value)
          const newPrep = Object.assign({}, this.state.prepField)
          newPrep.numeral = currentValue
          this.setState({prepField: newPrep})
      }

render(){
return (<PrepTime 
        handlePrep={this.handleInput}
        prepField={this.state.prepField}
        />
)
}
 

and here is the child component

export default function(props){
    
    return(
        <div id = 'prepForm'>
            
                <input id = 'prepFormInput' type='number' className='prepNumber' value={props.prepField.numeral} onChange={props.handlePrep} placeholder='prep time' />
               
        </div>
    )
}

Does anyone know why that is? Because if I accidentally type '10v', the e.target.value which I will set to my state 'prepField.numeral' just becomes emptied.

Thank you!

Upvotes: 2

Views: 7498

Answers (2)

Bhanu Sharma
Bhanu Sharma

Reputation: 121

(For react Applications)

If someone has text input and wants to accept only whole numbers. You can use the following code.

const numberInputKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
    const eventCode = event.code.toLowerCase();
    if (!(event.code !== null
    && (eventCode.includes("digit")
        || eventCode.includes("arrow")
        || eventCode.includes("home")
        || eventCode.includes("end")
        || eventCode.includes("backspace") 
        || (eventCode.includes("numpad") && eventCode.length === 7)))
    ) {
    event.preventDefault();
    }
};

I have compared the length of eventCode to 7 when it includes numpad because its actual value is like numpad0, numpad1 ... numpad9

This function can be specified in onKeyDown such as

<input
    id="myNumberInput"
    type="text"
    placeholder="numeric input"
    onKeyDown={numberInputKeyDown}
/>

To extent field to accept decimals or negative numbers you can console.log the eventCode in numberInputKeyDown to check your required key code and add it in if statement.

Upvotes: 0

Vinicius Farias
Vinicius Farias

Reputation: 111

You can use this code:

<input id = 'prepFormInput' type='number' className='prepNumber' value={props.prepField.numeral} onChange={props.handlePrep} placeholder='prep time' onkeydown="javascript: return ['Backspace','Delete','ArrowLeft','ArrowRight'].includes(event.code) ? true : !isNaN(Number(event.key)) && event.code!=='Space'" />

This will avoids all characters that are not numbers!

This part make's input accept only numbers:

!isNaN(Number(event.key))

This part make's accept the arrow and delete keys:

['Backspace','Delete','ArrowLeft','ArrowRight'].includes(event.code)

This part make's Firefox disallow spaces in numbers:

event.code!=='Space'

Upvotes: 1

Related Questions