4

I have a PrimeNG table which cells are editable. When I edit the value of the input text field the table model does not change. How do I make the table model bind to the input text?

Here is my code:

<p-dataTable [value]="data" [editable]="true">
    <p-column>
        <template pTemplate type="body" let-row="rowData">
            <custom-input [(inputModel)]="row.value"></custom-input>
        </template>
    </p-column>
</p-dataTable>

custom-input.html

<input #inputText pInputText type="text" [(ngModel)]="inputModel" />

custom-input.ts

export class ValidationInputComponent implements OnInit {
    @Input() inputModel: Object;

    constructor() {
    }

    ngOnInit() {
    }
}
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
myanmar
  • 81
  • 1
  • 2
  • 11
  • Is there a reason you are having an external custom-input.html? I do not know if it helps, but you could try to write the `` directly instead of referring to another html file. – John Jan 31 '17 at 07:37
  • Yes, you are right. Without the external custom component everything works fine. But I want to have a custom component, because it has some other css features unlike the normal input field. And it so often used in my project. – myanmar Jan 31 '17 at 07:45
  • What do you mean by *table model does not change* ? :) – AT82 Jan 31 '17 at 07:52
  • For example, I have some values, let say A, B, C (3 rows). And I change/edit the first one to ABC (A->ABC). Then when I click to save, it doesn't save (ABC, B, C) but (A, B, C) - the old values. – myanmar Jan 31 '17 at 07:57

2 Answers2

0

You need to emit the values to your parent, parent won't get the notification for change automatically. You need to use Output for this purpose.

So in your child, do this:

<input pInputText type="text" [(ngModel)]="inputModel" (ngModelChange)="emitChange()" />

Where we call a method when changes are made on the input. That method then emits the change to the parent.

@Output() inputModelChange: EventEmitter<any> = new EventEmitter<any>();

emitChange() {
  this.inputModelChange.emit(this.inputModel)
}

For two-way binding we use the same inputModel as in declared as Input, but just add the suffix Change, this means that the values in parent and child will be matched.

and here's a working plunker

AT82
  • 71,416
  • 24
  • 140
  • 167
  • myanmar, did this answer, or the other answer help? If so, please consider accepting one :) – AT82 Feb 06 '17 at 11:05
0

Instead of passing row.value to your inputModel, pass the whole row instead:

<p-dataTable [value]="data" [editable]="true">
    <p-column>
        <template pTemplate type="body" let-row="rowData">
            <custom-input [(inputModel)]="row"></custom-input>
        </template>
    </p-column>
</p-dataTable>

Then, instead of setting [(ngModel)] to inputModel in your custom template, set it to inputModel.value.

<input #inputText pInputText type="text" [(ngModel)]="inputModel.value" />

Here is an Example Stackblitz illustrating that the input binds to the title using a custom component.

The reason this works is because row.value is probably a primitive (e.g. string, number, or boolean), and you cannot two-way-bind a primitive, only objects. (eg. var row:any = {value:"some value"}). Your custom-input takes in the whole object (the row), and manipulates the value property on it.

EDIT:

Removed Example Plunkr because the example did not load. Added new example in Stackblitz instead.

John
  • 10,165
  • 5
  • 55
  • 71