I'm capturing input from a barcode scanner (which acts like keyboard input) and it works great, but I don't have access to a barcode scanner at the moment and need to test my code, so I need to simulate the barcode scanner (keyboard) input.
I thought triggering keypress
events for each character would work, but it doesn't. Here's my test code:
var barcodeScannerTimer;
var barcodeString = '';
// capture barcode scanner input
$('body').on('keypress', function (e) {
barcodeString = barcodeString + String.fromCharCode(e.charCode);
clearTimeout(barcodeScannerTimer);
barcodeScannerTimer = setTimeout(function () {
processBarcode();
}, 300);
});
function processBarcode() {
console.log('inside processBarcode with barcodeString "' + barcodeString + '"');
if (!isNaN(barcodeString) && barcodeString != '') { // @todo this check is lame. improve.
alert('ready to process barcode: ' + barcodeString);
} else {
alert('barcode is invalid: ' + barcodeString);
}
barcodeString = ''; // reset
}
window.simulateBarcodeScan = function() {
// simulate a barcode being scanned
var barcode = '9781623411435';
for (var i = 0; i < barcode.length; i++) {
var e = jQuery.Event("keypress");
e.which = barcode[i].charCodeAt(0);
$("body").focus().trigger(e);
}
}
If you type in a number quickly (like 1234
), you'll see the input is captured fine. However, click the button to run my test code, and the input is not captured. The event is triggered because an alert box pops up, but barcodeString
is empty!
Why isn't this working? Should I be triggering some event other than keypress
?
The handler is reading the charCode
but you are only setting which
on the event. Set charCode
, or read from which
. https://jsfiddle.net/mendesjuan/bzfeuezv/1/
barcodeString = barcodeString + String.fromCharCode(e.which);
This is a reminder that firing synthetic events is tricky business and typically requires you to have intimate knowledge of the handlers (which is bad) so that you don't have to construct a full event object. Also, beware that not all events triggered by jQuery will actually trigger the native events and cause its default action to apply.
Simply put, triggering keypress
does not actually type a character into a text field or fires event handlers not set with jQuery
.
document.querySelector('input').addEventListener('keypress', function() {
console.log('standard input key press handler');
});
var e = jQuery.Event("keypress");
e.which = "a".charCodeAt(0);
$('input').keypress(function(){
console.log('jQuery input key press handler');
}).trigger('keypress', e);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input value="yo" />