How to improve Angular dropdown?

Discussão em 'Angular' iniciado por Jack, Novembro 27, 2024.

  1. Jack

    Jack Guest

    I got this component that has a ul that is displaying total users and then a search input that also displays a ul when searched a term within a filter of total users. I'm trying to implement some keyboard logic to the dropdown, so i can choose the value without the mouse. Well, when one of them is good the other breaks, and vice-versa.

    Here's the html:

    <div class="flex gap-1 items-center h-[32px]" (keydown)="handleKeydown($event)" tabindex="0">
    <!-- Players no projeto -->
    <div class="bg-color-primary/40 pl-3 flex items-center justify-between border border-transparent text-color-contrast text-sm"
    (click)="toggleSelectedPlayers()"
    [ngClass]="isSelectedType && addedPlayers.length >0 ? ' border-b-color-brand': ''">
    <p class="mr-1">
    {{addedPlayers.length > 0 ? addedPlayers.length : '' }}
    </p>
    <p>
    {{addedPlayers.length > 1 ? 'Players' : 'Player' }}
    </p>
    <wp-icon *ngIf="addedPlayers?.length > 0" type="seta-dropdown" [ngClass]="isSelectedType ? '': '-rotate-90 transition transform'" size="large" class="cursor-pointer"></wp-icon>
    <wp-icon *ngIf="addedPlayers?.length == 0" type="adicionar"></wp-icon>
    </div>

    <!-- Pesquisa de usuarios não selecionados -->
    <div class="relative w-[100%]">
    <input-search [formControl]="form" (focus)="toggleSearchList()" (keydown)="handleKeydown($event)" [placeholder]="'SEARCH_PLAYERS' | translate" [filter]=true
    class="w-[100%] border border-transparent flex items-center" (click)="toggleSearchList()"
    [ngClass]="isSearchType ? 'border-b-color-brand': ''"></input-search>
    <ul [class.hidden]="!isSearchType"
    [class.dropdown-colors]="dropdownStyle"
    class="w-full shadow-md z-10 scrollbar-thin overflow-y-auto cursor-pointer bg-color-background absolute left-0
    transition-width max-h-[150px] top-[40px]">
    <li *ngIf="loader" class="loading-item">
    <loading container></loading>
    </li>
    <li *ngIf="!loader && searchTerm && playersList.length === 0"
    class="flex justify-between items-center px-3 py-1 text-color-contrast text-opacity-90 border-b border-b-color-primary/50 h-[45px] cursor-default">
    <p class="text-sm">{{'USER_NOT_FOUND_OR_ADDED' | translate}}</p>
    </li>
    <ng-container *ngFor="let player of playersList; let i = index; trackBy: trackByPlayerId">
    <li [class.active]="i === activeIndex"
    class="flex justify-between items-center px-3 py-1 text-color-contrast hover:text-color-brand/90 text-opacity-90
    border-b border-b-color-primary/50"
    (click)="selectPlayer($event, player, i)">
    <p class="text-sm">{{ player.name }}</p>
    <wp-icon *ngIf="isSearchType" type="adicionar"></wp-icon>
    </li>
    </ng-container>
    </ul>
    </div>

    <!-- ul de players no projeto -->
    <ul [class.dropdown-colors]="dropdownStyle" [class.hidden]="!(playersList?.length > 0 && isSelectedType)"
    class="w-[100%] shadow-md z-10 scrollbar-thin overflow-y-auto cursor-pointer bg-color-background absolute left-0
    transition-width max-h-[150px] top-[36px]">
    <ng-container *ngFor="let player of playersList; let i = index; trackBy: trackByPlayerId">
    <li [class.active]="i === activeIndex"
    class="flex justify-between items-center px-3 py-1 text-color-contrast hover:text-color-brand/90 text-opacity-90
    border-b border-b-color-primary/50"
    (click)="selectPlayer($event, player, i)">
    <p class="text-sm">{{ player.name }}</p>
    <wp-icon type="cancelar"></wp-icon>
    </li>
    </ng-container>
    </ul>
    </div>


    then the function that handles the keyboard logic:

    handleKeydown(event: KeyboardEvent): void {
    if (!this.showList) {
    this.showList = true; // Ensure the dropdown is shown when interacting with the input field
    }
    const list = this.playerListType === 'search' ? this.searchList : this.addedPlayers;
    if (list.length === 0) return;

    if (event.key === 'ArrowDown') {
    event.preventDefault();
    this.activeIndex = (this.activeIndex + 1) % list.length;
    } else if (event.key === 'ArrowUp') {
    event.preventDefault();
    this.activeIndex = (this.activeIndex - 1 + list.length) % list.length;
    } else if (event.key === 'Enter' && this.activeIndex > -1) {
    event.preventDefault();
    const selectedPlayer = list[this.activeIndex];
    const index = this.playerListType === 'search' ? this.searchList.indexOf(selectedPlayer) : this.addedPlayers.indexOf(selectedPlayer);
    this.selectPlayer(event, selectedPlayer, index);
    }


    }

    Continue reading...

Compartilhe esta Página