0

Please assist . I have the following table in stackblitz or stackblitz 2. The component of the table is as follows :

export class AppComponent {
   gender = [
      { id: 1, value : 'Female' },
      { id: 2, value : 'Male' }
    ];

   age = [
    { id: 1, value: 'Adults' },
    { id: 2, value: 'Children' },
    { id: 3, value: 'Creatures' },
    { id: 5, value: 'Youth' }
    ];

  color = [
    { id: 1, value: 'Black' },
    { id: 2, value: 'White' },
    { id: 3, value: 'Brown' },
  ];
}

The View of the table is as follows :

      <div *ngFor="let gender of gender; let g = index;">
        <table class="table-bordered">
          <tr>
            <td>
              <span>{{gender.value}}</span>
            </td>
            <td>
              <table class="table-bordered">
                <tr *ngIf="g === 0">
                  <td>Age</td>
                  <td *ngFor="let color of color; let r = index;">{{ color.value }}</td>
                </tr>
                <tr *ngFor="let age of age; let a = index;">
                  <td>{{ age.value }}</td>
                  <td>
                    <input [id]="" type="text" #black />
                  </td>
                  <td>
                    <input [id]="" type="text" #white />
                  </td>
                  <td>
                    <input [id]="" type="text" #brown/>
                  </td>
                </tr>
              </table>
            </td>
          </tr>
        </table>
      </div>

I can get data from the view to the component using ViewChildren like @ViewChildren(brown) brown: QueryList<elementRef>; since i added #brown. According to angular doc using ElementRef can result to some security risks.

Question: How can get data from component to view when i have such a table and is ther a better way to get data from the view to the component without using ViewChildren or ViewChild ?

If i have to introduce reactive forms to the table how can i implement it ?

Your help is much appreciated. Thank You.

1 Answer 1

1

Hey I managed to get your code working. I had to use ReactiveForms. Here is the link https://angular-multiple-forms.stackblitz.io. https://stackblitz.com/edit/angular-multiple-forms?file=src%2Fpolyfills.ts Here is the code itself.

app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
import { AppComponent } from './app.component';

@NgModule({
  imports:      [ BrowserModule, FormsModule, ReactiveFormsModule ],
  declarations: [ AppComponent ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

app.component.ts

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms' ;

@Component({
 selector: 'my-app',
 templateUrl: './app.component.html',
 styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit  {
   beneficiary: any[];
   validationForm:any;
   gender = [
      { id: 1, value : 'Female' },
      { id: 2, value : 'Male' }
    ];

  age = [
    { id: 1, value: 'Adults' },
    { id: 2, value: 'Children (6-17)' },
    { id: 3, value: 'Creatures' },
    {
      id: 4,
      value: 'Early Childhood (0-5)'
    },
    { id: 5, value: 'Youth (18-35)' }
  ];

  color = [
    { id: 1, value: 'Black' },
    { id: 2, value: 'White' },
    { id: 3, value: 'Brown' },
  ];

 constructor(private formBuilder: FormBuilder) {}

 ngOnInit() {
  this.validationForm = this.formBuilder.group({
  items: this.formBuilder.array(
    [this.buildForm()],
  )});
  this.initForm();
 }

 public initForm(): void{
  let formsCount = this.gender.length * this.age.length;
  for (let i= 1; i < formsCount; i++){
    this.validationForm.get('items').push(this.buildForm())
  }
 }

 public buildForm(): FormGroup {
  return this.formBuilder.group({
    black: this.formBuilder.control({value:'Me',disabled: false}, 
   [Validators.required]),
    white: this.formBuilder.control({value:'You',disabled: false}, [Validators.required]),
    brown: this.formBuilder.control({value:'Her',disabled: false}, 
   [Validators.required])
  });
 }

 public onSubmit(): void{
  let formData = this.validationForm.value.items;
  console.log(formData);
 }

}

app.component.html

          <div *ngFor="let gender of gender; let g = index;">
        <table class="table-bordered">
          <tr>
            <td>
              <span>{{gender.value}}</span>
            </td>
            <td>
              <table class="table-bordered">
                <tr *ngIf="g === 0">
                  <td>Age</td>
                  <td *ngFor="let color of color; let r = index;">{{ color.value }}</td>
                </tr>
                <tr *ngFor="let age of age; let a = index;">
                  <form (ngSubmit)="onSubmit()" [formGroup]="validationForm">
                    <fieldset formArrayName="items">
                      <div class="form-group" [formGroup]="validationForm.get('items').controls[a]">
                      <td>{{ age.value }}</td>
                      <td>
                        <input formControlName="black" [id]="" type="text"/>
                      </td>
                      <td>
                        <input formControlName="white" [id]="" type="text"/>
                      </td>
                      <td>
                        <input formControlName="brown" [id]="" type="text"/>
                      </td>
                      </div>
                    </fieldset>
                  </form>

                </tr>
              </table>
            </td>
          </tr>
        </table>
        <button (click)="onSubmit()" type="button">Submit</button>
      </div>
Sign up to request clarification or add additional context in comments.

8 Comments

managed to view the code. does that mean i have to add a Submit button inside the table to execute the onSubmit function
Thank you for the code, now the question is how can i get the data back to the view. lets say i want do a preview( or getting data from the database using http).
What do you exactly plan to do ? If you are trying to populate the form with data it is simple. In the buildForm() function you just add that value to the value attribute
You may add a submit button or not. It depends only on what you are planning to do. It two way binding so that data will always be the latest update.
Thanks for the response and update, is the a way to make the value me not to repeat to all black formControlName inputs but show to one input either the Creatures or Youth row. The reasoning i'm asking is the user will capture the data and might not add data to all inputs , so i wanted to add a save as draft button, then later depending what a user has added the form should populate the data and allow the user to continue...don't know if its possible when i have such table.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.