JSFiddle - React, Tailwind, and code Playground

by Chase Wilson

HTML

<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.3.0/lodash.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<header>
    <h1>Cross Browser Dropdown</h1>
</header>

<div id="target" class="left"></div>
<div id="select-target" class="left">
    <select data-as="FauxDropdown">
        <option>Hello</option>
        <option>Do</option>
        <option>You</option>
        <option>Like</option>
        <option>My</option>
        <option>Hat?</option>
    </select>
</div>
<div id="ajax-target" class="left"></div>

CSS

.left {
    position: relative;
    height: 50px;
}
.dropdown {
    margin: 0;
    padding: 0;
    border: 1px #ccc solid;
    border-radius: 3px;
    position: absolute;
    top: 0;
    left: 0px;
    z-index: 50;
    min-width: 100px;
    background: #fff;
}

.dropdown.collapsed {
    z-index: 1
}

.dropdown .dropdown-item {
    cursor: pointer;
    padding: .5em;
}
.dropdown .dropdown-item.active {
    background: #c6f8ff;
}
.dropdown .dropdown-item:hover {
    background: #efefef;
}


.dropdown.collapsed .dropdown-item:hover {
    background: none;
}
.dropdown.collapsed .dropdown-item {
    display: none;
}
.dropdown.collapsed .dropdown-item.active {
    display: block;
    background: none;
}

JavaScript

jQuery(document).ready(function () {
    var fauxDropdown = new FauxDropdown({
        opts:['one','two','three']
    })
    
    jQuery('#target').append( fauxDropdown.toElement() )
})

$.ajax({
    url: '/echo/json/', 
    dataType: 'json',
    type: 'POST',
    data: {
        json: JSON.stringify(["Hello","There","Son"]),
        delay: 3
    },    
    success: function(json, thing){    
        $('#ajax-target').append(new FauxDropdown({
            opts:json
        }).toElement())
    }           
})


/*
* must function like an ordinary <select > tag
* All css must be from scratch
* Bonus points if you use AJAX to populate the menu items
* Browser support must include browsers that use:
    - Gecko
    - WebKit
    - Trident
* All code must be your own work
*/
;(function (win, doc, j) {
    
function FauxDropdown (options) {
    /* 
     * Storing instances so we can blur all of them 
     * if something non-dropdown is clicked
     */
    FauxDropdown.instances.push(this)
    
    this.opts = options.opts || []
    this.listeners = _.assign(this.listeners, options.listeners)
    this.compiled = options.tmpl? 
        _.template( options.tmpl ) : 
        FauxDropdown.tmpl
}

FauxDropdown.prototype = {
    
    listeners: {
        '.dropdown-item click': function (event, self) {
            event.stopPropagation()

            // Blur every FauxDropdown instance except this one.
            _.invoke(_.reject(FauxDropdown.instances, function (it) {
                return it == self
            }), 'blur')

            self.toggle(this)
        }
    }
    
    ,reset:  function () {
        this.$lol = doc.createElement('div')
        // Load the parsed template into a dummy element
        this.$lol.innerHTML = this.compiled(this)
        this.frag = doc.createDocumentFragment()
        this.children = []
        this.selects = {}
    }
    
    ,applyListeners: function (el) {
        var self = this
        
        /* I don't want to talk about it....