Reputation: 582
I want to execute the function getUser()
via an onclick event or a listener. I have already tried both, however, none of them is working.
Below you can find my code. How can I make it work?
I have already tried to use a button and an input instead of a div, not working as well. Not even the listeners if you use a button or an input instead of a div.
$(document).on('focus', '#search_input', function() {
$("#autocomplete-list").show();
});
$(document).on('blur', '#search_input', function() {
$("#autocomplete-list").hide();
});
$(document).on('click', '.search-items', function() {
console.log(this);
});
function getUser(id){
console.log(id + "triggered");
}
/* Autocomplete Stlying */
.autocomplete-items {
position: absolute;
border: 1px solid #d4d4d4;
border-bottom: none;
border-top: none;
z-index: 99;
/*position the autocomplete items to be the same width as the container:*/
top: 100%;
left: 15px;
right: 15px;
}
.autocomplete-items div {
padding: 10px;
cursor: pointer;
background-color: #fff;
border-bottom: 1px solid #d4d4d4;
text-align: left;
}
.autocomplete-items div:hover {
/*when hovering an item:*/
background-color: #e9e9e9;
}
.autocomplete-active {
/*when navigating through the items using the arrow keys:*/
background-color: DodgerBlue !important;
color: #ffffff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<div class="col-md-4">
<div id="search_input_wrapper" class="autocomplete form-group" style="margin: 0px">
<input id="search_input" type="text" name="search_input" class="form-control" placeholder="Kunde" style="margin-top: 25px;">
<div id="autocomplete-list" class="autocomplete-items" style="display: none;">
<div class="search-items" onclick="getUser(2)">2: Max, Mustermann</div>
<div class="search-items" onclick="getUser(3)">3: Tom, Maier</div>
</div>
</div>
</div>
I would appreciate any kind of help.
Upvotes: 3
Views: 397
Reputation: 2585
You need to use stopPropagation() on input and the list elements like so:
$(document).on('focus', '#search_input', function() {
$("#autocomplete-list").show();
});
$(document).on('click', function() {
$("#autocomplete-list").hide();
});
$("#autocomplete-list, #search_input_wrapper").on('click', function() {
event.stopPropagation();
});
function getUser(id) {
console.log(id + "triggered");
}
/* Autocomplete Stlying */
.autocomplete-items {
position: absolute;
border: 1px solid #d4d4d4;
border-bottom: none;
border-top: none;
z-index: 99;
/*position the autocomplete items to be the same width as the container:*/
top: 100%;
left: 15px;
right: 15px;
}
.autocomplete-items div {
padding: 10px;
cursor: pointer;
background-color: #fff;
border-bottom: 1px solid #d4d4d4;
text-align: left;
}
.autocomplete-items div:hover {
/*when hovering an item:*/
background-color: #e9e9e9;
}
.autocomplete-active {
/*when navigating through the items using the arrow keys:*/
background-color: DodgerBlue !important;
color: #ffffff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<div class="col-md-4">
<div id="search_input_wrapper" class="autocomplete form-group" style="margin: 0px">
<input id="search_input" type="text" name="search_input" class="form-control" placeholder="Kunde" style="margin-top: 25px;">
<div id="autocomplete-list" class="autocomplete-items" style="display: none;">
<div class="search-items" onclick="getUser(2)">2: Max, Mustermann</div>
<div class="search-items" onclick="getUser(3)">3: Tom, Maier</div>
</div>
</div>
</div>
Upvotes: 5
Reputation: 8617
Using stopPropagation
is not necessary.
Your .blur (the first event to happen) prevents a .click on the menu, because it hides it before you even get to click on it. You could add a delay to the to the menu hide, or detect when a user is hovering on an item before hiding it. But now you get into the case where a user is hovering, but presses tab or loses focus some other way, so you'd have to handle that.
var focusedOnSearchItem = false;
$('.search-items').click(function() {
// console.log('search-items click()',this);
$("#autocomplete-list").hide();
});
$('.search-items').mouseenter(function() {
focusedOnSearchItem = true;
});
$('.search-items').mouseleave(function() {
focusedOnSearchItem = false;
});
$('#search_input').focus(function() {
$("#autocomplete-list").show();
});
$('#search_input').blur(function(event) {
if(!focusedOnSearchItem)
$("#autocomplete-list").hide();
});
function getUser(id){
console.log(id + "triggered");
}
/* Autocomplete Stlying */
.autocomplete-items {
position: absolute;
border: 1px solid #d4d4d4;
border-bottom: none;
border-top: none;
z-index: 99;
/*position the autocomplete items to be the same width as the container:*/
top: 100%;
left: 15px;
right: 15px;
}
.autocomplete-items div {
padding: 10px;
cursor: pointer;
background-color: #fff;
border-bottom: 1px solid #d4d4d4;
text-align: left;
}
.autocomplete-items div:hover {
/*when hovering an item:*/
background-color: #e9e9e9;
}
.autocomplete-active {
/*when navigating through the items using the arrow keys:*/
background-color: DodgerBlue !important;
color: #ffffff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<div class="col-md-4">
<div id="search_input_wrapper" class="autocomplete form-group" style="margin: 0px">
<input id="search_input" type="text" name="search_input" class="form-control" placeholder="Kunde" style="margin-top: 25px;">
<div id="autocomplete-list" class="autocomplete-items" style="display: none;">
<div class="search-items" onclick="getUser(2)">2: Max, Mustermann</div>
<div class="search-items" onclick="getUser(3)">3: Tom, Maier</div>
</div>
</div>
</div>
Upvotes: -1
Reputation: 17697
stopPropagation stops event bubbling up the DOM tree. In other terms, when you click on search-items
the default javascript behavior is to trigger the click on the clicked element parents/grandparents as well.
So when you click on search-items
it would trigger click on #search-input
. And so, the opened list closes. With stopPropagation()
you dismiss this behavior and tell javascript that the click event should only be listened on the clicked element.
In the below code, e
is short for event
which, in your case, is the click
event.
I made some minor changes to your code but you can still use blur
and focus
. There are many ways to re-write this code but the important thing is to stopPropagation
// changed to click and toggle() to show hide the list
// but you can keep the blur and focus if you like
$(document).on('click', '#search_input', function() {
$("#autocomplete-list").toggle();
});
$(document).on('click', '.search-items', function(e) {
e.stopPropagation()
getUser(e.target.id)
// event = click, target = .search-items, id = the id of the clicked target
// just pass the id to to your getUser function
});
function getUser(id) {
console.log(`user has id ${id}`)
// concatenate strings using new Template Literals
}
/* Autocomplete Stlying */
.autocomplete-items {
position: absolute;
border: 1px solid #d4d4d4;
border-bottom: none;
border-top: none;
z-index: 99;
/*position the autocomplete items to be the same width as the container:*/
top: 100%;
left: 15px;
right: 15px;
}
.autocomplete-items div {
padding: 10px;
cursor: pointer;
background-color: #fff;
border-bottom: 1px solid #d4d4d4;
text-align: left;
}
.autocomplete-items div:hover {
/*when hovering an item:*/
background-color: #e9e9e9;
}
.autocomplete-active {
/*when navigating through the items using the arrow keys:*/
background-color: DodgerBlue !important;
color: #ffffff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<div class="col-md-4">
<div id="search_input_wrapper" class="autocomplete form-group" style="margin: 0px">
<input id="search_input" type="text" name="search_input" class="form-control" placeholder="Kunde" style="margin-top: 25px;">
<div id="autocomplete-list" class="autocomplete-items" style="display: none;">
<div class="search-items" id="2">2: Max, Mustermann</div>
<div class="search-items" id="3">3: Tom, Maier</div>
</div>
</div>
</div>
From jQuery documentation
Description: Prevents the event from bubbling up the DOM tree, preventing any parent handlers from being notified of the event.
Prevents further propagation of the current event in the capturing and bubbling phases.
If you have any questions, just ask in the comments below
Upvotes: 2