UPDATE
In 2019 I have published a new library to work with barcode scanners: onScan.js. It is not jQuery-specific and works in any JavaScript environment. It also uses improved scanner detection algorithms and supports paste-mode in addition to keyboard-mode.
Most barcode scanners have a keyboard-emulation-mode: once you scan a barcode, the scanner "types" the scanned string just like a keyboard would do, if you would type it. So if you connect a barcode scanner to your PC, tablet or smartphone, click on an input field to set focus and scan a barcode, it's value will be typed into the field without any extra coding!
While this sure is a "quick win", this simplest approach is barely suitable for every-day use, just because it requires you to select exactly where you want the barcode to be scanned to every time. In other words, if you press a button, a link, or change the focus in any other way, the next scanned value will land somewhere else or just be ignored. A better idea would be to react on the event of a barcode scan explicitly, so that some handler function is called every time a barcode is scanner - regardless of what the user had been doing.
Holding apart scanner and keyboard
If you want to catch barcode scans in JavaScript, you need to make sure, you can distinguish them from regular keyboard typing. This is not so easy, as the scanner is just another keyboard from the point of view of your device, so a scan just results in regular keyboard events. The main idea is to listen to any keyboard event on a scan-enabled document and to decide then, whether it comes from the scanner or the keyboard. I have run across the following approaches so far:
- Measure the time between key strokes and assume a barcode if the keys are pressed quickly enough. This works pretty well, because even a bluetooth scanner only needs 20-60 ms to "press" a key. Noone will be able to type that fast.
- Configure the scanner to send some special prefix and suffix characters. If a prefix character is detected, assume that all following characters are a barcode and collect them. Stop collecting, once the suffix character is received. Assuming you pick characters, that are not present on a regular keyboard, this should also work well. However, you loose the possibility to use the scanner for regular inputs into fields without explicit scanner support. It is also not obvious, what to do if the suffix character never comes...
- Use a combination of the two methods above
- If the scanner has a physical scan button, that acts as a separate key, you could take that as the prefix character. This is only the case for built-in scanners. Bluetooth scanner just send the barcode. Apart from that you still don't know when the code ends (like in 2.). Additionally, pressing the scan button does not nesseserily mean, that a barcode is scanned - you can press it any time and it still will act as the same key.
- Try to work with the API of a built-in scanner of a mobile device directly via phonegap or similar software. The biggest advantage of this approach is that you might (depending on the API of course) get the code type along with the value. This can be very important if your application needs to work with barcodes with different encoding and possibly equal values. However, the result would be a real app for a mobile platform, not a web application.
From my point of view, the most versatile approach is mainly relying on the typing speed, but also using a suffix key code (ideally "enter", as it would also play nice with regular inputs). Additionally listening for the hardware button key code is very helpful for built-in scanners.
Available jQuery plugins
If have tried two jQuery plugins for barcode scanner support and ended up extending one of them:
- anysearch.js - it binds handlers to any kind of input not targeted on a specific input field and has additional support for barcode scanners. However, it does not seem to be actively maintained anymore. Apart from that I did not get it to work with the built-in scanners of MIO Work tablets for some reason: it simply did not react on the scans in any way. Still, the idea of just typing something without setting focus on a UI element and getting some meaningfull result is pretty nice.
- jQuery Scanner Detection - this one is made exclusively for barcode scanners, is very compact (<200 lines of code) and works fine with all scanners I have tested. I have added the support for prefix characters, hardware buttons and a possibility to disable the scanner detection if certain elements have focus. The last feature is usefull to enable the user to scan barcodes into any input field and thus using them for something else than the default scan action.
Basic usage
jQuery Scanner Detection is really easy to use: just call $(document).scannerDetection( {params...} ) and pass a handler function in the parameters and it will get called every time a barcode is scanned. See my tutorial for jQuery.ScannerDetection for step-by-step guide and more details on getting evertything set up. Here is a complete example:
$(document).scannerDetection({ timeBeforeScanTest: 200, // wait for the next character for upto 200ms endChar: [13], // be sure the scan is complete if key 13 (enter) is detected avgTimeByChar: 40, // it's not a barcode if a character takes longer than 40ms ignoreIfFocusOn: 'input', // turn off scanner detection if an input has focus onComplete: function(barcode, qty){ ... }, // main callback function scanButtonKeyCode: 116, // the hardware scan button acts as key 116 (F5) scanButtonLongPressThreshold: 5, // assume a long press if 5 or more events come in sequence onScanButtonLongPressed: showKeyPad, // callback for long pressing the scan button onError: function(string){alert('Error ' + string);} });
In this example you can also see some of my extensions in action: there is a keycode specified for the hardware scan button and a separate callback in case a user holds it down. That "holding down" will be detected if the keydown event fires five times or more before the scanned string.
Conclusion
As you see, it is technically very easy to read barcodes and qr codes with a barcode scanner in (mobile) web applications. You don't even need to care about the specific scanner model used. Much more tricky is getting the usability right. Think carefully about where and when the user will try to scan something and what he would expect the app to do.
On mobile devices one of the most important aspects of usability is, in fact, whether you need one or two devices.With a bluetooth barcode scanner the user will need both hands to operate the bundle of smartphone or tablet and the scanner - thus, there just won't be a hand left to hold the item to scan. For occasional scans a good solution might be using the built-in camera of the mobile device: there are various JavaScript libraries that support mobile cameras and even some solutions on that do not need any JS coding.