Reputation: 2945
I have an Angular application where I retrieve data when the user clicks a button:
getJobNotes() {
this.jobNoteService.getJobNotes()
.subscribe(
result => {
this.jobNotes = result.jobNotes;
}
);
}
I would like to scroll into view an element that has a specific job note Id, ie, this may be the 5th element in a list of 10 as an example.
I have tried the following:
this.selectedJobNoteId = result.selectedJobNoteId;
let el = document.getElementById(this.selectedJobNoteId);
el.scrollIntoView();
in this case my 'el' variable is undefined.
In my html I am setting the ID correctly:
<li *ngFor="let jobNote of jobNotes" id="{{jobNote.jobNoteId}}">
I have confirmed that the ID is set, and if I run document.getElementById with the correct ID in the chrome console then I get back the element - I suspect the issue is that the elements are dynamically created?
Upvotes: 1
Views: 2483
Reputation: 39432
You could assign a template variable to the list item:
<ul *ngIf="users">
<li #user *ngFor="let userDetail of users">
<h1>{{ userDetail.name }}</h1>
<h2>{{ userDetail.username }}</h2>
<h3>{{ userDetail.email }}</h3>
</li>
</ul>
And then in the Component class, you could access the list-items using ViewChildren
. Something like this:
@ViewChildren("user", { read: ElementRef }) renderedUsers: QueryList<ElementRef>;
And then finally, you could use scrollIntoView
on a nativeElement
of any item to scroll to it:
getData() {
this.http
.get("https://jsonplaceholder.typicode.com/users")
.subscribe(users => {
this.users = users;
this.timeoutId = setTimeout(() => {
const userToScrollOn = this.renderedUsers.toArray();
userToScrollOn[this.indexToScrollTo].nativeElement.scrollIntoView({
behavior: 'smooth'
});
}, 1000);
});
}
I've used a setTimeout
here coz, the list won't render as soon as you get the data. So there would be a slight delay before renderedUsers
is initialized.
So in ngOnDestroy
also make sure to clear the timeout by calling clearTimeout(this.timeoutId);
Here's a Working Sample Demo 🚀 for your ref.
Upvotes: 1