Johan Faerch
Johan Faerch

Reputation: 1206

Can I use multiple @hostlistener or events based on browser?

I'm using @hostlistener in Angular7 directive. Can I use more than one event on this?

Problem is that listening for the 'keydown' event is fine on anything but Android as the latter has no key events.

Switching to 'input' event solves this problem but doesn't cover Firefox (and probably Edge) as there's no 'inputType' (and other things) on the latter which causes the actual input field to allow any input.

So my goal is to be able to use 'keydown' for Firefox and Edge and use 'input' for anything else. Is that possible?

Used 'keydown', 'keypress' and 'input' events

    @HostListener('input', ['$event'])
    onInput(event: any) {
        this.parseKeyDown(event);
    }
    parseKeyDown(event: any) {
        if (event.inputType === 'deleteContentBackward' || event.inputType === 'deleteContentForward') {
            let str = this.ngModel.substr(0, this.ngModel.length - 1);
            if (str.length === 0) {
                str = '0';
            }
            // handle 'str'
        }
...
        if (e.inputType === 'insertText' && e.data.match(this.regex)) {
            // handle ngModel
        }
    }

Code shortened for readability.

This works in anything but Firefox/Edge where pressing backspace or delete keys deletes the last char. In Firefox the field just falls back to a text field, allows any GUI input and doesn't update ngModel.

Since there's no 'inputType' in Firefox nothing happens.


EDIT My solution

    @HostListener('keydown', ['$event'])
    @HostListener('input', ['$event'])
    onInput(e: any) {
        this.parseKeyDown(e);
    }

    parseKeyDown(e: any) {
        const key = e.key;
        if (key) { // Browsers WITH key events
...
        } else { // Browsers WITHOUT key events
            const data = e.data;
            const inputType = e.inputType;
...

Upvotes: 30

Views: 31742

Answers (1)

alt255
alt255

Reputation: 3576

With @hostlistener you can listen to single event with a single decorator. If you want to listen for multiple events you can add multiple @hostlistener to a single function e.g

@HostListener('click', ['$event'])
@HostListener('mouseover', ['$event'])
onEvent(event) {
    console.log(event)
}

If it's not desirable you can hook into Angular Event Manager Plugin and customize it. Here is an article show this.

Upvotes: 60

Related Questions