I am trying to make a component that shows data in rows from TableData model,
export class TableData{
constructor(
public id: number,
public country: string,
public capital: string){ }
}
I have my data in the component like this,
tableData: TableData[] = [
new TableData(1, 'Canada','Ottawa'),
new TableData(2, 'USA','Washington DC'),
new TableData(3, 'Australia','Canberra'),
new TableData(4, 'UK','London')
];
Then in my component, I am creating a table like this,
<table>
<tbody>
<tr *ngFor="#row of tableData>
<td contenteditable='true'>{{ row.id }}</td>
<td contenteditable='true' (click)="onRowClick($event)">{{ row.country }}</td>
<td contenteditable='true'>{{ row.capital }}</td>
</tr>
</tbody>
<span>{{ tableData | json }}</span>
</table>
onRowClick(event){
console.log(event);
}
I am able to edit the data as I marked the <td>
element as 'contenteditable', but don't know how to save it or retrieve the updated values. I inspected 'event' data that's passed to onRowClick method, but couldn't retrieve the 'id' of row (it's empty. event.srcElement.id or event.target.id are both empty).
In short, I want to edit the table and see it update the tableData variable. Sorry for not asking it clearly the first time.
Any guidance on how to solve my problem is greatly appreciated!
Juts pass id
as flag along with your id then detect as per id clicked on the row of table here is example -
tableData: TableData[] = [
new TableData('Canada','Ottawa',1),
new TableData('USA','Washington DC',2),
new TableData('Australia','Canberra',3),
new TableData('UK','London',4)
];
PS - your code is throwing error here please correct here.
<tr *ngFor="#row of tableData>
should be changed with
<tr *ngFor="#row of tableData">
working demo here Plunker example
Update -
Try using (input)
event binding on the td
and get the updated text using event.target.outerText
. please check update plnukr.
<tr *ngFor="#row of tableData">
<td contenteditable='true' (input)="onRowClick($event, row.id)">{{ row.country }}</td>
<td contenteditable='true'>{{ row.capital }}</td>
</tr>
onRowClick(event, id){
console.log(event.target.outerText, id);
}
I was looking an answer to the same question. First, I got here. Later, I found amazing article with answer you was looking for.
Updated: I have udpated plunk as well as directive code to latest verstion of angular
Directive: contenteditableModel
<span contenteditable [(contenteditableModel)]="text"></span>
https://www.namekdev.net/2016/01/two-way-binding-to-contenteditable-element-in-angular-2/
https://plnkr.co/edit/SRLYoX5chNYJIpZ4iqsG?p=preview
import {
Directive,
ElementRef,
Input,
Output,
OnChanges,
EventEmitter,
HostListener,
SimpleChanges
} from '@angular/core';
/**
*
*/
@Directive({
selector: '[contenteditableModel]'
})
export class ContenteditableModelDirective implements OnChanges {
@Input('contenteditableModel')
public model: any;
@Output('contenteditableModelChange')
public update = new EventEmitter();
private _lastViewModel: any;
constructor(private elRef: ElementRef) {}
public ngOnChanges(changes: SimpleChanges): void {
if(this._lastViewModel !== changes['model'].currentValue){
this._lastViewModel = this.model;
this._refreshView();
}
}
@HostListener('blur')
public onBlur() {
var value = this.elRef.nativeElement.innerText;
this._lastViewModel = value;
this.update.emit(value);
}
private _refreshView() {
this.elRef.nativeElement.innerText = this.model;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With