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

MustMatchValidator marks the matchingControl as touched #199

Closed
DavidTheProgrammer opened this issue Aug 3, 2021 · 4 comments
Closed

MustMatchValidator marks the matchingControl as touched #199

DavidTheProgrammer opened this issue Aug 3, 2021 · 4 comments
Assignees
Labels
enhancement New feature or request
Milestone

Comments

@DavidTheProgrammer
Copy link

DavidTheProgrammer commented Aug 3, 2021

Problem

I have "password" and "confirmPassword" inputs, I'm using a mustMatch validator on the form group and it's working as expected except for one thing. When I'm entering the password, the confirm password field automatically shows an error even before I've touched it.
I traced this down to the provided mustMatch validator as it marks the matching control as touched as long as the values do not match, triggering the error:

File: ...reactive_forms-10.5.0\lib\src\validators\must_match_validator.dart

    final formControl = control.control(controlName);
    final matchingFormControl = control.control(matchingControlName);

    if (formControl.value != matchingFormControl.value) {
      matchingFormControl.setErrors(error);
      matchingFormControl.markAsTouched();
    } else {
      matchingFormControl.removeError(ValidationMessage.mustMatch);
    }

Attempted Workaround

I've tried modifying the showErrors field of the ReactiveTextField to return false as long as the control value is an empty string (my default value). This works fine but because the control is marked as touched, the moment I enter any character in the confirm password input, the error shows up even though I haven't released focus on the input. There's a private field _hasFocus on the AbstractControl class but it's not exposed through any getters; this means I can't check if the control has focus to hide the error.

 showErrors: (control) {
    if (control.value.isEmpty) {
      return false;
    }

    return control.touched &&
        control.dirty &&
        control.invalid;
  },

Suggestions

If there's any way to get this to work other than my suggestions, please let me know. I'm aware I can write a custom validator and remove the line that's marking the control as touched, but I'm hoping we can find a solution that can work for anybody else who might run into this issue in future.

  1. We remove the code that marks the matching control as touched. That way the control will maintain it's default touch/pristine statuses and handle them accordingly.
  2. We add an optional field, that defaults to the current behavior, to the validator constructor that will determine whether or not we mark the matching control as touched. Same as above but opt-in.
  3. We expose the _hasFocus field so that errors can be hidden if the field currently has focus. I feel this one is kind of a hack, but I think it would get the job done.

Thanks in advance!

@joanpablo
Copy link
Owner

Hi @DavidTheProgrammer,

Thanks for your issue, it is very interesting. In my opinion, the best solution is your number 2:

  • Add an optional argument to the mustMatch validator to specify if we want it to marks the matchingFormControl as dirty or not.

It should have worked if we overrite the showError(control) => control.invalid && control.dirty in the passwordConfirmation Widget, but actually the setError is setting dirty = true by default to the confirmationPassword. So It is a missing an optionally argument to the mustMatch validator.

I will add it for the next release.

Thanks a lot.

@joanpablo joanpablo self-assigned this Aug 5, 2021
@joanpablo joanpablo added the enhancement New feature or request label Aug 5, 2021
@joanpablo joanpablo added this to High priority in Reactive Forms via automation Aug 5, 2021
@joanpablo joanpablo added this to the v10.6.0 milestone Aug 5, 2021
@joanpablo joanpablo moved this from High priority to In progress in Reactive Forms Aug 5, 2021
@joanpablo
Copy link
Owner

Hi @DavidTheProgrammer,

I have just released the v10.6.0 with the changes. Now you are ready to go.

Please don't hesitate to reopen again the issue or open a new one if you have any troubles.

Thanks

Reactive Forms automation moved this from In progress to Closed Aug 5, 2021
@DavidTheProgrammer
Copy link
Author

Hi @joanpablo Wow! That was really quick! Thanks! I really appreciate the work you've done with this library. I hope to contribute some day :-)

@byungjuJin
Copy link

@joanpablo
Hi I am using V14.1.0
It works as before. Can you check it, please?
validators: [ Validators.mustMatch('password', 'passwordConfirmation', markAsDirty: false), ],

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Reactive Forms
  
Closed
Reactive Forms
  
Awaiting triage
Development

No branches or pull requests

3 participants