Just to add another voice to this. I recently had a requirement to make a custom dropdown that included a checkbox group as its content instead of a single select list.
The way I eventually achieved the 'click away to close' behaviour ended up being far simpler than I at first thought. For one thing, I completely avoided adding click handlers to the window, as I just could not get that to work!
Here's what I did:
I added a clickable div that I called the 'Drop Down Mask' just above the button that opens the dropdown.
<!-- clickable mask -->
<div aura:id="dropdownMask" id="dropdownMask" class="slds-hide" onclick="{!c.toggleDropdown}"></div>
<!-- dropdown container -->
<div class="dropdown">
<!-- the button that triggers the dropdown -->
<div onclick="{!c.toggleDropdown}" class="dropbtn">
{!v.dropdDownButtonLabel}
<lightning:icon class="downArrow" iconName="utility:down" size="x-small" />
</div>
<!-- the dropdown content -->
<div aura:id="dropdown-content" class="dropdown-content slds-hide">
<lightning:checkboxGroup name="options checkboxes"
options="{! v.options}"
value="{! v.chosenValues}"
onchange="{! c.handleChange }"/>
</div>
</div>
In the controller I had a simple function that handles clicking either the button or the mask by showing or hiding the divs:
toggleDropdown : function(component, event, helper) {
$A.util.toggleClass(component.find('dropdown-content'), 'slds-hide');
$A.util.toggleClass(component.find('dropdownMask'), 'slds-hide');
}
...and in the css I made sure that:
- The mask covered the entire screen
- The mask 'displayed' (although invisible) above the the rest of the component
- The entire dropdown container displayed above the mask.
- Both classes that have z-index applied have their position set. Otherwise the z-index won't work.
.THIS.dropdownMask {
content: '';
width: 100%;
height: 100vh;
position: absolute;
left: 0px;
top: 0px;
z-index: 1;
}
/* The container - needed to position the dropdown content */
.THIS.dropdown {
position: relative;
width: 320px;
margin: auto;
z-index: 2;
}
Below, for funzies I've left all the css I used, just so anyone that's reading and needs a quick solution can copy/paste and then tweak. This also includes a custom scroll bar on the dropdown content.
/* ~~~~~~~~~~~ \/ drop down styling below this line \/ ~~~~~~~~~~~ */
.THIS#dropdownMask {
content: '';
width: 100%;
height: 100vh;
position: absolute;
left: 0px;
top: 0px;
z-index: 1;
}
/* The container <div> - needed to position the dropdown content
NOTE: My div sat at component level. If you want to put it inside a another element, you'll need to add a space. example: .THIS .dropdown
*/
.THIS.dropdown {
position: relative;
width: 320px;
margin: auto;
z-index: 2;
}
.THIS .dropbtn {
position: relative;
display: flex;
align-items: center;
width: 318.87px;
height: 34px;
padding: 0px 1rem;
background: white;
border: 1px solid #000000;
box-sizing: border-box;
border-radius: 5px;
cursor: pointer;
}
.THIS .dropbtn .downArrow {
position: absolute;
right: 1rem;
}
/* Dropdown button on hover & focus */
.THIS .dropbtn:hover, .THIS .dropbtn:focus {
background-color: #f7f7f7;
}
/* Dropdown Content (Hidden by Default) */
.THIS .dropdown-content {
position: absolute;
background-color: white;
max-height: 250px;
width: inherit;
border-radius: 5px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
overflow: auto;
}
/* checkboxes inside the dropdown */
.THIS .dropdown-content .slds-checkbox {
color: black;
padding: 12px 16px;
text-decoration: none;
}
/* Change color of dropdown links on hover */
.THIS .dropdown-content a:hover {background-color: #ddd}
/* ~~~~~~~~~~~ \/ scroll bar styling below this line \/ ~~~~~~~~~~~ */
/* Scroll Bar width */
.THIS .dropdown-content::-webkit-scrollbar {
width: 10px;
}
/* Scroll Bar Track */
.THIS .dropdown-content::-webkit-scrollbar-track {
box-shadow: inset 0 0 5px grey;
border-radius: 10px;
}
/* Scroll Bar Handle */
.THIS .dropdown-content::-webkit-scrollbar-thumb {
background: gray;
border-radius: 10px;
}
/* Scroll Bar Handle on hover */
.THIS .dropdown-content::-webkit-scrollbar-thumb:hover {
background: #bababa;
}
/* ~~~~~~~~~~~ /\ drop down styling above this line /\ ~~~~~~~~~~~ */
/* ~~~~~~~~~~~ /\ scroll bar styling above this line /\ ~~~~~~~~~~~ */
enter code here