Using a div as an HTML select element to display tabular data
I neded to display tabular data in a select element. Since the <option> tag does not allow for HTML, I came up with this. It emulates the function of a select element but allows the options to contain HTML tags. The only thing it is missing is an onchange event. Otherwise, it is a fully-working pseudo-select.
by schmidtc63
HTML
<div>
<div id="selectedOrder" class="selectedOption select-css" style="width: 533px; display: block;">
<div data-value="45628" style="float: left;">
<span style="float:left; min-width:200px;">Store 1</span>
<span style="float:left; min-width:50px"> 55628</span>
<span style="float:left; min-width: 150px;"> Quantity Discrepancy</span>
<span style="float:left; min-width:100px"> </span>
</div>
</div>
<div select-options-for="selectedOrder" class="selectOptions select-css" style="position: absolute; z-index: 1000; background-image: none; display: none; width:533px" tabindex="2">
<div class="selectOption" selected="selected" data-value="45628" style="float: left;">
<span style="float:left; min-width:200px;">Store 1</span>
<span style="float:left; min-width:50px"> 55628</span>
<span style="float:left; min-width: 150px;"> Quantity Discrepancy</span>
<span style="float:left; min-width:100px"> </span>
</div>
<div class="selectOption" data-value="45536" style="float: left;">
<span style="float:left; min-width:200px;">Store 2</span>
<span style="float:left; min-width:50px"> 55536</span>
<span style="float:left; min-width: 150px;"> Quantity Discrepancy</span>
<span style="float:left; min-width:100px"> Bad UPCs</span>
</div>
<div class="selectOption" data-value="45682" style="float: left;">
<span style="float:left; min-width:200px;">Store 3</span><span style="float:left; min-width:50px"> 55682</span>
<span style="float:left; min-width: 150px;"> Quantity Discrepancy</span>
<span style="float:left; min-width:100px"> Bad UPCs</span>
</div>
<div class="selectOption" data-value="45625" style="float: left;">
<span style="float:left; min-width:200px;">Store 4</span>
<span style="float:left; min-width:50px"> 55625</span>
<span style="float:left; min-width: 150px;"> Quantity Discrepancy</span>
<span style="float:left;...
CSS
.selectedOption {
height: 30px;
display: none;
}
/* class applies to select element itself, not a wrapper element */
.select-css {
font-size: 12px;
font-family: sans-serif;
font-weight: 700;
color: #444;
line-height: 1.3;
padding: .6em 1.4em .5em .8em;
/* width: 100%; */
max-width: 100%;
/* useful when width is set to anything other than 100% */
box-sizing: border-box;
margin: 0;
border: 1px solid #aaa;
box-shadow: 0 1px 0 1px rgba(0, 0, 0, .04);
border-radius: .5em;
-moz-appearance: none;
-webkit-appearance: none;
appearance: none;
background-color: #fff;
/* note: bg image below uses 2 urls. The first is an svg data uri for the arrow icon, and the second is the gradient.
for the icon, if you want to change the color, be sure to use `%23` instead of `#`, since it's a url. You can also swap in a different svg icon or an external image reference
*/
background-image: url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23007CB2%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E'),
linear-gradient(to bottom, #ffffff 0%, #e5e5e5 100%);
background-repeat: no-repeat, repeat;
/* arrow icon position (1em from the right, 50% vertical) , then gradient position*/
background-position: right .7em top 50%, 0 0;
/* icon size, then gradient */
background-size: .65em auto, 100%;
}
/* Hide arrow icon in IE browsers */
.select-css::-ms-expand {
display: none;
}
/* Hover style */
.select-css:hover {
border-color: #888;
}
/*...
JavaScript
$(document).on(`click`, `.selectOption`, function() {
const selectedOption = $(`#${$(this).closest(`.selectOptions`).attr(`select-options-for`)}`);
if ($(this).data(`value`) !== selectedOption.find(`.currentSelectedOption`).data(`value`)) {
// do whatever you need when the selection changes -- Ajax something, display something...
}
selectedOption.html($(this).prop(`outerHTML`)).find(`.selectOption`).removeClass(`selectOption`).addClass(`currentSelectedOption`);
$(this).closest(`.selectOptions`).hide();
});
$(document).on(`mouseenter`, `.selectOption`, function() {
const selectOptions = $(this).closest(`.selectOptions`);
selectOptions.find(`.selectOption`).removeAttr(`selected`);
$(this).attr(`selected`, `selected`);
});
$(document).on(`click`, function() {
$(`.selectOptions`).hide();
});
$(document).on(`click`, `.selectedOption`, function(e) {
e.stopPropagation();
e.preventDefault();
$(`.selectOptions`).not(`[select-options-for="${$(this).attr(`id`)}"]`).hide();
$(`[select-options-for="${$(this).attr(`id`)}"]`).toggle().trigger(`focus`);
});
$(window).on(`blur`, function() {
$(`.selectOptions`).hide();
});
$(`.selectOptions`).on(`keypress keydown`, function(event) {
if (event.which === 9 || event.which === 13) {
$(this).find(`[selected="selected"]`).trigger(`click`);
}
if (event.which === 38) {
$(this).find(`[selected="selected"]`).prev().trigger(`mouseenter`);
}
if (event.which === 40) {
$(this).find(`[selected="selected"]`).next().trigger(`mouseenter`);
}
});