Search code examples
javascriptjquerykeypress

Triggered keypress events not being captured?


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);
    }
}

JSFIDDLE

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?


Solution

  • 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);
    

    Firing Synthetic events

    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" />