angular-input-focus
v1.0.13
Published
An Angular focus attribute directive.
Downloads
244
Maintainers
Readme
Angular Input Focus Attribute Directive
This package is for handling focus on html elements in Angular apps. It is tightly coupled with the DOM but safe to use in server-side rendering settings since we are checking to make sure the directive is running in a browser before using any DOM-specific functions.
Installation
Install using NPM:
npm install angular-input-focus --save
Next, import the module in your application module:
import { AngularInputFocusModule } from 'angular-input-focus';
@NgModule({
imports: [AngularInputFocusModule]
})
Now you're ready to use the directive in your project.
Usage
Here are some standard use cases.
Autofocus
For autofocus-like functionality, you can set libFocus
to true (or a condition):
<!-- Focus First name when control is rendered -->
First name: <input type="text" name="fname" [libFocus]="true">
Last name: <input type="text" name="lname">
Focus using an EventEmitter
You can also pass an EventEmitter<boolean>
to the setFocus
input. Imagine a component called MyComponent
:
export class MyComponent {
// We will pass this to the directive in our view
focusEvent = new EventEmitter<boolean>();
// When called, will set the focus on our input
setFocus() {
this.focusEvent.emit(true);
}
}
In the template for MyComponent
:
<input [libFocus]="false" [setFocus]="focusEvent">`
Whenever your focusEvent
emits a value, your element will focus/blur depending on whether the emitted value is true
or false
. You can find a working example of this in the tester app for the project.
Focus last element with dynamic elements
You don't need to use EventEmitter
for this. Simply set libFocus
to a conditional boolean value:
rows = ['First', 'Second'];
addRow() {
this.rows.push('');
}
shouldFocusRow(index: number): boolean {
return index + 1 === this.rows.length;
}
trackByIndex(index, row) {
return index;
}
And in your template:
<button (click)="addRow()">Add row</button>
<!-- Important to use trackBy to prevent stuttering on input. -->
<div *ngFor="let row of this.rows; let i = index; trackBy: trackByIndex">
<input id="row{{ i }}" [libFocus]="shouldFocusRow(i)" [(ngModel)]="rows[i]" />
</div>
It's important in general to use trackBy
for dynamic inputs to avoid UI stutter as you're typing. Here's a working StackBlitz example you can run and modify.
Note on skipChangeDetection
If you're using Angular Material, Change Detection needs to run after setting focus because Angular Material tracks focus; otherwise you will get the dreaded ExpressionChangedAfterItHasBeenCheckedError
exception. If you are using native HTML inputs, you can skip change detection by setting [skipChangeDetection]="true"
.
Development
The main app (angular-input-focus-tester
) is for testing the angular-input-focus
library in the projects
folder. Run ng serve
to build and serve the test app.
To publish a new version of the library to NPM, run npm run publish-lib
. This will do the following:
- Run
npm version patch
to create a new patch. - Build the library.
- Copy readme/license from the main project to the library.
- Publish the patch on NPM.