1
votes

There are multiple sibling component with different NgForm (template-driven forms) inside each of them. All of them are wrapped with a parent component. Parent component has validation button. I need to validate certain child NgForm within click event on the button on a parent component.

What approaches to solve this would you propose?

// Parent template
<child id="0"></child>
<child id="1"></child>

// Parent component
validateChild(id: number) {
  // need somehow reach child component NgForm with a particular id
}

// Child Component template
<form #myForm="ngForm">...</form>

// Child Component template
@ViewChild('myForm') 
public myForm: NgForm;

When I am saying validation - I mean referring to following:

Object.keys(form.controls).forEach(key => {
   form.controls[key].markAsTouched();
})

I was thingking about following approach:

// Parent component
stages = [
  {
    validated: false
  },
  {
    validated: false
  },
]
// Parent component view
<child id="0" [validate]="stages[0].validated"></child>
<child id="1" [validate]="stages[1].validated"></child>

// Child component
@Input()
public set validate(value: boolean) {
  if (value === true)
  Object.keys(this.myForm.controls).forEach(key => {
     this.myForm.controls[key].markAsTouched();
  })
}

But I don't really like it..Probably there is a better approach. Because with this one without extra child EventEmitter I can't check whether form is valid or not

2

2 Answers

1
votes

If you want to have multiple forms for grouping, but not separate submit, then you could use FormGroup to track a related set of controls.

So you can validate child components like that:

@Component({
  selector: 'my-app',
  template: `
    <form [formGroup]="reactiveFormGroup">
      <input formControlName="foobar" />
      <my-component **[group]="reactiveFormGroup"**></my-comp>
    </form>

    form value: {{ reactiveFormGroup.value | json }}
  `
})
export class AppComponent { 
  reactiveFormGroup = new FormGroup({
    foo: new FormControl('default foobar'),
    bar: new FormControl('default foobar2')
  });
}

Child component code, e.g. my-component

@Component({
  selector: 'my-component',
  template: `
    <div [formGroup]="group">
      <input   [formControlName]="'foobar2'" />
    </div>
  `
})
export class MyComponent { 
  @Input() group: FormGroup;
}
0
votes

I have faced similar kind of issue, then I am following below approach

Parent Component

  @ViewChild(FirstChidComponent)
  public fChild: FirstChidComponent;

  validateChild(id: number) {
    console.log(this.fChild.myForm);
  }

you can access form values of the childComponent like this.fChild.myForm.

you can also do the validation for the child Form

 form.controls[controlName].markAsTouched();