0

I am programming a web application which accepts barcodes from a barcode reader in an input field. The user can enter as many barcodes that s/he wants to (i.e. there is no reason for a predefined limit). I have come up with a brute force method which creates a predefined number of hidden input fields and then reveals the next one in sequence as each barcode is entered. Here is the code to do this:

<form id="barcode1" name="barcode" method="Post" action="#">
    <div class="container"> 
        <label for="S1">Barcode 1 &nbsp </label>
        <input id="S1" class="bcode" type="text" name="S1" onchange="packFunction()" autofocus/>          
        <label for="S2" hidden = "hidden">Barcode 2  &nbsp </label>
        <input id="S2" class="bcode" type="text" hidden = "hidden" name="S2" onchange="packFunction()" />
        <label for="S3" hidden = "hidden">Barcode 3 &nbsp </label>
        <input id="S3" class="bcode" type="text" hidden = "hidden" name="S3" onchange="packFunction()" /> 
        <label for="S4" hidden = "hidden">Barcode 4 &nbsp </label>
        <input id="S4" class="bcode" type="text" hidden = "hidden" name="S4" onchange="packFunction()" />    
        <label for="S5" hidden = "hidden">Barcode 5 &nbsp </label>
        <input id="S5" class="bcode" type="text" hidden = "hidden" name="S5" onchange="packFunction()" />
    </div>

    <div class="submit">          
        <p><input type="submit" name="Submit" value="Submit"></p>
    </div>

</form>

<script>

$(function() {   
    $('#barcode1').find('.bcode').keypress(function(e){
        // to prevent 'enter' from submitting the form
        if ( e.which == 13 ) 
        {
            $(this).next('label').removeAttr('hidden')
                $(this).next('label').next('.bcode').removeAttr('hidden').focus();  
            return false;
        }
    }); 
});
</script>

This seems to be an inelegant solution. It would seem to be better to create a new input field after each barcode has been entered. I have tried creating new input elements in the DOM using jQuery, and I can get the new input element to show. But it uses the onchange event, which detects changes in the original input field. How do I transfer focus and detect onchange in the newly created input field? Here is the code that I have played with to test out the idea:

<div>
   <input type="text" id="barcode" class="original"/>
</div>
<div id="display">
    <div>Placeholder text</div>
</div>
<script src="./Scripts/jquery-2.2.0.min.js"></script>    
$(function () {
    $('#barcode').on('change', function () {            
        $('#display').append('<input id='bcode' class='bcode' type='text' name='S1' autofocus/>')
        });
    });
</script> 

Once I have these barcodes, I pack them into array which I then post them to a server-side script to run a mySQL query to retrieve data based on the barcodes, and then post that back to the client. So part of what I have to achieve is that each barcode that is entered into the different input fields need to be pushed into an array.

Is there an elegant way to accomplish the creation of input fields dynamically and then detecting changes in those to create yet more input fields?

2
  • Could you use a single input element which could contain multiple barcodes ? Commented Mar 2, 2016 at 23:59
  • I could, in theory (and this is what my code does in error), but from an aesthetic point-of-view it doesn't look good and could be confusing to the user. Also, it would mean that when I submit the barcode sequence I have to parse the data to individual barcodes. Commented Apr 4, 2016 at 14:48

3 Answers 3

1

The dynamic update you have tried out is all right. If you must push it into an array on submit you have to prevent default of form submit, serialize the form and then make an ajax request.

Heres an example:

$('form').on('submit',function(e){
    e.preventDefault();
    var formData = $(this).serializeArray();//check documentation https://api.jquery.com/serializeArray/ for more details
    $.ajax({
        type:'post',
        url:<your url>//or you could do $('form').attr('action')
        data:formData,
        success:function(){}//etc
    })
});
Sign up to request clarification or add additional context in comments.

Comments

1

If you do not display the barcodes in the html you can skip the input fields and store the read barcodes in an array[]. Not everything that happens in javascript has to be displayed in the website (View) . i do not know what code you use to scan the barcode but you do not need the input-elements at all. See the example on this site https://coderwall.com/p/s0i_xg/using-barcode-scanner-with-jquery

instead of console.log() the data from the barcode scanner can simply be saved in an array[] and be send from there.

If you want to create elements dynamcially see this thread: dynamically create element using jquery

The following code adds the p-element with the label "Hej" to the div "#contentl1"

`$("<p />", { text: "Hej" }).appendTo("#contentl1");`

1 Comment

That is a great idea. I will definitely use that in a future application, For this specific application I need to be able to show the input fields in the event of a scanner failure or where the user does not have a scanner. There are other apps that I need to develop where this is not a requirement, so I will definitely be able to use this.
1

UPDATE: I added some simple CSS to make each input field display on its own line.

Here's one strategy:

  • Listen for the enter/return key on the input box.
  • When the enter/return key is pressed (presumably after entering a barcode), create a new input box.
  • Stop listening for the enter key on the original input and start listening for it on the new input.
  • When a "submit all" button is pressed (or when tab is used to shift the focus from the most recent input to the "submit all" button and enter is pressed), then collect all the input values in an array.

$(function() {
  var finishBarcode = function(evt) {
    if (evt.which === 13) {
      $(evt.target).off("keyup");
      $("<input class='barcode' type='text'/>")
        .appendTo("#barcodes")
        .focus()
        .on("keyup", finishBarcode);
    }
  };

  var submitBarcodes = function(evt) {
    var barcodesArr = $(".barcode").map(function() {
      return $(this).val();
    }).get();
    $("#display").text("Entered Barcodes: " + barcodesArr);
  };

  var $focusedInput = $('.barcode').on("keyup", finishBarcode).focus();
  var $button = $('#submitAll').on("click", submitBarcodes);
});
input.barcode {
  display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
  <li>Type barcode into input box</li>
  <li>To enter barcode and allow new entry, press Return</li>
  <li>To submit all barcodes, either press tab and then return or click Submit button</li>
</ul>
<div id="barcodes"><input type="text" class="barcode" /></div>
<div><button id="submitAll">Submit all barcodes</button></div>
<div id="display">Placeholder text</div>

2 Comments

That will work well. The only thing that I now have to figure out is how to get each newly created input field onto a different line.
I just updated my answer with a quick solution: use CSS to make the input fields display as "block" instead of the default "inline".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.