Neolithic Prancing Minotaurs

    angular-input-focus
    TypeScript icon, indicating that this package has built-in type declarations

    1.0.13 • Public • Published

    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.

    NPM Build Status Test Status Code Coverage Issues License

    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.

    Install

    npm i angular-input-focus

    DownloadsWeekly Downloads

    95

    Version

    1.0.13

    License

    MIT

    Unpacked Size

    52.2 kB

    Total Files

    15

    Last publish

    Collaborators

    • deanpdx