0

I am trying to implement a dynamic row table where all the table cells are input fields. There is some preloaded data, but I am not able to add to the loaded data in the view. However add/ delete rows are working properly. I have tried ngModel and value but it's not working.

app.component.html:

    <table>
            <thead>
                <button (click)="onAddRow()" *ngIf="addForm.get('rows')">add row</button>
            </thead>
            <tbody>
                <tr *ngFor="let row of addForm.get('rows')?.controls;let index = index;">
          <!-- NOT WORKING with ngModel
          <td>name : <input [ngModel]="row.get('name')" [formControl]="row.get('name')"></td> -->
            <!-- NOT WORKING with value attribute
          <td>name : <input value="row.get('name')" [formControl]="row.get('name')">\</td> -->
          <td>
            name : <input  [formControl]="row.get('name')">
          </td>
          <td>
            description : <input [formControl]="row.get('description')">
          </td>
          <td>
            qty : <input [formControl]="row.get('qty')">
          </td>
          <td>
            <button (click)="onRemoveRow(index)">Remove</button>
          </td>
                </tr>
            </tbody>
        </table>

app.component.ts:

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

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  addForm: FormGroup;
  rows: FormArray;
  itemForm: FormGroup;

  constructor(private fb: FormBuilder) {
    this.addForm = this.fb.group({
      items: [null, Validators.required],
      items_value: ['no', Validators.required]
    });
    this.rows = this.fb.array([{
    "name": "Test Item",
    "description": "Dedsc",
    "qty": "q23"
  }]);

  }

  ngOnInit() {
    this.addForm.get("items").valueChanges.subscribe(val => {
      if (val === true) {
        this.addForm.get("items_value").setValue("yes");

        this.addForm.addControl('rows', this.rows);
      }
      if (val === false) {
        this.addForm.get("items_value").setValue("no");
        this.addForm.removeControl('rows');
      }
    });
  }

  onAddRow() {
    this.rows.push(this.createItemFormGroup());
  }

  onRemoveRow(rowIndex:number){
    this.rows.removeAt(rowIndex);
  }

  createItemFormGroup(): FormGroup {
    return this.fb.group({
      name: null,
      description: null,
      qty: null
    });
  }

}

My output: Current output

Expected output: Expected Output

Also putting one Stackblitz Example for better reference.

2 Answers 2

2

You don't need [ngModel] because you already working with reactive forms. These inputs are empty because you create each item form group with null values. If you have preloaded data you need to pass it as initial value for each control in createItemFormGroup method or update the value by methods setValue/patchValue of form array or appropriate form group.

Sign up to request clarification or add additional context in comments.

Comments

1

i am not sure if that will be exactly what you want, but check this one out: https://stackblitz.com/edit/dynamically-add-rows-k2lbkw

  • i replaced the formControl attribute with formControlName. Note the value property
<td>
     name : <input  formControlName="name" 
                   [ngModel]="row.get('name').value" >
</td>
  • added the name, description, qty to the form builder object.
    constructor(private fb: FormBuilder) {
        this.addForm = this.fb.group({
          items: [null, Validators.required],
          items_value: ['no', Validators.required],
          name: [null, Validators.required],
          description: [null, Validators.required],
          qty: [null, Validators.required]
        });
        this.rows = this.fb.array([]);
      }
  • and added some dummy values on the createItemFormGroup method

2 Comments

Thanks for the quick reply. The solution is fine, but just in case I have some previous values or an array of items inside the rows (formbuilder array), How do I use it? The functionality I require is I would load few data and list them in table and additionally people can add/ remove rows. On final submit, I will pass the rows array to API for update in backend.
I followed this example (ng-run.com/edit/BmjgZeJJqYSPfbDDh5Kq?layout=1) and was able to achieve what I wanted. But I am curious about what was the issue in the first place (as in my question).

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.