mat-select required validation not working

68.3k Views Asked by At

I have the following code

<form #createForm="ngForm">
 <mat-form-field>
   <mat-select placeholder="Favorite food"
      matInput
     [ngModel]
     food="food"
     #food="ngModel" required>
    <mat-option *ngFor="let food of foods" [value]="food.value">
      {{ food.viewValue }}
    </mat-option>
   </mat-select>
</mat-form-field>
</form>
<button [disabled]="!createForm.valid">submit</button>

Since I want the "selection" is a required field, the "submit" button should be disabled when the form is rendered. However, the "submit" button is enabled when the form is displayed. What is the problem?

7

There are 7 best solutions below

1
On

This works for me when I (a) use a name attribute and (b) use the two-way ngModel binding syntax.

i.e. Instead of this

<mat-select placeholder="Favorite food" matInput [ngModel] food="food" #food="ngModel" required>

use this:

<mat-select name="food" placeholder="Favorite food" [(ngModel)]="food" required>

0
On

Look at danger89's comment under your original question. You are missing the name attribute. E.g:

<form #createForm="ngForm" (ngSubmit)="submitFunction(createForm)">
      <mat-form-field>
          <mat-select 
            placeholder="Favorite food"
            ngModel
            name="food"
            required
          >
            <mat-option *ngFor="let food of foods" [value]="food.value">
              {{ food.viewValue }}
            </mat-option>
          </mat-select>
      </mat-form-field>
      <button type="submit" [disabled]="!createForm.valid">submit</button>
  </form>

Because of the name attribute, your food.value can now be found at createForm.value.food when submitting the form.

0
On

This worked for me: Import ReactiveFormsModule in you app module

import { ReactiveFormsModule } from '@angular/forms';

and add its dependency in @NgModule decorator

6
On

for validation in angular 5 use reactive forms. refer this

*** componenet.ts *******

import { FormControl, Validators, FormBuilder, FormGroup, ReactiveFormsModule, NgForm } from '@angular/forms';

export class Test implements OnInit{
foodform:FormGroup;
 constructor(){}

ngOnInit() {
// create form group of controls 
 this.foodform = new FormGroup({
   favoriteFood: new FormControl('', [Validators.required])
 });
}
}

**** Component.html************

   <form #createForm="ngForm" [formGroup]="foodform ">
     <mat-form-field>
       <mat-select placeholder="Favorite food"
          matInput
         [ngModel]
         food="food"
         #food="ngModel"  formControlName="favoriteFood">
        <mat-option *ngFor="let food of foods" [value]="food.value" >
          {{ food.viewValue }}
        </mat-option>
       </mat-select>
      <mat-error *ngIf="foodform.controls['favoriteFood'].hasError('required') && foodform.controls['favoriteFood'].pristine">
                Required Message
      </mat-error>
    </mat-form-field>
    </form>

use [formGroup] and formControlName in your html form.

0
On

The only way required field validation works on a mat-select is by using reactive form validation. Just import the respective components in typescript file:

import {FormControl, Validators} from '@angular/forms';

HTML file :

Remove your ngModel reference

<mat-form-field>
   <mat-select placeholder="Favorite food"
      matInput [formControl]="foodControl"     
     required>
    <mat-option *ngFor="let food of foods" [value]="food.value">
      {{ food.viewValue }}
    </mat-option>
   </mat-select>
</mat-form-field>

This works for the required field validation. If you wanted to validate more probably you will end up accessing the form in the typescript file. Its weird that there is no option to do form validation, this is the only way i found to make it work.

0
On

I don't know what I'm doing wrong but I can't get any solution to work using Ang8 + Material8 and a multi-select while using a FormGroup and a FormControl. I ended up doing the following as a workaround.

First I added a tag to the mat-select, #thisselect

Then I tested the value of the tag for zero length in the submit button

<form [formGroup]="bypartForm" (ngSubmit)="onSubmit()">
            <mat-form-field [hideRequiredMarker]="true">
                <mat-select #thisselect placeholder="Brands" formControlName="brands"
                    (selectionChange)="selectChanged($event)" multiple required>
                    <mat-option *ngFor="let brand of brandList" [value]="brand.name">{{brand.name}}</mat-option>
                </mat-select>
            </mat-form-field>
            <mat-form-field [hideRequiredMarker]="true">
                <input matInput autocomplete="off" placeholder="Part#" formControlName="part" required>
            </mat-form-field>
            <div class="form-buttons">
                <button mat-raised-button color="primary" type="submit" [disabled]="!bypartForm.valid || (thisselect.value != undefined && thisselect.value.length == 0)">Submit</button>
            </div>
        </form>
0
On

I had same problem like you, and ReactiveForms is not a valid solution for me. I solved it by adding ngModel AND value to the mat-input, in addition to what is mentioned above, the attribute name is very important, your code would end like this:

<form #createForm="ngForm">
 <mat-form-field>
   <mat-select placeholder="Favorite food"
      matInput
     [(ngModel)]="yourResult.foodId"
     [(value)]="yourResult.foodId"
     name="foodselect"
     required>
    <mat-option *ngFor="let food of foods" [value]="food.foodId">
      {{ food.viewValue }}
    </mat-option>
   </mat-select>
   <mat-error 
   *ngIf="createForm.controls['foodselect'].hasError('required')">
   This is required
 </mat-error>
</mat-form-field>
</form>
<button [disabled]="!createForm.valid">submit</button>