Angular Auto Tab Directive : Auto focus on next field

Angular Auto Tab Directive
Keys Points:
- Created an Angular custom directive
- Move Focus to next input field
- If there is a condition true on first input field, focus should auto move to next field
- In this example – we have input fields like Employee Id and Employee Name. So Once User enters 4 digits in Employee Id field, cursor should move to next input field Employee name.
Directive:
import { Directive, HostListener, Input } from '@angular/core';
@Directive({
selector: '[libAutoTab]'
})
export class AutoTabDirective {
@Input() libAutoTab;
constructor() {}
@HostListener('input', ['$event.target']) onInput(input) {
const length = input.value.length;
const maxLength = input.attributes.maxlength.value;
if (length >= maxLength && this.libAutoTab) {
const field = document.getElementById(this.libAutoTab);
if (field) {
field.focus();
}
}
}
}
HTML :
Input field Employee Id and Employee Name is created inside a for loop based on received data in empList array. We also given dynamic Id to field based on index value.
<div>
<ng-container *ngFor="let emp of empList; let i = index">
<div class="form-group">
<label>Employee ID</label>
<input
type="text"
[libAutoTab]="'empName' + i"
[(ngModel)]="emp.empId"
maxlength="4"
name="empId"
class="form-control"
required
/>
</div>
<div class="form-group">
<label>Employee Name</label>
<input
[id]="'empName' + i"
type="text"
[(ngModel)]="emp.empName"
name="empName"
class="form-control"
required
/>
</div>
</ng-container>
</div>
Test Cases:
import { Component, DebugElement } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { AutoTabDirective } from './auto-tab.directive';
@Component({
template: `
<input
libAutoTab="{{ tabName }}"
value="test value"
maxlength="6"
id="testTab"
/>
`
})
class TestComponent {
tabName = 'testTab';
}
describe('AutoTabDirective', () => {
let fixture: ComponentFixture<TestComponent>;
let inputEl: DebugElement;
const directive = new AutoTabDirective();
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [TestComponent, AutoTabDirective]
});
fixture = TestBed.createComponent(TestComponent);
inputEl = fixture.debugElement.query(By.directive(AutoTabDirective));
}));
it('should create an instance', () => {
expect(directive).toBeTruthy();
});
it('should focus on element if length is greater than max length', () => {
const eventObj = {
target: {
value: inputEl.attributes.value,
attributes: { maxlength: { value: inputEl.attributes.maxlength } }
}
};
fixture.detectChanges();
inputEl.triggerEventHandler('input', eventObj);
const field = document.getElementById('testTab');
expect(document.activeElement).toBe(field);
});
it('should not focus on element if length is less than max length', () => {
const eventObj = {
target: {
value: 'test',
attributes: { maxlength: { value: inputEl.attributes.maxlength } }
}
};
fixture.detectChanges();
inputEl.triggerEventHandler('input', eventObj);
const field = document.getElementById('testTab');
expect(document.activeElement).not.toBe(field);
});
});
Running Demo
https://stackblitz.com/edit/angular-auto-tab-directive?embed=1&file=src/app/auto-tab.directive.ts
Lets see Useful VS Code extensions:
https://www.jsmount.com/vs-code-useful-extensions-for-web-development/
Lets run latest in Typescript :
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-9.html