Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 - Edit table rows inline, then save the new data

Tags:

angular

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!

like image 786
scorpion35 Avatar asked Apr 24 '16 12:04

scorpion35


2 Answers

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);
  }
like image 176
Pardeep Jain Avatar answered Nov 27 '22 03:11

Pardeep Jain


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;
    }
}
like image 33
vorotech Avatar answered Nov 27 '22 05:11

vorotech