Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,15 @@
</button>
}
<button class="dropdown-item collection-item text-truncate"
[class.active]="selectedIndex === 0"
(click)="onSelect(undefined); sdRef.close()" (mousedown)="onSelect(undefined); sdRef.close()"
title="{{ 'dropdown.clear.tooltip' | translate }}" role="option"
type="button">
<i>{{ 'dropdown.clear' | translate }}</i>
</button>
@for (listEntry of optionsList; track listEntry; let i = $index) {
<button class="dropdown-item collection-item text-truncate"
[class.active]="i === selectedIndex"
[class.active]="selectedIndex === (i + 1)"
(keydown.enter)="onSelect(listEntry); sdRef.close()" (mousedown)="onSelect(listEntry); sdRef.close()"
title="{{ inputFormatter(listEntry) }}" role="option" type="button"
[attr.id]="inputFormatter(listEntry) === (currentValue|async) ? ('combobox_' + id + '_selected') : null">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ export class DsDynamicScrollableDropdownComponent extends DsDynamicVocabularyCom
}
}

loadOptions(fromInit: boolean) {
loadOptions(fromInit: boolean, scrollAfterLoad: boolean = false) {
this.loading = true;
this.getDataFromService().pipe(
getFirstSucceededRemoteDataPayload(),
Expand All @@ -167,7 +167,11 @@ export class DsDynamicScrollableDropdownComponent extends DsDynamicVocabularyCom
list.pageInfo.totalElements,
list.pageInfo.totalPages,
);
this.selectedIndex = 0;

if (!fromInit) {
this.setSelectedIndexToCurrentValue(scrollAfterLoad);
}

this.cdr.detectChanges();
});
}
Expand All @@ -185,26 +189,60 @@ export class DsDynamicScrollableDropdownComponent extends DsDynamicVocabularyCom
if (!this.model.readOnly) {
this.group.markAsUntouched();
this.inputText = null;
this.updatePageInfo(this.model.maxOptions, 1);
this.loadOptions(false);

const pageSize = Math.min(this.pageInfo.totalElements, 200);
this.updatePageInfo(pageSize, 1);

this.loadOptions(false, true);
this.setSelectedIndexToCurrentValue(true);
sdRef.open();
}
}

/**
* Set the selectedIndex to match the current value when dropdown opens
* @param shouldScroll Whether to scroll to the selected item after setting the index
*/
private setSelectedIndexToCurrentValue(shouldScroll: boolean = false): void {
if (this.currentValue) {
this.currentValue.pipe(take(1)).subscribe(currentVal => {
if (currentVal && this.optionsList.length > 0) {
const foundIndex = this.optionsList.findIndex(entry =>
this.inputFormatter(entry) === currentVal,
);
this.selectedIndex = foundIndex >= 0 ? foundIndex + 1 : 0;
} else {
this.selectedIndex = 0;
}

if (shouldScroll && this.selectedIndex > 0) {
// Ensure DOM is updated before scrolling
this.cdr.detectChanges();
// Use setTimeout to ensure the active class is applied and rendered
setTimeout(() => this.scrollToSelected(), 0);
}
});
} else {
this.selectedIndex = 0;
}
}

navigateDropdown(event: KeyboardEvent) {
const totalItems = this.optionsList.length + 1;

if (event.key === 'ArrowDown') {
this.selectedIndex = Math.min(this.selectedIndex + 1, this.optionsList.length - 1);
this.selectedIndex = Math.min(this.selectedIndex + 1, totalItems - 1);
} else if (event.key === 'ArrowUp') {
this.selectedIndex = Math.max(this.selectedIndex - 1, 0);
}
this.scrollToSelected();
}

scrollToSelected() {
const dropdownItems = this.dropdownMenu.nativeElement.querySelectorAll('.dropdown-item');
const dropdownItems = this.dropdownMenu.nativeElement.querySelectorAll('.dropdown-item:not(.disabled)');
const selectedItem = dropdownItems[this.selectedIndex];
if (selectedItem) {
selectedItem.scrollIntoView({ block: 'nearest' });
selectedItem.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
}
}

Expand All @@ -220,7 +258,11 @@ export class DsDynamicScrollableDropdownComponent extends DsDynamicVocabularyCom
event.preventDefault();
event.stopPropagation();
if (sdRef.isOpen()) {
this.onSelect(this.optionsList[this.selectedIndex]);
if (this.selectedIndex === 0) {
this.onSelect(undefined);
} else {
this.onSelect(this.optionsList[this.selectedIndex - 1]);
}
sdRef.close();
} else {
sdRef.open();
Expand Down
Loading