I wish to click on an <img> and make the browser simulate the typing out of a variable + [ENTER]. This should basically simulate the same thing that would happen if a scanner scanned a barcode
I'm developing an add-on for a webapp that we use at work. This work includes needing to scan barcodes which I've gotten to show on screen and we can scan, however in some instances it has proven to be a little difficult to scan. I'd like to be able to click on the barcode that is generated and have it simulate keystrokes. The characters don't need to end up in any input field as I assume the webapp is set to capture keystrokes for the whole window. I just need the keystrokes to be entered pretty fast to simulate a barcode scanner.
The jsfiddle provided currently has the variable being sent to an input field but that is not necessary for the final results.
I'd like to keep this vanilla javascript as I'm still learning it and don't wish to move on to Jquery until i have my feet firmly planted in JS.
https://jsfiddle.net/pshock13/o2gtzaj5/215
document.getElementById('barcode').addEventListener('click', function() {
//this is where I want theBarcode to be typed out + [ENTER] automatically.
main_input.value = theBarcode;
})
You can simulate a keypress by dispatching a KeyboardEvent for keydown and keyup.
E.g. simulating keypresses for your barcode:
document.getElementById('barcode').addEventListener('click', function() {
main_input.value = theBarcode;
[...theBarcode].forEach(function(c) {
window.dispatchEvent(new KeyboardEvent('keydown',{'key':c}));
window.dispatchEvent(new KeyboardEvent('keyup',{'key':c}));
});
window.dispatchEvent(new KeyboardEvent('keydown',{'key':'Enter'}));
window.dispatchEvent(new KeyboardEvent('keyup',{'key':'Enter'}));
});
Related
I have a search box that users can type in. When the user keys up, the search is performed. There are checks to see the length of text in the search box.
// THE SEARCH STRING IS BEING POPULATED
$SEARCH.SearchString.keyup($SEARCH.utilities.doSearch);
When someone uses ctrl+v to paste text, this works perfect. When someone uses the menu to paste, like in the image below, the search is not performed.
I am not sure of what to call this menu so it's difficult to search for an answer. What event should I have JavaScript listen for when this menu is present and the user selects "Paste"?
The input event triggers for both paste and typing, thus could be used in lieu of keyup or keydown and cover both scenarios for user entry in modern browsers.
The caveat is that IE shows support starting in IE9 as well as IE9 has some different behavior issues .
IE 9 does not fire an input event when the user removes characters
from input filled by keyboard, cut, or drag operations.
$('input').on('input', function(e){
$('body').append('<br>Input event triggered, value = ' + this.value);
});
Reference: MDN input event docs
DEMO
There is onpaste but it doesn't seem to be part of any standard so your milage may vary
$(selector).on('paste', function() {
doSomething();
});
What is the best cross-browser and cross-platform way to detect hardware keyboard presence with javascript?
This may be an old question, but a few months ago, I was looking for a solution to this myself. I was building a messaging system which should send the message when someone hits Return on their physical keyboard, but inserts a newline when someone hits Return on a virtual keyboard. The way I solved it was by counting the time between keydown and keyup events and getting the average when Return was hit.
I finally got around to documenting it on my blog here.
Could you try the theoretical opposite? Instead of trying to detect keyboard hardware, why not try to detect a touch screen? With the ontouchstart event;
if ('ontouchstart' in document.documentElement) {
// show icon
}
Keyboard in JS is accessible via browser APIs which delegate to OS APIs and it's not possible to tell if there's a physical keyboard. I can cut the cord off of my physical keyboard right now, turn on virtual keyboard, click on the on-screen buttons with my mouse and the browser will still trigger every keyboard event the scripts are listening to. Form browsers's/JS's perspective the virtual keyboard is indistinguishable from a physical one.
And what does "presence" even mean? If I have a phone with a touch screen and slide-out keyboard do you expect the browser to trigger some kind of "keboardIn"/"keyboardOut" event? Same with cable plug-in/out? :)
If your app absolutely requires a physical keyboard just inform/ask the user.
Edit - after clarification by OP:
You know the facebook chat? You send messages simply by pressing
"Enter", I have to show users that do not have a keyboard button to
replace the "Enter" key.
So just make a form with text input and listen to the input/form events. Most (every?) soft keyboards have some kind of "Done", "Ready" or similar button. You don't need to know if the "keyCode" is equal to "13", but detect that the user has an intent to submit what he has typed. Or, as the last resort, detect f the device i touch-enabled and display the button then. ( if('ontouchstart' in document.documentElement)/* show touch sbmit button */ )
Use keyboard event to detect if the user have keyboard or not (he/she may press it). Save it in localStorage and the browser will remember it for the next time.
var app = this;
app.hasKeyboard = false;
this.keyboardPress = function() {
app.hasKeyboard = true;
$(window).unbind("keyup", app.keyboardPress);
localStorage.hasKeyboard = true;
console.log("has keyboard!")
}
$(window).on("keyup", app.keyboardPress)
if(localStorage.hasKeyboard) {
app.hasKeyboard = true;
$(window).unbind("keyup", app.keyboardPress);
console.log("has keyboard from localStorage")
}
When a virtual keyboard pops up on the screen on a mobile device, the height of your application reduces in order to accommodate the virtual keyboard. So, what you can do is that you can add an event listener that checks whether the screen has resized as the user focuses on the input field.
You can add this functionality using the resize event listener when the input field is focused:
const inputField = document.querySelector(".my-input");
const virtualKeyboardDetected = () => alert("Virtual keyboard detected!");
inputField.addEventListener("focusin", () => {
window.addEventListener("resize", virtualKeyboardDetected )
})
inputField.addEventListener("focusout", () => {
window.removeEventListener("resize", virtualKeyboardDetected )
})
if (confirm('Do you have hardware keyboard?')) {
} else {
}
Edit according to description in comments under question:
What about support 'Enter' everytime and add 'Send' icon only for touch screens (What's the best way to detect a 'touch screen' device using JavaScript?) and as a 'hover' pseudoclass for mouse?
Consider this Example.
The essential bit is the JavaScript:
function encodeInput(editor) {
theText = editor.val();
theText = theText.replace(/\*\*\*(.*?)\*\*\*/, '<strong><i>$1</i></strong>', 'g');
theText = theText.replace(/\*\*(.*?)\*\*/, '<strong>$1</strong>', 'g');
theText = theText.replace(/\*(.*?)\*/, '<i>$1</i>', 'g');
console.log(theText);
$('#preview').html(theText);
}
$(function() {
$editor = $('#editor');
$editor.keyup(function() {
encodeInput($(this));
});
});
Tested and works great (I do need the \*\*\* part or it doesn't work).
Anyways, on to the main course
The Problem
Because I'm using keyup, the script is not very responsive (eg. it only "runs" once the user had let go of the key). I want it to behave more like the editor here on StackOverflow, where the key is pressed and response occurs immidiately.
I tried using keydown and keypress but it seems as if the val() attribute is not updated when it runs, so I can't really know the updated value.
In Short
How can I make it more responsive, so that when the user pressed a key, the preview is automatically updated??
You can use the HTML5 input event in most browsers and the propertychange event in IE < 9. These events fire immediately after the textarea's value is updated.
Here's an updated demo using these events:
http://jsfiddle.net/muWm2/1/
I've written about this in a few places on SO. Here are two of them:
Catch only keypresses that change input?
jQuery keyboard events
I would recommend against updating the preview on every single change to the textarea's value because it could quickly get unresponsive, which is a big no-no for user experience. I'd suggest "debouncing" the event, in this case waiting for a period of user inactivity (say half a second) before updating the preview. Here's an answer and a link that may help:
How to trigger an onkeyup event that's delayed until a user pauses their typing?
Debouncing Javascript Methods by John Hann
You can bind() both the keyup and keydown events:
$editor.bind('keyup keydown', function() {
encodeInput($(this));
});
I noticed that only the first occurrence was working, adding the g flag to the regex seemed to help, and for the purpose of the jsfiddle demo only, unchecking "normalize css" made the bold text appear.
http://jsfiddle.net/tuUym/3/
Keypress fires when the key is pressed continously, so you have to bind it to keypress in order to see the result. And thats it.
http://jsfiddle.net/tuUym/4/
UPDATE: I see what you mean. Maybe you need an input poller? Check out the de obfuscated wmd code. That will help you achieve the lagless editor you aim for:
WMD Download
Like if they press A regardless of the caps for it to pull up Apps, Pressing D pulls up Dashboard. This should only work if their mouse is not in a area where they can type. How would i do this?
Here is the pseudo code I would follow:
onKeyPress {
if (body.hasFocus && !input.hasFocus ) {
coolStuff();
}
}
Basically, you have an event listener waiting for your particular key(s) to be pressed. You only execute the coolFunc(), however, if they have focus on your webpage (i.e. not the address bar) and they are not inside a input element.
I would also recommend using jQuery; it will make your code a lot cleaner and easier to write.
Let me know if you need an actual JS example, not pseudo-code.
I'm building a site that after the page is loaded, needs to listen for a particular keyboard string.
The event I am interested in is actually a scanner scanning an object, but it presents to the site as keyboard input, of the form ~XXX~.
I see jQuery has a keypress() event that you can bind to a particular object.
But how can I listen for general keyboard input, after $(document).ready?
Try this:
$(function() {
$(window).keypress(function(e) {
var key = e.which;
//do stuff with "key" here...
});
});
See it in action on jsFiddle
I've done this before. There are many other things to worry about besides how to handle keypress events.
Your scanner probably sends the input wrapped by a start and end characters. I would create a ScanReader object that attaches to the keypress event. Once it detects the start character, it starts accumulating the presses until the end character is detected.
To prevent it from getting confused with the user typing, the keypresses should be relatively close (in time) to each other, you need to test it out and see what a good number of ms between keypresses is. Fast typers can type as fast as 50ms in between key presses.