I am trying to stop the enter key from triggering all actions from other scripts on input fields.
Here is the code I am using:
$(document).bind("keydown", function(e) {
var code = e.keyCode || e.which;
if (code == 13) {
// alert('enter pressed');
e.preventDefault();
return false;
}
});
An example of the code in action is here http://jsfiddle.net/8SJYn/ ,
It should be disabling enter but it is not.
Opinions?
You can do it by turning off the keydown and blur events for the input created by the tagit for this element alone.
Try this:
$('#myTags + ul .ui-autocomplete-input').off('keydown').off('blur');
http://jsfiddle.net/JzJRY/
Go into tag-it.js, and on line 245, find this part and remove it:
event.which === $.ui.keyCode.ENTER
JavaScript events have a "bubbling" phase, where they fire first on the inner-most DOM element, and then work their way up to the top-level document. If you try to stop the event at the document level, as in your example code, it is too late.
In some browsers (Firefox, for one) there is a "capturing" phase that occurs before the bubbling phase, and it works in the opposite direction: from top down. You cannot add a capturing phase event handler using jQuery. You must use the native addEventListener function and pass true as the third parameter. If you add the code below into your jsfiddle, it will prevent the Enter keydown event in some browsers.
document.addEventListener('keydown', function (e) {
if (e.keyCode === 13) {
// alert('Enter keydown');
e.stopPropagation();
}
}, true);
Be aware that the tag-it control in your jsfiddle also performs its text-to-tag conversions on blur, so if you uncomment the alert statement above, it will perform its text-to-tag conversion anyway, because of the blur event that occurs when the alert message is displayed.
Lastly, if you want to prevent not just other scripts from processing the Enter keydown, but also the browser itself, add an e.preventDefault(); line to the above.
Related
I was fiddling with preventDefault() and must be doing something wrong.
$("#input").bind("keypress", function(event) {
if(event.which == 9) {
event.preventDefault();
alert("You pressed tab.");
}
});
The tab functionality isn't prevented. What's wrong with this?
Try this FIDDLE. The input loses focus when you tab. Binding to the body fixes this.
$("body").on("keydown", function(event) {
if(event.which == 9) {
event.preventDefault();
alert("You pressed tab.");
}
});
The keypress event is simply not fired when the Tab is pressed - this also explains why there is no alert, independent of what preventing the default may do.
Changing the code to use keydown allows the Tab to be caught and prevents the default focus-change (in Chrome1, anyway).
$("#input").bind("keydown", function(event) {
if(event.which == 9) {
event.preventDefault();
}
});
1 I tested the above in Chrome 35 with jQuery 1.6-2.1; it does not work under the KO 3.0 library.
From the documentation on JQuery,
Note: as the keypress event isn't covered by any official specification, the actual behavior encountered when using it may differ across browsers, browser versions, and platforms.
This method is a shortcut for .on( "keypress", handler ) in the first two variations, and .trigger( "keypress" ) in the third.
The keypress event is sent to an element when the browser registers keyboard input. This is similar to the keydown event, except that modifier and non-printing keys such as Shift, Esc, and delete trigger keydown events but not keypress events. Other differences between the two events may arise depending on platform and browser.
So in this case you are using the wrong event. Also it might have browser compatibility issues.
For some odd reason event.PrventDefault is not working properly in meteor events.
I try this on jsFiddle and it works as expected (The enter doesn't go to the new line).
Here is a link
However, similar code in meteor events is not working, the enter is registering a break in the textarea.
'keyup #add_comment_content' : function(event) {
if (event.keyCode == 13) { // When the enter key is pressed
event.preventDefault();
//var content = $(this).val();
//var id = $(this).parent().find('comment_content_id').val();
//console.log(content);
//console.log(id);
console.log("Hey");
}
}
I got it to work by using the keypress event instead of the keyup event. I tried this because the docs mentioned:
keypress is most useful for catching typing in text fields, while keydown and keyup can be used for arrow keys or modifier keys.
This is my code:
$('#Login').keydown(function(e){
if(e.which == 32){
alert("enter");
this.preventDefault();
}
});
This code doesn't work but sends the alert:
$('#Pwd,#Pwd2').on('keydown',function(e){
if(e.which == 32){
e.preventDefault();
}
});
And this code works.
I do not understand why.
You are wanting to prevent the default action of the Event (which is passed in as the parameter for your event function, you are calling it e).
this is the element that is the target of your event (ie: in this case e.target which will be your #Login element) and not an event itself, this does not have a preventDefault().
Just use the Event object for this as well:
$('#Login').keydown(function(e){
if(e.which == 32){
e.preventDefault();
}
});
With the above you'll see the event is cancelled every time you hit the space bar within #Login: http://jsfiddle.net/xWmUU/
preventDefault is a method of the Event object, so it makes sense that it works when called on an event.
this will refer to #Login in this case, which is a DOM object and will not have the preventDefault method.
Note that because of how event propagation works, this will not always be equal to e.target.
After pressing enter I would like that only the keyup event be fired but blur is fired first. How to cancel blur when keyup is fired with enter?
Please don't suggest to bind both blur and keyup into a single live() method.
$(".textbox").on("blur",function () {
alert("blur Event fired");
});
$(".textbox").on("keyup",function (event) {
if(event.keyCode == 13){ // Detect Enter
alert("KeyUp fired after pressing Enter");
}
});
Edit
To prevent both events from firing, you'll have to somehow mark the element before causing it to lose focus. That way, your blur event handler can tell if the event is the subject of a keyup, or if it legitimately lost focus. Something like this:
$(".textbox").live("blur",function (event) {
if (!$(this).hasClass('keyupping'))
alert("blur Event fired");
});
$(".textbox").live("keyup",function (event) {
$(this).addClass('keyupping');
if(event.keyCode == 13){ // Detect Enter
alert("KeyUp fired after pressing Enter");
}
$(this).removeClass('keyupping');
});
Try it out: http://jsfiddle.net/GRMule/sR6zm/
Original answer
When the event for keyup fires, it prepares to draw the browser alert dialog, which takes focus from the document and applies it to the modal dialog. This causes the blur event to fire.
The blur event is then jumping in and finishing its execution context before keyup knows what hit it.
This is demonstrated by using something that does not take the focus off the element, like console.log: http://jsfiddle.net/GRMule/7vRLW/
The order that events fire is implementation-specific, meaning that you can't rely on Firefox acting like IE. See the spec: http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html#Events-eventgroupings. Try the fiddle with alerts in IE, and in this case you'll see that blur does hit before keyup in IE 7 -- and blur doesn't fire in Chrome!
I had a similar problem. I'm allowing the user to edit a single field and when they press Enter or move off that field, I send an Ajax request to update it. I found that when I pressed Enter the Ajax request was sent twice.
So rather than calling my request on Enter, I tried calling $input.blur() instead, and that worked! Which got me to thinking... If the Enter key causes a blur do I even need to try to capture it?
In my case, I did not need to. I found that all I needed was the blur because the Enter key triggered it anyway. I'm not sure if that's 100% across all browsers, but I did test on current versions of Chrome, Firefox, IE and Safari, all of which worked fine.
So, I suggest that you either just don't capture the Enter at all, or you simply call blur() to trigger the actions you need.
I have an input where a user can change it, focus out or press enter.
But when you press enter both keydown and blur is triggered, so myFunction() gets triggered twice.
So instead of writing two separate functions for keydown and blur, you can instead put them into a single function:
my_input.on('keydown blur', function (e) {
// was it the Enter key?
if (e.which == 13) {
$(this).blur();
}
if (e.type == 'blur') {
myFunction();
}
});
Try the following. Adding a class -- added in this example, in the keyup event handler and modifying the selector for the blur event will prevent the blur event handler from firing.
$(".textbox:not(.added)").on("blur", function () {
alert("blur Event fired");
});
$(".textbox").on("keyup", function (event) {
if (event.keyCode == 13) {
$(event.currentTarget).addClass('added');
alert("KeyUp fired after pressing Enter");
}
});
The below code worked for me, in primefaces 5.2.5
<p:inputText onkeydown="if (event.keyCode === 13) {return false; }" value="#{myForm.name}">
<p:ajax event="blur" update="#this" listener="#{bean.func()}" />
</p:inputText>
Blur event was not triggered even though Enter key was pressed.
Basically, keyup is a trigger for blur event. You should add a flag when keyup fires:
$('#exemple').keyup(function (e) {
if (e.which == 13) {
$('#exemple').addClass('keyupfired');
alert('whatever');
}
});
Then, when blur is fired, it should ask if keyup has already been fired too. Remember to remove the flag if you want the event to be fired when the user get off the textbox:
$('#exemple').on("blur", function () {
if (!$('#exemple').hasClass('keyupfired')) {
alert('whatever');
}
$('#exemple').removeClass('keyupfired');
});
I Couldn't alter class attribute so i'd ended up with,
$(".textbox").on("blur",function () {
if($(this).attr('flag')!='1')
alert("blur Event fired");
});
$(".textbox").on("keyup",function (event) {
$(this).attr('flag','1');
if(event.keyCode == 13){ // Detect Enter
alert("KeyUp fired after pressing Enter");
}
$(this).attr('flag','0');
});
It has been brought to my attention than rather then providing hints I should give more complete explanations and code examples, so here it is:
there is always the cheap way of setting a external variable:
var triggerBlur = true;
$(".textbox")
.live({
blur : function () {
if (triggerBlur) {// if not preceded by keyup 'Enter' event
alert("blur Event fired");
}
// reset variable to true to allow the blur event to be triggered subsequently when not preceded by keyup 'Enter' event
triggerBlur = true;
},
keyup : function (event) {
if(event.which === 13){ // Detect Enter
alert("KeyUp fired after pressing Enter");
triggerBlur = false;
}
});
Also it's preferable to use event.which rather than event.keyCode (see http://api.jquery.com/event.which/ to understand why), and it is recommended to use the identity operator '===' rather than the equality '==' in javascript, as the latter is broken (see Which equals operator (== vs ===) should be used in JavaScript comparisons?)
I have an input field that I would like to validate on when the user either presses enter or clicks away from it, for this I use the events keypress and blur. If the input fails validation, an alert box is called.
I noticed that in IE (all versions), if I press enter with invalid input, for some reason both the keypress and blur events are fired (I suspect it's the alert box, but it doesn't do this on FF/Chrome) and it shows two of the same alert box. How can I have it so only one is shown?
EDIT: In FF/Chrome, I now noticed that a second alert box appears when I click anywhere after I try to validate with enter.
Simplified code:
$("#input-field").keypress(function(event) {
if (event.keycode == 13) {
event.stopPropagation();
validate();
return false;
}
});
$("#input-field").blur(function() {
validate();
});
function validate() {
if ($("#input-field").val() == '') {
alert("Invalid input");
}
}
EDIT: Ah-ha. Not really a fix but a separate detail I forgot - I need to restore the invalid input to its previously valid value, so when the validate function checks the value again it doesn't fail twice.
I ended up just checking for an IE UserAgent and skipping the keypress event for IE (binding keypress and blur to the same function, as below). Not a direct or terrific solution, tragically, but I've been looking to solve the same problem to no avail. Some minor notes that might be helpful: jQuery normalizes which, so you can confidently use e.which == 13 with keypress. I'd also combine the functions into one bind, e.g.
$("#input-field").bind('blur keypress', function(e) {
if(e.which == 13) {
// keypress code (e.g. check for IE and return if so)
}
validate();
});
I've tried setting globals and using jQuery's data() to assign arbitrary flags to indicate whether (in your case) validation has already been triggered for the element, but the events trigger simultaneously or at least, if sequentially, rapidly enough that even with an opening line setting some flag to true did not do the trick. I'd read that putting in a tiny callback delay might help, but that is hella dirty and I wouldn't do it even as a workaround so I've not tested it. stopPropagation() and preventDefault() also did not help.
Firefox does not get the keypress event right. Those events are only triggered when a key combination that produces a character is pressed (which is not the same as pressing any key).
Use keydown instead (as this is probably the only event IE handles correctly - as it should, since MS "invented" it ;-) ).
See http://www.quirksmode.org/dom/events/keys.html.