Form validation is an essential feature of the Angular2 template-driven sub form component

I'm currently working on a template-driven form that includes a group of inputs generated through an ngFor.

My goal is to separate this repeating 'sub-group' into its own child component. However, I'm encountering difficulties in ensuring that the parent ngForm recognizes and applies the validation rules from the child component.

Here's a simplified example illustrating the issue:

Parent Template:

<form #parentForm="ngForm">
    <input name="firstName" ngModel required>
    <input name="lastName" ngModel required>

    <child-component *ngFor="let child of children;"></child-component>
</form>

Child Template:

<div>
    <input name="foo" required ngModel>
    <input name="bar" required ngModel>
</div>

I've attempted to make the parent form recognize the required attributes set in the child inputs by placing the child within its own form and passing the instance of #parentForm to the child, followed by calling:

this.parentForm.addFormGroup(this.childForm.form)

Unfortunately, this approach hasn't yielded the desired results.

Alternatively, I've tried having the parent form fetch the ContentChildren of the sub forms and integrating each one into the main form. Yet, the validation still doesn't function as expected.

While aware that implementing ControlValueAccessor in the subcomponent could potentially solve the issue, I prefer not to go down that route as it would entail developing custom validators for existing validations such as required.

If you have any insights on how I can successfully incorporate a sub-form into the parent while leveraging the child's validation settings, your assistance would be greatly appreciated.

Answer №1

One way to potentially solve this issue is by enabling communication between child components and parent forms through additional controls:

child.component.ts

@Component({
  selector: 'child-component',
  template: `
   <div>
    <input name="foo" required ngModel>
    <input name="bar" required ngModel>
  </div>
  `
})
export class ChildComponent {
  @ViewChildren(NgModel) controls: QueryList<NgModel>;

  constructor(private parentForm: NgForm) { }

  ngAfterViewInit() {
    this.controls.forEach((control: NgModel) => {
      this.parentForm.addControl(control);
    });
  }
}

Check out the example on Plunker

Answer №2

To solve your issue, you can utilize property binding and @Input in the following manner:

<form #parentForm="ngForm">
    <input name="firstName" ngModel required>
    <input name="lastName" ngModel required>

    <child-component #parentForm.childForm="ngForm" [children]="kids"></child-component>
</form>

Implement the following steps to make it work:

  1. Create an input variable like this:

    @Input() kids:any[]=[];
    
  2. Update the template as shown below:

    <div *ngFor="let kid of kids;">
       <input name="bar" required [(ngModel)]="kid.bar"/>
    </div>
    

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

Tips for identifying when a tab has been reopened following closure?

There seems to be a problem with the JS state where it changes but then reverts back to its original state when the tab is closed and restored using cmd/ctrl + shift + t. Typically, data is fetched from the server via ajax using Vue's mounted() lifec ...

Using Blob to save CSV file on Safari

Here are the codes I am using to generate a download link for users to download a .csv file from my website. var link = document.createElement("a"); link.id = "csvDwnLink"; window.URL = window.URL || window.webkitURL; var csv = "\ufeff" + CSV, b ...

What's causing this issue in Angular?

In this scenario, there is a parent component and a child component communicating with each other. The parent component passes a method to the child component, which the child component then calls and sends its own instance back to the parent. However, wh ...

Having difficulty updating the state with editorState retrieved from the server in ReactJs when using draftJs

Incorporating a rich text editor into React using draftJs has been successful. The editorState data is converted to raw data, stringified, and sent to the server for rendering on the front end. However, I am facing challenges in updating the editorState ...

Struggling to align the image elements accurately

I am aiming to create a layout similar to the image displayed below. To be more specific, my goal is to scatter smiley faces randomly within a 500px area while also having a border on the right side of the area. However, with the current code I'm us ...

TypeScript issue encountered with parseInt() function when used with a numeric value

The functionality of the JavaScript function parseInt allows for the coercion of a specified parameter into an integer, regardless of whether that parameter is originally a string, float number, or another type. While in JavaScript, performing parseInt(1. ...

What causes the error message "No exported member 'ɵɵFactoryDeclaration' in @angular/core/core" to appear during project compilation?

I am facing an issue where the global Angular CLI version is 13.0.1 and the local version in my project is 10.2.3. Despite making changes to some components (without touching package.json), I encountered an error during the build step of my bitbucket pipel ...

Guide to showing the username on the page post-login

My MongoDB database is filled with user information. I'm looking to create a feature on the webpage that displays "Logged in as username here" at the top once users log in. My CSS skills are strong, but when it comes to JavaScript, I'm struggling ...

If I click on a different VueJS menu, make sure to close the current menu

When using a component menu, each item is displayed independently. However, I would like the open items to close automatically when I click on another item with the menu. I employ a toggle functionality on click to control the opening and closing of the c ...

Utilizing distinct useState for mapped elements

I am struggling to find a solution on how to pass specific useState states to respective mapped elements. export const Polska = () => { const [riverVisible, setRiverVisible] = useState(false) const [mountainVisible, setMountainVisible] = useState(fa ...

Prevent assigning values to rxjs observables recursively

I am seeking suggestions on how to enhance the code provided below. I will outline the issue and present my current solution, which I aim to refine. The code is written in Angular 4 (TS). herelistOfItems$: Observable<Array<Item>>; // Fetchin ...

"Resulting in 'undefined' due to an asynchronous function call

Encountering an issue with async method implementation. In my authServices, there is a loginWithCredential function which is asynchronous: async loginWithCredential(username, password){ var data = {username: username, password: password}; api.pos ...

Updating a .txt file using JavaScript

Is there a method on the client side to add text to a file called text.txt using JavaScript? In Python: f = open("text.txt","w") f.write("Hello World") f.close() The code snippet above would input "Hello World" into the text file. I am looking for a sim ...

Having trouble with clearTimeout and clearInterval functions not functioning properly?

Currently, I've set up a countdown using both setInterval and setTimeout functionalities, and it seems to be running smoothly. However, I encounter an issue when trying to stop the countdown upon clicking a certain button; it pauses only after complet ...

What is the proper way to confirm the authenticity of a captcha code

hey there, I'm struggling with my captcha code. The issue is that it still accepts wrong captchas when entered in the input box. Can someone guide me on how to validate the wrong captcha entry? Here's my form code: <p class="Captcha" style=" ...

Having a slight hiccup with pixel alignment and browser compatibility in my jQuery animation

To emphasize a specific paragraph element, I developed a JavaScript function that displays it above a darkened background. My approach involved using jQuery to generate an overlay and then duplicating the targeted paragraph element while positioning it ab ...

Error occurred while attempting to execute the method

Here's a MongoDB Mongoose query we're dealing with: sampleSchema.find({ $where: "expired <= " + (new Date()) }) .limit(9) // Problems may arise from here .sort({ postedDate: -1 }) .then((docs) => { console.log(&apos ...

Error: The function type 'Dispatch<SetStateAction<string>>' cannot be assigned to the type '(value: OptionValue) => void'

I recently dove into the world of integrating Typescript generics with React after reading this insightful article. I followed the code provided in the article, but encountered the following error: Type 'Dispatch<SetStateAction<string>>&ap ...

The latest error in the Next.js 13 app directory: React child is not valid (detected: [object Promise])

I am currently utilizing the new app directory feature in Next.js 13. Within my project, I have a page component located at app/page.tsx. This component contains the following code snippet: "use client"; import { useState } from "react" ...

Is it possible to incorporate Microdata from HTML5 into an XHTML Strict website while remaining compliant?

I have a website coded in XHTML 1.0 Strict and I am looking to incorporate Microdata for breadcrumbs so that Google can better understand them. Currently, my non-microdata marked-up breadcrumbs are structured like this: <ul> <li><a href= ...