mantine icon indicating copy to clipboard operation
mantine copied to clipboard

NumberInput spinner buttons do not trigger form onChange

Open grahampcharles opened this issue 3 years ago • 2 comments

What package has an issue

@mantine/form

Describe the bug

A NumberInput within a form controlled by ...form.getInputProps does not fire the form's onChange event when the up and down spinner buttons are pressed. onChange fires as expected when a number is typed manually into the input section of the box.

Here's a slice of my code.

                    <form onChange={(e) => { setDirty(true) }} >
                        <NumberInput
                            label="Price"
                            {...form.getInputProps('price')}
                        ></NumberInput>
                    </form>

Here, setDirty does not fire unless a value is typed in.

In which browser did the problem occur

Chrome 103.0.5060.134

If possible, please include a link to a codesandbox with the reproduced problem

https://codesandbox.io/s/vigorous-moore-6qoj3t?file=/src/App.tsx

Do you know how to fix the issue

No

Are you willing to participate in fixing this issue and create a pull request with the fix

No response

Possible fix

No response

grahampcharles avatar Jul 24 '22 00:07 grahampcharles

I confirm I can reproduce this bug. It's not realy a mantine bug but react work as it... When you manage input value with states (like mantine do), onChange event on form html tag is not fired on state update.

The only workaround I see is to use onChange property on NumberInput directly...

Elsewhere, what about add a onChange function in useForm hook ? But it's a new core feature, not a bigfix.

If someone see a better solution...

fabienlege avatar Jul 24 '22 20:07 fabienlege

I don't understand how it's a react bug, but then I don't understand internals at all!

Anywho, this is my workaround: https://codesandbox.io/s/gracious-chatelet-o1v4me.

Essentially, I use the approach you suggested, discarding ...getInputProps and rolling my own onChange:

        <NumberInput label="Price"
          value={form.values.price}
          onChange={(newValue) => {
            form.setFieldValue("price", newValue);
            handleFormOnChange();
          }}
        ></NumberInput>

The only disadvantage is that if users do change the value by typing, then handleFormOnChange runs twice for every keystroke. Since I'm only using it to setDirty(true) that's not a problem. Just seems weird.

grahampcharles avatar Jul 25 '22 18:07 grahampcharles

I've tried to solve it, but unfortunately, I wasn't able to come up with any solution for this issue, so I doubt that it is event possible to capture this event. @mantine/form package now provides touched and dirty state – https://mantine.dev/form/status/, so maybe it will help you solve the issue without for onChange event.

rtivital avatar Aug 12 '22 07:08 rtivital