JQuery focus without entering key event shortcut - javascript

Using keymaster library for defining and dispatching keyboard shortcuts, I defined shortcut key / to focus input element.
key('/', function() {
$(".topbar input").focus();
});
The issue is that when the / key is pressed, the input is focused with / entered value. I want to get rid of that.

Try this.
key('/', function(event) {
$(".topbar input").focus();
event.preventDefault();
});

It gets focused because you tell it to do so.
Remove this line:
$(".topbar input").focus();
Or give it a function so that you can do stuff when it gets focused
$(".topbar input").focus(function(){
});

Related

On keypress does not fire on the first key press

I have this method:
$(".txtB").on("keypress", function(event) {
console.log($(this).val());
if (...)
event.preventDefault();
});
But it works only after the second key pressed not for the first one. After that is triggered on every key press.
Anyone have an idea what could be?
Thanks.
Later edit:
It might be related to the way i use the function?
in HTML: onkeyup = "caseValuePercentageTwoDecimalRestriction()"
in JS:
function caseValuePercentageTwoDecimalRestriction() {
$(".caseValuePrecentageRestriction").on("keypress", function (event) {
...
??
The error is calling caseValuePercentageTwoDecimalRestriction on keyup event which is fired after keypress event.
keyup is called when you release the key while keypress is called when you press the key.
You should bind you keypress event handler on a document.ready event like this:
$(document).ready(function() {
$(".caseValuePrecentageRestriction").on("keypress", function (event) {
// do whatever you need
});
});
$(".txtB").keyup(function (event) {
console.log($(this).val());
});
To answer your question, Keypress event happens before the input change. But Keyup happens after the change. That's the only difference.
For input fields there is one more property input propertychange which works on change of text by keyboard as well as of you copy from mouse. Try using it
$(".txtB").on("input propertychange", function(event) {
console.log($(this).val());
if (...)
event.preventDefault();
});
use keyup instead of key press - Try:
$(".txtB").keyup(function (event) {
console.log($(this).val());
});
Then maybe .keydown would work for you?
Here we go:
Your code have to be like this:
$("input").keypress(function(){
$("span").text(i += 1);
alert("Test key pres");
});
<input type="text">
<p>Keypresses: <span>0</span></p>
Hope it helps;)
This will work for you but this is not perfect solution, it is just a work around:
$(document).ready(function(){
$(".txtB").on("keypress", function (event) {
console.log($(this).val() + event.key);
});
});
Here is a jsbin
As other users has shared Keypress event triggers before the value of textbox changed. You should use other events if you want updated value of textbox.
keypress events are fired before the new character is added to the input.
So the first keypress event is fired before the first character is added, while the input is still empty.
If you check this JSFIDDLE you will see an alert box even before you see value in input.
For example if you type a initially you will see an empty alert box, then type a different character, at that point you will see it is alerting a
You need to use either keyup or keydown. You can aslo use event.preventDefault() with keyup & keydown
try to use change instead of keypress or keyup because it will call first :
$(".txtB").change(function(event){
console.log($(this).val());
});

Virtual Keyboard with Jquery

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.

jQuery bind to keyup only, not focus

This seems like a simple thing but google hasn't turned up anything for me:
How can I bind to a text / value change event only, excluding an input gaining focus? Ie, given the following:
$(function(){
$('input#target').on('keyup', function(){
alert('Typed something in the input.');
});
});
...the alert would be triggered when the user tabs in and out of an element, whether they actually input text or not. How can you allow a user to keyboard navigate through the form without triggering the event unless they input/change the text in the text field?
Note: I'm showing a simplified version of a script, the reason for not using the change event is that in my real code I have a delay timer so that the event happens after the user stops typing for a second, without them having to change focus to trigger the event.
Store the value, and on any key event check if it's changed, like so:
$(function(){
$('input#target').on('keyup', function(){
if ($(this).data('val')!=this.value) {
alert('Typed something in the input.');
}
$(this).data('val', this.value);
});
});​
FIDDLE
Simply use the .change event.
Update: If you want live change notifications then do you have to go through the keyup event, which means that you need to program your handler to ignore those keys that will not result in the value being modified.
You can implement this with a whitelist of key codes that are ignored, but it could get ugly: pressing Del results in the value being changed, unless the cursor is positioned at the end of the input in which case it does not, unless there happens to be a selected range in the input in which case it does.
Another way which I personally find more sane if not as "pure" is to program your handler to remember the old value of the element and only react if it has changed.
$(function() {
// for each input element we are interested in
$("input").each(function () {
// set a property on the element to remember the old value,
// which is initially unknown
this.oldValue = null;
}).focus(function() {
// this condition is true just once, at the time we
// initialize oldValue to start tracking changes
if (this.oldValue === null) {
this.oldValue = this.value;
}
}).keyup(function() {
// if no change, nothing to do
if (this.oldValue == this.value) {
return;
}
// update the cached old value and do your stuff
this.oldValue = this.value;
alert("value changed on " + this.className);
});
});​
If you do not want to set properties directly on the DOM element (really, there's nothing wrong with it) then you could substitute $(this).data("oldValue") for this.oldValue whenever it appears. This will technically have the drawback of making the code slower, but I don't believe anyone will notice.
See it in action.
This will do it, set a custom attribute and check against that:
$('input').focus(function(){
$(this).attr('originalvalue',$(this).val());
});
$('input').on('keyup',function(){
if($(this).val()===$(this).attr('originalvalue')) return;
alert('he must\'ve typed something.');
});
Be wary of events firing multiple times.
Here is another version that plainly tests if the input field is empty.
If the input is empty then the action is not performed.
$(function(){
$(selector).on('keyup', function(){
if ($(this).val()!='') {
alert('char was entered');
}
})
});

fire .change with keyup and keydown

I have the following which works as long as I use the mouse to select an option from the selectbox, or use keyboard arrow keys to select the option, but when using the keyboard, the change event does not fire until I press enter on the keyboard.
How would I detect a change using the keyboard arrow keys without having to press enter?
$('#select_box').change(function() {
some_function($(this).val());
});
You'll probably want to avoid calling your function multiple times unnecessarily, which will happen if you are not careful with multiple events. You can avoid this by checking if the value of the field has actually changed before calling it. One way of doing this, shown below, is to store a property on the field with the previous value and then using that to check if the field's value has changed before calling your function:
var previousValuePropertyKey = 'previousValue';
$('#select_box').bind('keyup change', function(event) {
var previousValue = $(this).prop(previousValuePropertyKey);
var currentValue = $(this).val();
$(this).prop(previousValuePropertyKey, currentValue );
if(previousValue != currentValue ){
alert(currentValue);//TODO remove alert
//Yourfunction(..);
}
});
Here's a fiddle for an example.
TRY
$('#select_box').bind('keyup change',function() {
some_function($(this).val());
});
Reference
$('#select_box').change(function() {
alert($(this).val());
});
$('#select_box').keyup(function() {
alert($(this).val());
});

Looking for a better workaround to Chrome select on focus bug

I have the same problem as the user in this question, which is due to this bug in Webkit. However, the workaround provided will not work for my app. Let me re-state the problem so that you don't have to go read another question:
I am trying to select all the text in a textarea when it gets focus. The following jQuery code works in IE/FF/Opera:
$('#out').focus(function(){
$('#out').select();
});
However, in Chrome/Safari the text is selected--very briefly--but then the mouseUp event is fired and the text is deselected. The following workaround is offered in the above links:
$('#out').mouseup(function(e){
e.preventDefault();
});
However, this workaround is no good for me. I want to select all text only when the user gives the textarea focus. He must then be able to select only part of the text if he chooses. Can anyone think of a workaround that still meets this requirement?
How about this?
$('#out').focus(function () {
$('#out').select().mouseup(function (e) {
e.preventDefault();
$(this).unbind("mouseup");
});
});
The accepted answer (and basically every other solution I found so far) does not work with keyboard focus, i. e. pressing tab, at least not in my Chromium 21. I use the following snippet instead:
$('#out').focus(function () {
$(this).select().one('mouseup', function (e) {
$(this).off('keyup');
e.preventDefault();
}).one('keyup', function () {
$(this).select().off('mouseup');
});
});
e.preventDefault() in the keyup or focus handler does not help, so the unselecting after a keyboard focus seems to not happen in their default handlers, but rather somewhere between the focus and keyup events.
As suggested by #BarelyFitz, it might be better to work with namespaced events in order to not accidentally unbind other event handlers. Replace 'keyup' with 'keyup.selectText' and 'mouseup' with 'mouseup.selectText' for that.
Why not simply:
$('#out').focus(function(){
$(this).one('mouseup', function() {
$(this).select();
});
});
Seems to work in all major browsers...
A very slightly different approach would be to separate the focus event from the mouse sequence. This works really nicely for me - no state variables, no leaked handlers, no inadvertent removal of handlers, and it works with click, tab, or programmatic focus. Code and jsFiddle below -
$('#out').focus(function() {
$(this).select();
});
$('#out').on('mousedown.selectOnFocus', function() {
if (!($(this).is(':focus'))) {
$(this).focus();
$(this).one('mouseup.selectOnFocus', function(up) {
up.preventDefault();
});
}
});
https://jsfiddle.net/tpankake/eob9eb26/27/
Make a bool. Set it to true after a focus event and reset it after a mouse up event. During the mouse up, if it's true, you know the user just selected the text field; therefore you know you must prevent the mouse up from happening. Otherwise, you must let it pass.
var textFieldGotFocus = false;
$('#out').focus(function()
{
$('#out').select();
textFieldGotFocus = true;
});
$('#out').mouseup(function(e)
{
if (textFieldGotFocus)
e.preventDefault();
});
$(document).mouseup(function() { textFieldGotFocus = false; });
It's important that you put the mouseup listener that resets the variable on document, since it's not guaranteed that the user will release the mouse button over the text field.
onclick="var self = this;setTimeout(function() {self.select();}, 0);"
Select the text before putting the focus on the input box.
$('#out').select().focus();
digitalfresh's solution is mostly there, but has a bug in that if you manually trigger .focus() using JS (so not using a click), or if you tab to the field, then you get an unwanted mouseup event bound - this causes the first click that should deselect the text to be ignored.
To solve:
var out = $('#out');
var mouseCurrentlyDown = false;
out.focus(function () {
out.select();
if (mouseCurrentlyDown) {
out.one('mouseup', function (e) {
e.preventDefault();
});
}
}).mousedown(function() {
mouseCurrentlyDown = true;
});
$('body').mouseup(function() {
mouseCurrentlyDown = false;
});
Note: The mouseup event should be on body and not the input as we want to account for the user mousedown-ing within the input, moving the mouse out of the input, and then mouseup-ing.
tpankake's answer converted to a reusable jQuery function..
(If you upvote this, please also upvote his answer)
Load the following AFTER loading the jQuery library:
$.fn.focusSelect = function () {
return this.each(function () {
var me = $(this);
me.focus(function () {
$(this).select();
});
me.on('mousedown.selectOnFocus', function () {
var me2 = $(this);
if (me2.is(':focus') === false) {
me2.focus();
me2.one('mouseup.selectOnFocus', function (up) {
up.preventDefault();
});
}
});
});
};
Use it like this:
$(document).ready(function () {
// apply to all inputs on the page:
$('input[type=text]').focusSelect();
// apply only to one input
$('#out').focusSelect();
});

Categories