Keypress events without a focused input


#1

Hello,

I am trying to integrate bluetooth hardware barcode scanner into my Ionic app. The scanner emulates a keyboard device according to the Human Interface Device standards. The scanner’s output can be directed into any input field where keyboard entry can occur.

But this is not the case I’m trying to solve. I need to acquire the virtual keystrokes generated by the scanner when there is no active input focus - no HTML5 input. I created a document level keypress event handler that works perfectly when running the app within Safari on Mac OS X. In my UI I have no inputs that take keyboard entry. When I scan a barcode my document-level keypress handler gets all the events. Perfect.

However, when running the same Ionic app on iOS, I get no events. After some experimentation, I determined that the document receives keypress events only if focus is on an input field. This is not what I want. An input field, even if off screen, causes the soft keyboard to raise. It also can easily lose focus if the user taps somewhere.

I can’t figure why the document-level keypress handler that works perfectly for the Ionic app running in Safari on OS X does not receive keypress events from the external keyboard on iOS. I tested a vanilla Cordova app as well. I don’t think it has anything to do with Ionic. I’m really stuck here. Any ideas?

Here’s the top level keypress-events directive that is attached to the body element. Try it out. You’ll see you can bang away at the keyboard within an Ionic UI that has no inputs in a browser and it works just fine – gets all the events. Run it on iOS and it’s deaf.

...
.directive (
'keypressEvents', function ($document, $rootScope) {
   return {
      restrict: 'A',
      link: function () {
         $document.bind (
            'keypress', function (e) {
               console.debug ("keypress:" + e.which, "'"
                  + String.fromCharCode (e.which) +"'");
               $rootScope.$broadcast ('keypress', e, String.fromCharCode (e.which));
            });
      }
   }
})

Thanks
Jason


#2

I am seeing the same behavior. Did you ever figure out something w/out a focused input field?


#3

Hi,

I found that I wasn’t the only one having this problem as well. Sadly, on iOS there is no solution because the ability to for the app to receive keystrokes from a barcode scanner device, acting as a bluetooth keyboard, is dependent on Apple’s UIWebView. The underlying implementation only accepts keystrokes and passes them onto Cordova/Ionic when focus is on a field into which ordinary keystrokes can be made. This also has the effect of – raising the soft keyboard. I found the only solution short of using a plugin to drive the scanner (e.g. Socket Mobile SDK) is to create a UI text field that could receive the scanner input. I know that answer sucks, but it seems to be the reality of the situation. It’s too bad that it doesn’t behave the same way Safari (or any other browser) behaves on the Mac OS X desktop.


#4

Hi Jason,

I am currently trying to address this same issue. I have built an app for scan fulfilment of ecommerce orders that involves several scan events from pick tote to location to items. Input boxes are proving to be a pain with .setFocus appearing to be unreliable and it being too easy for a user to lose focus if they touch the screen.

I am wondering if you ever found a better solution? I can see a number of cordova plugins available for other scanners including Linea Pro which is pretty popular but we already have very good motorola scanners which suit our operations better as they are not attached to the device like the Linea Pro would be.

Have you come across any other novel solutions since you last posted here?

Thanks


#5

I’ve ended up forking a plugin that I found and it works great.


#6

Hi Codiqa,

I’m looking for a solution from many days, could you please share the code snippet or the way how did you used cordova-externalkeyboard plugin helped you solve the issue.


#7

Please post the solution here, so that it will be useful for others too