question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Changing NumberInput does not set form dirty

See original GitHub issue

What you were expecting: Changing a NumberInput sets the form dirty and enables the save button. Similar to other input types as TextInput, ReferencInput, DateInput, … When saving, the number shown in the NumberInput is saved.

What happened instead: Changing a NumberInput does not set the form dirty and does not enable the save button. Whether you change a NumberInput by typing in it, by using keyboard up/down arrow or by clicking on the up/down arrows in the input, it doesn’t make a difference. You need to leave the input first, make it loose focus. Only then the save button gets enabled and the value is bound to that input.

This is especially problematic in a scenario with submitOnEnter enabled, which is the default. If the last input you change is that NumberInput and you press Enter, then the old value of the NumberInput is saved. The changed NumberInput value is not saved!

Steps to reproduce:

Old values are saved:

  • Go to the posts resource
  • Click on a post to go to the edit view
  • Choose the Miscellaneous tab
  • Modify the Category (save button gets enabled)
  • Click inside the “Average note” input
  • Modify that “Average note” value using keyboard or up/down arrows
  • Don’t leave that field but simply press Enter to save the form
  • Notice the Category is changed but the “Average note” value is not!

Save button not enabled:

  • Go to the posts resource
  • Click on a post to go to the edit view
  • Choose the Miscellaneous tab
  • Modify the “Average note”
  • Notice the save button not being enabled untill you leave the input

Other information: We currently work around this by disabling the submitOnEnter functionality (as described in the upgrade docs) to prevent old values being saved. But even without submitOnEnter, it is not user friendly needing an extra click to be able to save a changed NumberInput. One click outside the NumberInput to enable the save button and one click to do the actual save. In Firefox 102.0 (64-bit) on Win10 21H2 (OS build 19044.1766), removing focus from the NumberInput still does not enable the save button when input is changed using the arrows in the input itself.

Environment

  • React-admin version: 4.2.0
  • Last version that did not exhibit the issue (if applicable):
  • React version: 17.0.2
  • Browser: Chrome Version 103.0.5060.66 (Official Build) (64-bit)

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
lvernaillencommented, Jul 25, 2022

@fzaninotto That seems correct interpretation.

I would indeed expect that the default behavior of <NumberInput> does not have the cumbersome UX as it is now. A default <NumberInput> for integers that does not require onBlur of the input to set the form dirty. An additional prop to support decimals.

The current docs warn that <NumberInput> converts the input value to a number (integer or float) on blur and state:

[…] you can build your own number input using <TextInput>, and the format and parse props. But be aware that this only works for integer values.

However in my tests it seems it should work for floats too. With the parse prop we can parse the value to a number using parseInt for integers and parseFloat for decimals. Without parsing a string value is sent to the api which is not correct.

const parseNumberInputToRecord = (v: string): number => {
    console.log({v});
    return parseFloat(v);
}

<TextInput
    source="points"
    type="number"
    parse={parseNumberInputToRecord}
/>

Without parsing you can enter numbers 0 through 9, a decimal separator, a “-” sign and an exponent “e”. All others characters are discarded as you type.

When using the parse prop I notice these things:

  • using parseInt in the parse function:

    • I can enter numbers 0 through 9 (e.g. 23)
    • I can even use decimal separator BUT only if the value results in an integer (e.g enter 23.00). Value passed to api is number 23 (without the decimals) because of parsing to int, which is ok.
    • If the value is not an integer (e.g. try to enter 23.7) the parsing removes the decimals immediately and the input shows 23, which is also ok.
    • To use negative number I first need to enter the number and then prefix it with ‘-’. If I start with the ‘-’ character, the console log shows empty string for variable v and logs “the specified value “NaN” cannot be parsed, or is out of range.”. That is strange. It seems there is some already some parsing done before it enters my parseNumberInputToRecord method. I would have expected to receive that ‘-’ in my parse method.
    • I cannot enter an “e” for exponential values, which I can enter if there is no parse prop used. As soon as I enter “e”, the input is cleared and the NaN message is logged. Same here, it seems there is some already some parsing done before it enters my parseNumberInputToRecord method. I would have expected to receive that ‘e’ in my parse method.
  • using parseFloat in the parse function:

    • I can enter numbers 0 through 9 (e.g. 23)
    • I can use decimal separator (e.g. 23.75). Value passed to api is float number 23.75, which is ok.
    • Same issue with negative numbers where you need to enter the number first and then prefix it with ‘-’.
    • Same issue with exponential values “e”, where entering “e” clears the input field.

As for scientific notation with exponantials, we don’t need them, but other users might. I tried using inputProps={{ inputmode: 'numeric' pattern: '[0-9]*' }} on <TextInput> but the pattern and input mode seem to be neglected. Those would help in preventing an “e” to be entered if scientific notation is not allowed.

1reaction
lvernaillencommented, Jul 12, 2022

Screen capture of issue where removing focus from the NumberInput still does not enable the save button when input is changed using the arrows in the input itself in Firefox (Chrome is ok).

Animation5

Firefox 102.0 (64-bit) on Win10 21H2 (OS build 19044.1766)

Read more comments on GitHub >

github_iconTop Results From Across the Web

Explicitly setting an input to dirty #55 - final-form/final ... - GitHub
The FormAPI currently offers ways to blur , focus , and change fields. However, there is no way to explicitly set a field...
Read more >
Angular 2++ | NgForm: Form.Dirty is Always Dirty
Another option is to use reactive forms instead of template-driven forms. Then your data model is not changed by any changes that the...
Read more >
ngModel - AngularJS: API
The ngModel directive binds an input , select , textarea (or custom form control) to a property on the scope using NgModelController, which...
Read more >
Controller | React Hook Form - Simple React forms validation
Dirty fields will not represent as isDirty formState, because dirty fields are marked field dirty at field level rather the entire form. If...
Read more >
Working with Angular 4 Forms: Nesting and Input Validation
Validating user inputs is an essential part of any robust web application. Angular 4 makes it especially easy for both template-driven and reactive...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found