I have created a multiple select dropdown list which is opened when you click on a div. Then when you click inside the dropdown list it needs to be open to be able to select more than one thing. Then when you click outside of the dropdown it should close.
I got this code which works as expected, given the logs:
$(document).mouseup(function(e){
if(!e.target.parentNode.id.includes('multipleSelectDropdown')){
$('*[id*=multipleSelectDropdown]').css('display', 'none');
console.log("Outside!");
}
else{
console.log("Inside!");
}
});
function clickedMultiSelectDropdown(optionsWrapperInput){
var optionsWrapper = document.getElementById(optionsWrapperInput);
if(optionsWrapper.style.display == 'none'){
optionsWrapper.style.display = 'block';
}
else{
optionsWrapper.style.display = 'none';
}
}
.multiple-select-wrapper{
width: 1000px;
height: 1000px;
}
.multiple-select{
cursor: pointer;
}
.multiple-select-options-wrapper {
box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
}
.own-input-field{
border: 1px solid rgb(180 180 180);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<div class="multiple-select-wrapper">
<div class="multiple-select">
<div class="own-input-field" tabindex="0" onclick="clickedMultiSelectDropdown('multipleSelectDropdownSize')">Size...</div>
<div id="multipleSelectDropdownSize" class="multiple-select-options-wrapper" style="display: none;">
<div class="multiple-select-options-item">1</div>
<div class="multiple-select-options-item">2</div>
</div>
</div>
</div>
</body>
If I click on the "Size…" element the box with options opens. When when I click on the box it logs "inside" and it stays open. When I click below or outside of all elements it says "outside" and the box closes.
Problem
For some reason though, when I click on the "Size…" div again when the box is open it again logs "outside" as expected, BUT the box doesn’t close. Why? This drives me mad…
3
Answers
I got some inspiration from both @KooiInc and @Pointy who nearly solved my issue. For my case below code did what I want. It will open the options when you click "Size...", keep the options open when you click them, and close them if you click anywhere else:
Thank you both, couldn't have solved it without you!
Your code is confusing. The use of 2 handlers creates a race condition, where
mouseup
wins (as @Pointy noted).Here is a plain js solution using event delegation, handling only
click
events and usingclassList.toggle
to handle the showing/hiding of the values.It’s up to you to convert that to jquery (if deemed necessary).
Your "mouseup" handler fires for each element in the ancestry chain for the target element. When it bubbles to a point in the DOM where the parent id does not have the content you’re matching, it will hide the element.
After that event has been dealt with, the browser fires the "click" event, and your handler for the select element will see that the select dropdown is hidden, and so it will open it back up.
Here’s what I would do: