After pressing enter I would like that only the keyup
event be fired but blur
is fired first. How to cancel blur
when
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.
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!
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');
});
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 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.
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");
}
});