5

I have a component that has a bootstrap dropdown, I want to focus on the current week that is set on the dropdown span

I can do it with plain javascript by setting ids, and then using Jquery .focus() method to focus on it, But wanted to know if there is any angular 7/ 7+ way to do it using ViewChildren etc.

<button class="btn dropdown-toggle"
        (click)="focusOnWeek(currentWeek)"
        type="button" data-toggle="dropdown">
  <span>Week {{currentWeek}}</span> // currentWeek = 5 need to focus on week 5 <a> tag on click of this span
</button>
<ul class="dropdown-menu">
  <li *ngFor="let week of weekList">//weekList = [1,2,3,4,5,6,7,8,9,10]>
    <a class="dropdown-item"
      Week {{week}} 
    </a>

  </li>
</ul>

On Click of Button the Currentweek is focused.

1
  • 1
    Is it me or is your ngFor on the wrong element. I'm guessing you would want to have multiple list element with an anchor inside right? Commented Apr 12, 2019 at 22:26

2 Answers 2

4

You can use ViewChildren to find the anchor element that you want to focus. First, you set a template reference variable (e.g. #anchor) on the anchor elements:

<ul class="dropdown-menu">
  <li *ngFor="let week of weekList">
    <a #anchor class="dropdown-item">Week {{week}}</a>
  </li>
</ul>

In the code, you get a reference to the anchor elements with ViewChildren:

@ViewChildren("anchor") anchorList: QueryList<ElementRef>;

and you set the focus on the anchor that corresponds to the specified week:

focusOnWeek(week) {
  const weekIndex = this.weekList.indexOf(week);
  const elementRef = this.anchorList.find((item, index) => index === weekIndex);
  elementRef.nativeElement.focus();
}

See this stackblitz for a demo.


If the menu is not immediately visible when the click is made, you can monitor the creation of the menu items with the QueryList.changes event. When you detect that the items are visible, you can then set the focus with currentWeek.

ngAfterViewInit() {
  this.anchorList.changes.subscribe(() => {
    if (this.anchorList.length > 0) {
      const weekIndex = this.weekList.indexOf(this.currentWeek);
      const elementRef = this.anchorList.find((item, index) => index === weekIndex);
      elementRef.nativeElement.focus();
    }
  });
}

See this stackblitz for a demo.

Sign up to request clarification or add additional context in comments.

1 Comment

I updated the code to use bootstrap instead of SetTimeout to show the drop down stackblitz.com/edit/angular-nmvn6g and created a new Stackoverflow question stackoverflow.com/q/55692527/5724889
0

Please add following code in html file

 <ul class="dropdown-menu">
      <li class="dropdown-item" [ngClass]="{'focus': currentWeek === week}" *ngFor="let week of weekList">
        <a>
          Week {{week}} 
        </a>

      </li>
    </ul>

add following class in css file

.focus{
   background-color: red;
}

Make sure you have change detection implemented in focusOnWeek() function.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.