Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Int value input not stripping all invalid characters on dialog submit #16

Closed
AlanJMac opened this issue Aug 13, 2022 · 2 comments · Fixed by #17
Closed

Int value input not stripping all invalid characters on dialog submit #16

AlanJMac opened this issue Aug 13, 2022 · 2 comments · Fixed by #17

Comments

@AlanJMac
Copy link
Collaborator

In an edit dialog, the text input for an integer appears to work visually when entering non-numerical characters however on saving the value the last bad character entered is still there. And no error message is shown by the client or in the server logs.

For example, try to add a new item with a weight containing non-numerical characters, e.g.

Edit
name: "Bad Weight Input"
weight: "5kg"

The input textbox will, correctly, not show the non-numerical characters "kg":
image
However, upon clicking save you will notice the item has not been created and in the console you can see the following value has actually been submitted to the server:
TO SUBMIT {name: 'BadWeight', weight: '5g'}
i.e. the last non-numerical character entered is still in the input value.

The [dmIntInputDirective] handleValue() method appears to work as intended for the display in the text box.
I have a doubt whether there needs to be a change detection forced before clicking "save" because after this line:
this.ngControl.valueAccessor.writeValue(cleanedValue); (where cleanedValue is correctly e.g. "5")
the value of this.ngControl.value is still e.g. "5g" inside the handleValue() function. So perhaps the ngControl value is not being written to before it is used by the "save" function..?

Environment:
Seen on Chrome on Windows.

@AlanJMac
Copy link
Collaborator Author

Replacing this.ngControl.valueAccessor.writeValue(cleanedValue); with this.ngControl.reset(cleanedValue); appears to work though...

@AlanJMac
Copy link
Collaborator Author

(Ignore the previous comment as using reset would surely not be the correct behaviour to use)

I have a solution although I haven't really understood what is going on behind the scenes, however it seems that ngControl.valueAccessor.writeValue(...) will modify the native element's value, so this is why we see the desired change, but it does not inform the underlying FormControl of this change of value.

My understanding therefore is as follows:
The abstractControl object in a DmFormInputData is initialised in DmFormUtils.getFormInputData(...) as
let abstractControl: AbstractControl = new FormControl();
and is mapped to the formControl of the input box,
<input ... [formControl]="this.getFormControl()" ... >

This abstractControl can listen to, and will hear, changes to the value of the input box when a key is pressed.

The NgControl injected in the DmIntInputDirectiveDirective appears to refer to the controller of the DOM element rather than the FormControl object. But once initialised it contains a reference to the FormControl object (ngControl.control).

e.g.

  1. type 'k' in the integer input box
  2. [dmIntInputDirective] handleValue() will clean the value shown to ''
  3. the abstractControl will hear that the value in the input box changed from '' to 'k'
  4. type 'g'
  5. [dmIntInputDirective] handleValue() will clean the value shown to ''
  6. the abstractControl will hear that the value in the input box changed from '' to 'g'

The comment in this thread and the answer to this stackoverflow led me to a possible solution, which would be to set the value of the abstractControl directly instead of using the NgControl's valueAccessor.
i.e.

    this.abstractControl = this.ngControl?.control;
    ...
    if (this.abstractControl && cleanedValue !== numValue) {
      this.abstractControl.setValue(cleanedValue);
      cursorPos--;
    }

The value submitted for the inputs in the initial bug report will then be correct:
TO SUBMIT {name: 'BadWeight', weight: '5'}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
1 participant