0
votes

I'm using React and Material-UI's TextField with type='number' but as I saw the validation is rather simple, it just allows any character that could represent part of a number [0-9\.eE-]*, allowing inputs like this: eee---...e---0.-1, I decided to implement my own validation. (not sure if that trivial validation is Material-UI's or HTML native, but doesn't matter anyway)

So I wrote this regular expression for validation, but as soon as I enter a character that doesn't match my regular expression, my onChange event handler doesn't get called at all and it seems the component takes control and applies its basic validation. My event handler doesn't get called again until I correct the input and make it match with my regular expression.

Can I prevent the component from doing this somehow?

onValueChange = (ev) => {
    if( /^-?(\d+)?(\.\d*)?$/.test(ev.target.value)) {
        this.setState({ value: ev.target.value });
    }

Complete code: https://codepen.io/anon/pen/eoZOaE?editors=1000

1
PS: my regex allows for partial input, so it doesn't invalidate a single "-" if the user then enters "-1", in case you wondered why it doesn't really match only valid numbers.Petruza
Ok, I figured out that if I was going to apply my own validation, why not just use a plain TextField? That way it works. But I'd still like to know why the odd behavior.Petruza

1 Answers

0
votes

(not sure if that trivial validation is Material-UI's or HTML native, but doesn't matter anyway)

This trivial validation is native, since Material-UI InputBase component only transmits type='number' to the native <input /> and doesn't define any additional validations.

And seems like onchange event that doesn't get fired on every input - is also the behavior of native input. You can check it in this example: https://codesandbox.io/s/20z5qrnqq0?fontsize=14 - as you can see - onChange event is also getting fired only for the 'valid' characters.

I tried to find some other solutions, with oninput HTML5 event, as it was suggested here, but it doesn't work either. So in this case I think that you do the right decision with using the type='text' input to control all possible inputs.