Disable submit form when form invalid Angular + Material

11,418

Solution 1

it is necessary to instantiate a form in class, something like this

flagForm: FormGroup;

Solution 2

Please correct the syntax for disable in angular

 <button mat-button type="submit" [disabled]="!flagForm.valid" color="primary" class="btn btn-accent m-btn m-btn--air m-btn--custom">Submit</button>

Solution 3

Besides declaring a FormGroup in the class as @tihoroot mentioned, you might want to get an instance of the formControl in the class definition like so:

get flagFormControl() { return this.flagForm.get('flagFormControl'); }

Otherwise Angular cannot find an instance of the required field.

Share:
11,418

Related videos on Youtube

buzibuzi
Author by

buzibuzi

Updated on June 04, 2022

Comments

  • buzibuzi
    buzibuzi almost 2 years

    Im building a form using Angular 5.1.1 /Typescript 2.4.2 + Material 5 with sat-popover library

    Trying to disable submit button while input is invalid without success. am using the Material Input validation example

    validation works and i get an error message, but button is not disabled and form is been submitted with an empty value. i can't figure out how to use the right condition to disable the button while input is invalid. have tried

    ng-disabled="!flagForm.valid"
    

    and

    ng-disabled="flagForm.$invalid"
    

    when using

    [disabled]="!flagForm.valid"
    

    i get 'TypeError: Cannot read property 'valid' of undefined'

    none of them seem to work. what am i missing ? here is the full code.

       import { Component, Input, Optional, Host } from '@angular/core';
        import { FormControl, FormGroupDirective, NgForm, Validators} from '@angular/forms';
        import { SatPopover } from '@ncstate/sat-popover';
        import { filter } from 'rxjs/operators/filter';
        import { ErrorStateMatcher} from '@angular/material/core';
    
        /** Error when invalid control is dirty, touched, or submitted. */
        export class MyErrorStateMatcher implements ErrorStateMatcher {
          isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
            const isSubmitted = form && form.submitted;
            return !!(control && control.invalid && (control.dirty || control.touched || isSubmitted));
          }
        } 
    
        @Component({
          selector: 'inline-edit',
          styleUrls: ['inline-edit.component.scss'], 
          template: `
            <form (ngSubmit)="onSubmit()" name="flagForm" novalidate>
              <div class="mat-subheading-2">Submit Your flag</div>
    
              <mat-form-field>
                <input matInput maxLength="140" name="flag" [(ngModel)]="flag" [formControl]="flagFormControl"
                   [errorStateMatcher]="matcher">
                <mat-hint align="end">{{flag?.length || 0}}/140</mat-hint>
                <mat-error *ngIf="flagFormControl.hasError('required')">
                  Flag is <strong>required</strong>
                </mat-error>        
              </mat-form-field>
    
              <div class="actions">
                <button mat-button type="button" color="primary" (click)="onCancel()" class="btn btn-secondary m-btn m-btn--air m-btn--custom">CANCEL</button>
                <button mat-button type="submit" ng-disabled="!flagForm.valid" color="primary" class="btn btn-accent m-btn m-btn--air m-btn--custom">Submit</button>
              </div>
            </form>
          `
        })
        export class InlineEditComponent {
    
          flagFormControl = new FormControl('', [
            Validators.required
          ]);
    
          matcher = new MyErrorStateMatcher();
    
          /** Overrides the flag and provides a reset value when changes are cancelled. */
          @Input()
          get value(): string { return this._value; }
          set value(x: string) {
            this.flag = this._value = x;
          }
          private _value = '';
    
          /** Form model for the input. */
          flag = '';
    
          constructor(@Optional() @Host() public popover: SatPopover) { }
    
          ngOnInit() {
            // subscribe to cancellations and reset form value
            if (this.popover) {
              this.popover.closed.pipe(filter(val => val == null))
                .subscribe(() => this.flag = this.value || '');
            }
          }
    
          onSubmit() {
            if (this.popover) {
              this.popover.close(this.flag);
            }
          }
    
          onCancel() {
            if (this.popover) {
              this.popover.close();
            }
          }
        }
    
    • Harry Ninh
      Harry Ninh about 6 years
      It's [disabled]
    • buzibuzi
      buzibuzi about 6 years
      i tried that too.. i get 'TypeError: Cannot read property 'valid' of undefined'
  • buzibuzi
    buzibuzi about 6 years
    oh yes, i tried that too.. i get 'TypeError: Cannot read property 'valid' of undefined'