(iOS) Capture event from non-ascii keys - ios

I am trying to subscribe to the physical keyboard events (non-ASCII keys) in my app written with Ionic Framework (issue occurs when I am trying to reach page launched by ionic serve, deploying app on my ios device or run it in ios emulator from xcode).
<div tabindex="1" (keyup)="onKey($event)" (keydown)="onKey($event)" (keypress)="onKey($event)"></div>
In the onKey function I'm just printing on screen info about which key was hit:
onKeyDown(event: any): void {
console.log(JSON.stringify(event.key));
}
This function works as expected, until I will hit one of non-ascii keys:
command,
control,
option,
arrow_up,
arrow_down,
arrow_left,
arrow_right,
caps lock,
shift
They are just not logged. I don't get any error message, nothing. When running ionic serve in the regular browser, everything works.
What should be mentioned. Those keys works correctly (ie I can navigate within textarea with arrow keys).
I tried also plain JavaScript:
document.onkeydown = function(evt) {
evt = evt || window.event;
alert(evt.keyCode);
};
Same result - works with arrow keys on desktop, not works on iPad.
As another try, I used angular hotkeys, but this library doesn't work on the ios device.

Try keydown event. Unlike the keypress event, the keydown event is fired for keys that produce a character value and for keys that do not produce a character value.

Related

pagehide and/or beforeunload not firing in IOS Chrome, Safari

I'm trying to prompt the user whenever he/she tries to navigate away from the current browser (refresh, close tab and window, clicking back button from the browser). I'm having this issue on IOS mobile that it does not fire pagehide and/or beforeunload.
I'm aware that Safari does not support beforeunload event anymore so I've added an event listener for pagehide with similar logic, and that too does not fire. Code is written in angular.
Approach tried:
// Method decorator, Did not work for both
#Hostlistner(window:pagehide), #Hostlistner(window:beforeunload)
doSomething(event:any){
event.returnValue = true;
return true;
}
// Component host property, Also tried this on beforeunload, did not work for both
#Component({
...
host: "(window:pagehide)" : "doSomething($event)"
})
// Plain javascript, have tried pagehide too, did not work for both
window.onbeforeunload = (event) => {
event.returnValue = true;
return true;
};
//Also tried binding it via addEventListener method of window/document, did not work for both
window.addEventListener('beforeunload', (event) => {
this.log("before unload");
event.returnValue = true;
return true;
});
I have been trying it via stackblitz: https://stackblitz.com/edit/angular-qkezha?file=src%2Fapp%2Fapp.component.ts.
Device use for testing the issue: IPhone 6, IOS 12.1
Issue arise on Mobile IOS both for Chrome and Safari, have not tested it in yet in Firefox but I doubt that it will work on there too. Code works on Android Chrome and Windows Desktop Chrome.
I've been on this for several days now. Searching here and there. Any help or hints is very much appreciated.

Interactions are not available for this element in Appium

I am getting the following message while identifying element the highlighted element in “Appium”.
Appium: 1.7.1
Device: IPhone X (12.0 & Simulator)
Java client: 1.6.1
Xcode: V 10
Interactions are not available for this element.
Appium- IOS
Aim to read the content of the element using .gettext() method.
Logic used.
// Explicit wait with 30 seconds.
return driver.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(WebElement))).getText();
WebElement used.
1, /XCUIElementTypeApplication[#name=“Event Manager”]/XCUIElementTypeWindow1/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther[3]/XCUIElementTypeOther
2, //XCUIElementTypeOther[3]/XCUIElementTypeOther
None of the above return the text that are there in the image. Also no exception/error thrown as well.
Any help on what else can be done to read the web element?
I am facing the same problem where icons having some kind of call to action are not tappable when test case is executed. These are easily identified when I capture it, but if the same is tried within a script, katalon is unable to find it.

IIOS IPAD No Unload,beforeunloador, paghide events

I have a MVC web database application where the records are basically documents with items.
Documents are locked, not items and they locked by code when the user looks in any of 4 or 5 different screens for any given document.
there is a 10 minute time out on the record locks. The user does not do anything with the record for 10 minutes and another can take the record. There is code that detects the lock was lost and taken by someone else. It works fine and is technically sound.
The workflow of the application relies on the lock being released when the user leaves the screen or closes the browser, or if they press the refresh button.
These are work fine on windows and android but not on ipad.
I understand there is no
beforeunload
on ios but I though there was
unload
or
pageHide
neither of these work.
Here is my code.
var isOnIOS = navigator.userAgent.match(/iPad/i)||
navigator.userAgent.match(/iPhone/i); var eventName = isOnIOS ?
"pageHide" : "beforeunload";
window.addEventListener(eventName, function (event) {
ReleaseRecordLock(); } );
This code works on all mentioned platforms except that the events don't fire on IOS.
It looks to me that this is deliberate on Apple's part so I an not thinking it will change.
So now the question.
What can I do to ensure that these records get unlocked if a user changes screens or closes the browser. If they don't no users will be able to access the document for 10 minutes which will not be acceptable.
Thanks
Edit... I don't need pop ups or notification. I just need reliable unlocking
As mentioned above none of the events that are supposed to work actually fire. pageHide and unload do nothing.
I found mentions of how to get around this problem but no details so I though I would detail it here.
This solutions works with areas and standard sites.
My solution to get around part of this was to detect if the browser is running on IOS and if so to change the link in the menu.
<li>
#{
if(Request.UserAgent.Contains("iPad") || Request.UserAgent.Contains("iPhone"))
{
<a onclick="IOSReleaseLock('controller', 'action')" href="javascript:void(0);">LinkText</a>
}
else
{
#Html.ActionLink("link Text","action","controller",new { Area = "Tasks" },null);
}
}
</li>
Every single link in the application has to have a function called IOSReleaseLock() available or the solution will not work. Not all pages lock records, only those that actually change documents. Reports, and basic website functions such as change password, log out, and the sys admin stuff do not need record locks.
At this point I have 2 versions of IOSReleaseLock()
This is the version that is used on pages that do not required unlocking.
function IOSReleaseLock(_controller, _action)
{
var url = '/__controller__/__action__/';
url = url.replace('__controller__', _controller);
url = url.replace('__action__', _action);
window.location.href = url;
}
This is the version that is placed on pages that required unlocking.
function IOSReleaseLock(_controller, _action )
{
var url = '/__controller__/__action__/';
url = url.replace('__controller__', _controller);
url = url.replace('__action__', _action);
UnloadingRecordLockRelease();
window.location.href = url;
}
Every link has a wrapper so every single page must load a version of IOSReleaseLock(). This includes your /home/index or where ever your application starts. If you miss one then once you are on that page your menu system links will not work anymore.
Pages that require the UnloadingRecordLockRelease() function load that version and the pages that do not require unlocking load the first version.
On IOS every time you click a link, IOSReleaseLock() is called. This may seem to be obvious, but for clarity, the version of IOSReleaseLock() that executes is the version that is on the current page, not the version on the page you are going to.
So as long as the user stays on the site and does not close the browser then the records are unlocked correctly.
When the user logs out all records are unlocked but I have no solution for when the browser tab is closed or when the browser is closed without the user logging out.

How to bind the HTML5::stalled event from soundmanager?

I'm trying to to write a javascript app that use the [SoundManager 2][1] api and aim to run in
all desktop and mobile browsers. On the iPad platform, Soundmanager is using the HTML5 audio api since there is on flash support. Now, when I'm trying to play two audio files back to back, both loaded in response to a click event, a [HTML5::stalled][2] event is occasionally raised. How do I set an event handler to catch the stalled event?
Since sound objects in my app are created on the fly and I don't know how to access directly to tags that are created by SoundManager, I tried to use a delegate to handle the stalled event:
document.delegate('audio', 'stalled', function (event) {...});
It doesn't work. the event did not raised in respond to stalled. (I had an alert in my handler).
Also tried to use [Sound::onsuspend()][3] to listen for stalled, but onsuspend pops out
on the end of sound::play(). How can we distinguish between stalled and other events that may raise the audio::suspend? Is there any other way to access the tags that SoundManager must create in order to play HTML audio?
I solved it with the following solution. This is not documented and found by reverse engineering.
It is all about accessing the html audio object, which is availalbe under _a.
currentSound = soundManager.createSound({..});
currentSound._a.addEventListener('stalled', function() {
if (!self.currentSound) return;
var audio = this;
audio.load();
audio.play();
});
The body of the method is based on this post about html5 stalled callback in safari
I can suggest a different "fix" I use with an html5 using platform (samsung smart TV):
var mySound = soundManager.createSound({..});
mySound.load();
setTimeout(function() {
if (mySound.readyState == 1) {
// this object is probably stalled
}
}, 1500);
This works since in html5, unlike flash, the 'readystate' property jumps from '0' to '3' almost instantanously, skipping '1'. ('cause if the track started buffering it's playable...).
Hope this works for you as well.

Capture backspace key press in BlackBerry with jQueryMobile

Is there a way to capture backspace key press on a input[type="text"] in BlackBerry? I have tried with $('input[type="text"]').bind('keydown', function(event) { ... }); and it captures all key press events except the one for the backspace (del). Pressing this key does not fire any key event.
Does anyone know a way to capture the event?
I am developing for OS 6.0 and testing with BlackBerry simulator 9800.
EDITED - the code that I am testing
<div id="myPage" data-role="page" data-theme="b">
<div data-role="content">
<input type="text" id="ddd" />
</div>
<script type="text/javascript">
$('input[type="text"]').bind('keydown', function(e){
if(e.keyCode == 8)
alert('backspace trapped')
});
</script>
</div>
I have just come up against this annoyance, and found this question in my search for answers, so here are details of my investigation and solution (well, workaround).
The keyup and keydown events simply will not be triggered on input or textarea elements in the Blackberry browser when the backspace key is pressed. It will, however, be triggered when the event handler is bound to the document:
$("#myInput").keydown(someFn); //Will not fire for backspace
$(document).keyup(someFn); //Will fire for backspace
Why this is the case, I have absolutely no idea. The keyup event should bubble, and it does, but since it doesn't even fire when you press the backspace key, that's not much use.
However, there is another event at our disposal. The input event is supported by the Blackberry browser, and correctly fires any time the value of the element changes (including, fortunately for us, when that change is due to a press of the backspace key).
Therefore, we can kind of workaround the problem by binding event handlers to both keydown and input. The keydown event will fire before input, except if the backspace key is pressed, in which case keydown won't fire. So we can keep track of that quite easily:
function handler(e) {
if (e.keyCode === 8) {
alert("Backspace!"); //Backspace was pressed :)
}
}
var elem = document.getElementById("example");
elem.addEventListener("keydown", function (e) { //Bind to keydown event
this.keydownFired = true; //Remember that keydown fired in expando property
handler.call(this, e); //Call the event handler
}, false)
elem.addEventListener("input", function (e) { //Bind to input event
if (!this.keydownFired) { //Keydown didn't fire, must have pressed backspace
e.keyCode = 8; //Fix the event object
handler.call(this, e); //Call the event handler
}
delete this.keydownFired; //Clean up so we can handle next key press
}, false);
Some notes:
As far as I can tell this is only an issue in the browser on Blackberry 6. I've tested Blackberry 5 (physical device and simulator) and 7 (simulator) and both will fire the keydown and keyup events for the backspace key.
This "fix" works in almost every single browser I have tested it in (so you can use it to properly support Blackberry 6 without breaking other browsers) except Opera Mobile (tested in version 12), which for some reason likes to fire the input event twice sometimes.
This only allows you to detect backspace presses when there is text in the input to delete (otherwise the input event doesn't fire). This is probably the biggest downfall of the script.
You can find a working example here, but for mobile device testing it's quicker to load the embedded version.
the following code, works fine. you can see it on jsfiddle . tested it on chrome
$(document).ready(function() {
$('input[type="text"]').bind('keydown', function(e){
if(e.keyCode == 8)
alert('backspace trapped')
});
});​
for Blackberry use
function captureBackButton() {
blackberry.system.event.onHardwareKey(blackberry.system.event.KEY_BACK,
function() {
alert('Backspace Pressed')
});
}
see detail
You can use this http://jsbin.com/ezucen/13/ to see what keycode you are getting back.
On BlackBerry 9900 7.1 I am getting keyCode 8.
There is no way to accomplish this in the general browser.
The only way to track the back key event using JavaScript is to use a
Widget/WebWorks application using KEY_BACK API.

Resources