Building Dynamic Form Validation in Angular 5 with Template-Driven Forms

I am dynamically generating form fields using the ngFor directive, with each field having a unique name attribute. However, I am facing challenges when it comes to validating these fields. Here is an example of my code:

<div *ngFor="let dimension of lstShippingDimensions; let i = index" class="dimension-item">
        <input type="text" name="units-{{i}}" [(ngModel)]="dimension.units" 
        class="first-f" placeholder="# of units" required>
        <input type="text" name="width-{{i}}" [(ngModel)]="dimension.width" 
        class="second-f" placeholder="W" required>
        <input type="text" name="height-{{i}}" [(ngModel)]="dimension.height" 
        class="third-f" placeholder="H" required>
        <input type="text" name="length-{{i}}" [(ngModel)]="dimension.length" 
        class="forth-f" placeholder="L" required>
        <select class="five-f" name="unitType-{{i}}" [(ngModel)]="dimension.unitType" 
        required>
            <option>inches</option>
            <option>feet</option>
        </select>
        <div *ngIf="!units-{{i}}.valid && units-{{i}}.touched" class="text-danger text-left">
            <small *ngIf="units-{{i}}.errors.required">Field is required.</small>
        </div>
    </div>

Answer №1

Managed to resolve the issue by simply including #units="ngModel". It seems like Angular takes care of referencing within the ngFor loop automatically. The following code snippet is working flawlessly:

<div *ngFor="let dimension of lstShippingDimensions; let i = index" class="dimension-item">
    <input type="text" name="units-{{i}}" #units="ngModel" [(ngModel)]="dimension.units" class="first-f" placeholder="# of units" required>
    <input type="text" name="width-{{i}}" [(ngModel)]="dimension.width" class="second-f" placeholder="W" required>
    <input type="text" name="height-{{i}}" [(ngModel)]="dimension.height" class="third-f" placeholder="H" required>
    <input type="text" name="length-{{i}}" [(ngModel)]="dimension.length" class="forth-f" placeholder="L" required>
    <select class="five-f" name="unitType-{{i}}" [(ngModel)]="dimension.unitType" required>
        <option>inches</option>
        <option>feet</option>
    </select>
    <div *ngIf="!units.valid && units.touched" class="text-danger text-left">
        <small># of units is required.</small>
    </div>
</div>

Answer №2

Your illustration serves as a prime example of how reactive form handling can be implemented. I suggest utilizing form arrays and form groups for better structure:

<form formArrayName="formArray">
<div *ngFor="let dimension of lstShippingDimensions; let i = index" class="dimension-item" [formGroupName]="i">

        <input type="text" name="units-{{i}}" [formControlName]="'units'"
        class="first-f" placeholder="# of units" required>
        <input type="text" name="width-{{i}}" [formControlName]="'width'" 
        class="second-f" placeholder="W" required>
        <input type="text" name="height-{{i}}" [formControlName]="'height'" 
        class="third-f" placeholder="H" required>
        <input type="text" name="length-{{i}}" [formControlName]="'length'" 
        class="forth-f" placeholder="L" required>
        <select class="five-f" name="unitType-{{i}}" [formControlName]="'unitType'" 
        required>
            <option>inches</option>
            <option>feet</option>
        </select>
        <div class="text-danger text-left">
            <small *ngIf="formArrayName[i].errors.required">Field is required</small>
        </div>
    </div>
</form>

Upon review, it appears that your initial approach did not yield the desired outcome due to

!units-{{i}}.valid && units-{{i}}.touched"
not being passed to the template as expected. Utilizing a template variable might resolve this issue:

    <input type="text" name="height-{{i}}" [(ngModel)]="dimension.height" 
    class="third-f" placeholder="H" required #templateVar="ngForm">
   <div *ngIf="templateVar.valid && templateVar.touched" class="text-danger text-left">
        <small *ngIf="templateVar.errors.required">Field is required.</small>
    </div>

Please note that dynamically creating template variable names like #DynamicVar-{{i}} is not supported.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issue with Pagination in Angular 7: Functioning Error

I am having trouble with my pagination setup. I am struggling to understand how to properly pass this.total = res.totalPage; from the Component to the Service so that it can count the pages correctly. Currently, it is only displaying one page as shown in t ...

Incorporating ngrx/Store into a current Angular application

Currently, I am working on an Angular 7 project that consists of numerous components communicating with an API to update data. The constant refreshing of the data using setTimeout has made it quite overwhelming as all the components are pulling data from t ...

Tips for implementing curry and compose functions in Typescript 4

After diving into the world of variadic types, I was inspired to create something new. Now, I'm facing a challenge - how do I effectively utilize an array of functions? This is my initial attempt: function curry<T extends any[]>(fn: (...args: T ...

Issue with *ngIf on Nativescript not functioning properly on iOS

I am encountering a major issue in my project. The *ngIf directive I am using is functioning only on the Android platform and not on iOS. Here is the HTML code snippet: <GridLayout columns ="auto, auto" rows="*" (tap)="open()"> <StackLayout co ...

Troubleshooting the unexpected behavior of the shareReply() method in Angular version 15

Utilizing the same API across 3 components can lead to duplicate HTTP calls. To prevent this, I decided to cache the response using shareReply() from RxJs so it can be reused wherever needed. Here's how I implemented it: api-service.ts getUsers(): Ob ...

The modal template in Angular UI is not displaying properly with Bootstrap styling

I've been working on displaying a modal template when a row is selected on a table. The issue I'm facing is that upon clicking a row, a 2px thick black shadowed line appears, which seems to represent the modal but doesn't display its conten ...

What is the most efficient way to halt the pipe if the value of an HTML input element remains unchanged using RxJS?

I'm currently incorporating RxJS into my Angular 9 project. My goal is to bind a keyup event to an input field and trigger an HTTP request whenever the user types a new value. Here's the code snippet I have: fromEvent(this.inputBox.nativeElemen ...

New feature incorporated at the end of choices in MUI auto-suggest widget

Currently, I'm working on enhancing a category adder feature. Previously, I had limited the display of the "add category chip" to only appear for the no-options render scenario. However, I came across an issue where if there was a category like "softw ...

Side navigation in Angular is not causing the main content to shrink

In my layout, I have a container that includes two sidenavs and multiple tables in between them. When I toggle the left sidenav, instead of the expected behavior where the content shrinks to accommodate the sidenav, the tables get pushed to the right as if ...

Optimal method for accessing params and queryParams in Angular 2

Seeking insights on how to craft a route with information stored in its URL parameters. Here's an example of my route (app.routes.ts): {path: 'results/:id', component: MyResultsComponent}, How I navigate to the route : goToResultsPage(qu ...

Leverage Redux in Angular for account balance management

As I work on creating an app in Angular where users can make purchases and have the price deducted from their account balance, I've been delving into Redux. The scenario involves individual user accounts with independent balances and no interaction be ...

Managing two select fields in a dynamic Angular form - best practices

On my screen, I am dynamically creating elements using a reactive form. Specifically, I am creating cards with two selection fields each: https://i.sstatic.net/WUvQH.png Situation: When I add a card and choose a layout, the options for that specific layo ...

Ensuring Proper Tabulator Width Adjustment Across All Browser Zoom Levels

<div id="wormGearTabulatorTable" style="max-height: 100%; max-width: 100%; position: relative;" class="tabulator" role="grid" tabulator-layout="fitDataTable"><div class="tabulator-header" role="rowgroup"><div class="tabulator-header-co ...

Using FullCalendar within an Ionic3 framework powered by Angular 4

Is there a way to initialize fullCalendar in an event (such as a click) on Ionic 3, using Angular 4? This code works when the calendar options are set in a variable: calendarOptions: Object = { fixedWeekCount: true, editable: true }; However, ...

An extensive array of consequences and impacts tailored for a particular entity

As my Angular application continues to grow in size, the number of actions and effects also increases. How should I manage the growing action/effect files for a specific entity? I have attempted to separate actions into multiple files, but encountered an ...

Best practice for entering events in callback

Recently, I delved into Angular because I anticipate needing to use it down the line. My current focus is on studying components communication, particularly from child to parent. I came across various methods of achieving this. In each example, the ChildC ...

The angular.json file contains a script and a styles property

After encountering issues with adding styles and scripts to my angular.json file, I discovered that neither Bootstrap nor other scripts were taking effect. It turns out there are two places where you can define scripts and styles in the angular.json file a ...

"What are the necessary components to include in UserDTO and what is the reasoning behind their

Presenting the User entity: package com.yogesh.juvenilebackend.Model; import jakarta.annotation.Generated; import jakarta.persistence.*; import lombok.*; @Entity @Getter @Setter @NoArgsConstructor @AllArgsConstructor @RequiredArgsConstructor public class ...

First, download a npm package and integrate it into TSX files

Hello all, I am currently working on my very first project using React, Typescript, and ASP.NET Core. As a beginner in this technology stack, I seek your patience and understanding as I encounter challenges along the way. Right now, I'm facing an issu ...

Validation of form fields in Angular 2 using custom data attributes

Currently, I am working on implementing form validation in Angular 2 for an add product form. The form allows users to add a product to a specific store's inventory. One of the requirements is to validate that the price of the product is higher than t ...