JSFiddle - React, Tailwind, and code Playground
by Glenn Marks
HTML
<select class="FancySelect">
<option>Glenn</option>
<option>Katie</option>
<option>Bill</option>
<option>Jill</option>
</select>
<br/>
<br/>
<select class="FancySelect">
<optgroup label="The BEST">
<option>Glenn</option>
<opt>sdfsdfsdf</opt>
<option>Katie</option>
</optgroup>
<optgroup label="The Okay"><!-- DON'T WANT TO OFFEND ANYONE :D -->
<option selected>Bill</option>
<option>Jill</option>
</optgroup>
</select>
<br/>
<br/>
<select class="FancySelect" multiple>
<option>Glenn</option>
<option>Katie</option>
<option selected>Bill</option>
<option>Jill</option>
</select>
<br/>
<br/>
<select class="FancySelect" multiple>
<optgroup label="The BEST">
<option>Glenn</option>
<option>Katie</option>
</optgroup>
<optgroup label="The Okay"><!-- DON'T WANT TO OFFEND ANYONE :D -->
<option>Bill</option>
<option>Jill</option>
</optgroup>
</select>
SCSS
$fsBorder: #a9a9a9;
$fsHoverBgCol: #48f;
$fsHoverCol: #fff;
.fsSelect {
display: flex;
align-items: center;
flex-wrap: wrap;
border: 1px solid $fsBorder;
position: relative;
padding-right: 20px;
cursor: pointer;
>.fsSelOpts{
padding: 2px 5px;
>.fsOpt {
display: flex;
align-items: center;
}
}
>.fsOptCont{
display: none;
z-index: 1;
position: absolute;
top: 100%;
left: -1px;
right: -1px;
border: 1px solid $fsBorder;
border-top-color: lighten($fsBorder, 25%);
background-color: #fff;
.fsSearchBar {
border: 1px solid $fsBorder;
border-radius: 5px;
width: 100%;
margin: 3px 10px;
}
.fsOpt {
padding: 2px 5px;
&:hover {
background-color: $fsHoverBgCol;
color: $fsHoverCol;
}
}
}
&.fsActive {
>.fsOptCont {
display: block;
}
}
&.fsMulti {
> .fsSelOpts > .fsOpt >.fsOptIco {
margin-left: 5px;
display: flex;
align-items: center;
justify-content: space-around;
box-sizing: border-box;
width: 1em;
height: 1em;
background-color: #F00;
border-radius: 50%;
text-align: center;
cursor: pointer;
&:after, &:before {
content: '';
position: absolute;
height: .7em;
width: .15em;
background-color: #FFF;
transform: rotate(45deg)
}
&:before {
transform: rotate(-45deg)
}
}
}
&:after {
content: '';
...
JavaScript
/*
Problems:
What to do about HTML / Image / Background before it
Data?? data-fs-pre="" data-fs-post=""
*/
(function($) {
/* VARIABLES */
var
/* ENUMS */
menuDisplay = {
Single: 0,
Multiple: 1
},
throwType = {
Exception: 0,
Warning: 1,
Information: 2
};
$.fn.FancySelect = function(options) {
if (!$(this))
return this;
var
opt = $.extend({
SelectClass: "",
SearchInputClass: "",
AccessibilityClass: "fsAccessible",
ShowSearch: "OptGroup|Multiple",
SortSearchOptions: true
}, options);
$(this).each(function() {
var
t = $(this),
fsSel = $("<div class=\"fsSelect\" />"),
fsOptCont = $("<div class=\"fsOptCont\" />"),
fsSelOpts = $("<div class=\"fsSelOpts\" />"),
fsSrch = $("<input type=\"text\" class=\"fsSearchBar\" />");
WriteMenu(t, opt, fsSel, fsOptCont, fsSelOpts, fsSrch);
fsSelOpts.on("click", ">.fsOpt>.fsOptIco", function() {
RemoveOption($(this), fsOptCont);
});
fsOptCont.on("click", ".fsOpt", function() {
SelectOption($(this), fsSelOpts, fsOptCont);
});
fsSel.mouseup(function(e) {
if (
(!$(e.target).hasClass("fsSearchBar") || !fsSel.hasClass("fsActive")) &
e.button == 0 &
!window.getSelection().toString().length
)
fsSel.toggleClass("fsActive");
});
fsSrch.on("keyup", function(){
var arr = fsSrch[0].value.split(" ").filter(function(v){return v!==''});
if (!arr.length)
return;
fsOptCont.children().each(function(i,e){
var elm=$(e);
if (arr.length != $.grep(arr, function(v){...