Mutliselect

by Mike McCaughan

HTML

<select multiple class="multiselect">
    <option value="-1" class="select-all">Select All</option>
    <option value="77">Twin Cities</option>
    <option value="80">Chicago</option>
    <option value="85">Baltimore</option>
    <option value="86">Pittsburgh</option>
    <option value="92">Detroit</option>
    <option value="93">Cleveland</option>
    <option value="96">Boston</option>
    <option value="535">Cranford</option>
</select>
<ul class="checkbox-list">
    <li class="select-all">
        <input type="checkbox" value="-1" id="select-all" />
        <label for="select-all">Select All</label>
    </li>
    <li>
        <input type="checkbox" value="77" id="checkbox-77" />
        <label for="checkbox-77">Twin Cities</label>
    </li>
    <li>
        <input type="checkbox" value="80" id="checkbox-80" />
        <label for="checkbox-80">Chicago</label>
    </li>
    <li>
        <input type="checkbox" value="85" id="checkbox-85" />
        <label for="checkbox-85">Baltimore</label>
    </li>
    <li>
        <input type="checkbox" value="86" id="checkbox-86" />
        <label for="checkbox-86">Pittsburgh</label>
    </li>
    <li>
        <input type="checkbox" value="92" id="checkbox-92" />
        <label for="checkbox-92">Detroit</label>
    </li>
    <li>
        <input type="checkbox" value="93" id="checkbox-93" />
        <label for="checkbox-93">Cleveland</label>
    </li>
    <li>
        <input type="checkbox" value="96" id="checkbox-96" />
        <label for="checkbox-96">Boston</label>
    </li>
    <li>
        <input type="checkbox" value="535" id="checkbox-535" />
        <label for="checkbox-535">Cranford</label>
    </li>
</ul>
<div class="autocomplete-checkbox-list">
<input type="text" class="autocomplete"/>
<ul class="checkbox-list">
    <li class="select-all">
        <input type="checkbox" value="-1" id="select-all" />
        <label for="select-all">Select All</label>
    </li>
    <li>
        <input type="checkbox" value="77"...

CSS

.multiselect, .checkbox-list {
    height: 200px;
    min-width: 120px;
}
.checkbox-list {
    margin: 0;
    padding: 0;
    text-indent: 0;
    font-size: 12px;
    line-height: 14px;
    display: inline-block;
    overflow-x: hidden;
    overflow-y: scroll;
    border: 1px solid #b0b0b0;
}
.checkbox-list li {
    display: block;
    white-space: nowrap;
}
.checkbox-list li input[type="checkbox"] {
    display: inline-block;
    margin-bottom: -4px;
}
.autocomplete-checkbox-list {
    display: inline-block;
    position: relative;
}
.autocomplete-checkbox-list .autocomplete {
    width: 120px;
    height: 16px;
}
.autocomplete-checkbox-list .checkbox-list {
    position: absolute;
    left: 0;
    top: 21px;
    width: 122px;
    display: none;
}

JavaScript

$('.checkbox-list').on('click', function (e) {
    var $target = $(e.target),
        $skip = $('#select-all');
    if ($target.hasClass('select-all') || $target.closest('.select-all').length > 0) {
        $('.checkbox-list').find('input:checkbox').not($skip).prop('checked', $skip.prop('checked'));
    }
});
$('.multiselect').on('click', 'option', function (e) {
    var $target = $(e.target),
        $skip = $('option.select-all'),
        $allNotSkip = $('.multiselect').find('option').not($skip),
        checked = [],
        allChecked = false;
    if ($target.hasClass('select-all')) {
        checked = $allNotSkip.map(function (index, element) {
            return element.selected;
        });
        if (checked.length > 0) {
            allChecked = checked.get().every(function (element) {
                return element === true;
            });
            $allNotSkip.prop('selected', !allChecked);
        }
    }
});
$('.autocomplete-checkbox-list').on('focusin', '.autocomplete', function (e) {
    $('.autocomplete-checkbox-list').find('.checkbox-list').show();
}).on('focusout', '.autocomplete', function (e) {
    $('.autocomplete-checkbox-list').find('.checkbox-list').hide();
});