Reputation: 995
I'm trying to use an ElementRef to focus on an input. This works fine except for inside a dropdown from the ng-bootstrap library. How do you trigger the event in a ngbDropdown?
Example: https://stackblitz.com/edit/angular-z7q9xm
component class
import { Component, ViewChild, ElementRef } from '@angular/core';
@Component({
selector: 'ngbd-dropdown-basic',
templateUrl: './dropdown-basic.html'
})
export class NgbdDropdownBasic {
@ViewChild("search") searchField: ElementRef;
@ViewChild("searchOutside") searchFieldOutside: ElementRef;
onToggle(dropDownOpen: boolean) {
if (dropDownOpen) {
this.searchField.nativeElement.focus();
}
}
focusOtherField() {
this.searchFieldOutside.nativeElement.focus();
}
}
component template
<div class="row">
<div class="col"><h3>Example 1: Inside dropdown <br>(not working)</h3></div>
</div>
<div class="row form-group">
<div class="col">
<div ngbDropdown (openChange)="onToggle($event)" class="d-inline-block">
<button class="btn btn-outline-primary" id="dropdownBasic1" ngbDropdownToggle>Toggle dropdown</button>
<div ngbDropdownMenu aria-labelledby="dropdownBasic1">
<div class="p-2"><input #search name="search" class="form-control" placeholder="Search..."></div>
</div>
</div>
</div>
</div>
<hr>
<div class="row">
<div class="col"><h3>Example 2: Outside dropdown</h3></div>
</div>
<div class="row form-group">
<div class="col-auto"><button (click)="focusOtherField()" type="button" class="btn btn-outline-primary">Focus this field:</button></div>
<div class="col">
<input #searchOutside name="searchOutside" class="form-control" placeholder="Search...">
</div>
</div>
Upvotes: 3
Views: 2571
Reputation: 6128
The problem is that at the point of clicking on the dropdown and calling your onToggle
, the DOM has not yet been updated to render the dropdown and the input within the dropdown.
What you can do is inject a ChangeDetectorRef
into the component via the constructor:
import { ChangeDetectorRef } from '@angular/core';
...
export class NgbdDropdownBasic {
...
constructor(private _cdRef: ChangeDetectorRef) {}
and call this._cdRef.detectChanges();
before you focus on the input in your onToggle
method:
onToggle(dropDownOpen: boolean) {
if (dropDownOpen) {
this._cdRef.detectChanges();
this.searchField.nativeElement.focus();
}
}
This will result in the dropdown and input being rendered, so that when you call this.searchField.nativeElement.focus();
it is already visible and will get the focus.
Please see this StackBlitz for a working demo.
Upvotes: 4