junior_dn
junior_dn

Reputation: 77

hiding elements after a button is clicked - angular2 - ngFor

I am still learning Angular2 and I currently can't find a solution for my problem. I am displaying 1-3 Tiers/Packages using the ngFor, which than looks like this tiers in display mode. After I click the edit button I only want the clicked element to go into edit mode, currently all of them switch into edit mode, which looks like this tiers in edit mode.

Here is the code, reduced it to the relevant parts.

<h1 class="page-title"><span class="fw-semi-bold">Packages</span></h1>
<div class="row">
  <div class="col-md-4" *ngFor="let tier of tiers; let i=index;">
    <!-- Show Mode -->
    <ul [hidden]="editMode" class="pricing-table">
      <li class="plan-name">
        {{ tier.title }} {{i}}
      </li>
      <li>
        description
      </li>
      <li>
        description
      </li>
      <li>
        description
      </li>
      <li>
        description
      </li>
      <p class="plan-price">{{ tier.price }}</p>
      <li class="plan-action">
        <a class="btn btn-primary" (click)="this.onEdit()">Edit</a>
        <a class="btn btn-success" (click)="this.clickSave()">SaveYes</a>
        <a class="btn btn-warning" >Get</a>
      </li>
    </ul>
    <!-- Edit Mode -->
    <ul [hidden]="!editMode" class="pricing-table-edit">
      <li class="plan-name-edit">
        <input type="text" class="form-control" style=" font-size: 3rem;" placeholder="{{ tier.title }} " formControlName="package_name">

      </li>
      <li >
        <div class="rewards-edit" style="background-color: #3a3d46; ">Feature 1</div>
      </li>
      <li>
        <div class="rewards-edit" style="background-color: #3a3d46">Feature 1</div>
      </li>
      <li>
        <div class="rewards-edit" style="background-color: #3a3d46">Feature 1</div>
      </li>
      <li>
        <div class="rewards-edit" style="background-color: #3a3d46">Feature 1</div>
      </li>
      <div style="align:center; padding-left: 40%; padding-right: 40%;"><input type="text" id="package_price1" class="form-control plan-price" placeholder="4,99" formControlName="package_price"></div>

      <li class="plan-action">
        <a class="btn btn-primary">Edit</a>
        <a class="btn btn-success">Save</a>
        <a class="btn btn-warning">Publish</a>
      </li>
    </ul>
  </div>

Components-File:

export class PackagesComponent {
  editMode = false;

  onEdit () {
    this.editMode = true;
  }
}

Is there a way to use the index variable in my method, so that I know which of the 3 tiers is currently clicked? Or are there any other solutions or maybe ideas?

Thanks a lot :)

UPDATED CODE, thanks to Abrar:

export class PackagesComponent {  //this has to be renamed to TierComponent for less confusion
  public tierToEdit: Tier;
  editMode = false;
  tiers: Tier[] = [
    new Tier(
      10,
      'First Tier',
      [
        {id: 500, title: 'desc', description: 'crazy description'},
        {id: 501, title: 'desc', description: 'crazy description'},
        {id: 502, title: 'desc', description: 'crazy description'},
        {id: 503, title: 'desc', description: 'crazy description'}
      ],
      5.00),
      *[more code..]*
  ]


  constructor (private tierService: TierService) {}

  ngOnInit() {
  }



  onEdit (tier: Tier) {
    this.editMode = true;
    this.tierToEdit = tier;
  }

Template-File:

<h1 class="page-title"><span class="fw-semi-bold">Packages</span></h1>
<div class="row">
  <div class="col-md-4" *ngFor="let tier of tiers; let i=index;">
    <!-- Show Mode -->
    <ul *ngIf="!editMode || tierToEdit != tier" class="pricing-table">
      <li class="plan-name">
        {{ tier.title }} {{i}}
      </li>
     <li class="plan-name">
        {{ tier.title }} {{i}}
      </li>
      <li>
        description
      </li>
      <li>
        description
      </li>
      <li>
        description
      </li>
      <li>
        description
      </li>
      <p class="plan-price">{{ tier.price }}</p>
      <li class="plan-action">
        <a class="btn btn-primary" (click)="onEdit(tier)">Edit</a>
        <a class="btn btn-success" (click)="this.clickSave()">SaveYes</a>
        <a class="btn btn-warning" >Get</a>
      </li>
    </ul>
    <!-- Edit Mode -->
    <ul *ngIf="editMode && tierToEdit == tier " class="pricing-table-edit">
      <li class="plan-name-edit">
        <input type="text" class="form-control" style=" font-size: 3rem;" placeholder="{{ tier.title }} " formControlName="package_name">

      </li>
      <li >
        <div class="rewards-edit" style="background-color: #3a3d46; ">Feature 1</div>
      </li>
      <li>
        <div class="rewards-edit" style="background-color: #3a3d46">Feature 1</div>
      </li>
      <li>
        <div class="rewards-edit" style="background-color: #3a3d46">Feature 1</div>
      </li>
      <li>
        <div class="rewards-edit" style="background-color: #3a3d46">Feature 1</div>
      </li>
      <div style="align:center; padding-left: 40%; padding-right: 40%;"><input type="text" id="package_price1" class="form-control plan-price" placeholder="4,99" formControlName="package_price"></div>

      <li class="plan-action">
        <a class="btn btn-primary">Edit</a>
        <a class="btn btn-success">Save</a>
        <a class="btn btn-warning">Publish</a>
      </li>
    </ul>
  </div>

Upvotes: 2

Views: 121

Answers (3)

Abrar
Abrar

Reputation: 7232

First of all, you don't actually need to call this.onEdit() or this.clickSave() in the (click) event handler. Only onEdit() or clickSave() will work alright.

Notice here that you are not passing any reference to the clicked item which you want to go into edit mode. So, here you can either pass the index like this - onEdit(i) or the object like this - onEdit(tier).

In your PackagesComponent you can set the tier that is clicked to a member variable -

export class PackagesComponent {
  public packageToEdit:Package;   // <------- new code

  editMode = false;

  onEdit (tier:Package) {
    this.packageToEdit = tier;    // <------- new code
    this.editMode = true;
  }
}

Now, in your HTML code

<!-- Edit Mode -->
<ul [hidden]="!editMode && packageToEdit==tier" class="pricing-table-edit">

  <li class="plan-name-edit">
    <input type="text" class="form-control" style=" font-size: 3rem;" placeholder="{{ tier.title }} " formControlName="package_name">

  </li>
  <li >
    <div class="rewards-edit" style="background-color: #3a3d46; ">Feature 1</div>
  </li>
  <li>
    <div class="rewards-edit" style="background-color: #3a3d46">Feature 1</div>
  </li>
  <li>
    <div class="rewards-edit" style="background-color: #3a3d46">Feature 1</div>
  </li>
  <li>
    <div class="rewards-edit" style="background-color: #3a3d46">Feature 1</div>
  </li>
  <div style="align:center; padding-left: 40%; padding-right: 40%;"><input type="text" id="package_price1" class="form-control plan-price" placeholder="4,99" formControlName="package_price"></div>

  <li class="plan-action">
    <a class="btn btn-primary">Edit</a>
    <a class="btn btn-success">Save</a>
    <a class="btn btn-warning">Publish</a>
  </li>
</ul>

Upvotes: 0

drtechno
drtechno

Reputation: 323

I would assign an ID to the section and in each section trigger its own editMode in ID instead of using the "this" class descriptor.

Upvotes: 0

joshsisley
joshsisley

Reputation: 310

What I would do is when you click to edit one of the tiers, pass in the tier into the edit function.

Then set a variable like selectedTier to be set to that tier or id/name of some sort associated with that tier.

Then you can match that selectedTier to the tier in your ngFor.

And then for hiding all but the selected one use [hidden]="selectedTier != tier"

Upvotes: 2

Related Questions