Open only specific input field created with ngFor loop in Angular

ngmodel in ngfor angular 6
angular ngfor
angular 4 ngfor multiple arrays
angular for loop
dynamic ngmodel angular 6
ngfor not working
no directive is matched on attribute ngfor
ngfortemplate

I have the following code:

table.component.html:

...
<tr *ngFor="let item of items; let i = index">
        <td>{{i+1}}</td>
        <td>{{ item.name }}</td>

        <td>
          <div *ngIf='!openDateSold; else dateEdit2'>
            {{ item.dateSold | date:'MM/dd/yyyy, hh:mm a'}}
            <br>
            <button class="icon-button" type="button" (click)='showDateSold()'>
              <i class="glyphicon glyphicon-pencil pencil" style="font-size:15px"></i>
            </button>
          </div>
          <ng-template #dateEdit2>
            <input id="date" #date type="datetime-local" [ngModel]="item.dateSold | date:'yyyy-MM-ddTHH:mm'" (ngModelChange)="item.dateSold=$event">
            <button type="button" (click)='showDateSold()'>
              <i class="glyphicon glyphicon-pencil pencil"></i>
            </button>
          </ng-template>
        </td>
</tr>
...

table.component.ts:

...
export class TableComponent implements OnInit {
  public openDateSold: boolean;
  ...
  ngOnInit() {
    this.openDateSold = false;
  }
  showDateNotified() {
    this.openDateNotified = !this.openDateNotified;
  }
  ...
}

The third <td> creates a column that looks like this:

I should be able to click the pencil icon and edit that specific date. However, when I click it, it opens the input field for all the dates. Here's an image where you can see what I mean:

How can I make it so that when I click an icon, it only shows the input field in that specific cell?

Create a component and use its scope:

main component

<table>
<tr *ngFor="let item of items; let i = index">
    <td>{{i+1}}</td>
    <td>{{ item.name }}</td>

  <item item="item"></item>
</tr>
</table>

ts:

@Component({
  selector: 'item',
  templateUrl: './item.component.html',
  styleUrls: [ './item.component.css' ]
})
export class ItemComponent  {
  openDateSold;
  openDateNotified:any;
  @Input() item:any
ngOnInit() {
    this.openDateSold = false;
  }
  showDateSold() {
    this.openDateSold = !this.openDateSold;
  }
}

html:

<td>
    <div *ngIf='!openDateSold; else dateEdit2'>
        {{ item.dateSold | date:'MM/dd/yyyy, hh:mm a'}}
        <br>
        <button class="icon-button" type="button" (click)='showDateSold()'>
              <i class="glyphicon glyphicon-pencil pencil" style="font-size:15px"></i>
            </button>
    </div>
    <ng-template #dateEdit2>
        <input id="date" #date type="datetime-local" [ngModel]="item.dateSold | date:'yyyy-MM-ddTHH:mm'" (ngModelChange)="item.dateSold=$event">
        <button type="button" (click)='showDateSold()'>
              <i class="glyphicon glyphicon-pencil pencil"></i>
            </button>
    </ng-template>
</td>

demo:stackblitz

if you want only one item to be open you should try this

open-only-specific-input-field-created-with-ngfor-loop , Toggle light/dark theme. Toggle Zen Mode. Project. Download Project. Info. Starter project for Angular apps that exports to the Angular CLI. 85. 2. Files. src. NgFor only supports binding to Iterables such as Arrays. You might fix it in the back end so you get an array of objects, but ain’t no body got time for that. Don’t you worry child, I’ve got us.

You can use

I have create a demo on Stackblitz

Component.html

<tr *ngFor="let item of items; let i = index">
    <td>{{i+1}}</td>
    <td>{{ item.name }}</td>

    <td>
        <div *ngIf='!item.isEdit'>
            {{ item.dateSold | date:'MM/dd/yyyy, hh:mm a'}}
            <br>
            <button class="icon-button" type="button" (click)='showDateNotified(item)'>
                <i class="glyphicon glyphicon-pencil pencil" style="font-size:15px"></i>
            </button>
        </div>
        <div *ngIf='item.isEdit'>
            <input id="date" #date type="datetime-local" [ngModel]="item.dateSold | date:'yyyy-MM-ddTHH:mm'" (ngModelChange)="item.dateSold=$event">
            <button type="button" (click)='showDateNotified(item)'>
                <i class="glyphicon glyphicon-pencil pencil"></i>
            </button>
        </div>
    </td>
</tr>

Component.ts

showDateNotified(items:any) {
    items.isEdit = !items.isEdit;
}

Form inputs created with *ngFor ( and thus having same "name") are , Sign up for a free GitHub account to open an issue and contact its maintainers Form inputs created with *ngFor ( and thus having same "name") are having I am asking this only because I am curious why the code behaves that way. angular-automatic-lock-bot bot locked and limited conversation to  In addition to the current element of the iteration, ngFor only provides a set of exported values that can be aliased to local variables: index, last, even and odd. Question. It would be interested to have a way to define custom local variables within the loop. This way you could define a computed variable once and use it several times in the loop block.

Define this varibale in TS

toggle=[]

<tr *ngFor="let item of items; let i = index">
        <td>{{i+1}}</td>
        <td>{{ item.name }}</td>

        <td>
          <div *ngIf='!openDateSold; else dateEdit2'>
            {{ item.dateSold | date:'MM/dd/yyyy, hh:mm a'}}
            <br>
            <button class="icon-button" type="button" (click)='showDateSold();toggle[i]=!toggle[i]'>
              <i class="glyphicon glyphicon-pencil pencil" style="font-size:15px"></i>
            </button>
          </div>
          <ng-template #dateEdit2>
            <input id="date" #date type="datetime-local" [ngModel]="item.dateSold | date:'yyyy-MM-ddTHH:mm'" (ngModelChange)="item.dateSold=$event">
            <button type="button" (click)='showDateSold();toggle[i]=!toggle[i]'>
              <i class="glyphicon glyphicon-pencil pencil"></i>
            </button>
          </ng-template>
        </td>
</tr>

...

Biding to array elements using ngModel and inside a ngFor · Issue , After some time making changes to the inputs, the bindings stop working But the issue only seems to happen on the inputs generated inside a ngFor. Open the demo and stress the first row of inputs firing changes at random until weird Pls refer this link Angular 2 get Input element value Its not still wrk. What's the Scope of the ngFor Loop Variable? The variable used to represent the data availabe for each iteration inside an ngFor directive is only only visible inside the loop. How to Get the Index of an Element Inside an ngFor Loop? You can get the index of the current element in the ngFor loop by using the index variable:

Angular ngFor, ng-template and the compiler, Angular's ngFor is a built-in Directive that allows us to iterate over a import { Component, Input } from '@angular/core'; import { Contact } from '. Secondly, we're creating a context called contact , using a “for of” loop - just like in ES6. and a card will be “stamped out” in the DOM for each particular item  Create a Feature Component. Add In-app Navigation. Get Data from a Server. User actions such as clicking a link, pushing a button, and entering text raise DOM events. This page explains how to bind those events to component event handlers using the Angular event binding syntax. Run the live example / download example.

Display a selection list, Create a file called mock-heroes.ts in the src/app/ folder. Open the HeroesComponent class file and import the mock HEROES . List heroes with *​ngFor link Add an <h2> at the top,; Below it add an HTML unordered list ( <ul> )​; Insert an <li> within The component should only display the selected hero details if the  When using the shorthand syntax, Angular allows only one structural directive on an element . If you want to iterate conditionally, for example, put the *ngIf on a container element that wraps the *ngFor element. For futher discussion, see Structural Directives.

NgFor • Angular, We use the NgFor directive to loop over an array of items and create multiple It's point is to repeat a given HTML template once for each value in an array,  I created a simple note app which for loops through an array of objects which holds note data. I have a button which opens up the note for edit by returning true when clicked returning false when c…

Comments
  • When you click the button, you're toggling what appears to be some sort of component-level boolean or flag. How do you expect it to know which particular item in your list of data it should be targetting?
  • see my answer below
  • This works. However, by doing this, I'm adding another parameter to the item object (i.e. isEdit), and that breaks the rest of my code (I'm sending this object to a REST service and the service doesn't recognize isEdit, so it returns an error). Any other way to do it without adding another property to the object?
  • I tried this, but it doesn't work. Could you be more specific about how to define the variable in the ts component and how to use it there?
  • Your example works on that website, but when I try it in my code I keep getting Cannot read property '0' of undefined, because I guess toggle[0] was never defined.
  • did you add *ngFor="let item of items; let i = index" this in your code
  • Yeah, I had that line in my original code. The problem occurs when it goes to the line with this: *ngIf="toggle[i]", because that value was never initialized. Same thing happens when I click the icon, it throws the same error.