Search code examples
cssangularformspseudo-class

How to mix pseudo class valid/invalid with Angular form control validator?


I'm using an Agular form control to control a "select" validity. When said "select" is invalid, class "ng-invalid" can be found on the "select". Class "ng-valid" is, when "select" is valid.

However, pseudo class remains ":valid" either way. The problem is I'm using a third party library for style which is based on pseudo classes to handle style.

Take a look at this example, https://stackblitz.com/edit/angular-xypbcc

I'd like that the pseudo class :invalid apply (and it's css style), when class is "ng-invalid", when select is empty. (I know I could add the required to the select element, but I actually have other validators in my real use case)

Thanks


Solution

  • the easy way is copy the .css of inactive to .ng-invalid

    A work-around is use setCustomValidity You can use a directive

    @Directive({
      selector: "[invalid]"
    })
    export class InvalidDirective implements OnInit, OnDestroy {
      subscription$: any;
      @Input("invalid") checkAtFirst: boolean = false;
      constructor(private control: NgControl, private el: ElementRef) {}
      ngOnInit() {
        this.subscription$ = this.control.statusChanges.subscribe(res => {
          this.el.nativeElement.setCustomValidity(res == "INVALID" ? "error" : "");
        });
        if (this.checkAtFirst && this.control.invalid)
          this.el.nativeElement.setCustomValidity("error");
      }
      ngOnDestroy() {
        this.subscription$.unsubscribe();
      }
    }
    

    The directive inject in the constructor the ngControl (the input) and the elementRef (the HTMLElement) and subscribe to statusChange. I use the input if you want to check at first

    So you use like

     <select invalid=true formControlName="fcselect">
    //or
     <select invalid formControlName="fcselect">
    

    You can see the example in the stackblitz