0

I'm new to Angular (we are using Angular 10) and I'm looking for something like ASP MVC Core's TagHelper asp-for and asp-validation-for in order to reduce copy'n'paste:

<div class="form-group">
    <label asp-for="FirstName"></label>
    <input asp-for="FirstName" class="form-control" />
    <span asp-validation-for="FirstName"></span>
</div>
<div class="form-group">
    <label asp-for="Gender"></label>
    <select asp-for="Gender" class="form-control" asp-items="Html.GetEnumSelectList<Gender>()"></select>
    <span asp-validation-for="Gender"></span>
</div>
<div class="form-group">
    <label asp-for="DateOfBirth"></label>
    <input asp-for="DateOfBirth" class="form-control" />
    <span asp-validation-for="DateOfBirth"></span>
</div>

The result is:

  • <label> has the correct for attibute.
  • <input>, <select>, ... have the correct id, name attribute and the correct type, validation attributes are driven by the model ([Required], [StringLength(20)], [EmailAddress], ...)
  • the validation <span> has default messages or from [Required(ErrorMessage ="Your first name is required")]
  • all labels (and especially enum values) are driven by the model ([Display(Name = "Intersex")])

Simple form in ASP MVC Core

<div class="form-group">
    <label for="FirstName">Your first name</label>
    <input class="form-control input-validation-error" type="text" data-val="true"
        data-val-required="Your first name is required" id="FirstName" name="FirstName" value="Marcel"
        aria-describedby="FirstName-error" aria-invalid="true">
    <span class="text-danger field-validation-error" data-valmsg-for="FirstName" data-valmsg-replace="true"><span
            id="FirstName-error" class="">Your first name is required</span></span>
</div>
<div class="form-group">
    <label for="Gender">Your gender</label>
    <select class="form-control valid" data-val="true" data-val-required="The Your gender field is required."
        id="Gender" name="Gender" aria-describedby="Gender-error" aria-invalid="false">
        <option selected="selected" value="0">Male</option>
        <option value="1">Female</option>
        <option value="2">Intersex</option>
    </select>
    <span class="text-danger field-validation-valid" data-valmsg-for="Gender" data-valmsg-replace="true"></span>
</div>
<div class="form-group">
    <label for="DateOfBirth">Your are born at</label>
    <input class="form-control valid" type="date" data-val="true"
        data-val-required="The Your are born at field is required." id="DateOfBirth" name="DateOfBirth"
        value="1992-02-09" aria-describedby="DateOfBirth-error">
    <span class="text-danger field-validation-valid" data-valmsg-for="DateOfBirth"
        data-valmsg-replace="true"></span>
</div>

What's the best replacement? Directives?

Marcel
  • 1,002
  • 2
  • 16
  • 37

1 Answers1

0

Some time ago I use a component. gone from this SO

Improve it a few:

@Component({
  selector: 'app-error',
  template: `
    <small class="form-text text-danger" *ngIf="isInvalid" >
       <ng-content></ng-content>
    </small>
`
})
export class ErrorComponent {

  get isInvalid() {
    const control = this.form.form.get(this.controlName);
    return control.touched && control.invalid && (this.error ? control.errors[this.error] : true);
  }
  constructor(@Optional() @Host() private form: FormGroupDirective,
    @Attribute("controlName") private controlName,
    @Attribute("error") private error) { }


}

You use, e.g.

    <!--if your FormControl has an unique validator-->
    <div class="form-group">
      <label for="name">Name:</label>
      <input class="form-control" name="name" formControlName="Name">
      <app-error controlName="Name">The name is mandatory</app-error>
    </div>

    <!--if your FormControl has severals validators-->
    <div class="form-group">
      <label for="email">e-mail:</label>
      <input class="form-control" name="email" formControlName="email">
      <app-error controlName="email" error="required">Email is mandatory.</app-error>
      <app-error controlName="email" error="email">Email mal formatted.</app-error>
    </div>

I suppose you can improve even more.

You can also take a look to this Netanel Basal amazing article about "Make Your Angular Form’s Error Messages Magically Appear"

Eliseo
  • 50,109
  • 4
  • 29
  • 67