I’ve been playing about with some little features of my new site. The specific feature that I was working on was the ability to show any text that doesn’t fit into a drop-down list as a tooltip. If you want to see the final product, it’s here (feel free to add any useful resources!)
Typically, to add a tooltip to a HTML element, you’d set the title
property, however, drop-down lists don’t have them; as a result, you can basically create the whole thing yourself. Starting with the HTML, you can create a simply div element:
<div>
@Html.DropDownListFor(a => a.SelectedResource,
new SelectList(Model.ResourceList, "Id", "DisplayDescription"), null,
new { @class = "select-list-full-size", @size = "3" });
</div>
<div id="tooltip"></div>
The next step is to add a little Javascript to get the two elements:
const select = document.querySelector('#SelectedResource');
const tooltip = document.querySelector('#tooltip');
There’s a couple of ways to do this - you can hide and show the tooltip element, but I wanted it to fade in and out, so I simply change the opacity of the tooltip:
select.addEventListener('mouseover', (event) => {
if (event.target.tagName === 'OPTION') {
tooltip.innerText = event.target.innerText;
tooltip.style.top = event.clientY + 'px';
tooltip.style.left = event.clientX + 'px';
tooltip.style.opacity = 0.7;
}
});
select.addEventListener('mouseout', (event) => {
if (event.target.tagName === 'OPTION') {
tooltip.style.opacity = 0;
}
});
The animation of fading in and out is a little CSS:
#tooltip {
position: absolute;
top: 0;
left: 0;
background-color: #000;
color: #fff;
padding: 5px;
opacity: 0;
transition: opacity 0.5s ease-in-out;
}
#tooltip.show {
opacity: 0.7;
}
Finally, you need to handle the situation where the mouse moves within the dropdown, as well as outside the entire element:
select.addEventListener('change', (event) => {
const selectedOption = event.target.selectedOptions[0];
if (tooltip.innerText != selectedOption.innerText) {
tooltip.innerText = selectedOption.innerText;
}
});
It’s probably more fiddly than it needs to be, but it does the job. I guess that someone will tell me there’s a Javascript plug-in or library that does all this for me!