jQuery: fire click() before blur() event
I have an input field, where I try to make autocomplete suggestion. Code looks like
<input type="text" id="myinput">
<div id="myresults"></div>
On input's blur()
event I want to hide results' div:
$("#myinput").live('blur',function(){
$("#myresults").hide();
});
When I write something into my input I send request to server and get json response, parse it into ul->li structure and put this ul to my #myresults
div.
When I click to this parsed li element I want to set value from li to input and hide #myresults
div
$("#myresults ul li").live('click',function(){
$("#myinput").val($(this).html());
$("#myresults").hide();
});
Everything is going good, but when I click to my li blur()
event fires before click()
and input's value don't get li's html.
How can I set up click()
event before blur()
?
Solution 1:
Solution 1
Listen to mousedown
instead of click
.
The mousedown
and blur
events occur one after another when you press the mouse button, but click
only occurs when you release it.
Solution 2
You can preventDefault()
in mousedown
to block the dropdown from stealing focus. The slight advantage is that the value will be selected when the mouse button is released, which is how native select components work. JSFiddle
$('input').on('focus', function() {
$('ul').show();
}).on('blur', function() {
$('ul').hide();
});
$('ul').on('mousedown', function(event) {
event.preventDefault();
}).on('click', 'li', function() {
$('input').val(this.textContent).blur();
});
Solution 2:
$(document).on('blur', "#myinput", hideResult);
$(document).on('mousedown', "#myresults ul li", function(){
$(document).off('blur', "#myinput", hideResult); //unbind the handler before updating value
$("#myinput").val($(this).html()).blur(); //make sure it does not have focus anymore
hideResult();
$(document).on('blur', "#myinput", hideResult); //rebind the handler if needed
});
function hideResult() {
$("#myresults").hide();
}
FIDDLE
Solution 3:
I faced this issue and using mousedown
is not an option for me.
I solved this by using setTimeout
in the handler function
elem1.on('blur',function(e) {
var obj = $(this);
// Delay to allow click to execute
setTimeout(function () {
if (e.type == 'blur') {
// Do stuff here
}
}, 250);
});
elem2.click( function() {
console.log('Clicked');
});
Solution 4:
I just answered a similar question: https://stackoverflow.com/a/46676463/227578
An alternative to the mousedown solutions is have it ignore blur events caused by clicking specific elements (i.e., in your blur handler, skip the execution if it's a result of clicking a specific element).
$("#myinput").live('blur',function(e){
if (!e.relatedTarget || !$(e.relatedTarget).is("#myresults ul li")) {
$("#myresults").hide();
}
});