I posted the same question on Stackoverflow but got no answer. Maybe it is better suited in this forum. I’m currectly working on Android TV controls in Ionic 3.3.0 with Cordova 7.0.1. Since the device has no touchscreen I have to use the remote control. I’m using
@HostListener('document:keydown', ['$event'])
handleKeyboardEvent(event: KeyboardEvent) {
// Check the key code and determine the next element to focus
// ...
// Focus the element
this.renderer.invokeElementMethod(nextElement._elementRef.nativeElement,'focus');
}
to check for remote control pushes to change focus. This works fine. When the enter key is pressed I want that the click action of the button is activated. Now i tried using something like
@HostListener('document:keydown', ['$event'])
handleKeyboardEvent(event: KeyboardEvent) {
if(event.key == 'Enter') {
var focusedButton = Helper.getCurrentlyFocusedButton();
focusedButton._elementRef.nativeElement.click();
// Using the debugger I know that these lines are triggered, but nothing happens
}
}
to programmatically press the button. This works fine when using ionic serve with Chrome but doesn’t work on the Android device (Sony KD-49XD7005 with Android TV 6.0.1). As far as i could gather from googling, this is because click() is not supported. But there must be another way to trigger this event? I also tried to create touch events manually
var e1 = document.createEvent('TouchEvent'); // Also tried 'UIEvent'
e1.initEvent('touchstart', true, true);
var e2 = document.createEvent('TouchEvent');
e2.initEvent('touchend', true, true);
this.renderer.invokeElementMethod(focusedButton._elementRef.nativeElement, 'dispatchEvent', [e1]);
this.renderer.invokeElementMethod(focusedButton._elementRef.nativeElement, 'dispatchEvent', [e2]);
// Also tried
// focusedButton._elementRef.nativeElement.dispatchEvent(e1);
// focusedButton._elementRef.nativeElement.dispatchEvent(e2);
but ultimately nothing worked. Is there any way to do this?
I figured it out myself by looking at the source code of ionic-angular. In the file node_modules/ionic-angular/tap-click/tap-click.js is a method that handles the click event. It calls another method called shouldCancelClick(ev) which returns true when this.dispatchClick is undefined or false. this.dispatchClick is set by pointerStart(ev) which is bound to the mousedown event.
So all that has to be done is to trigger a mousedown event before triggering the click event.
I solved it like this:
var e1 = document.createEvent('MouseEvents');
e1.initEvent('mousedown', true, true);
focusedButton.dispatchEvent(e1);
var e2 = document.createEvent('MouseEvents');
e2.initEvent('click', true, true);
focusedButton.dispatchEvent(e2);
I didn’t find any generic solution to solve I navigation, so I had to write that logic myself. Basically checking which item has the focus, finding out where it is in relation to the other items and then deciding which will be the next item based on the keypress.
Hey @markusmr, could you elaborate a bit and maybe even include some code? I have to do the same things soonish, so I would appreciate any pointers and ideas.
If you have anything other than a list, things get complicated since, rather than simply using the index, you have to involve the position the find the next element. But I never got around to actually implementing that. I hope that was at least a little helpful. Good luck!