Virtual Keyboard with Jquery - javascript

I have a div that operates as a button. Once the button is clicked, I want it to simulate the pressing of a key. Elsewhere on Stackoverflow, people have suggested using jQuery.Event("keydown"); but the suggestions all use a .trigger() bound to the button as opposed to .click. So, my example code looks like this:
var press = jQuery.Event("keydown");
press.which = 69; // # The 'e' key code value
press.keyCode = 69;
$('#btn').click( function() {
$('#testInput').focus();
$(this).trigger(press);
console.info(press);
});
I've set up a dummy example at JSFiddle:
http://jsfiddle.net/ruzel/WsAbS/
Eventually, rather than have the keypress fill in a form element, I just want to register the event as a keypress to the document so that a MelonJS game can have it.
UPDATE: It looks like triggering a keypress with anything other than the keyboard is likely to be ignored by the browser for security reasons. For updating a text input, this very nice Jquery plugin will do the trick: http://bililite.com/blog/2011/01/23/improved-sendkeys/
As for anyone who comes here looking for the solution in the MelonJS case, it's best to use MelonJS's me.input object, like so:
$('#btn').mousedown(function() {
me.input.triggerKeyEvent(me.input.KEY.E, true);
});
$('#btn').mouseup(function() {
me.input.triggerKeyEvent(me.input.KEY.E, false);
});

I'm not sure why, but even though this is triggering the event correctly, it doesn't fill the input with the character.
I've modified the code to show that the document is indeed receiving keypress events when we say $(document).trigger(p)
Try it out:
http://jsfiddle.net/WsAbS/3/
var press = jQuery.Event("keydown");
press.which = 69; // # Some key code value
press.keyCode = 69;
press.target = $('#testInput');
$(document).on('keydown', function(event) {
alert(event.keyCode);
});
$('#btn').click( function() {
$(document).trigger(press);
});
I believe this should be good enough for your end goal of a MelonJS game picking up keypresses.

If you want a virtual keyboard (As the title suggests) you can use this one.

Related

Handling events for mouse click and keydown or keypress (for non-modifier keys)

I am new to JS and trying to learn on my own - thanks for any help!
I am trying to have a simple program respond to a click differently depending on what other key is pressed at the time of the mouse click.
I have searched far and wide and have not been able to find an answer that works for non-modifier keys alt and shift (which I have had no trouble implementing). However, I can't for the life of me figure out how to achieve the same result with a regular character key.
The example below (which I found in other comments on this site) works if the alt key is employed.
<div id="targetDiv">I want to put a ding in the universe.</div>
$(function() {
$("#targetDiv").click(function(event) {
if (event.altKey) {
//do something, alt was down when clicked
}
});
});
However, the intuitive modification does not work.
For example, the otherwise identical code (now using event.keyCode===114) does not work (?!) when the 'r' key is pressed (nor does event.charCode===114 do the trick):
<div id="targetDiv">I want to put a ding in the universe.</div>
$(function() {
$("#targetDiv").click(function(event) {
if (event.keyCode===114) {
//do something, alt was down when clicked
}
});
});
What went wrong?
I am able to get functionality out of a keyPress if I listen to it alone:
addEventListener("keypress", rIsPressed, false);
function rIsPressed(event){
if(event.keyCode===114){
console.log("the 'r' key is pressed");
}
}
however nothing seems to work when I try to pair a character keypress with a mouse click or even a character keypress with a modifier keypress:
addEventListener("keypress", rIsPressed, false);
function rIsPressed(event){
if((event.keyCode===114) && (event.altKey)){
console.log("the 'alt' and 'r' keys are pressed");
}
}
Note: I have tried keydown instead of keypress in all of these examples with no success.
Suggestions please on what I am missing or overlooking - what is problematic about pairing a character key down/press with a modifier key or a mouse click !?
Thank you!!
As I commented above, the click event does not have a property called keyCode so doing event.keyCode will not work. The only reason that control and alt work is because they are properties of the click event, event.ctrlKey and event.altKey. You can be a little more creative and use something like this maybe though I don't really know what you need:
var currKey = null;
$("#targetDiv").click(function (event) {
if (currKey != null) {
$("#targetDiv").text(currKey);
}
});
$(window).keydown(function (event) {
currKey = event.which;
});
$(window).keyup(function (event) {
currKey = null;
});
This stores the key code when keydown is fired, when keyup is fired it clears the var. The stuff in the click event is only allowed to run if the var shows something other than null.

How to simulate typing in input field using jQuery?

What I want is to simulate typing in <input> field using javascript.
I have the following code:
var press = jQuery.Event("keydown");
press.ctrlKey = false;
press.which = 65;
$("#test").trigger(press);
But when I load the page, the #test input field has no typed characters, the keycode of '65' represents 'A', but there is no 'A' input.
Basically what I want is to automatically typing in the website using Greasemonkey.
Please give me some ideas or some library with which I can use to do this.
Thanks a lot!
You can send key events, and anything listening for them will get them, but they will not change the input, so you will not see the letter A appear, for example. This is mostly a security thing; see "Manually firing events" for a discussion about that.
So, if you want the letter to appear, you must alter the input's value as you send the key event. There is a jQuery plugin for that, see "The $.fn.sendkeys Plugin".
You can see how an <input> reacts with user-applied keys, key events, and that plugin at this jsFiddle.
For reference, this is the key piece of code from that jsFiddle:
$("button").click ( function (zEvent) {
if (zEvent.target.id == "simA_plain") {
console.log ("Send Plain key event");
var keyVal = 65;
$("#eventTarg").trigger ( {
type: 'keypress', keyCode: keyVal, which: keyVal, charCode: keyVal
} );
}
else {
console.log ("Use the Plugin to simulate a keystroke");
$("#eventTarg").sendkeys ("B") ;
}
} );
That plugin should be sufficient if you are just trying to "simulate typing on an <input>". However, depending on what you are really trying to do, you may need to do one or more of the following:
Just set the text to what you want it to be.
Send a keydown event, if the page's javascript triggers off of that.
Likewise, send a change event, etc., if the page's javascript triggers off of that.
Just find and call the page's javascript directly. Use script injection, the location hack, unsafeWindow, and/or #grant none mode to do that.
Something else? State your true objective and link to the target page.

jquery custom keycode trigger not working

I want to send keystrokes on the selected element like this:
$(":input").click(function(){
$(this).trigger("keydown", [{
preventDefault:function(){},
keyCode:9,
shiftKey: true
}]);
});
//wants to send Shift+Tab keystroke on input click
Demo: http://jsfiddle.net/NYwCT/.
You cannot send keystrokes. It currently triggers any functions that are bound, but does not execute the relevant thing at browser level (what about a script sending ALT+F4?).
If you want to focus the input before the clicked one, you can use .prev() (previous sibling): http://jsfiddle.net/NYwCT/1/.
$(":input").click(function(){
$(this).prev().focus();
});
This will not fire the actual event
var press = jQuery.Event("keypress");
press.shiftKey = true;
press.keyCode = 9;
$(this).trigger(press);
you could also try this plug-in: fn.sendkeys or jwerty

How to trigger backspace on a textfield?

Say I have this:
<textarea id="myarea">Hello</textarea>
How would i trigger backspace on that textarea possibly using trigger() and key codes. The code for backspace is 8.
And i am not looking for this:
$('#myarea').val( $("myarea").val().slice(0,-1) );
I need to simulate someone actually pressing the 'backspace' key on their keyboard.
Thanks
You can create a keydown event:
var e = jQuery.Event("keydown", { keyCode: 20 });
Then trigger it in your textarea:
$("#myarea").trigger( e );
Update:
After doing some more research and testing, I realize that this solution does NOT simulate a natural keypress event on the HTML element. This method only triggers the keydown event, it does not replicate the user going into the element and pressing that key.
To simulate the user going into that textbox and pressing that key, you would have to create a dispatch event
The dispatch event is also not globally supported. Your best bet would be to trigger the keydown event and then update the text area as intended.
I found this:
http://forum.jquery.com/topic/simulating-keypress-events (answer number 2).
Something like this should work, or at least give you an idea:
<div id="hola"></div>
$(function(){
var press = jQuery.Event("keyup");
press.ctrlKey = false;
press.which = 40;
$('#hola').keyup(function(e){
alert(e.which);
})
.trigger(press); // Trigger the event
});
Demo: http://jsfiddle.net/qtPcF/1/
You shouldn't be forcing key events in js. Try simulating the character removal instead.
const start = textarea.selectionStart - 1;
const value = textarea.value;
const newValue = value.substr(0, start) + a.substr(start);
textarea.value = newValue;
Or if you just want the event, instead call the handler directly, rather than forcing the event. This is too hacky.

How to detect a textbox's content has changed

I want to detect whenever a textbox's content has changed. I can use the keyup method, but that will also detect keystrokes which do not generate letters, like the arrow keys. I thought of two methods of doing this using the keyup event:
Check explictly if the ascii code of the pressed key is a letter\backspace\delete
Use closures to remember what was the text in the textbox before the key stroke and check whether this has changed.
Both look kinda cumbersome.
Start observing 'input' event instead of 'change'.
jQuery('#some_text_box').on('input', function() {
// do your stuff
});
...which is nice and clean, but may be extended further to:
jQuery('#some_text_box').on('input propertychange paste', function() {
// do your stuff
});
Use the onchange event in HTML/standard JavaScript.
In jQuery that is the change() event. For example:
$('element').change(function() { // do something } );
EDIT
After reading some comments, what about:
$(function() {
var content = $('#myContent').val();
$('#myContent').keyup(function() {
if ($('#myContent').val() != content) {
content = $('#myContent').val();
alert('Content has been changed');
}
});
});
The 'change' event doesn't work correctly, but the 'input' is perfect.
$('#your_textbox').bind('input', function() {
/* This will be fired every time, when textbox's value changes. */
} );
How about this:
< jQuery 1.7
$("#input").bind("propertychange change keyup paste input", function(){
// do stuff;
});
> jQuery 1.7
$("#input").on("propertychange change keyup paste input", function(){
// do stuff;
});
This works in IE8/IE9, FF, Chrome
Use closures to remember what was the text in the checkbox before the key stroke and check whether this has changed.
Yep. You don't have to use closures necessarily, but you will need to remember the old value and compare it to the new.
However! This still won't catch every change, because there a ways of editing textbox content that do not involve any keypress. For example selecting a range of text then right-click-cut. Or dragging it. Or dropping text from another app into the textbox. Or changing a word via the browser's spell-check. Or...
So if you must detect every change, you have to poll for it. You could window.setInterval to check the field against its previous value every (say) second. You could also wire onkeyup to the same function so that changes that are caused by keypresses are reflected quicker.
Cumbersome? Yes. But it's that or just do it the normal HTML onchange way and don't try to instant-update.
$(document).on('input','#mytxtBox',function () {
console.log($('#mytxtBox').val());
});
You can use 'input' event to detect the content change in the textbox. Don't use 'live' to bind the event as it is deprecated in Jquery-1.7, So make use of 'on'.
I assume that you are looking to do something interactive when the textbox changes (i.e. retrieve some data via ajax). I was looking for this same functionality. I know using a global isn't the most robust or elegant solution, but that is what I went with. Here is an example:
var searchValue = $('#Search').val();
$(function () {
setTimeout(checkSearchChanged, 0.1);
});
function checkSearchChanged() {
var currentValue = $('#Search').val();
if ((currentValue) && currentValue != searchValue && currentValue != '') {
searchValue = $('#Search').val();
$('#submit').click();
}
else {
setTimeout(checkSearchChanged, 0.1);
}
}
One key thing to note here is that I am using setTimeout and not setInterval since I don't want to send multiple requests at the same time. This ensures that the timer "stops" when the form is submitted and "starts" when the request is complete. I do this by calling checkSearchChanged when my ajax call completes. Obviously you could expand this to check for minimum length, etc.
In my case, I am using ASP.Net MVC so you can see how to tie this in with MVC Ajax as well in the following post:
http://geekswithblogs.net/DougLampe/archive/2010/12/21/simple-interactive-search-with-jquery-and-asp.net-mvc.aspx
I would recommend taking a look at jQuery UI autocomplete widget. They handled most of the cases there since their code base is more mature than most ones out there.
Below is a link to a demo page so you can verify it works. http://jqueryui.com/demos/autocomplete/#default
You will get the most benefit from reading the source and seeing how they solved it. You can find it here: https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.autocomplete.js.
Basically they do it all, they bind to input, keydown, keyup, keypress, focus and blur. Then they have special handling for all sorts of keys like page up, page down, up arrow key and down arrow key. A timer is used before getting the contents of the textbox. When a user types a key that does not correspond to a command (up key, down key and so on) there is a timer that explorers the content after about 300 milliseconds. It looks like this in the code:
// switch statement in the
switch( event.keyCode ) {
//...
case keyCode.ENTER:
case keyCode.NUMPAD_ENTER:
// when menu is open and has focus
if ( this.menu.active ) {
// #6055 - Opera still allows the keypress to occur
// which causes forms to submit
suppressKeyPress = true;
event.preventDefault();
this.menu.select( event );
}
break;
default:
suppressKeyPressRepeat = true;
// search timeout should be triggered before the input value is changed
this._searchTimeout( event );
break;
}
// ...
// ...
_searchTimeout: function( event ) {
clearTimeout( this.searching );
this.searching = this._delay(function() { // * essentially a warpper for a setTimeout call *
// only search if the value has changed
if ( this.term !== this._value() ) { // * _value is a wrapper to get the value *
this.selectedItem = null;
this.search( null, event );
}
}, this.options.delay );
},
The reason to use a timer is so that the UI gets a chance to be updated. When Javascript is running the UI cannot be updated, therefore the call to the delay function. This works well for other situations such as keeping focus on the textbox (used by that code).
So you can either use the widget or copy the code into your own widget if you are not using jQuery UI (or in my case developing a custom widget).
do you consider using change event ?
$("#myTextBox").change(function() { alert("content changed"); });
I'd like to ask why you are trying to detect when the content of the textbox changed in real time?
An alternative would be to set a timer (via setIntval?) and compare last saved value to the current one and then reset a timer. This would guarantee catching ANY change, whether caused by keys, mouse, some other input device you didn't consider, or even JavaScript changing the value (another possiblity nobody mentioned) from a different part of the app.
Use the textchange event via customized jQuery shim for cross-browser input compatibility. http://benalpert.com/2013/06/18/a-near-perfect-oninput-shim-for-ie-8-and-9.html (most recently forked github: https://github.com/pandell/jquery-splendid-textchange/blob/master/jquery.splendid.textchange.js)
This handles all input tags including <textarea>content</textarea>, which does not always work with change keyup etc. (!) Only jQuery on("input propertychange") handles <textarea> tags consistently, and the above is a shim for all browsers that don't understand input event.
<!DOCTYPE html>
<html>
<head>
<script class="jsbin" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="https://raw.githubusercontent.com/pandell/jquery-splendid-textchange/master/jquery.splendid.textchange.js"></script>
<meta charset=utf-8 />
<title>splendid textchange test</title>
<script> // this is all you have to do. using splendid.textchange.js
$('textarea').on("textchange",function(){
yourFunctionHere($(this).val()); });
</script>
</head>
<body>
<textarea style="height:3em;width:90%"></textarea>
</body>
</html>
JS Bin test
This also handles paste, delete, and doesn't duplicate effort on keyup.
If not using a shim, use jQuery on("input propertychange") events.
// works with most recent browsers (use this if not using src="...splendid.textchange.js")
$('textarea').on("input propertychange",function(){
yourFunctionHere($(this).val());
});
There's a complete working example here.
<html>
<title>jQuery Summing</title>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"> </script>
$(document).ready(function() {
$('.calc').on('input', function() {
var t1 = document.getElementById('txt1');
var t2 = document.getElementById('txt2');
var tot=0;
if (parseInt(t1.value))
tot += parseInt(t1.value);
if (parseInt(t2.value))
tot += parseInt(t2.value);
document.getElementById('txt3').value = tot;
});
});
</script>
</head>
<body>
<input type='text' class='calc' id='txt1'>
<input type='text' class='calc' id='txt2'>
<input type='text' id='txt3' readonly>
</body>
</html>
Something like this should work, mainly because focus and focusout would end up with two separate values. I'm using data here because it stores values in the element but doesn't touch the DOM. It is also an easy way to store the value connected to its element. You could just as easily use a higher-scoped variable.
var changed = false;
$('textbox').on('focus', function(e) {
$(this).data('current-val', $(this).text();
});
$('textbox').on('focusout', function(e) {
if ($(this).data('current-val') != $(this).text())
changed = true;
}
console.log('Changed Result', changed);
}
This Code detects whenever a textbox's content has changed by the user and modified by Javascript code.
var $myText = jQuery("#textbox");
$myText.data("value", $myText.val());
setInterval(function() {
var data = $myText.data("value"),
val = $myText.val();
if (data !== val) {
console.log("changed");
$myText.data("value", val);
}
}, 100);
document.getElementById('txtrate' + rowCount).onchange = function () {
// your logic
};
This one works fine but triggers the event on click too which is not good. my system went into loop.
while
$('#txtrate'+rowCount).bind('input', function() {
//your logic
} );
works perfectly in my scenario. it only works when value is changed.
instead of $ sign one can use document.getElementById too

Categories