I have items in the div *ngFor loop which applies css class 'message-list-active' on the selected message.
app.html
<div id="listText" *ngFor="let message of messages; let i=index" activeIndex = i"
[ngClass]="{'message-list-active': activeIndex === i }">
{{message.name}}
</div>
component.ts //listen for keyboard event using arrow up and down to select message
messages; // we have date stored here
activeIndex = 0;
@HostListener("document:keydown", ['$event'])
doSomething(event: KeyboardEvent): void {
if (event.code == "ArrowUp" && this.activeIndex > 0) {
this.activeIndex--
}
if (event.code == "ArrowDown" && this.activeIndex < this.messages.length-1) {
this.activeIndex++
}
}
app.css
#listText {
width: auto;
height:100%;
overflow: auto
}
.message-list-active {
margin: 0;
padding: 15px 15px 5px 13px;
border-radius: 0;
background-color: #CDE6F7;
border-style: dotted;
border-width: 1px;
border-bottom: 1px dotted;
}
And the problem is when selected message comes to the end of the list it will not scroll. So what I am trying to achieve is to have the selected item always focused and be able to scroll down and up:
Also similar example here:
Here is what I am trying to achieve this was answered using jquery jsfiddle http://jsfiddle.net/38zR3/42/, similar question/answer but how can I achieve this in Angular 4 using typescript
It will looking something like this:
private scrollTo(_index: any) {
let elmnt = document.getElementById(_index);
elmnt.scrollIntoView();
window.scrollTo(0, 0); // only if it's innerhtml
}
This will ensure that ever item that's focus will be into view.
In html need to do something like:
id={{item.uniqueID}} (focus)="scrollTo(item.uniqueID)"
Make sure to make it unique for everything that uses this function.
EDIT
Try an in html: id="list{{i}}"
if (event.code == "ArrowUp" && this.activeIndex > 0) {
this.activeIndex--
let str = `list${this.activeIndex}`;
let elmnt = document.getElementById(str);
elmnt.scrollIntoView();
window.scrollTo(0, 0);
}
Ok so fixed it by making a custom directive [focused]
app.html
<div id="listText">
<div *ngFor="let message of messages; [focused]="i === activeIndex" let i=index" activeIndex = i"
[ngClass]="{'message-list-active': activeIndex === i }">
{{message.name}}
</div>
Focused.directive:
import {Directive, Input, Renderer, ElementRef} from '@angular/core'
@Directive({
selector: '[focused]'
})
export class FocusedDirective {
@Input()
set focused(value: boolean){
if(value){
this.renderer.invokeElementMethod(this.elementRef.nativeElement, 'scrollIntoViewIfNeeded');
}
}
constructor(private elementRef: ElementRef, private renderer: Renderer){}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With