简体   繁体   中英

USB Barcode scanner repeat scans without server call

Not sure if my terminology is correct on all of this. I know my code is not efficient either. Looking for functional over efficiency at this point. (just a teacher trying to solve logistical issues).

I have a webapp that we use to check students into and out of the library. Because of COVID, we are trying to touch the keyboard less and have a faster check-in process. To do this, we have a USB scanner that will scan student IDs.

My Webapp loads template html and then adds names etc to the different select elements. When a student checks in, the name appears on the other half of the window and waits for them to click the checkout next to their name. I believe this is done on what is called client side.

To add the barcode scanner, I added a form element with a text input. Is this the only way to have the barcode scanner interact with the client side?

<form><input type="text" id = "barcodeInput" size="1"></form>  

I then have some jQuery that tests to see that the input is a barcode (Prefix and return key pressed), if so, the student ID number from the barcode is then put through a loop to find the matching id in the select options of student names (ids are stored in the values and student names are stored in the text). Default action is also prevented here

All of this works and I can get 1 student to add to the "checked in" panel of my app.

I cannot get the scanner to work on a second student. I think this has to do with the fact that I'm using the form input element and that might require a server call but I cannot do that since I need to have a growing list of students who are checked into the library.

I borrowed this and am currently using

$(document).ready(function() {
    var barcode=""; //sets my variable
    $(document).keydown(function(e) //looking to intercept the barcode scanner output
    {
        var code = (e.keyCode ? e.keyCode : e.which); //don't really know what this does since I borrowed this
        if(code==13&&(barcode.substring(1,5)=="SCAN"))// Enter key hit & from scanner
        {
            e.preventDefault(); //stops the enter key from actually "running" and stops the barcode from going into the input field (I think)
            barcode = barcode.slice(5);// remove the prefix so I am left with student number aka barcode
            alert(barcode); //lets me know I'm getting the correct student number
            processBarcode(barcode);        //sends to process barcode
        }
        else if(code==9)// Tab key hit    //I may not need these next 10ish lines
        {
            e.preventDefault();
            alert(barcode);      
        }
        else
        {
            e.preventDefault();
            barcode=barcode+String.fromCharCode(code);
        }
    });
});

This find the student in the select element and then changes the select element to read that name and also posts the name on the "Who is checking in" Table cell

function processBarcode(barcode){
     var name = "";
   $("#studentNameSelect option").each(function(){ //runs through the select element that has all student names...the name is in the parameter "text" and student ID # is in the parameter val
        if($(this).val()==barcode){ //looking to see if the student ID # matches the specific option in the select element
             name = $(this).text(); //figure out the student name based on ID #
             $(this).prop('selected', true); //set the select element to show this specific option
             $("#selectedName").html(name);  //puts student name in a table cell so they know they are picking the correct name
             //$("#barcodeInput").trigger("reset"); //here I'm trying to get the form element input to reset so I can use it again...this didn't work so its commented out
             $("#teacherNameSelect").focus(); //puts the focus onto the next select item so I can do other things
             return false; //breaks the each loop once student name has been found
        }
    }); 
}

And then this is the code that moves the name onto the "checked in" panel so that the next student can check in

function buildAttendanceRow(stringPackage){ //this function takes info from the selection panel and builds a table row in the "I'm at the library" panel. Students click check out when they leave the library
console.log(stringPackage);
    var package = JSON.parse(stringPackage); //receives a package of info from the selects, I do send this to a server function to email teachers that student arrived to the library...
console.log(package);
    var html = "";
    var hiddenId = new Date().getTime().toString(); //this cell is used to keep track of a specific instance of a student checked into the library so I can remove later and then mark in a backend spreadsheet database
    var nameCell = '<td class="package" id="'+hiddenId+'">'+package.student+'</td>';
    var checkOutButton = '<input type="button" value="Check Out" id="COButton">';
    var checkoutButtonCell = '<td class="center">'+checkOutButton+'</td>';
    html+="<tr>"+nameCell+checkoutButtonCell+"</tr>";
    $("#checkedInTable").append(html);   //puts the new table row into the checked in table
    $('#'+hiddenId).data("package",package); //stores info so I can remove table row and update database
    
    
    var lastTableRow = $('#checkedInTable tr:last');
    var button = lastTableRow.find('#COButton');
        //add the click function for removing row and sending checked out info to server for email and for database purposes
        button.click(function(e){
            var x = e.pageX;
            var y = e.pageY;
            var o = {
                left: x,
                top: y
            };
           $("#progressMonitor").show().offset(o);
            $(this).prop("disabled",true);
            var row = $(this).closest('tr');
            var carrierCell =$('#'+hiddenId); 
            var d = new Date();
            var payload = new Object(); //this object gets transferred to the server function, the user interface doesn't refresh here, it just has a dynamic html table built and shrunk as kids check in or check out
                payload.checkInTime = carrierCell.data("package").checkInTime;
                payload.timeIn = carrierCell.data("package").timeIn;
                payload.student = carrierCell.data("package").student;
                payload.teacherEmail = carrierCell.data("package").teacherEmail;
                payload.teacherName = carrierCell.data("package").teacherName;
                payload.reason = carrierCell.data("package").reason;
                payload.checkOutTime = d;
                payload.timeOut = d.getTime();
           var stringPayload = JSON.stringify(payload);
           row.hide();
           alternateRowColors($("#checkedInTable"));
           google.script.run.withSuccessHandler(emailAndRecordsSuccess).withFailureHandler(emailAndRecordsFailure).emailAndRecords(stringPayload);//calling the server function
        });
    
    var numRows =  $("#checkedInTable tr" ).length;
    if(numRows>2){
        alphaSortTable(); //puts the student names in alpha order so it is easier for them to checkout of the library
    }
    alternateRowColors($("#checkedInTable")); 
    $("#progressMonitor").hide();
    $("#barcodeInput").focus(); //here is me trying to get the scanner back into the input field so there is somewhere for the scanner data to go; I expected this to be all I needed to do, but at this point, even though the input is focused, the the scanner won't fire onto the document or into the field or anything like that
     alert($("#barcodeInput").val()); //this is telling me that there is no value in the input field at this point, I thought there might be info stored here screwing up the scanner

}

The solution was to rebind a function to the document after my client side work was done. Changed this into a named function:

$(document).ready(function() {
    var barcode=""; 
    $(document).keydown(function(e) 
    {
        var code = (e.keyCode ? e.keyCode : e.which); 
        if(code==13&&(barcode.substring(1,5)=="SCAN"))
        {
            e.preventDefault(); 
            barcode = barcode.slice(5);
            processBarcode(barcode); 
        }else if(code==9)// Tab key hit  
             {e.preventDefault();     
        }else{
            e.preventDefault();
            barcode=barcode+String.fromCharCode(code);
        }
    });
});

Now I have:

function getBarcode(){
var barcode=""; 
    $(document).keydown(function(e) 
    {
        var code = (e.keyCode ? e.keyCode : e.which); 
        if(code==13&&(barcode.substring(1,5)=="SCAN"))
        {
            e.preventDefault(); 
            barcode = barcode.slice(5);
            processBarcode(barcode); 
        }else if(code==9)// Tab key hit  
             {e.preventDefault();     
        }else{
            e.preventDefault();
            barcode=barcode+String.fromCharCode(code);
        }
    });

and

$(document).ready(function() {
     getBarcode();
}

and I can call

getBarcode();

anywhere to re-connect the document to be looking for the barcode scanner.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM