I have a component.ts file:
import { Component } from "@angular/core";
import {
FormBuilder,
FormControl,
FormGroup,
Validators,
} from "@angular/forms";
import { FaIconLibrary } from "@fortawesome/angular-fontawesome";
import { fas } from "@fortawesome/free-solid-svg-icons";
@Component({
selector: "app-course-form",
templateUrl: "./course-form.component.html",
styleUrls: ["./course-form.component.scss"],
})
export class CourseFormComponent {
constructor(
public fb: FormBuilder,
public library: FaIconLibrary
) {
library.addIconPacks(fas);
}
profileForm = this.fb.group({
title: ["", [Validators.required, Validators.minLength(2)]],
description: ["", [Validators.required, Validators.minLength(10)]],
author: ["", [Validators.required, Validators.pattern(/^[a-zA-Z0-9 ]+$/)]],
duration: [0, [Validators.required, Validators.min(1)]],
});
courseForm!: FormGroup;
title = new FormControl("");
description = new FormControl("");
author = new FormControl("");
duration = new FormControl(0);
authors: any[] = [];
durationText: string = "";
submitted = false;
removeAuthor(author: string) {
this.authors = this.authors.filter((a) => a !== author);
}
getDurationFormatted(minutes: number): string {
const hours = Math.floor(minutes / 60);
const mins = minutes % 60;
return `${hours.toString().padStart(2, "0")}:${mins
.toString()
.padStart(2, "0")}`;
}
}
and html component:
<h2>Create / Edit Course</h2>
<form [formGroup]="profileForm">
<div class="app-plate">
<div class="course">
<h3>Main Info</h3>
<div class="form__control">
<label for="title">Title</label>
<input type="text" id="title" placeholder="Input text" />
<span
*ngIf="profileForm.invalid"
id="titleErrorMessage"
class="text-danger"
>Title is required.</span
>
</div>
<div class="form__control">
<label for="description">Description</label>
<textarea
id="description"
placeholder="Input text"
rows="4"
cols="5"
></textarea>
<span
*ngIf="profileForm.invalid && profileForm.value.description"
id="descriptionErrorMessage"
class="text-danger"
>Description is required.</span
>
</div>
<div class="separator"></div>
<h3>Authors</h3>
<div class="form__control">
<div class="course__flex">
<input type="text" id="author" placeholder="Input Author Name" />
<app-button
id="createAuthor"
button_text="Create author"
></app-button>
</div>
<span *ngIf="" id="authorErrorMessage"
>New author should contain only latin letters and numbers.</span
>
<div class="course__authors">
<ul class="authors-list">
<li
*ngFor="let author of authors; track: author"
class="authors-list-item"
>
Id: {{ author.id }}. Name: {{ author.name }}
<app-button button_text="Remove" (click)="removeAuthor(author)">
</app-button>
</li>
</ul>
</div>
</div>
<div class="separator"></div>
<h3>Duration</h3>
<div class="form__control">
<div class="course__flex">
<input
type="number"
id="duration"
placeholder="Input duration"
formControlName="duration"
/>
<div class="course__duration">
<strong> </strong>
hours
</div>
</div>
<span *ngIf="" id="durationErrorMessage" class="text-danger"
>Duration is required and must be greater than 0.</span
>
</div>
<div class="form__action"></div>
</div>
</div>
</form>
<div class="buttons-container">
<app-button button_text="Cancel"></app-button>
<app-button button_text="Create course"></app-button>
</div>
I want to show:
<span
*ngIf="profileForm.invalid "
id="titleErrorMessage"
class="text-danger"
>Title is required.</span
>
only when the input field was touched and is still invalid. Now the error is showed on the loaded fresh new form. How to do it?
following:
touched and valid using reactive forms in Angular
I tried using form control like:
<div class="form__control">
<label for="title">Title</label>
<input
type="text"
id="title"
placeholder="Input text"
[formControl]="title"
/>
<span
*ngIf="profileForm.invalid && profileForm.controls['title'].touched"
id="titleErrorMessage"
class="text-danger"
>Title is required.</span
>
</div>
But it didnt work.