<dl class="custom-dropdown" aria-expanded="false">
<dt class="custom-dropdown__title" data-value="">Select a country</dt>
<dd class="custom-dropdown__item" data-value="BR">Brazil</dd>
<dd class="custom-dropdown__item" data-value="NL">Netherlands</dd>
<dd class="custom-dropdown__item" data-value="ES">Spain</dd>
<dd class="custom-dropdown__item" data-value="TK">Turkey</dd>
<dd class="custom-dropdown__item" data-value="US">United States</dd>
</dl>
<select class="dropdown" data-observer-changes>
<option value="">Select a country</option>
<option value="BR">Brazil</option>
<option value="NL">Netherlands</option>
<option value="ES">Spain</option>
<option value="TK">Turkey</option>
<option value="US">United States</option>
</select>
<p class="console">Listener Select field change value: <span></span></p>
.custom-dropdown {
$self: &;
list-style: none;
margin: 0;
padding: 0;
cursor: pointer;
border: 2px solid;
display: inline-flex;
flex-direction: column;
font-family: Arial, 'sans-serif';
&__title,
&__item {
margin: 0;
padding: 10px 20px;
}
&__title {
display: block;
#{$self}[aria-expanded="true"] &,
#{$self}:hover &{
color: red;
}
}
&__item {
display: none;
&:hover {
background: #dcdcdc;
}
#{$self}[aria-expanded="true"] & {
display: block;
}
}
}
.console {
padding: 10px;
border: 1px dotted;
font-family: Arial, 'sans-serif';
}
View Compiled
class CustomDropDown {
constructor() {
this.customDropdown = document.querySelector('.custom-dropdown');
this.customDropdownItems = [...this.customDropdown.querySelectorAll('.custom-dropdown__item')];
this.console = document.querySelector('.console');
this.dropdown = document.querySelector('.dropdown');
this.init();
}
toggleCustomDropdown(evt) {
const customDropDownEl = evt.currentTarget;
const customDropDownStatus = customDropDownEl.getAttribute('aria-expanded');
customDropDownEl.setAttribute('aria-expanded', customDropDownStatus === 'true' ? 'false' : 'true');
}
selectedCustomDropDown(evt) {
const customDropDownClicked = evt.target;
const dropDownOptionHasSelected = this.dropdown.querySelector(`option[selected]`);
const dropDownOptionNewSelected = this.dropdown.querySelector(`option[value=${customDropDownClicked.dataset.value}]`);
if(dropDownOptionHasSelected) {
dropDownOptionHasSelected.removeAttribute('selected', '');
}
if(dropDownOptionNewSelected) {
dropDownOptionNewSelected.setAttribute('selected', '');
}
this.dropdown.value = customDropDownClicked.dataset.value;
}
showCountrySelected(value) {
this.console.querySelector('span').textContent = value;
}
listenDropDownChanges() {
const observer = new MutationObserver(mutations => {
const dropDownOptionSelected = mutations
.filter(item => item.target[item.attributeName])
.map(item => item.target.value);
if(dropDownOptionSelected) {
this.showCountrySelected(dropDownOptionSelected);
}
});
observer.observe(this.dropdown, {
subtree: true,
attributes: true,
attributeFilter: ['selected']
});
}
registerEvents() {
this.customDropdown.addEventListener('click', evt => this.toggleCustomDropdown(evt));
this.customDropdownItems.forEach(item => {
item.addEventListener('click', evt => this.selectedCustomDropDown(evt));
});
this.listenDropDownChanges();
}
init() {
this.registerEvents();
}
}
new CustomDropDown();
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.