Alim Charaniya
Alim Charaniya

Reputation: 119

Apply *ngif tag to current scope/table row

I have a table built in HTML and AngularJS (Angular 2). I am using an ngIf directive to trigger an editable fields from the scope where it was clicked. If a user clicks "Edit" button, then all the fields in ONLY that row should become editable.

See my code below. Currently, when user clicks "Edit" button, then it will make all the input fields in the table editable. How can I prevent this? Only the row inside the scope of the "Edit" button should become editable. I am not sure how to accomplish this using AngularJS.

<tbody>
    <tr *ngFor="let location of locations">
      <td *ngIf="!editing">{{location.apName}}</td>
      <td id="apNameInpit" *ngIf="editing"> <input [(ngModel)]="location.apName" type="text" placeholder="{{location.slackMemberID}}"/></td>

      <td *ngIf="!editing">{{location.locationName}}</td>
      <td id="locationNameInput" *ngIf="editing"> <input [(ngModel)]="location.locationName" type="text" placeholder="{{location.slackMemberID}}"/></td>

      <td *ngIf="!editing">{{location.lat}}</td>
      <td id="latInput" *ngIf="editing"> <input [(ngModel)]="location.lat" type="text" placeholder="{{location.slackMemberID}}"/></td>

      <td *ngIf="!editing">{{location.long}}</td>
      <td id="longInput" *ngIf="editing"> <input [(ngModel)]="location.long" type="text" placeholder="{{location.slackMemberID}}"/></td>

      <td *ngIf="!editing">{{location.mac}}</td>
      <td id="macInput" *ngIf="editing"> <input [(ngModel)]="location.mac" type="text" placeholder="{{location.slackMemberID}}"/></td>

      <td>
        <input type="button" *ngIf="!editing" class="btn btn-warning" (click)="engageEditing()" value="Edit" />
        <input type="button" *ngIf="editing" class="btn btn-primary" (click)="updateField(location)"  value="Update" />
        <input type="button" *ngIf="editing" class="btn btn-warning" (click)="cancelEditing()"  value="Cancel" />
      </td>
    </tr>
  </tbody>

This is my location.component.ts code

    engageEditing(){
    this.editing = true;
    }

Upvotes: 0

Views: 673

Answers (3)

Adam Michalski
Adam Michalski

Reputation: 1792

Without index you can change your model of locations to:

locations = [{
  name: "apName",
  value: null,
  slackMemberID: "something"
  }
...
]

<tr *ngFor="let location of locations; let i = index" 
    (click)="markToEdit(location.name)">
   <td *ngIf="editing !== location.name">{{location.apName}}</td>
   <td id="location.name" *ngIf="editing === location.name">
     <input [(ngModel)]="location.value" type="text" 
            placeholder="{{location.slackMemberID}}"/>
   </td>
</tr>


public markToEdit(name: string){
  this.editing = name;
}

Or use Reactive forms and in the end you have values in

form.value

Upvotes: 0

Soviut
Soviut

Reputation: 91714

Rather than tracking editing as a boolean, track it as an integer. Then you know which index in your array is being edited.

this.editing = 5;

Then in your source you could use the for loop index to see if this is the current row being edited:

<tr *ngFor="let location of locations; let i = index">
  <td *ngIf="editing == i">{{location.apName}}</td>

You'll also need to pass the index to your engageEditing() method so that it knows which row is being edited.

engageEditing(index) {
  this.editing = index;
}

And call it from your button and pass the index into it. Note the i we got from our ngFor.

<input type="button" *ngIf="!editing" class="btn btn-warning" (click)="engageEditing(i)" value="Edit" />

When nothing is being edited, set the value to -1. It might be tempting to use 0 but that's the index of the first item:

cancelEditing() {
  this.editing = -1;
}

Upvotes: 2

alexmac
alexmac

Reputation: 19617

If you want to enable editing for a single location instead of for the entire component, you need to remember it for each location. To add editing to your location object:

<tr *ngFor="let location of locations">
  <td *ngIf="!location.editing">{{location.apName}}</td>
  <td id="apNameInpit" *ngIf="location.editing"> <input [(ngModel)]="location.apName" type="text" placeholder="{{location.slackMemberID}}"/></td>

  ....

  <td>
    <input type="button" *ngIf="!location.editing" class="btn btn-warning" (click)="engageEditing(location)" value="Edit" />
    <input type="button" *ngIf="location.editing" class="btn btn-primary" (click)="updateField(location)"  value="Update" />
    <input type="button" *ngIf="location.editing" class="btn btn-warning" (click)="cancelEditing(location)"  value="Cancel" />
  </td>
</tr>

And update it in engageEditing and cancelEditing:

engageEditing(location) {
   location.editing = true;
}

cancelEditing(location) {
  location.editing = false;
}

Upvotes: 3

Related Questions