JSFiddle - React, Tailwind, and code Playground
HTML
<div>
<input id="trigger" type="button" value="Open" />
</div>
<div class="control">
<select id="menu">
<option></option>
<option>One</option>
<option>Two</option>
<option>Three</option>
<option>Four</option>
</select>
</div>
<br/>
<br/>
<label for="output">You have selected option: </label>
<input id="output" type="text" />
CSS
div{
float: left;
position: relative;
}
select {
display: none;
}
select.open {
position: absolute;
display: block;
}
* {
font-family: sans-serif;
font-size: 12px;
}
JavaScript
(function($) {
$.fn.openable = function(options) {
// Cache our settings
var settings = $.extend({}, $.fn.openable.defaults, options);
return this.each(function() {
// This plugin only works for <select>-tags
if(! $(this).is("select")) return;
// Add methods to the DOM HTMLSelectElement
$.extend(true, this, new control(settings));
// Initialize the control
this.initialize();
});
};
// Default options for all openables
$.fn.openable.defaults = {
className: "open"
};
// This class defines instance methods to be added to
// the HTMLSelectElement
var control = function(settings) {
this.settings = settings;
};
// Adds event handlers for behavior
control.prototype.initialize = function() {
$(this)
.on("click", this.clickHandler)
.on("keydown", this.keyHandler);
// Handle clicks outside the list box
$(document).on(
"click",
{ element: this },
this.outsideClickHandler
);
};
// Opens the <select> by turning it into a list box
control.prototype.open = function() {
// Don't open when already open
if($(this).data("openable.isOpen")) return this;
this.size = this.length;
$(menu)
.addClass(this.settings.className)
.data("openable.isOpen", true)
.focus();
// Return DOM element for chaining
return this;
};
// Closes the <select> by turning it into a drop down
control.prototype.close = function() {
// Don't close unless opened
if(! $(this).data("openable.isOpen")) return this;
this.size = 1;
$(menu)
.data("openable.isOpen", false)
.removeClass(this.settings.className)
.focus();
// Return DOM...