Multiple keypress function jquery - javascript

i am complete newbie in jquery/js
I am trying to create web interface for my robotcar and check for multiple keypresses, whenever i release all keys robotcar would stop.
http://jsfiddle.net/gFcuU/1105/
var keys = {};
$(document).keydown(function (e) {
keys[e.which] = true;
keypr();
printKeys();
});
$(document).keyup(function (e) {
delete keys[e.which];
printKeys();
});
function printKeys() {
var html = '';
for (var i in keys) {
if (!keys.hasOwnProperty(i)) continue;
html += '<p>' + i + '</p>';
}
$('#out').html(html);
}
function keypr(){
if (keys[87] && keys[68] == true){
alert('shit works');
}
}
Multiple keypress detection works but if i press W+D stated in function keypr it stops working properly.
Thanks for help

Dude. Your code is working perfectly, but when you do the alert while detecting keypresses, it gets stuck.
Just remove the alert and everything is gonna be fine. if you don't wanna remove the alert i guess you have to remove the object, before displaying the alert.
function keypr(){
if (keys[87] && keys[68] == true){
delete keys[68];
delete keys[87];
alert('shit works');
}

Related

Code won't work when merging a javascript code in one function

Good day everyone!
I have a problem merging the codes in one function. (If it's possible).
First:
There is a table.
When the table row click two buttons will be enabled.
Here's the code:
function enableRegButton() {
$('#registerExist').prop('disabled', false);
$('#edit').prop('disabled', false);
// regButton execute when Enter key pressed
$(document).unbind("keyup").keyup(function(e){
var code = e.which; // recommended to use e.which, it's normalized across browsers
if(code==13)
{
$("#registerExist").click();
}
});
}
Second:
When Escape key pressed it will disable all bind buttons.
Here's the code:
$(document).keyup(function(e) {
if (e.keyCode == 27) { // escape key maps to keycode `27`
$('#registerExist').prop('disabled', true);
$('#edit').prop('disabled', true);
document.getElementById("enStudID").value = "";
document.getElementById("enInfoID").value = "";
document.getElementById("enCoffID").value = "";
document.getElementById("enYearID").value = "";
}
});
Now, what I want to do are those two codes above will merge in one function and it will call the function and trigger all those codes so when I edit the code it will be centralized.
Here's my final code:
function enableRegButton() {
$('#registerExist').prop('disabled', false);
$('#edit').prop('disabled', false);
// regButton execute when Enter key pressed
$(document).unbind("keyup").keyup(function(e){
var code = e.which; // recommended to use e.which, it's normalized across browsers
settings();
});
}
// This code is for ESC button when pressed.
$(document).keyup(function(e) {
settings();
});
function settings(){
if(code==13)
{
$("#registerExist").click();
}
else if (code==27){ // escape key maps to keycode `27`
$('#registerExist').prop('disabled', true);
$('#edit').prop('disabled', true);
document.getElementById("enStudID").value = "";
document.getElementById("enInfoID").value = "";
document.getElementById("enCoffID").value = "";
document.getElementById("enYearID").value = "";
}
}
Problem:
Only the enable button is working when table row is click
Pressing Escape key will not disable the enabled buttons.
Code won't run when pressing Enter Key.
You need to pass the key code to the settings method.
$(document).keyup(function(e) {
settings(e.keyCode);
});
function settings(code) {
Use the browser's developer console when debugging Javascript issues, it's an invaluable tool and picks up problems like this quite easily.
You are assigning the code variable in the unbind callback, not in the bind callback :)

on trigger click event script called 2 time in first attempt

I am creating an image gallary using owl carousel and php.there mouse click event working perfectly but when click command over keyboard having problem skip one image on prev keyup only and only first time. which code are calling after keyup function when write that code inside that function working perfectly
$(document.documentElement).keyup(function(event) {
// handle cursor keys
if (event.keyCode == 37) {
$(".prev").click();
});
var prevkey = $(".prev");
prevkey.unbind("click").click(function() {
$(".reset").click();
setTimeout(function() {
$(".printable").load(function(){
$(".owl-carousel").myfunction();
});
}, 200);
curEle = $(".item.active").parent();
//console.log(curEle);
if(curEle.find(".item").attr("data-id")==0)
{
$(this).addClass("disabled");
}
else
{
$(this).removeClass("disabled");
prevEle = curEle.prev();
console.log(prevEle);
prevEle.find(".item").addClass("active");
curEle.find(".item").removeClass("active");
prevEle.find(".printable").attr("src",prevEle.find(".printable").attr("data-src"));
carousel.trigger("owl.prev");
curEle.find(".printable").attr("src","");
}
});
Insert preventDefault() to avoid other events than yours...
$(document.documentElement).keyup(function(event) {
// handle cursor keys
event.preventDefault();
if (event.keyCode == 37) {
$(".prev").click();
}
});
EDIT check this answer if you're using IE8
try this using one will prevent a second call
$(".prev").one("click",function(){
//your stuff
});

Javascript: How to read a hand held barcode scanner best?

I'd like to be able to scan barcodes via a hand held scanner and handle the results with Javascript.
A barcode-scanner works almost like a keyboard. It outputs the scanned/translated (barcode->number) data raw (right?). Actually I just need to catch the output and proceed. But how?
Here's some pseudocode I'd like to make work:
$(document).on("scanButtonDown", "document", function(e) {
// get scanned content
var scannedProductId = this.getScannedContent();
// get product
var product = getProductById(scannedProductId);
// add productname to list
$("#product_list").append("<li>" + product.name + "</li>");
});
Any ideas (frameworks, plugins, snippets)?
Any barcode-scanner (hardware) recommendation?
I found this and this good questions but I'd like to get more information about the handling. Just to focus a textarea may be not enough in my case.
Your pseudo code won't work, because you don't have access to the scanner to catch events like scanButtonDown. Your only option is a HID scanner, which behaves exactly like a keyboard. To differentiate scanner input from keyboard input you have two options: Timer-based or prefix-based.
Timer-based
The scanner is likely to input characters much quicker than a user can (sensibly) with a keyboard. Calculate how quickly keystrokes are being received and buffer fast input into a variable to pass to your getProductsId function. #Vitall wrote a reusable jQuery solution for catching barcode scanner input, you would just need to catch the onbarcodescanned event.
Prefix-based
Most scanners can be configured to prefix all scanned data. You can use the prefix to start intercepting all input and once you've got your barcode you stop intercepting input.
Full disclosure: I work as a consultant to Socket Mobile, Inc. who make handheld scanners.
After a lot of research and testing, what worked the best for me was to capture input from a barcode scanner without focusing a form input. Listen to the keydown and textInput events.
The textInput event acts like a paste event. It has then entire barcode data. In my case I am looking for UPC barcodes. The e.preventDefault() prevents the barcode data from being inserted into a form input:
document.addEventListener('textInput', function (e){
if(e.data.length >= 6){
console.log('IR scan textInput', e.data);
e.preventDefault();
}
});
I have tested this on Android 4.4 and 7.0 with a CipherLab IR scanner.
Example for listening to the keydown event. In my case I am able to assume that as long as a form input is not focused, the user is scanning a barcode.
let UPC = '';
document.addEventListener("keydown", function(e) {
const textInput = e.key || String.fromCharCode(e.keyCode);
const targetName = e.target.localName;
let newUPC = '';
if (textInput && textInput.length === 1 && targetName !== 'input'){
newUPC = UPC+textInput;
if (newUPC.length >= 6) {
console.log('barcode scanned: ', newUPC);
}
}
});
Of course, rather than checking the length of the string to determine a scan, you can listen for the e.keyCode === 13 in the keydown event listener.
Not all IR scanners will trigger the textInput event. If your device does not, then you can check to see if it is emitting something similar with:
monitorEvents(document.body);
Found this monitoring trick here: How do you log all events fired by an element in jQuery?
I'm little late but I made this work around based in some answers here.
let code = "";
let reading = false;
document.addEventListener('keypress', e => {
//usually scanners throw an 'Enter' key at the end of read
if (e.keyCode === 13) {
if(code.length > 10) {
console.log(code);
/// code ready to use
code = "";
}
} else {
code += e.key; //while this is not an 'enter' it stores the every key
}
//run a timeout of 200ms at the first read and clear everything
if(!reading) {
reading = true;
setTimeout(() => {
code = "";
reading = false;
}, 200); //200 works fine for me but you can adjust it
}
});
A barcode-scanner works almost like a keyboard.
It depends on the model. Every one that I've used works exactly like a keyboard (at least as far as the computer is concerned)
It outputs the scanned/translated (barcode->number) data raw (right?).
It outputs keycodes.
$(document).on("scanButtonDown"
You probably want keypress, not scanButtonDown.
Look at the event object to determine the "key" that was pressed.
To determine when the entire code has been scanned, you might get an "end of data" key (possibly a space or a return) or you might have to just count how many characters are being input.
Here is working fine.
It's working when input has focus and input hasn't focus
on_scanner() // init function
function on_scanner() {
let is_event = false; // for check just one event declaration
let input = document.getElementById("scanner");
input.addEventListener("focus", function () {
if (!is_event) {
is_event = true;
input.addEventListener("keypress", function (e) {
setTimeout(function () {
if (e.keyCode == 13) {
scanner(input.value); // use value as you need
input.select();
}
}, 500)
})
}
});
document.addEventListener("keypress", function (e) {
if (e.target.tagName !== "INPUT") {
input.focus();
}
});
}
function scanner(value) {
if (value == '') return;
console.log(value)
}
HTML
<input type="text" id="scanner" placeholder="scanner">
Tried all the solutions, but not worked as expected. I found very easiest solution onscan.js I have application using angular 8.
Very simple and good implementation.
For angular 8, I followed steps:
1.npm install onscan.js --save
2.open angular.json, add one entry to script array as "node_modules/onscan.js/onscan.min.js"
3.In component class, implement interface AfterViewInit
declare var onscan:any;
ngAfterViewInit(): void {
//Put focus to textbox and press scanner button
onScan.attachTo(document, {
suffixKeyCodes: [13], // enter-key expected at the end of a scan
reactToPaste: true, // Compatibility to built-in scanners in paste-mode (as opposed to keyboard-mode)
onScan: function (sCode, iQty) { // Alternative to document.addEventListener('scan')
console.log('Scanned: ' + iQty + 'x ' + sCode);
},
});
}
Best thing is scanned text appears into focued textbox element
Hope this help.
I wanted to share this topic using React too, as I struggled a lot with it.
I think most of the barcode scanners, such as Hanz Herdel said, terminate with ENTER. In my case, I found easier to wrap the input in a form and catch the submission event, prevent default and retrieve the value of the input.
I preferred this type of approach so to handle any type of barcode length, instead to check the length of it.
Here's how I handled it in React:
import { useState } from "react";
export default function Modal() {
const [repairArticles, setRepairArticles] = useState([]);
function handleBarcodeInput(e) {
e.preventDefault();
const input = e.target.querySelector("input");
const value = input.value;
setRepairArticles((prev) => {
return (prev = [...prev, value]);
});
input.value = "";
}
return (
<div>
<form onSubmit={(e) => handleBarcodeInput(e)} >
<input id="barcode-input" />
<button type="submit" className="hidden" />
</form>
<div className="mt-3">
{repairArticles.map((el, index) => {
return <p key={index}>{el}</p>;
})}
</div>
</div>
)
}
This is an extension to the answer given by Hanz Herdel incase you are using one of the PosX scanners or any other scanner that are capable of adding a special symbol to the beginning of the characters. In this case, the tilde (~) symbol:
let barcode = "";
let reading = false;
document.addEventListener("keydown", e => {
//console.log(e.key);
if (e.key == 'Enter') {
if (barcode.length == 17) {
if (barcode.charAt(0) == '~') {
console.log(barcode);
barcode = "";
}
}
}
else {
if (e.key != 'Shift') {
barcode += e.key;
}
}
if (!reading) {
reading = true;
setTimeout( () => {
barcode = "";
reading = false;
}, 200);
}
}, true)
You can change the barcode length and the timeout speed to your liking but this worked perfect for me.
Vue 2 implementation (i think vuejs's syntax is similar to angular):
BarcodeScanner.vue component code is here:
<template>
<input type="hidden" name="_barcode" v-model="finalCode" />
</template>
<script>
export default {
props: {
onSuccess: {
type: Function,
required: true
},
minLength: {
type: Number,
default: () => 10
}
},
data() {
return {
code: "",
finalCode: "",
fromScanner: false,
reading: false
};
},
mounted() {
document.addEventListener("keypress", this.documentKeyboardListener);
},
destroyed() {
document.removeEventListener("keypress", this.documentKeyboardListener);
},
methods: {
documentKeyboardListener(e) {
if (e.target.nodeName !== 'BODY') return;
if (e.code === "Enter") {
if (this.reading && this.code.length > this.minLength) {
if (this.onSuccess)
this.onSuccess(this.code);
this.finalCode = this.code;
this.code = "";
this.fromScanner = true;
}
} else {
this.code += e.key; //while this is not an 'enter' it stores the every key
}
//run a timeout of 200ms at the first read and clear everything
if (!this.reading) {
this.reading = true;
setTimeout(() => {
this.code = "";
this.reading = false;
this.fromScanner = false;
}, 200); //200 works fine for me but you can adjust it
}
},
},
};
</script>
You can invoke the component anywhere:
...
<barcode-scanner onSuccess="yourListener"/>
...
(Js scanner code is taken from Hanz Herdel)
I've just started working on a plugin that handles barcode scanning and credit card scanning (built on jQuery):
https://github.com/ericuldall/jquery-pos
Simple implementation:
$(function(){
$(document).pos();
$(document).on('scan.pos.barcode', function(event){
var barcode = event.code;
//handle your code here....
});
});
So far this plugin is only tested with one type of scanner and codes containing only digits, but if you have further requirements that aren't working with it, I'd be happy to adapt it to your needs. Please check out the github page and give it a whirl. Contributions are encouraged.
E
var txt = "";
function selectBarcode() {
if (txt != $("#focus").val()) {
setTimeout('use_rfid()', 1000);
txt = $("#focus").val();
}
$("#focus").select();
setTimeout('selectBarcode()', 1000);
}
$(document).ready(function () {
setTimeout(selectBarcode(),1000);
});
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input type="text" name="tag" id="focus" placeholder="Use handheld RFID scanner">
Needs hardening but this routine, which counts on scanned data being sent in under 100ms, is working in production. Thanks to #jfbloom22 and other answers for inspiration and reminding me of monitorEvents.
It appears scanners need to be set to send "HID Keyboard"-type data(?) and be set to terminate with "Enter".
Although is purely JavaScript logic, was written in TypeScript app for a PCF (Power Apps Component Framework) project that allows the app to accept scan data without the need to focus on an input box. Globals were used as a convenience.
public Scan(evt: Event): void {
const e:KeyboardEvent = evt as KeyboardEvent;
const timeDiff = e.timeStamp - CheckInPCF.LastTimeStamp;
CheckInPCF.LastTimeStamp = e.timeStamp; //"global"
//console.log(e.key + ': ' + timeDiff);
if (timeDiff < 100) {
if (e.key == 'Enter') {
//Assemble complete scan text
CheckInPCF.ScanText = CheckInPCF.FirstCharacterCandidate + CheckInPCF.ScanText; //.replace('\u000D','');
//console.log('finished: ' + CheckInPCF.ScanText);
CheckInPCF._this._notifyOutputChanged(); //Power Apps related
}
else {
CheckInPCF.ScanText += e.key;
}
}
else {
CheckInPCF.ScanText = '';
CheckInPCF.FirstCharacterCandidate = e.key;
}
}
This code works fine for me, you can try it
var barcode = '';
var interval;
document.addEventListener('keydown', function(evt) {
if (evt.code === 'F12'){
evt.preventDefault();
}
if (interval){
clearInterval(interval);
}
if (evt.code == 'Enter') {
if (barcode){
$('#barcode').val(barcode);
console.log(barcode);
}
barcode = '';
return;
}
if (evt.key != 'Shift'){
barcode += evt.key;
}
interval = setInterval(() => barcode = '', 20);
});

Layout mess-up when JavaScript "keyup" run in Google Chrome

I create simple function when keyup using JavaScript like so :
<script>
//when press enter, submit this form, when press shift and enter create new line
$("#text_reply1778").keyup(function(e) {
var textVal = $(this).val();
if(e.which == 13 && e.shiftKey) {
//here create new line
}
else if (e.which == 13) {
e.preventDefault();
var text_input = $("#text_reply1778").val();
if(text_input != '') { //dont submit if value is empty
$('#reply1778').ajaxSubmit( {
target: '#reply_output1778',
success: function() {
//do somthing here
}
});
}
}
});
</script>
When I run this using browser Google Chrome Version 26.0.1410.43 my layout will mess-up but this not happen when I'm using Firefox.
You can try from here (full code) chat1.html , then type any message inside textarea(chat box) then you will see layout will mess-up.
So how to avoid this? Any method that I can use? I tried to replace keyup with keypress but the result was still the same.

using a function on textbox focus?

I want to add a autocomplete function to a site and found this guide which uses some js code which works really nice for one textbox: http://www.sks.com.np/article/9/ajax-autocomplete-using-php-mysql.html
However when trying to add multiple autocompletes only the last tetbox will work since it is the last one set.
Here is the function that sets the variables for the js script
function setAutoComplete(field_id, results_id, get_url)
{
// initialize vars
acSearchId = "#" + field_id;
acResultsId = "#" + results_id;
acURL = get_url;
// create the results div
$("#auto").append('<div id="' + results_id + '"></div>');
// register mostly used vars
acSearchField = $(acSearchId);
acResultsDiv = $(acResultsId);
// reposition div
repositionResultsDiv();
// on blur listener
acSearchField.blur(function(){ setTimeout("clearAutoComplete()", 200) });
// on key up listener
acSearchField.keyup(function (e) {
// get keyCode (window.event is for IE)
var keyCode = e.keyCode || window.event.keyCode;
var lastVal = acSearchField.val();
// check an treat up and down arrows
if(updownArrow(keyCode)){
return;
}
// check for an ENTER or ESC
if(keyCode == 13 || keyCode == 27){
clearAutoComplete();
return;
}
// if is text, call with delay
setTimeout(function () {autoComplete(lastVal)}, acDelay);
});
}
For one textbox I can call the function like this
$(function(){
setAutoComplete("field", "fieldSuggest", "/functions/autocomplete.php?part=");
});
However when using multiple textboxes I am unsure how I should go about doing this, here is something I did try but it did not work
$('#f1').focus(function (e) {
setAutoComplete("f1", "fSuggest1", "/functions/autocomplete.php?q1=");
}
$('#f2').focus(function (e) {
setAutoComplete("f2", "fSuggest2", "/functions/autocomplete.php?q2=");
}
Thanks for your help.
You should be using classes to make your function work in more than one element on the same page. Just drop the fixed ID's and do a forEach to target every single element with that class.

Categories