Reputation: 1236
I have built a dynamic form component in Angular 5 (based on documentation and example from https://angular.io/guide/dynamic-form).
Everything works find until I try and use angular material.
I have read a number of articles here on similar issues but they all seem to be because people were not importing correct modules or using mdInput or mat-Input instead of matInput. This is not the case for the problem I am experiencing.
Any thoughts or advice would be appreciated.
CHANGED CODE - BREAKS with ERROR -
*mat-form-field must contain a MatFormFieldControl.***
Dynamic Form Control Component Template
The only change I made to the working code below is to wrap the input field in and add the matInput attribute to the input field.
I am importing all the Material Modules (MatFormFieldModule and MatInputModule etc through a core module. All my material Inputs and Form Fields work in all other components in the application, so i don't believe the issues is that i am missing anything in the imports.
<div [formGroup]="form">
<div [ngSwitch]="control.controlType">
<mat-form-field>
<input matInput placeholder="{{control.label}}" *ngSwitchCase="'textbox'" [formControlName]="control.key" [id]="control.key"
[type]="control.type">
</mat-form-field>
<select [id]="control.label" *ngSwitchCase="'dropdown'" [formControlName]="control.key">
<option value="">Select {{control.label}}</option>
<option *ngFor="let opt of control.options" [value]="opt.key">{{opt.value}}</option>
</select>
</div>
<div class="errorMessage" *ngIf="!isValid">{{control.label}} is required</div>
</div>
CURRENT CODE - This works perfectly but I am not getting the angular material formatting
Selector
<mi-dynamic-form [controls]="controls"></mi-dynamic-form>
Dynamic Form Component
import { Component, Input } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
import { DynamicFormBase } from './dynamic-form-base';
@Component({
selector: 'mi-control',
templateUrl: './dynamic-form-control.component.html'
})
export class DynamicFormControlComponent {
// API
@Input() control: DynamicFormBase<any>;
@Input() form: FormGroup;
get isValid() { return this.form.controls[this.control.key].valid; }
}
Dynamic Form Component Template
<div [formGroup]="form">
<div [ngSwitch]="control.controlType">
<input placeholder="{{control.label}}" *ngSwitchCase="'textbox'" [formControlName]="control.key" [id]="control.key"
[type]="control.type">
<select [id]="control.label" *ngSwitchCase="'dropdown'" [formControlName]="control.key">
<option value="">Select {{control.label}}</option>
<option *ngFor="let opt of control.options" [value]="opt.key">{{opt.value}}</option>
</select>
</div>
<div class="errorMessage" *ngIf="!isValid">{{control.label}} is required</div>
</div>
Dynamic Form Control Component
import { Component, Input } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
import { DynamicFormBase } from './dynamic-form-base';
@Component({
selector: 'mi-control',
templateUrl: './dynamic-form-control.component.html'
})
export class DynamicFormControlComponent {
// API
@Input() control: DynamicFormBase<any>;
@Input() form: FormGroup;
get isValid() { return this.form.controls[this.control.key].valid; }
}
Dynamic Form Control Component Template
<div [formGroup]="form">
<!-- <label [attr.for]="control.key">{{control.label}}</label> -->
<div [ngSwitch]="control.controlType">
<mat-form-field>
<input matInput placeholder="{{control.label}}" *ngSwitchCase="'textbox'" [formControlName]="key" [id]="control.key"
[type]="control.type">
</mat-form-field>
<mat-select [id]="control.label" *ngSwitchCase="'dropdown'" [formControlName]="control.key">
<mat-option value="">Select {{control.label}}</mat-option>
<mat-option *ngFor="let opt of control.options" [value]="opt.key">{{opt.value}}</mat-option>
</mat-select>
</div>
<div class="errorMessage" *ngIf="!isValid">{{control.label}} is required</div>
</div>
Upvotes: 5
Views: 11566
Reputation: 769
I was able to get this working with both Angular Dynamic Forms and Material. Check out working stackblitz example here showing both Dynamic Forms and use of Material.
Upvotes: 4
Reputation: 1
I am sure you had solved this problem. The error of mat-form-field must contain a MatFormFieldControl. means the material components used are not imported. i.e. MatButtonModule needs to be imported when using mat-button directive.
Upvotes: 0