I am using NgbTypeahead component of ng-bootstrap. My problem is, when I put the typeahead component inside a scrollable component and make a scroll down, the position of dropdo
typeahead-scrollable.html file
typeahead-scrollable.ts file
@ViewChild('typeaheadInstance')
private typeaheadInstance: NgbTypeahead;
typeaheadKeydown($event: KeyboardEvent) {
if (this.typeaheadInstance.isPopupOpen()) {
setTimeout(() => {
const popup = document.getElementById(this.typeaheadInstance.popupId);
const activeElements = popup.getElementsByClassName('active');
if (activeElements.length === 1) {
// activeElements[0].scrollIntoView();
const elem = (activeElements[0] as any);
if (typeof elem.scrollIntoViewIfNeeded === 'function') {
// non standard function, but works (in chrome)...
elem.scrollIntoViewIfNeeded();
} else {
//do custom scroll calculation or use jQuery Plugin or ...
this.scrollIntoViewIfNeededPolyfill(elem as HTMLElement);
}
}
});
}
}
private scrollIntoViewIfNeededPolyfill(elem: HTMLElement, centerIfNeeded = true) {
var parent = elem.parentElement,
parentComputedStyle = window.getComputedStyle(parent, null),
parentBorderTopWidth = parseInt(parentComputedStyle.getPropertyValue('border-top-width')),
parentBorderLeftWidth = parseInt(parentComputedStyle.getPropertyValue('border-left-width')),
overTop = elem.offsetTop - parent.offsetTop < parent.scrollTop,
overBottom = (elem.offsetTop - parent.offsetTop + elem.clientHeight - parentBorderTopWidth) > (parent.scrollTop + parent.clientHeight),
overLeft = elem.offsetLeft - parent.offsetLeft < parent.scrollLeft,
overRight = (elem.offsetLeft - parent.offsetLeft + elem.clientWidth - parentBorderLeftWidth) > (parent.scrollLeft + parent.clientWidth),
alignWithTop = overTop && !overBottom;
if ((overTop || overBottom) && centerIfNeeded) {
parent.scrollTop = elem.offsetTop - parent.offsetTop - parent.clientHeight / 2 - parentBorderTopWidth + elem.clientHeight / 2;
}
if ((overLeft || overRight) && centerIfNeeded) {
parent.scrollLeft = elem.offsetLeft - parent.offsetLeft - parent.clientWidth / 2 - parentBorderLeftWidth + elem.clientWidth / 2;
}
if ((overTop || overBottom || overLeft || overRight) && !centerIfNeeded) {
elem.scrollIntoView(alignWithTop);
}
}
Working example:
https://stackblitz.com/edit/angular-utd9ii?file=app%2Ftypeahead-scrollable.ts
- 热议问题