I tried many variations based on answers here but none worked, the KeyboardEvent never sets value on the input.
How can I simulate a user typing characters?
Unit test:
@Component({
selector: 'app-test-container',
template: `
<div>
<label for="integerValue">Integer Value</label>
<input id="integerValue" type="text" class="form-control"
formControlName="IntegerValue" appOnlyInteger>
</div>
`
})
class MyComponent {}
fdescribe('IntegerOnlyDirective', () => {
let fixture: ComponentFixture<MyComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [MyComponent, IntegerOnlyDirective],
}).compileComponents();
fixture = TestBed.createComponent(MyComponent);
fixture.detectChanges();
});
it('should accept integer as is', async () => {
fixture.detectChanges();
await fixture.whenStable();
const inputElement: HTMLInputElement =
fixture.debugElement.nativeElement.querySelector('input[type=text]');
inputElement.dispatchEvent(new KeyboardEvent('keydown', { key: '1' }));
fixture.detectChanges();
expect(inputElement.value).toBe('1'); // FAILS -> value is ''
});
});
Directive
@Directive({
selector: '[appOnlyInteger]'
})
export class IntegerOnlyDirective {
constructor(private el: ElementRef) { }
@HostListener('input', ['$event']) onKeyDown(event) {
const initialValue = this.el.nativeElement.value as string;
// Will only keep the positive integers because any other character than digit is ignored
// g for global, to catch all matches
this.el.nativeElement.value = initialValue.replace(/D*/g, '');
}
}