webcat12345 / ngx-intl-tel-input

Phone number input field to support international numbers, Angular
MIT License
213 stars 335 forks source link

Field being marked as dirty on load #340

Open gritbranch opened 3 years ago

gritbranch commented 3 years ago

Hi,

The input field for ngx-intl-tel-input is being marked as dirty for template driven forms.

Screenshot 2020-10-15 at 11 13 58 AM

Here is a Stackblitz that shows this error: https://stackblitz.com/edit/ngx-intl-tel-input-demo-ng-10-wyshxe

Thank you.

pasevin commented 3 years ago

Hey, I never used this library with template-driven forms. I think it was only meant to be used with reactive forms. I would gladly accept and merge a PR if someone can take a look at that.

TylerOrtiz commented 3 years ago

In my own investigation of a similar issue using Reactive Forms; I discovered that using patchValue to update the form control (such as binding to already existing data in a backend) causes the control to be flagged as dirty.

After attempting to repro in Stackblitz, it would appear the the field is always dirty even if the user doesn't do anything.

See the following Stackblitz for example: https://stackblitz.com/edit/ngx-intl-tel-input-demo-ng-9-buwrnp?file=src/app/app.component.html

After viewing this in my own implementation I discovered a possible cause is the propagation invocation inside writeValue: https://github.com/webcat12345/ngx-intl-tel-input/blob/dc3be1411070f39a4b1f331e27ca88b76bf48fc4/projects/ngx-intl-tel-input/src/lib/ngx-intl-tel-input.component.ts#L420-L428

onPhoneNumberChange inside writeValue may be necessary to make the control work, but for any write value of the control to propagate a change is likely wrong (since it will always cause the control to be flagged dirty by nature of propagateChange).

    writeValue(obj: any): void {
...
        setTimeout(() => {
            this.onPhoneNumberChange(false); // <--- I am suggesting passing a flag to propagate changes
        }, 1);
...
    }
amiram commented 3 years ago

Happened to me also in reactive forms. The initial value is null. When the form loads, valueChanges fires with a null value. Ugly workaround:

let phoneInitiated = false;
this.form.get('fieldName').valueChanges.pipe(
            tap(() => {
                if (!phoneInitiated) {
                    this.form.get('fieldName').markAsPristine();
                    phoneInitiated = true;
                }
            }),
dna1969 commented 3 years ago

Is there any workaround to set this field pristine when the value of the field is set at the initialisation ?

amiram commented 3 years ago

@dna1969 Is my workaround good for you?

anton6378 commented 3 years ago

@dna1969 Is my workaround good for you?

Your solution works.

The second problem is when I choose country code only (having option 'separateDialCode' set to true), the control becomes 'touched' and 'required' validator is being fired. I get 'required' error message displayed right away. How to workaround this?

amiram commented 3 years ago

You can add a condition to the span that shows the required message to not show it if there is only a code, but anyway the control is in invalid state. You don't want the user to enter only country code.

anton6378 commented 3 years ago

@amiram the thing is - user is in process of filling the phone number, first he chooses the country code, and then he types the number itself. However the 'required' error appears right after selecting country code, coz control becomes dirty and value still invalid. This is not how I want it to be. To me the reliable behavior for this is not to mark control as dirty and set focus to number input. Control should be market as dirty only after number input looses focus. If I add condition to span not to show 'required' message if only code is selected then user will be able to leave this as is without being seen 'required' error message at all

praveenptl71 commented 3 years ago

Hi,

The input field for ngx-intl-tel-input is being marked as dirty for template driven forms.

Screenshot 2020-10-15 at 11 13 58 AM

Here is a Stackblitz that shows this error: https://stackblitz.com/edit/ngx-intl-tel-input-demo-ng-10-wyshxe

Thank you.

@gritbranch did you got any solution for this issue? I'm also facing the same issue. @pasevin please take a look into this.

gritbranch commented 3 years ago

Hi @praveenptl71, unfortunately no. Instead, I only validate if the control is marked as touched. Not very ideal as Angular recommends checking both states but checking just for touched works for us as per our use case at the moment.

praveenptl71 commented 3 years ago

Thanks @gritbranch

nullbytesoftware commented 3 years ago

facing the same issue with reactive forms. Input is dirty directly.

aldrashan commented 3 years ago

Same issue with reactive forms. The input has the correct classes "ng-untouched ng-pristine ng-valid" but the formcontrol itself is marked as invalid, dirty but untouched which triggers our validation messages to show immediately.

Currently using the workaround of setting fc.markAsPristine(); fc.setErrors(null); the first time valueChanges is triggered. Simply touching the control, without changing the value, isn't enough to retrigger the required validation then though.

asolovieff commented 2 years ago

Same issue even in 2022. Nothing as be done about it ? @pasevin

pasevin commented 2 years ago

I'm aware of what year it is @asolovieff ;) unfortunately, I had only maintained this project until it was relevant to my own project. Currently, I don't have time to maintain it. If you want to contribute feel free to pin @webcat12345, he is the owner of this repo.

justin-002 commented 1 year ago

@webcat12345 is there any chance this issue can be fixed soon?