Closed jonmikelm closed 4 years ago
This problem also occurs for the setErrors()
function.
ng-valid
/ng-invalid
is set correspondingly, but the corresponding ionic ion-valid
/ion-invalid
class is not changing.
Seeing related issue in my project also. ng-touched
class is added to ion-input
when the control loses focus. That is expected. However, ion-touched
is added to ion-item
when ion-input
receives focus.
Ionic team, please refer to Angular documentation. https://angular.io/api/forms/AbstractControl#touched
Hey,
I also ran into this issue using stencil, and a custom value accessor inspired by the one using by Ionic.
Because the onBlur / onChange method is not trigged by the setErrors()
method, the classes are not updated => The ng-valid
class is added, but the setIonClasses()
is not triggered in the value accessor.
I'm trying to find a workaround, by trigerring a blur on the input, I'll let you know if I find any solution to this problem
Hey, I'm working with @gagaXD and here is our workaround for this.
First we created a Directive to add the nativeElement to the control:
native-element-injector.directive.ts
import { Directive, OnInit, ElementRef } from '@angular/core';
import { NgControl, AbstractControl } from '@angular/forms';
export interface BetterAbstractControl extends AbstractControl {
nativeElement?: HTMLElement;
}
@Directive({
// tslint:disable-next-line:directive-selector
selector: '[formControlName]',
})
export class NativeElementInjectorDirective implements OnInit {
constructor(private el: ElementRef, private control: NgControl) {}
public ngOnInit() {
(this.control.control as BetterAbstractControl).nativeElement = this.el.nativeElement as HTMLElement;
}
}
In our forms, when we want to reset or setErrors:
control.setErrors(null); // or control.setErrors(data);
// blur nativeElement to force change it's State
// @see https://github.com/ionic-team/ionic/issues/17414
const betterControl: BetterAbstractControl = control;
if (betterControl.nativeElement && control.touched) {
betterControl.nativeElement.blur();
}
In our input stencil component, we implement a blur method:
/**
* Method to blur manually.
*/
@Method()
blur() {
if (this.nativeInput) {
this.nativeInput.blur();
}
}
With this workaround we can Blur programmatically when we change programmatically the input state (with setErrors).
Great workaround! @Nightbr and @gagaXD Nonetheless, in my opinion, it's Ionic team's responsibility to provide its developer community with a properly working component library. I think I am going to wait for them to release a bug fix.
It is not trivial since they use ValueAccessor to bind with Angular framework and ValueAccessor has no hook when the state valid/invalid of the formControl is changed without changing the Value. We look but if Angular doesn't implement a Hook for this use case in the custom ValueAccessor https://angular.io/api/forms/ControlValueAccessor it will be very difficult.
Other try for us but with a drawback in performance is to listen with the MutationObserver class changes and refresh the ion-* classes. But it's not a valid solution because of the low performance of this (and potential loops...).
See:
Hey, just to inform that we have renamed the blur()
method to setBlur()
to remove the warning that stenciljs can throw.
If the Ionic controls could add the markAs* methods and then just pass it on to the Angular controls, that would work for me. Even if that was just a stop-gap until such time when the needed Angular hooks are added...
If it will be useful to someone, I will share my workaround. I update the value of the field with its own value using the submit() method.
public submit(): void {
if (this.form.get('confirmPassword').value !== this.form.get('password').value) {
this.form.get('confirmPassword').setErrors({ passNotEqual: true });
this.form.get('confirmPassword').setValue(this.form.get('confirmPassword').value);
}
}
Input 'confirmPassword' validator:
private confirmPassword(): ValidatorFn {
return (currentControl: AbstractControl): { [key: string]: any } => {
if ( currentControl.parent && (currentControl.value !== currentControl.parent.get('password').value) ) {
return { passNotEqual: true };
} else return null;
};
}
How can it be that after 1 year there is no response from Ionic-Team ?? This is a major issue, form validation is completely not in sync with angular and the framework is useless ? When you have a (reactive) angular form and the user presses Submit, not errors are shown, validation is not working. Don't you think form validation is a key concept in nearly every App ?? I really don't get, there is not even a usefull documentation on forms on the Ionic Homepage. I don't understand how you guys can continue working on new versions without providing a framework that has the basic functionality in it...
So sad. I upgrade to version 5. Same problem.
Hi everyone,
Can you try the following dev build and let me know if it resolves the issue?
npm i @ionic/angular@5.2.0-dev.202006032038.ebb3f9a
The proper solution to this issue is https://github.com/angular/angular/issues/10887, but we are waiting on the Angular team to implement that. In the mean time, this dev build patches the markAs*
methods to manually sync Angular's form classes with Ionic's form classes.
Thanks for the issue. This has been resolved via https://github.com/ionic-team/ionic/pull/21429, and a fix will be available in an upcoming release of Ionic Framework.
Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out.
Bug Report
Ionic version:
4.0.0
Current behavior: Using the Angular Reactive Forms API, when
markAsTouched()
function is called over a FormControl,ng-touched
class is applied to theion-item
element but theion-touched
class is not applied.This problem occurs with each of the Angular Forms
markAs***
functions:(Didn't take the time to test the
reset
function, but I suspect that the result will be the same.)Expected behavior: Whenever an Angular FormControl status changes
ng-XXX
classes applied to the DOM element are updated.ion-XXX
classes should work the same way. On every FormControl status change,ion-XXX
classes should also be updated.Steps to reproduce:
markAsXXX
functions.ng-XXX
andion-XXX
classes applied to the corresponding ion-item.ion-XXX
classes don'tRelated code:
Other information:
Ionic info: