selectr
A jquery plugin for select boxes that doesn't suck
by Casey Webb
HTML
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<select data-selectr-opts='{ "title": "What's for breakfast? (max 5)", "placeholder": "Search foods", "maxSelection": 5 }' multiple>
<option data-selectr-color="rgb(0, 163, 0)" value="1">Bacon (Extra long name foo bar baz quz)</option>
<option data-selectr-color="rgb(255, 0, 151)" value="2">Eggs</option>
<option data-selectr-color="rgb(159, 0, 167)" value="3">Toast</option>
<option data-selectr-color="rgb(185, 29, 71)" value="4">Oatmeal</option>
<option data-selectr-color="rgb(227, 162, 26)" value="13">Steak</option>
<option data-selectr-color="rgb(218, 83, 44)" value="14">Sausage</option>
<option data-selectr-color="rgb(96, 60, 186)" value="23">Coffee</option>
<option data-selectr-color="rgb(0, 171, 169)" value="24">Milk</option>
<option data-selectr-color="rgb(45, 137, 239)" value="33">Fresh Fruit</option>
</select>
SCSS
// selectr was built using Bootstrap components, so the css required is
// rather lean. If your project is not using Bootstrap, include the selectrPolyfill
// css rather than this one, or write your own styles.
.selectr {
margin: 0;
display: inline-block;
max-width: 100%;
.panel-heading.no-title {
padding: 0;
border-bottom: none;
}
.panel-body {
position: relative;
}
.clear-search {
position: absolute;
right: 25px;
top: 12px;
font-size: 28px;
font-weight: bold;
color: #333;
opacity: 0.8;
cursor: pointer;
&:hover {
opacity: 1;
}
}
.list-group {
overflow-x: hidden;
.list-group-item {
padding: 0 !important;
overflow: hidden;
cursor: pointer;
&.selected {
background-color: #4679bd;
color: white;
font-weight: 700;
.add-remove {
transform: rotate(0deg);
}
}
}
}
&.multi {
.list-group-item:hover {
.option-name {
margin-right: 50px;
border-right: 1px solid #ddd;
}
.selected {
.option-name {
border-right: 1px solid white;
}
}
.add-remove {
display: block;
}
}
}
.option-name {
height: 100%;
padding: 10px 15px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.color-code {
width: 20px;
height: 20px;
margin: 10px;
margin-right: 0;
float: left;
border-radius: 5px;
&.no-color {
width: 0;
height: 0;
margin: 0;
}
}
.add-remove {
...
CoffeeScript
do ($, window) ->
class Selectr
defaults:
Selectr: this
title: 'Select Options'
placeholder: 'Search'
resetText: 'Clear All'
width: '300px'
maxListHeight: '250px'
tooltipBreakpoint: 25
maxSelection: NaN
constructor: (@el, @args) ->
@$el = $(el)
@args = $.extend @defaults, @args, @$el.data('selectr-opts')
@$el.data 'selectr-opts', @args
@container = @CreateContainer()
@opts = @PrepareOpts($('option', @el))
$('.list-group', @container).append(@opts)
selectedCount = 0
for opt in @opts
selectedCount++ if opt.hasClass 'selected'
$('.current-selection', @container).text(selectedCount if selectedCount > 0)
@MonitorSource()
@container.insertAfter(@el)
@$el.hide()
CreateContainer: ->
$(document.createElement 'div').attr({
'class': "selectr panel panel-default #{if @$el.prop 'multiple' then 'multi'}",
'style': "width: #{@args.width};"
}).html("""
<div class='panel-heading #{if @args.title is "" then "no-title"}'>
<h4 class='panel-title'>
#{@args.title}
</h4>
</div>
<div class='panel-body'>
<input class='form-control' placeholder='#{@args.placeholder}'>
<span class='clear-search hidden'>×</span>
</div>
<ul class='list-group' style='max-height: #{@args.maxListHeight}'>
</ul>
<div class='panel-footer #{'hidden' if not @$el.prop 'multiple'}'>
<button class='reset btn btn-sm btn-default'>
#{@args.resetText}
</button>
#{if @$el.prop 'multiple' then "<span class='current-selection badge'></span>"}
</div>
""")
PrepareOpts: (opts) ->
for opt in opts
$(document.createElement 'li').attr({
'class':...