user1999324
user1999324

Reputation: 58

how to make selected row editable on click of edit button In angular 4

I have a table with select and select all check box , i want to make the selected row editable on select and click of edit button.

<tbody>
  <tr *ngFor='let row of rowData'>
    <td class="text-center">
      <input type="checkbox" />
    </td>
    <td>{{row.name}}</td>
    <td>{{row.email}}</td>
    <td>{{row.remark}}</td>
    <td>{{row.test1}}</td>
    <td>{{row.Test2}}</td>
    <td>{{row.Test3}}</td>
    <td>{{row.Test4}}</td>
    <td>{{row.Test5 }}</td>
    <td>{{row.Test6 }}</td>
  </tr>
</tbody>

Upvotes: 1

Views: 6945

Answers (4)

anonymous programmer
anonymous programmer

Reputation: 73

First thanks for asking and @Günter Zöchbauer for answering your answer gave me a hint!

So, my solution would be to create a new key in your iterating object (row). With input tag disabled and some css for that, or another approach would be adding two elements with *ngIf.

<tbody>
<tr *ngFor='let row of rowData'>
<td class="text-center">
  <input type="checkbox" [(ngModel)]="checkboxVal" (change)="checkboxChangeHandler(row)"/>
</td>
<td><input type="text" [disabled]="row.isEditable" [value]="row.name"/> 
</td>
<td>
<ng-container *ngIf="!row.isEditable">{{row.email}}</ng-container>
<ng-container *ngIf="row.isEditable"><input type="text" [value]="row.email"/></ng-container>
</td>
<td>{{row.remark}}</td>
<td>{{row.test1}}</td>
<td>{{row.Test2}}</td>
<td>{{row.Test3}}</td>
<td>{{row.Test4}}</td>
<td>{{row.Test5 }}</td>
<td>{{row.Test6 }}</td>
</tr>
</tbody>

Logic Js/Ts:

checkboxChangeHandler(row: any) {
    if (checkboxVal) {
         row.isEditable = true;
    }else {
         row.isEditable = false;
    }
    // or simply change it like this -> row.isEditable = !row.isEditable;
}

CSS if you are using the Input with the disabled approach:

input:disabled {
   background-color: transparent; // based on your preference!
   border: none;
}

Upvotes: 0

EldarGranulo
EldarGranulo

Reputation: 1615

You should add a property to your rowData, such as editable. Then layout your code like this:

<tbody>
        <tr *ngFor='let row of rowData' [ngClass]="{ 'selected': row.selected }">
          <td class="text-center>
              <input type="checkbox" [(ngModel)]="row.selected" />
          </td>
          <td>
             <input type="text" *ngIf="row.editable" [(ngModel)]="row.name" />
             <ng-container *ngIf="!row.editable">{{row.name}}</ng-container>
             <!-- You can use span or whatever instead of ng-container-->
          </td>
          <!-- Repeat for other cells -->      
        </tr>
      </tbody>

For the select all part, I assume you have checkbox in the thead. It needs to have this code:

<td><input type="checkbox" (change)="selectAll($event)" /></td>

Then in your component:

    selectAll(event) {
        if (event.target.checked) {
            this.rowData = this.rowData.map((row) => {
               row.selected = true;
               return row;
            });
        } else {
            this.rowData = this.rowData.map((row) => {
               row.selected = false;
               return row;
            });
        }
    }

Then you must have an edit button above table that takes all selected rows and makes them editable.

makeEditable() {
  this.rowData = this.rowData.map((row) => {
     if (row.selected) { row.editable = true; }
     else { row.editable = false; }
     return row;
  });
}

Call this on edit button click.

Upvotes: 1

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 658205

<tbody>
  <ng-container *ngFor='let row of rowData; let i = index'> 
    <tr *ngIf="selected === i">
      <td class="text-center">
        <input type="checkbox" />
      </td>
      <td><input [(ngModel)]="row.name"></td>
      <td><input [(ngModel)]="row.email"></td>
      <td><input [(ngModel)]="row.remark"></td>

      <td><input [(ngModel)]="row.test1"></td>
      <td><input [(ngModel)]="row.test2"></td>
      <td><input [(ngModel)]="row.test3"></td>
      <td><input [(ngModel)]="row.test4"></td>
      <td><input [(ngModel)]="row.test5"></td>
      <td><input [(ngModel)]="row.test6"></td>
    </tr>

    <tr *ngIf="selected !== i" (click)="selected = i">
      <td class="text-center">
        <input type="checkbox" />
      </td>
      <td>{{row.name}}</td>
      <td>{{row.email}}</td>
      <td>{{row.remark}}</td>

      <td>{{row.test1}}</td>
      <td>{{row.Test2}}</td>
      <td>{{row.Test3}}</td>
      <td>{{row.Test4}}</td>
      <td>{{row.Test5 }}</td>
      <td>{{row.Test6 }}</td>
    </tr>
  </ng-container>
</tbody>

Upvotes: 4

Anton Lee
Anton Lee

Reputation: 694

I think you need a new component, like this, and write all logic there, for example (very fast code writing):

    <span [hidden]="!isDisplay" (click)="beginEdit(editText)">
        {{ text }}
    </span>
    <span [hidden]="isDisplay">
        <input #editText type="text" [value]="text">
    </span>


export class InlineEditComponent {
    @Input() public text: any;
    @Output() public edit = new EventEmitter<string>();

    public isDisplay = true;

    constructor(private _eref: ElementRef) {
    }

    @HostListener('document:click', [ '$event.target' ])
    public onClick(targetElement) {
        if (!this._eref.nativeElement.contains(targetElement)) {
            this.isDisplay = true;
        }
    }

    public beginEdit(el: HTMLElement): void {
        this.isDisplay = false;
        setTimeout(() => {
            el.focus();
        }, 100);
    }

    public editDone(newText: any): void {
        this.isDisplay = true;
        this.edit.emit(newText);
    }
}

then use it in your table

Upvotes: 0

Related Questions