I have a requirement to handle the input of up-to four scanners. These scanners can read bar-codes concurrently. Depending on their configured prefix, I need to load the bar-code in the correct text-box on my web page.
Assuming the scanners will be prefixed with 1, 2, 3, 4. Here is my code -
<input type="text" id="barcode1" />
<input type="text" id="barcode2" />
<input type="text" id="barcode3" />
<input type="text" id="barcode4" />
Above text boxes may/may not have the focus, hence using addEventListener for keypress below
<script>
var barcodewithPrefix = "";
document.addEventListener("keypress", function(e) {
if (e.keyCode != 13) {
barcodewithPrefix += e.key;
}
else {
var prefix = barcodewithPrefix.substring(0, 1);
var barcode = barcodewithPrefix.substring(1, barcodewithPrefix.length); //remove the prefix and get the actual barcode
//display in correct text box
if (prefix == "1") {
document.querySelector("#barcode1").value = barcode;
}
else if (prefix == "2") {
document.querySelector("#barcode2").value = barcode;
}
else if (prefix == "3") {
document.querySelector("#barcode3").value = barcode;
}
else{
document.querySelector("#barcode4").value = barcode;
}
barcodewithPrefix = ""; //clear for next input
}
e.preventDefault();
});
</script>
This code is working fine for one scanner as well as for keyboard input.
However, it does not run correctly if there is more than one scanner and are used concurrently. The bar-codes digits get all jumbled up and doesn't appear correctly in their respective text-box.
I understand this is expected - looking at the code where each input char is interpreted with a keypress event.
Can anyone please guide how can I make it work. Are there any workarounds to tackle it?
Thank you!
Related
Here's my current setup:
I have a barcode scanner in keyboard mode. I am trying to scan to a hidden and out of focus input.
The barcode I am trying to read is as follows: asterisk [barcode-info] asterisk.
<form method="post">
<input type="hidden" name="action" value="barcode-scan"/>
<input type="hidden" name="barcode-input" value="" id="barcode-input" onchange="this.form.submit()" />
</form>
When a barcode input is made, Javascript should capture it and update the "barcode-input" hidden input, which will then submit itself to the server.
Someone recommended trying to use a paste event listener, but it simply didn't seem to capture the input at all.
Update: because of wonderful suggestions below, I've been able to get the input working! The form will test to see if two specific inputs follow each other, then it will execute the next function. Otherwise, it will erase any information contained in the log const. Ultimately, yes, I got this working correctly!
document.addEventListener('keyup', function(e){
const log = document.getElementById('barcode-input');
log.textContent += ' ' + e.code;
document.getElementById('barcode-input').value = log.textContent;
if (log.textContent.startsWith(' ShiftLeft')) {
if (log.textContent.startsWith(' ShiftLeft Backslash')) {
document.getElementById('barcode-input').form.submit();
console.log('e.code, submit barcode info');
}
}
else {
log.textContent = '';
document.getElementById('barcode-input').value = '';
}
});
Without an input[type="text"] element on the screen, you will need to capture the keyboard input manually. Something along the lines of:
document.addEventListener('keydown', (ev) => {
if (ev.ctrlKey || ev.altKey) return; // Ignore command-like keys
if (ev.key == 'Enter') {
// ...submit the content here...
} else if (ev.key == 'Space') { // I think IE needs this
document.getElementById('barcode-input').value += ' ';
} else if (ev.key.length == 1) { // A character not a key like F12 or Backspace
document.getElementById('barcode-input').value += ev.key;
}
});
That should get you most of the way...
Alternatively, rather than looking for events on the input or values of the input (*'s), define an event on the value and use the input event to simply set the value.
Once input has stopped, be it 1 second (or most likely much less) then fire off the form.
If you have to place the cursor into input, then scan. your prob only option is to use autofocus attribute and hide the input as you cant focus a hidden element, though you also cant focus multiple so keep that in mind if you're looking to scan into multiple inputs, then you will have to show the inputs, no way around it.
For example
let elm = document.querySelector('input[name="barcode-input"]')
// watcher on the value, after 1 second, it invokes an event, i.e post form
let timer = 0
Object.defineProperty(window, 'barcode', {
get: function () { return this.value },
set: function (value) {
clearTimeout(timer)
this.value = value
timer = setTimeout(() => {
console.log('Post form')
}, 1000) // do some tests, tweak if much less then 1 second to input the value
}
})
// it should trigger input even if its a keyboard
elm.addEventListener("input", e => barcode = e.target.value)
// ignore, below this line..
// set a value of barcode at intervals, only when its stopped entering (>1 second), then will it fire the callback
let i = 0
let t = setInterval(() => {
barcode = (barcode || '')+"X"
if (i >= 40) clearInterval(t)
i++
}, 100)
// ignore... grab value from hidden input, put in #current
setInterval(() => document.querySelector('#current').innerHTML = barcode, 1000)
<input type="text" name="barcode-input" autofocus style="display:none" />
<div id="current"></div>
Here's demonstrator using keypress that scans the incoming key stream for *[ and captures the barcode until it sees ]*. Then it sends the code to the server. Although I've reproduced the form in your HTML, the code here doesn't use it.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
Working...
<form method="post">
<input type="hidden" name="action" value="barcode-scan"/>
<input type="hidden" name="barcode-input" value="" id="barcode-input" onchange="this.form.submit()" />
</form>
<p id="response"></p>
<script>
(function(){
"use strict";
const bcAst = '*';
const bcLeft = '[' ;
const bcRight = ']';
let barcodeIncoming = false;
let lastChar = 0;
let barcode = '';
document.addEventListener('keypress', function(e){
function sendCode(barcode) {
console.log(barcode);
let fd = new FormData();
fd.append('barcode', barcode);
fetch('myFile.php', {
method: 'POST',
body: fd
})
.then(resp=>{
resp.text().then(txt=>{document.getElementById('response').innerText = txt;})
});
}
console.log(e.key);
switch (e.key) {
case bcAst:
if (barcodeIncoming && (lastChar === bcRight)) {
barcodeIncoming = false;
sendCode(barcode);
}
break;
case (bcLeft):
if (lastChar === bcAst) {
barcodeIncoming = true;
barcode = '';
}
break;
case (bcRight):
break;
default:
barcode += (barcodeIncoming)?e.key:'';
break;
}
lastChar = e.key;
});
})();
</script>
</body>
</html>
The current server file is very rudimetary, but serves the purpose here:
<?php
if (isset($_POST['barcode'])) {
echo "Your barcode is {$_POST['barcode']}";
} else {
echo "No barcode found";
}
Note - this has had only basic testing. You'll want to improve its resilience against possible collisions with similar data in the key stream.
transfrom
<input type="hidden" name="barcode-input" value="" id="barcode-input" onchange="this.form.submit()" />
in
<input type="test" name="barcode-input" value="" id="barcode-input" onchange="this.form.submit()" style="display:none;" />
I am doing a form window before you get in the main website so I tried to make it so that if you don't fill any of the spaces it will open a window alert asking to fill those spaces. Plus I'd like that you would only get to the main website if you fill all the spaces but yet the button on the form window always takes to the main website without requiring filling of the camps.
On the button I wrote this:
<a href="index1.html">
<input type="button" value="Terminar" onclick = location.href='index1.html' >
</a>
and on the js window I wrote the window alert command to each one of the categories:
if(frm.name.value=="" || frm.name.value==null || frm.name.length < 3) {
alert("Please write your first name ")
frm.name.focus();
return false;
It seems you are trying to validate the an input field based on a few criteria.
Your question is not clear. Is this what you are trying to do?
function validateInput() {
if (frm.value == "" || frm.value == null || frm.value.length < 3) {
alert("Please write your first name ")
frm.focus();
} else
location.href = 'index1.html'
}
<input type="text" id="frm" placeholder="Please write your first name" />
<input type="button" value="Terminar" onClick="validateInput()">
You want something like this. In your code the input is wrapped in an a tag. so it will always trigger the event. Adding a button the trigger the event will help.
button = document.getElementById('enter');
input = document.getElementById('fill');
button.onclick = function() {
if (input.value == null || input.value == "" || input.value == " ") {
alert('Please write your first name');
} else {
window.location.href = 'index1.html';
}
};
<input id="fill">
<button id="enter">Enter</button>
I am using following javascript code to autopopulate slashes and colons in a date field
Javascript
var $dateField = jQuery('input[name='dateFieldId']');
//Bind keyup/keydown to the input
$dateField.bind('keyup', 'keydown', function (e) {
// if backspace, do nothing:
var thisVal;
var appender = '';
if (e.which !== 8) {
var numChars = $dateField.val().length;
// insert '/' after 2nd and 5th character is entered
if (numChars === 2 || numChars === 5) {
appender = '/';
}
// insert whitespace after 10th character is entered
else if (numChars === 10) {
appender = ' ';
}
// insert ':' after 13th character is entered
else if (numChars === 13) {
appender = ':';
}
}
thisVal = $dateField.val() + appender;
$dateField.val(thisVal);
});
HTML
<form:input size="26" type="text" class="form-control" name="dateFieldId" id="dateFieldId" path="dateFieldId" value="" placeholder="dd/mm/yyyy hh:mm" maxlength="16" />
This is working fine on latest browsers on desktops. But its failing in old version of chrome browsers and chrome/firefox on android. One issue is that when key is pressed in datefield the focus is lost sometimes. Another is that along with the slash it adds the existing value again
For example when I type '28', instead of having '28/' which is my expected it adds 28 again after filling the slash which results in '28/280' as shown below
If anyone have encountered this please let me know. I was referring following post to do this
What's the best way to automatically insert slashes '/' in date fields
I have a phone number input that I am trying to get the dashes to appear in the number as the user types.
I am wanting the number to appear as 555-555-5555.
The function works for the most part, but the dashes aren't entered until after the whole number is entered. I am using the keyup function, which I thought would solve this, but no luck.
Does anyone have any recommendations as to what I have to do to get the dashes to be entered as the user types in the digits?
$('#phone').keyup(function() {
$(this).val($(this).val().replace(/(\d{3})\-?(\d{3})\-?(\d{4})/,'$1-$2-$3'))
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div>
<label class="contact-label">Phone Number:</label>
<input type="tel" class="contact_input" name="phone" id="phone">
</div>
I modified your code slightly to produce something that I think is a little easier to read, but still does the job.
I just evaluated the length of the <input /> tag's value on each .keyup() event and then augmented the value accordingly. Take a look at the snippet below:
--UPDATE--
After comments regarding backspacing issues I added a couple lines of code that seem to fix the issue:
First I checked for either backspace or delete .keyup() events to prevent the formatting code from interfering with correcting errors in the number.
I also added a few checks, and a global formatFlag variable to ensure that if the user backspaces to an awkward index like 3 or 6(where hyphens would normally be added), that formatting would resume as normal on the next .keyup() event.
let formatFlag = false;
$(function(){
$('#phone').keyup(function(evt) {
let modifiedValue = $(this).val().replace(/-/g, "");
if(evt.keyCode == 8 || evt.keyCode == 46) { //8 == backspace; 46 == delete
//Checks whether the user backspaced to a hyphen index
if(modifiedValue.length === 3 || modifiedValue.length === 6) {
//Checks whether there is already a hyphen
if($(this).val().charAt($(this).val().length - 1) !== '-') {
formatFlag = true; //Sets the format flag so that hyphen is appended on next keyup()
} else {
return false; //Hyphen already present, no formatting necessary
}
} else {
formatFlag = false;
}
return false; //Return if backspace or delete is pressed to avoid awkward formatting
}
if(!!formatFlag) {
// This re-formats the number after the formatFlag has been set,
// appending a hyphen to the second last position in the string
$(this).val($(this).val().slice(0, $(this).val().length - 1) + '-' +
$(this).val().slice($(this).val().length - 1));
formatFlag = false; //Reset the formatFlag
}
if(modifiedValue.length % 3 == 0) {
if(modifiedValue.length === 0 || modifiedValue.length >= 9){
return false;
} else {
$(this).val($(this).val() + '-');
return;
}
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div>
<label class="contact-label">Phone Number:</label>
<input type="tel" class="contact_input" name="phone" id="phone" />
</div>
OK so i have this task that im not sure how to achieve. I have a text field that is only allowing the users to enter numeric values....I am validating on keypress to make sure that only numeric numbers are allowed
That works well
My problem is that the client wants text after the numbers to say " Miles" so if the user enters 100 they see "100 Miles"
I guess for usability. Does anyone know a good technique or jquery plugin to do this
In addition to a javascript solution, you may also want to look into the HTML 5 pattern attribute for <input>. For example, in modern browsers you could do something like:
<input name="miles" pattern="^\d+\s?[Mm]iles$" required>
Which requires no javascript at all :) Here's the relevant spec.
How about this:
$('input').keypress(function(e) {
if (e.which < 48 || e.which > 57) {
// not a number
return false;
}
// gets current entered numer
var number = this.value.split(' ')[0];
// adds new number
number = '' + number + String.fromCharCode(e.which);
this.value = number + ' miles';
return false;
})
It would be easier and I think clearer to do this in some sort of tag just outside of the textbox. Have a span directly below or something then update it on your keypress.
$('#textBox').keydown(function(){
// Validation code
$('#someSpan').html($(this).val() + " Miles");
});
How about this http://jsfiddle.net/TmxSN/1/
$(function(){
var timerOutId;
$('#inp').keypress(function(e) {
var key = e.which;
clearTimeout(timerOutId);
try{
if(this.value){
this.value = $.trim(this.value.match(/\d+/g)[0]);
}
}catch(e){}
if ((key < 48 || key > 57) && !(key == 8 || key == 9 || key == 13 || key == 37 || key == 39 || key == 46) ){
return false;
}
}).keyup(function(e) {
var textBox = this;
if(this.value){
timerOutId = setTimeout(function(){
textBox.value = $.trim(textBox.value.match(/\d+/g)[0]) + " Miles";
}, 2000);
}
})
});
My problem is that the client wants text after the numbers to say "
Miles" so if the user enters 100 they see "100 Miles"
Then you can handle it in the onfocus and onblur event of your input type="text" like this.
Try this
<input type="text" min="0" max="1000" step="1" id="distance" placeholder="Enter the value in miles"/>
And Script
$(document).ready(function() {
//$("#distance").keypress(PassNumbersOnly);
$("#distance").focus(OnFocus);
$("#distance").blur(OnBlur);
});
function OnFocus() {
var $this = $(this);
if ($this.val().indexOf("Miles") != -1) {
$this.val($this.val().split(" ")[0]);
}
}
function OnBlur() {
var $this = $(this);
if ($.trim($this.val()) != "") {
$this.val($this.val() + " Miles");
}
}
Demo here: http://jsfiddle.net/naveen/EQEMr/
Tell your client that anyone with enough intelligence to use the web can understand:
<label for="distance">Distance in miles:
<input type="text" name="distance" id="distance"></label>
and that doing anything else is:
confusing for users
problematic as javascript may or may not be enabled/available
of zero practical use for the business as the value must be validated on the server anyway
the value requires additional processing at the server to remove the appended characters