Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

angular

events

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;
...
like image 417
Johan Faerch Avatar asked Apr 13 '19 16:04

Johan Faerch


People also ask

Can we use HostListener in service?

Seems like its not possible to use HostListener in a service. like Stanislasdrg Reinstate Monica wrote, there's a more elegant and more angular way using the renderer.. You could use the old way window. addEventListener like @yurzui pointed out already.

Can we use HostListener in component?

Introduction. @HostBinding and @HostListener are two decorators in Angular that can be really useful in custom directives. @HostBinding lets you set properties on the element or component that hosts the directive, and @HostListener lets you listen for events on the host element or component.

What are the HostListener events in angular?

@HostListener is Angular's decorator method that's used for listening to DOM events on the host element of both component and attribute directives. @HostListener sets the listeners once the directive is initialized and removes them automatically once the directive gets destroyed.

What is the use of HostListener?

HostListenerlink Decorator that declares a DOM event to listen for, and provides a handler method to run when that event occurs.


1 Answers

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.

like image 126
alt255 Avatar answered Oct 17 '22 21:10

alt255