{"id":19719369,"url":"https://github.com/korniychuk/angular-autofocus-fix","last_synced_at":"2025-04-29T21:30:26.064Z","repository":{"id":35077045,"uuid":"95212647","full_name":"korniychuk/angular-autofocus-fix","owner":"korniychuk","description":"Angular 5+ directive for fix autofocus on dynamically created controls (*ngIf, *ngFor, etc.). Uses native [autofocus] selector, no need to change your HTML template. Doesn't use any dependencies.","archived":false,"fork":false,"pushed_at":"2023-01-07T09:00:45.000Z","size":1378,"stargazers_count":37,"open_issues_count":27,"forks_count":9,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-18T19:52:27.467Z","etag":null,"topics":["angular","angular-autofocus","angular-autofocus-fix","angular2","angular2-autofocus","angular2-focus","angular5","angular6","angular7","angular8","angular9","autofocus","autofocus-directive","ng","ng-autofocus","ng2","ng2-autofocus","ng8"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/korniychuk.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-06-23T11:04:41.000Z","updated_at":"2024-07-08T03:32:36.000Z","dependencies_parsed_at":"2023-01-15T13:20:57.621Z","dependency_job_id":null,"html_url":"https://github.com/korniychuk/angular-autofocus-fix","commit_stats":null,"previous_names":["ancor-dev/angular-autofocus-fix"],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/korniychuk%2Fangular-autofocus-fix","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/korniychuk%2Fangular-autofocus-fix/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/korniychuk%2Fangular-autofocus-fix/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/korniychuk%2Fangular-autofocus-fix/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/korniychuk","download_url":"https://codeload.github.com/korniychuk/angular-autofocus-fix/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251585710,"owners_count":21613267,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["angular","angular-autofocus","angular-autofocus-fix","angular2","angular2-autofocus","angular2-focus","angular5","angular6","angular7","angular8","angular9","autofocus","autofocus-directive","ng","ng-autofocus","ng2","ng2-autofocus","ng8"],"created_at":"2024-11-11T23:08:05.428Z","updated_at":"2025-04-29T21:30:25.296Z","avatar_url":"https://github.com/korniychuk.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ngx-autofocus-fix\n\n\u003c!-- BADGES --\u003e\n[![CircleCI](https://img.shields.io/circleci/build/github/korniychuk/angular-autofocus-fix?token=none)](https://circleci.com/gh/korniychuk/angular-autofocus-fix/tree/master)\n[![Coverage Status](https://coveralls.io/repos/korniychuk/angular-autofocus-fix/badge.svg?branch=master)](https://coveralls.io/r/korniychuk/angular-autofocus-fix?branch=master)\n[![npm version](https://img.shields.io/npm/v/ngx-autofocus-fix)](https://www.npmjs.com/package/ngx-autofocus-fix)\n![npm downloads](https://img.shields.io/npm/dw/ngx-autofocus-fix)\n[![Known Vulnerabilities](https://snyk.io/test/github/korniychuk/angular-autofocus-fix/badge.svg)](https://snyk.io/test/github/korniychuk/angular-autofocus-fix)\n\u003c!-- /BADGES --\u003e\n\nAngular 5+ directive for fix autofocus on dynamically created controls (`*ngIf`, `*ngFor`, etc.).  \n[legacy version for Angular 2/4](https://github.com/korniychuk/angular-autofocus-fix/tree/legacy-version)\n\n[Online Demo](https://stackblitz.com/edit/ngx-autofocus-fix-demo) (Stackblitz.com)\n\n![Autofocus Demo](demo.gif)\n\n## Advantages over the other libraries\n\n* **Uses native HTML attribute `autofocus` as the selector!** [example](#quick-start)\n* There are no custom selectors, no need to change your HTML template.\n* Works with native DOM. Doesn't use any dependencies(jQuery, lodash, etc.).\n* [Configurable](#configuration). Use can use input attributes or provide global options via `AutofocusFixConfig`\n* 100% Coverage, over 60 unit tests.\n* E2E tests for 8,7,6 and 5 versions of Angular including e2e test for Angular Material Input.\n* The library understands an extensive list of input data. (`null/NaN/'true'/[]/...`). See [Advanced examples](#advanced-examples)\n* Supports asynchronous focusing(optionally wrapping `.focus()` execution with `setTimeout()`).\n* Works perfectly with Angular Material. (there is an E2E test)\n* Works with AOT mode. (tested via E2E test)\n\n## Installation\n\nNotice: npm package renamed `angular-autofocus-fix` -\u003e `ngx-autofocus-fix`\n\nTo install this library, run:\n\n```bash\n$ npm i ngx-autofocus-fix --save\n```\nor\n```bash\n$ yarn add ngx-autofocus-fix\n```\n\n## Quick start\n\n1. Import the library in your Angular application, for example in `AppModule`:\n\n```typescript\nimport { BrowserModule } from '@angular/platform-browser';\nimport { NgModule } from '@angular/core';\n\nimport { AutofocusFixModule } from 'ngx-autofocus-fix'; // \u003c--- new code\n\nimport { AppComponent } from './app.component';\n\n@NgModule({\n  declarations: [\n    AppComponent,\n  ],\n  imports: [\n    BrowserModule,\n\n    AutofocusFixModule.forRoot(), // \u003c--- new code\n  ],\n  providers: [],\n  bootstrap: [ AppComponent ]\n})\nexport class AppModule { }\n```\n\n2. You can now use autofocus directive in app.component.html\n\n```html\n\u003cinput autofocus\n       placeholder=\"I have autofocus\"\n       *ngIf=\"showInput\"\n\u003e\n\u003cbutton (click)=\"showInput = !showInput\"\u003eToggle Input\u003c/button\u003e\n```\n\n## Advanced examples\n\nWays to **disable autofocus:** any js-falsy value, except an empty string (default `@Input`'s [normalization mode](#inputs-smart-empty-check-normalization-mode))\n\n```html\n   \u003c!-- with data binding --\u003e\n   \u003cinput [autofocus]=\"\"\u003e \u003c!-- undefined value --\u003e\n   \u003cinput [autofocus]=\"undefined\"\u003e\n   \u003cinput [autofocus]=\"false\"\u003e\n   \u003cinput [autofocus]=\"null\"\u003e\n   \u003cinput [autofocus]=\"0\"\u003e\n   \u003cinput [autofocus]=\"NaN\"\u003e\n   \n   \u003c!-- without data binding --\u003e\n   \u003cinput autofocus=\"undefined\"\u003e\n   \u003cinput autofocus=\"false\"\u003e\n   \u003cinput autofocus=\"null\"\u003e\n   \u003cinput autofocus=\"0\"\u003e\n   \u003cinput autofocus=\"NaN\"\u003e\n   \n   \u003cinput\u003e \u003c!-- disabled by default --\u003e\n``` \n\nWays to **enable autofocus:** any js-truthy value and an empty string (default `@Input`'s [normalization mode](#inputs-smart-empty-check-normalization-mode))\n\n```html\n   \u003c!-- an empty string will enable autofocus, this is default HTML behavior --\u003e\n   \u003cinput [autofocus]=\"''\"\u003e\n   \u003cinput autofocus=\"\"\u003e\n   \u003cinput autofocus\u003e \u003c!-- this is an empty string too --\u003e\n   \n   \u003cinput autofocus=\"autofocus\"\u003e\n   \n   \u003cinput [autofocus]=\"true\"\u003e\n   \u003cinput [autofocus]=\"1\"\u003e\n   \u003cinput autofocus=\"true\"\u003e\n   \n   \u003cinput [autofocus]=\"'any other values'\"\u003e\n   \u003cinput autofocus=\"any other values\"\u003e\n\n   \u003cinput [autofocus]=\"{}\"\u003e\n   \u003cinput [autofocus]=\"[]\"\u003e\n```\n\n## Input's Smart Empty Check normalization mode\n\nAll input values are passed through the function: `normalizeInputAsBoolean(value: any, smartEmptyCheck = false): boolean`.\n\nSmart Empty Check mode changes the behavior so that the following values are treated as falsy:\n* An empty string `''`\n* An empty object `{}`\n* An empty array `[]`\n\nSee [Configuration](#configuration) to understand how to enable the mode.\n\n**Notes:**\n* Smart Empty Check normalization mode available only for `autofocus` attribute. All other directive `@Input`'s always works in the default normalization mode.\n* Using attribute `autofocus` without any value doesn't enable autofocusing in Smart Empty Check mode. Because of an empty value means an empty string in terms of Angular templates syntax. \n\n## Configuration\n\n### Options\n\n```typescript\nexport class AutofocusFixConfig {\n  ...\n\n  /**\n   * In case `true` .focus() events will be wrapped by `setTimeout(() =\u003e ...)`.\n   *\n   * Notice:\n   * I'm not sure that the action is a good practice, however this ability added because of next issues:\n   * - https://github.com/korniychuk/angular-autofocus-fix/issues/1\n   * - https://github.com/spirosikmd/angular2-focus/issues/46\n   */\n  public readonly async: boolean = false;\n  /**\n   * In case `true`: treat an empty string, an empty array and an empty object as a falsy value.\n   * In case `false`(default): each of these values treats as truthy.\n   */\n  public readonly smartEmptyCheck: boolean = false;\n  /**\n   * In case `true`: trigger {@link ChangeDetectorRef.detectChanges}() after {@link HTMLElement.focus}().\n   *\n   * This is helpful in the case when the HTMLElement to which {@link AutofocusFixDirective} added\n   * wrapped by another directive/component that has some binding related to focus of the element.\n   * In this case without enabling .triggerChangeDetection option Angular throws ExpressionChangedAfterItHasBeenCheckedError.\n   *\n   * A striking example is the \u003cmat-form-field\u003e from the Angular Material that wraps \u003cinput\u003e control.\n   */\n  public readonly triggerDetectChanges: boolean = false;\n}\n```\n\n### There are four ways to configure the `AutofocusFixDirective`:\n\n**1. Specify attribute-options for specific HTML Element**\n   ```html\n   \u003cinput type=\"text\"\n          autofocus\n          autofocusFixAsync\n          autofocusFixSmartEmptyCheck\n          autofocusFixTriggerDetectChanges\n   \u003e\n   ```\n   [Normalization](#inputs-smart-empty-check-normalization-mode)(only default) available and binding supported.\n   ```html\n   \u003cinput type=\"text\"\n          autofocus\n          [autofocusFixAsync]=\"true\"\n          [autofocusFixSmartEmptyCheck]=\"true\"\n          [autofocusFixTriggerDetectChanges]=\"true\"\n   \u003e\n\n   \u003cinput type=\"text\"\n          autofocus\n          autofocusFixAsync=\"true\"\n          [autofocusFixSmartEmptyCheck]=\"isSmart\"\n          autofocusFixTriggerDetectChanges=\"a truthy value\"\n   \u003e\n   ```\n\n**2. Specify global options for the whole application by passing it to `.forRoot({ ... })`**\n  ```typescript\n  @NgModule({\n    ...\n    imports: [\n      ...\n      AutofocusFixModule.forRoot({\n        async: true,\n        smartEmptyCheck: true,\n        triggerDetectChanges: true,\n      }),\n    ],\n    ...\n  })\n  export class AppModule { }\n  ```\n\n**3. Provide Lazy-Route level `AutofocusFixConfig` config**\n\n  ```typescript\n  import { NgModule } from '@angular/core';\n  import { AutofocusFixModule, AutofocusFixConfig } from 'ngx-autofocus-fix';\n\n\n  const autofocusFixConfigProvider: Provider = {\n    provide: AutofocusFixConfig,\n    useValue: new AutofocusFixConfig({\n      async: true,\n      smartEmptyCheck: true,\n      triggerDetectChanges: true,\n    }),\n  };\n\n  @NgModule({\n    ...\n    imports: [\n      ...\n      AutofocusFixModule,\n    ],\n    providers: [ autofocusFixConfigProvider ],\n  })\n  export class MyLazyLoadableModule { }\n  ```\n\n**4. Provide Component level `AutofocusFixConfig` config**\n  ```typescript\n  import { Component, Provider } from '@angular/core';\n  import { AutofocusFixConfig } from 'ngx-autofocus-fix';\n\n  const autofocusFixConfigProvider: Provider = {\n    provide: AutofocusFixConfig,\n    useValue: new AutofocusFixConfig({\n      async: true,\n      smartEmptyCheck: true,\n      triggerDetectChanges: true,\n    }),\n  };\n\n  @Component({\n    ...\n    providers: [ autofocusFixConfigProvider ],\n  })\n  export class MyComponent {}\n  ```\n\n\n## Development\n\nBuild the library:\n\n```bash\n$ npm run build\n```\n\nPublish the library:\n\n```bash\ncd dist/ngx-autofocus-fix\nnpm publish\n```\n\nTo lint all `*.ts` files:\n\n```bash\n$ npm run lint\n```\n\nTo run library unit-tests:\n\n```bash\n$ npm run test-lib\n```\n\nTo run e2e tests:\n\n```bash\n$ npm run e2e -- --prod=true\n```\n\nTo run local dev server [http://localhost:4200](http://localhost:4200):\n\n```bash\n$ npm start\n$ npm run serve:prod -- angular-8-test # AoT \u0026 Prod env\n```\n\n## Author\n\n| [\u003cimg src=\"https://www.korniychuk.pro/avatar.jpg\" width=\"100px;\"/\u003e\u003cbr /\u003e\u003csub\u003eAnton Korniychuk\u003c/sub\u003e](https://korniychuk.pro) |\n| :---: |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkorniychuk%2Fangular-autofocus-fix","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkorniychuk%2Fangular-autofocus-fix","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkorniychuk%2Fangular-autofocus-fix/lists"}