The picture below shows my table where the data is dynamically set. E.g., it could have 2,3,4 ... columns.
My html code is below: <thead>
contains the title values, and tbody
contains the values that can be modified.
<table class="table-conf">
<thead>
<tr>
<th *ngFor="let data of jsonText[0]" style="text-align: center;">{{data}}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let data of jsonText; let i=index">
<ng-container *ngIf="i!=0">
<td class="padding-table" *ngFor="let dt of data; let j=index">
<input style="text-align: center;" [(ngModel)]="jsonText[i][j]">
</td>
</ng-container>
</tr>
</tbody>
</table>
Below is an example of jsonText
variable that I iterated:
jsonText Array(6)
0: (2) ["Task", "Hours per Day"]
1: (2) ["Work", 11]
2: (2) ["Eat", 2]
3: (2) ["Commute", 2]
4: (2) ["Watch TV", 2]
5: (2) ["Sleep", 7]
The issue is: when I try to modify an element in the table, I can modify just one character at a time. For example: If I want to change "Eat"
to "Lunch"
, I need to delete "Eat"
, then write L
, click again on the input, write u
, click again, etc...
Could anyone help me, please?
As correctly said in other answer, When you bind jsonText
to ngModel
then ngFor
re-evaluate and you lose focus out of input.
and when you do [(ngModel)]="dt"
then ngModel can't bind to dynamically created variable.
So you face this issue.
So to make it work:
(a) you have to apply trackBy
function to your ngFor
, Read
So in HTML add trackBy
function, and do binding as [(ngModel)]="data[j]
, Like :
<tr *ngFor="let data of jsonText; let i=index">
<ng-container *ngIf="i!=0">
<td class="padding-table" *ngFor="let dt of data; let j=index; trackBy:customTrackBy">
<input style="text-align: center;" [(ngModel)]="data[j]">
</td>
</ng-container>
</tr>
(b) and in your component add the function and track the index.
customTrackBy(index: number, obj: any): any {
return index;
}