Cyril
Cyril

Reputation: 47

How to retrieve data entered by user in inputs table where row are dynamically added?

I try to retrieve data entered by user in inputs table where row are dynamically added. But I have to add a new array in the component.ts for each new line add dynamically in table to recover data using Two way data binding.

Here is my Html :

<tbody id="tbody">
    <tr>
        <td></td>
        <td *ngFor="let column of table.columns; let index = index; trackBy:trackByIndex;"><input [(ngModel)]="inputValue[index]" type="{{ column.type }}" name="cell" maxLength="{{ column.length }}" required="{{ column.nullable }}" value="{{ column.dataDefault }}"></td>
    </tr>
    <tr>
        <td></td>
        <td *ngFor="let column of table.columns; let i = index; trackBy:trackByIndex;"><input [(ngModel)]="inputValue2[i]" type="{{ column.type }}" name="cell" maxLength="{{ column.length }}" required="{{ column.nullable }}" value="{{ column.dataDefault }}"></td>
    </tr>
    <tr>
        <td></td>
        <td *ngFor="let column of table.columns"><input type="{{ column.type }}" name="cell" maxLength="{{ column.length }}" required="{{ column.nullable }}" value="{{ column.dataDefault }}"></td>
    </tr>
    <tr>
        <td></td>
        <td *ngFor="let column of table.columns"><input type="{{ column.type }}" name="cell" maxLength="{{ column.length }}" required="{{ column.nullable }}" value="{{ column.dataDefault }}"></td>
    </tr>
    <tr>
        <td></td>
        <td *ngFor="let column of table.columns" id="myCell"><input id="myInput" type="{{ column.type }}" name="cell" maxLength="{{ column.length }}" required="{{ column.nullable }}" value="{{ column.dataDefault }}"></td>
    </tr>
    <tr *ngFor="let dynamic of dynamicArray; let i = index;" id="myRow">
        <td id="deleteCell" (click)="deleteRow(i)">
            <img id="deleteIcon" src="../../assets/img/cancel.png" /><span>suppr</span>
        </td>
        <td *ngFor="let column of table.columns; let j = index; trackBy:trackByIndex;"><input [(ngModel)]="inputValue3[j]" type="{{ column.type }}" name="cell" maxLength="{{ column.length }}" required="{{ column.nullable }}" value="{{ column.dataDefault }}"></td>
    </tr>
    <tr>
        <td id="addCell" (click)="addRow()">
            <img id="addIcon" src="../../assets/img/add.png" /><span>ajouter</span>
        </td>
    </tr>
</tbody>

Here is my component.ts :

  export class DashboardComponent implements OnInit {
    table: Table;
    dynamicArray: Array<any> = [];
    newDynamic: any = {};
    inputValue: string[] = [];
    inputValue2: string[] = [];
    inputValue3: string[] = [];
}

Here is my results :

enter image description here

Upvotes: 0

Views: 31

Answers (1)

Alex Egli
Alex Egli

Reputation: 2064

I would recommend rethinking the structure of your DashboardComponent and your template. You probably want a header row on your table based on the columns in it, and a single array of row objects that you can add and remove objects from to add/remove rows from your UI. The KEY takeaway is that however your choose to structure your template and data, you need to have a unique name field on every input element!

See the angular guide/tutorial for more information: https://angular.io/start/forms

Here is a very rough example that should hopefully help give you some ideas:

export class DashboardComponent {
  table: Table; // assuming there is a name field on each table.column for the sake of the example
  rows: Array<any> = [];

  addRow() {
    const row = {};
    table.columns.forEach((column) => row[column.name] = 0);
    rows.push(row);
  }
}

NOTE: Having a unique name field on each input is key! That way each input value ends up uniquely identified to angular and it can assign the ngModel correctly. The example below is just one way to guarantee uniqueness.

<table>
  <thead>
    <tr>
      <th *ngFor="let column of table.columns">{{column.name}}</th>
    </tr>
  </thead>
  <tbody>
    <tr *ngFor="let row of rows; let i = index">
      <td *ngFor="let column of table.columns">
        <input name="{{column}}_{{i}}
          [(ngModel)]="row[column.name]"
        />
      </td>
    </tr>
    <tr>
      <td id="addCell" (click)="addRow()">
        Add
      </td>
    </tr>
  </tbody>
</table>

Upvotes: 1

Related Questions