UPDATE
onScan.js is the successor of jQuery.ScannerDetection with proper support for Bower and npm and zero dependencies (no jQuery needed!). It has more features and is licensed under the MIT.
The principles of using a barcode reader with jQuery were discussed one of my previous articles, which also shows, why I chose jQuery.ScannerDetection for my projects and what alternatives there are. In short, jQuery.ScannerDetection is a lightweight plugin, which makes it possible to register handlers, listening to scan events from a keyboard-mode barcode scanner. It uses different types of detection mechanisms at the same time, so it is not neccessary to configure the scanner in any special way. This, in turn, allows to conntect different scanner models to your application at the same time!
Quick start
- Download jQuery.ScannerDetection from here.
- Add the following lines to the head of each page of your application, where you want to use a scanner
<script type="text/javascript" src="your_path/jquery.scannerdetection.js"></script> <script type="text/javascript"> $(document).scannerDetection({ timeBeforeScanTest: 200, // wait for the next character for upto 200ms startChar: [120], // Prefix character for the cabled scanner (OPL6845R) 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 onComplete: function(barcode, qty){ ... } // main callback function }); </script>
This is my universal setup, that works well for all tested scanners. The complete docs on every single option can be found in the readme of the project.
Figuring out start and end characters
The first thing to do, when connecting a new scanner model is to figure out, what character codes it sends before and after the actually scanned code. The easiest way to do this, is to log all keys pressed by adding a callback to the onKeyDetect event in jQuery ScannerDetection:
$(document).scannerDetection({ ... onKeyDetect: function(event){console.log(event.which); return false;} ... });
Now you will see a list of all detected keys (charCodes) in the console right after you scan a code. Here is a nice table of possible charCodes. Put the charCodes before the first character of the actual code in startChar and those after the last code character in endChar. Note, that if the scan-button acts as a key itself, the charCode of that key will typically preceed the entire code. You can find the key code of the scan button by pressing it without pointing the scanner at a barcode - if a key is detected, it's your hardware button. We will discuss possibilities to use the scan button in further chapters.
JS console on mobile devices
If your scanner is connected to (or built into) a mobile device, you can use the DevTools-library Eruda to make the console visible.
Scanner settings
The table below shows the settings per scanner in detail. All scanners were used in stock configuration. In principle, most of them can be configured to send specific prefixes and suffixes. In this case, those characters will need to be added to startChar and endChar respectively. I do not recommend using visible characters though, because they will need to be stripped back off every time you want to use the scanned barcode in your application and the user will not be able to use the scanner simply to fill an arbitrary input field.
Opticon OPN2006 | Opticon PX-20 | Scanfob OPN2002 | Motorola CS3070 | MioWork A125 | MioWork L135 | Opticon OPL6845R | DataLogic Touch65 | DataLogic GD4430 / HP4430 | BLUEBIRD BM180 | |
---|---|---|---|---|---|---|---|---|---|---|
Interface | Bluetooth | Bluetooth | Bluetooth | Bluetooth | Built-in | Built-in | USB | USB | USB | Built-in |
Scanner type | 1D laser | 2D CMOS | 1D laser | 1D laser | 1D laser | 2D CMOS | 1D laser | 1D laser | 2D laser | 2D laser |
avgTimeByChar | 40 | 40 | 40 | 40 | 40 | 40 | 40 | 40 | 40 | 40 |
startChar | 120 | |||||||||
endChar | 13 | 13 | 13 | 13 | 0 | 0 | 13 | 13 | 13 | |
timeBeforeScanTest | 200 | 200 | 200 | 200 | 200 | 200 | 200 | 200 | 200 | 200 |
scanButton KeyCode |
116 | 116 | ||||||||
scanButton LongPressThreshold |
3 | 3 | ||||||||
Note | Must set "DataWedge Type" to "Keyboard" | Tend to glue multiple codes together | Must set "DataWedge Type" to "Keyboard" |
Scan modes of built-in scanners (especially on Android)
Most barcode readers simply act as a (very fast) keyboard, but built-in devices like the ones in Android PDAs (like the MioWork series or BlueBird handhelds), can either emulate a keyboard or the clipboard. I have noticed, that the clipboard mode is the default setting in most cases. Be sure to change it to keyboard emulation to work with jQuery.ScannerDetection! The difference is, that the entire code is "pasted" at once if in clipboard mode, while being typed character-by-character when emulating a keyboard.
Scanning speed
Scanning speed is very important. People using the barcode readers every day will tend to scan pretty quickly, so you need to take care of not missing events. Keeping the avgTimeByChar as low as possible is generally a good idea. If you set it too low however, you will only receive part of the code, which will probably be not usable. Setting it to high will result multiple codes glued together or some simply missing.
In any case, I recommend creating a fallback in your event handler to check for two codes glued together: just try splitting the received code in halfs if it seems wrong before you throw an error.
You can also play around with timeBeforeScanTest too, but I have not noticed much difference so far.
Ignoring focused inputs
In most cases, it is a good idea not to handle barcodes, which were read while an input field was explicitly focused. This gives the user the possibility to scan barcodes into arbitrary inputs like filters, etc.. You can turn off scanner detection for focused elements matching a specific jQuery selector by specifying the ignoreIfFocusOn option. To exclude all input elements, set it to ignoreIfFocusOn: 'input' or use a special class like ignoreIfFocusOn: '.scannerOff'.
Using the hardware scan button
Some build-in scanners in Android devices will have hardware buttons for scanning. These behave often like a keyboard key themselves. If you register the respective key codes as scanButtonKeyCode, you can count, how many times the user presses the button. This is very usefull to increase scanning speed. The tested Mio enterprise tables, for example, are not really fast at scanning, but they will send a scan button keyCode. Thus, if the user presses the button multiple times in a row, the application will probably only receive the scanned code once. However, counting, how many times the button was pressed, still lets us know, that the user actually conducted multiple scans. Use this, if your app uses scanning for counting (e.g. at goods-in).
Another way to use the hardware button is enabling the user to long press it for a special action. Coming back to the previous counting example, a long press might result in a virtual number pad popping up on the screen to allow comfortable direct input of larger quantities. You can register a listener on the onScanButtonLongPressed event to build such functions. A long press is detected if the scan button code is received multiple times in a row - you can set the threshold via scanButtonLongPressThreshold.
Scanner detection with jQuery mobile
Since I actually focus on mobile devices, I also needed the barcode readers to work with jQuery mobile. This is slightly more difficult, because enabling it for $(document) would make the entire app listen for barcode scans, regardless of what page is active right now. This is, of course, only true for single-page apps using AJAX to load pages, but that is exactly what I prefer in jQuery mobile. The solution was to enable scanner detection on $(document) at the time specific pages were loaded and disable it again when those pages were hidden (using pageshow and paghide events).
$(document).on('pageshow', '#pageId', function(){ $(document).scannerDetection({ avgTimeByChar: 40, onComplete: function(barcode, qty){ ... }, onError: function(string){alert('Error ' + string);} }); }); $(document).on('pagehide', '#pageId', function(){ $(document).scannerDetection(false); });
Using the built-in camera on mobile devices
Last but not least, scanning barcodes and QR-codes does not necessarily mean using a real barcode scanner. Take a look at the alternatives using the built-in camera on mobile devices: Reading barcodes with the QuaggaJS library or even some options without any JavaScript.