简体   繁体   中英

Navigating a multi list using up/down arrow key using Angular 8

I have been trying to build a autocomplete using several "ul". Those list item should be navigable using up/down arrow key, but not sure what would be the best way to achieve that using Angular. I tried some work around with *ngFor, but that works for only one "ul" with "li". Here is the stackblitz with my code, but it has has some issue.

https://stackblitz.com/edit/angular-urnur5

//Code to handle navigation
navigateUsingKey(event) {
      switch (event.keyCode) {
          case 38: // this is the ascii of arrow up
                    this.linkIndex--;
                  break;
          case 40: // this is the ascii of arrow down
                    this.linkIndex++;
                  break;

      }
  }

Here is the html for the same.

<input (keyup)="navigateUsingKey($event)"/>
<div>
  <h4>Fruit</h4>
  <ul>
    <li *ngFor="let item of list1; let i = index;" [class.activeSearchLink]="i === linkIndex"> {{item.name}}</li>
  </ul>
  <h4>Vegie</h4>
  <ul>
    <li *ngFor="let item of list2; let i = index;" [class.activeSearchLink]="i === linkIndex"> {{item.name}}</li>
  </ul>
  <h4>Phone</h4>
  <ul>
    <li *ngFor="let item of list3; let i = index;" [class.activeSearchLink]="i === linkIndex"> {{item.name}}</li>
  </ul>
</div>

Working Demo in this StackBlitz Link

you need to check section and length of each section.. so as you reached end or beginning of the section change section traversal at that time and change index according to that.

navigateUsingKey(event) {
  switch (event.keyCode) {
      case 38: // this is the ascii of arrow up        
        this.linkIndex === -1 ?  this.linkIndex = 0 : this.linkIndex-- ;
        // each section traversal...
        if(this.currentSectionIndex === 0){
          this.downTraverse(2,this.list3.length);
        } else if(this.currentSectionIndex === 2){
          this.downTraverse(1, this.list2.length);
        } else if(this.currentSectionIndex === 1){
          this.downTraverse(0, this.list1.length)
        }
      break;

      case 40: // this is the ascii of arrow down
        if(this.currentSectionIndex === 0){
          this.upTraverse(1, this.list1.length);
        } else if(this.currentSectionIndex === 1){
            this.upTraverse(2, this.list2.length);
        } else if(this.currentSectionIndex === 2){
            this.upTraverse(0, this.list3.length);
        }
        this.linkIndex++;
      break;       
  }
}

downTraverse(sectionIndex:number, listLength){
// calls when DOWN key press...
  this.linkIndex === -1 ? (this.currentSectionIndex = sectionIndex, this.linkIndex = listLength - 1) : '';
}
upTraverse(sectionIndex: number, listLength: number){
  // calls when UP key press...
  listLength-1 <= this.linkIndex ? (this.currentSectionIndex = sectionIndex, this.linkIndex = -1) : '';
}

Template file is

<input (keyup)="navigateUsingKey($event)"/>
<hr>
  <h5> You are in :   {{currentSectionIndex}} section
<hr>
<div>
  <h4 [ngClass]="{'section-color' : currentSectionIndex === 0}">Fruit </h4>
  <ul>
     <li *ngFor="let item of list1; let i = index;" [class.activeSearchLink]="i === linkIndex && currentSectionIndex === 0"> {{item.name}} 
     </li>
  </ul>
  <h4 [ngClass]="{'section-color' : currentSectionIndex === 1}">Vegie</h4>
  <ul>
     <li *ngFor="let item of list2; let i = index;" [class.activeSearchLink]="i === linkIndex && currentSectionIndex === 1"> {{item.name}}
    </li>
 </ul>
 <h4 [ngClass]="{'section-color' : currentSectionIndex === 2}">Phone</h4>
 <ul>
    <li *ngFor="let item of list3; let i = index;" [class.activeSearchLink]="i === linkIndex && currentSectionIndex === 2"> {{item.name}}
    </li>
 </ul>
</div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM