4

How can i trigger click on specific nth-child(x) item in ngFor listing ?

<ul>
    <li class="list"  *ngFor="let ver of versions; (click)="versionView()">{{ver.name}}</li>
</ul>
3
  • Do you need to trigger the click programmatically after rendering the block? Besides, there is a syntax error in your HTML above. Commented May 3, 2019 at 14:46
  • Yes, I need to trigger the click programmatically after rendering the block @briosheje Commented May 3, 2019 at 14:57
  • Ok, answer incoming. Commented May 3, 2019 at 14:58

4 Answers 4

2

If you need to trigger programmatically the click on init (assuming you need a real click event that will also include the propagation, otherwise you can just raise the click event), you can do that using ViewChildren and NgAfterViewInit.

Basically, you can use a selector to acquire all the <li> items:

<ul>
  <li #items class="list" *ngFor="let ver of versions;" (click)="versionView(ver)">{{ver.name}}</li>
</ul>

(note the #items selector).

In your component, you can declare a selector targeting "items": @ViewChildren('items') liItems: QueryList<ElementRef>.

After that, you can loop through the items after the view is ready and trigger the click on the native html element:

  public ngAfterViewInit() {
    const targetItem = 10;
    // If the item is the 10th element, click it.
    this.liItems.forEach((item, index) => {
      if (index === (targetItem - 1)) (item.nativeElement as HTMLElement).click();
    });
  }

Full component code sample:

import { Component, ViewChildren, QueryList, ElementRef } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  @ViewChildren('items') liItems: QueryList<ElementRef>

  public versions: { name: string }[];

  public constructor() {
    this.versions = Array.from({length: 10}).map((_, i) => {
      return { name: i.toString() };
    });
  }

  public versionView(i: {name: string}) {
    console.log('clicked item: ', i);
  }

  public ngAfterViewInit() {
    const targetItem = 10;
    // If the item is the 10th element, click it.
    this.liItems.forEach((item, index) => {
      if (index === (targetItem - 1)) (item.nativeElement as HTMLElement).click();
    });
  }
}

Working stackblitz: https://stackblitz.com/edit/angular-1eha8j

(check the console to see that the item 10 is clicked)

Beware: In the sample above I've used forEach to loop the items, but you can simply acquire the item you need using .find or by simply getting the item at a specific index. The above example is just to show that many manipulations are possible through selectors.

Sign up to request clarification or add additional context in comments.

7 Comments

How can I target a specific item using the index ? any example code?
@ShibinRagh What do you mean by "a specific item"?
Yes, I got the syntax (this.liItems.find( (item , index) => index === 1 ).nativeElement as HTMLElement).click();
@ShibinRagh if you somehow just need to trigger the element at index 3 (assuming you are talking about the array index), you can do (this.liItems[3].nativeElement as HTMLElement).click(), you don't need to iterate through it, you can also directly access the array or just use .find.
Its error - ERROR TypeError: Cannot read property 'nativeElement' of undefined
|
2

Click event will be called every time, but it can be checked through index, whether it matches the expected index or not?

<ul>
    <li class="list" *ngFor="let ver of versions; let i = index" (click)="versionView(i)">{{ver.name}}</li>
</ul>

And index can be checked on *.ts code as below:

function versionView(i) {
    if (i == NTH_VALUE) {
         
    }    
}

Comments

1
<ul>
    <li class="list" *ngFor="let ver of versions; let i = index" (click)="versionView()">{{ver.name}}</li>
</ul>

You can add let i = index in order to refer the nth element, and use it as you prefer. You can pass it as a parameter in your versionView() function and use it there.

function versionView(i) {
    if (i !== NTH_VALUE) {
        return 
    }
    // Execute your function here
}

I hope this is what you were looking for.

1 Comment

If your problem is to run some code of n-th element of version, you won't probably need to change anything in your template, you can simply add a this.versionView(versions[i]) wherever you need it in your JS/TS component file. Probably you can even use an easier syntax.
1

You are really close. Modify your code like so:

<ul>
  <li class="list" *ngFor="let ver of versions" (click)="versionView(ver)">{{ver.name}}</li>
</ul>

In your corresponding component you just need to add:

versionView(ver: any) {
  // Do something with the ver object
}

1 Comment

When do you wish to call this function? You could for example call it in ngAfterViewInit: ngAfterViewInit() { this.versionView(this.versions[n]); } . This would call the function after the view has been initialised.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.