Skip to content

Instantly share code, notes, and snippets.

@slavafomin
Created November 5, 2021 21:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save slavafomin/d6d92d1dacae927ab19f2745f93a4abc to your computer and use it in GitHub Desktop.
Save slavafomin/d6d92d1dacae927ab19f2745f93a4abc to your computer and use it in GitHub Desktop.
Angular 11+ autofocus directive
/**
* This smart directive accepts boolean value as an input and focuses the
* element based on the evaluated boolean expression.
*
* Also, the directive could be applied to the input/button/select/a elements
* directly or to any parent element as well. It will search the DOM for the first
* suitable element to focus automatically.
*/
import { AfterViewInit, Directive, ElementRef, Input, NgModule } from '@angular/core';
const focusableElements = [
'input',
'select',
'button',
'a',
];
@Directive({
selector: '[autofocus]',
})
export class AutofocusDirective implements AfterViewInit {
@Input()
public set autofocus(shouldFocus: boolean) {
this.shouldFocus = shouldFocus;
this.checkFocus();
}
private shouldFocus = true;
constructor(
private readonly elementRef: ElementRef
) {
}
public ngAfterViewInit() {
this.checkFocus();
}
private checkFocus() {
if (!this.shouldFocus) {
return;
}
const hostElement = (
<HTMLElement>
this.elementRef.nativeElement
);
if (!hostElement) {
return;
}
if (focusableElements.includes(
hostElement.tagName.toLowerCase())
) {
hostElement.focus?.();
} else if (hostElement?.querySelector) {
for (const tagName of focusableElements) {
const childElement = (
<HTMLInputElement>
hostElement.querySelector(tagName)
);
if (childElement) {
childElement?.focus?.();
break;
}
}
}
}
}
@NgModule({
declarations: [
AutofocusDirective,
],
exports: [
AutofocusDirective,
],
})
export class AutofocusModule {
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment