Reputation: 35
I'm working on an Angular project using Angular Material component library.
I'm making a form which has multiple fields and everything works, except that it just looks a little funny:
What's supposed to happen here is that a user chooses a number of files he wants and it generates that amount of fields (in this example 2), user fills the input fields and submits.
For some reason there is a input field inside of my input field and I can't figure out what I'm missing. I'm able to correctly get data from the input field, the form works correctly, I just don't want to have a field inside a field.
HTML:
<div class="config-wrapper">
<mat-form-field id="config-field">
<div>
<mat-label>Number of configuration files</mat-label>
</div>
<mat-select formControlName="numberOfConfigPaths" (selectionChange)="onConfigChange($event)"
[ngClass]="{ 'is-invalid': isSubmitted && formControls.numberOfConfigPaths.errors }">
<option value=""></option>
<mat-option *ngFor="let number of configNumber" [value]="number.value">{{number.value}}</mat-option>
</mat-select>
</mat-form-field>
<button type="button" mat-icon-button aria-label="Configuration path folder open" id="config-path-button"
(click)="openConfigDialog();">
<mat-icon>folder_open</mat-icon>
</button>
</div>
<div *ngIf="isSubmitted && formControls.numberOfConfigPaths.errors" class="invalid-feedback">
<div *ngIf="formControls.numberOfConfigPaths.errors.required">
Number of configuration files is required
</div>
</div>
<mat-form-field [formGroup]="cfg" class="example-full-width"
*ngFor="let cfg of configPaths.controls; let i = index">
<div class="config-container">
<mat-form-field id="config-field">
<input type="text" matInput placeholder="Configuration file {{i+1}}"
formControlName="configPath"
[ngClass]="{ 'is-invalid': isSubmitted && cfg.controls.configPath.errors }"
[matAutocomplete]="comparisonAutoGroup" />
<mat-autocomplete #comparisonAutoGroup="matAutocomplete">
<mat-option *ngFor="let name of availableConfigFiles" [value]="name">
{{name}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</div>
<div *ngIf="isSubmitted && cfg.controls.configPath.errors" class="invalid-feedback">
<div *ngIf="cfg.controls.configPath.errors.required">Path is required</div>
</div>
</mat-form-field>
Relevant typescript:
ngOnInit() {
this.checkForm = this.formBuilder.group({
numberOfConfigPaths: [1, Validators.required],
configFilePaths: new FormArray([])
});
.
.
.
}
get formControls() { return this.checkForm.controls; }
get configPaths() { return this.formControls.configFilePaths as FormArray; }
onConfigChange(e) {
const numberOfConfigPaths = e.value || 0;
if (this.configPaths.length < numberOfConfigPaths) {
for (let i = this.configPaths.length; i < numberOfConfigPaths; i++) {
this.configPaths.push(
this.formBuilder.group({
configPath: ['', Validators.required]
}
));
}
} else {
for (let i = this.configPaths.length; i >= numberOfConfigPaths; i--) {
this.configPaths.removeAt(i);
}
}
}
While debugging I tried to isolate the field and make it only display 1 field (just copied the element somewhere else) and it worked fine, but I need to make it display multiple fields.
I'm stuck with finding the solution. I will reply if you need any additional info.
EDIT: Stackblitz URL: https://stackblitz.com/edit/angular-7bcgcw
Upvotes: 1
Views: 1046
Reputation: 957
The problem in your code is that you have mat-form-field
twice for each of the form controls, that is why it shows like that. I have removed the inner mat-form-field
and now it looks ok. I have updated the solution to StackBlitz
It looks like this now:
Upvotes: 1