0

I am working on yii2. I am using typeahead in my forms. Now there is a use-case in which user will scan a barcode with barcode scanner and then it's input will be shown in the typeahead. For now, things are working fine.

But I want to minimize the user entry error to not to type anything in the typehead instead he will scan the barcode and then the scanned value will appear below the text box and user will click on it so the input box will be filled. For reference see the below image.

enter image description here

Below is my code.

View

<style>
span.twitter-typeahead{
    width: 100%;
}
</style>

  <?php  if($model->isNewRecord){?>
    <label class="control-label">Select Meter #</label><br />
    <input type="text" id="the-meter-id" class="form-control col-md-12" value="<?=$model->meter_id?>"/>
    <div style="clear: both;"></div>
    <div id="selected_meter_container" ></div>
    <div style="clear: both;"></div>

    <label class="control-label">Select IMSI #</label><br />
    <input type="text" id="the-sim-id" class="form-control col-md-12" value="<?=$model->sim_id?>"/>
    <div style="clear: both;"></div>
    <div id="selected_imsi_container" ></div>
    <div style="clear: both;"></div>
<?php } ?>

JS

$urlsim = Url::toRoute('/metertosimmapping/sim');
$(document).ready(function (){

var surveyReferences = new Bloodhound({
              datumTokenizer: Bloodhound.tokenizers.obj.whitespace('imsi'),
              queryTokenizer: Bloodhound.tokenizers.whitespace,
              prefetch: 'survey',
              remote: {
                url: '$urlsim?q=%QUERY',
                wildcard: '%QUERY'
              }
        });
 $('#the-sim-id').typeahead(null, {
            limit: 50,
            name: 'ref-numbers',
            display: 'imsi',
            source: surveyReferences,
            suggestion: function(data) {
                    return '<p><strong>' + data.id + '</strong> – ' + data.imsi + '</p>';
        }
    }
    );
 jQuery('#the-sim-id').on('typeahead:selected', function (e, datum) {   
       $('#selected_imsi_container').html('');
        $('#metertosimmapping-imsi').val('');
         $('#metertosimmapping-sim_number').val('');
         $('#metertosimmapping-operator_name').val('');
         //$('#metertosimmapping-sim_status').val(datum.sim_status);
        $('#metertosimmapping-historic').val(datum.historic);
        var html = '<div class="selected-imsi"><input type="hidden" name="selected_imsi[]" value="'+datum.id+'" />'+datum.imsi+'<a onclick="$(this).closest(\'.selected-imsi\').remove()">X</a></div>';
        $('#selected_imsi_container').append(html);
        $('#metertosimmapping-imsi').append(datum.imsi);
         $('#the-sim-id').typeahead('val','');
         $('#metertosimmapping-sim_number').val(datum.sim_number);
         $('#metertosimmapping-operator_name').val(datum.operator_name);
         //$('#metertosimmapping-sim_status').val(datum.sim_status);
        $('#metertosimmapping-historic').val(datum.historic);
     });

});

I have checked this solution but it's for autocomplete and I am using typeahead.

How can I disable keyboard entry on a particular Text box on the front form and allow the user to scan a value into that textbox (USB scanner)

Update 1

Ok I have done the first part i.e. Disable user input by doing the following

<input type="text" id="the-sim-id" class="form-control col-md-12" onkeydown="return false" value="<?=$model->sim_id?>"/>

Now it does disable the user input but also disabled the scanner input.How can I allow the user to scan a value into that textbox (USB scanner)?

Any help would be highly appreciated.

Moeez
  • 494
  • 9
  • 55
  • 147

1 Answers1

1

I solved a similar problem by watching for keypress events on the document in js. When the curser focus is not on a input field it's on the BODY node. The USB barcode scanner is technically a key press.

My Code

document.onkeypress = (e) => {
  e = e || window.event;
  const digit = e.key;
  if(e.target.nodeName === 'BODY' && digit.match(/[0-9]/i)){
    console.log(digit)
  }
};

I'm not sure this is a best practice in modern frameworks to access Document directly. Using jQuery you might be able to use something like

$('body').keypress()
wnordmann
  • 301
  • 2
  • 11
  • @MuhammadOmerAslam The keypress event is fired when a HID USB scanner scans a barcode. https://jsfiddle.net/wnordmann/xu1jLbnp/1/ , are you getting different results from your scanner? – wnordmann Feb 27 '18 at 16:10