Skip to content

Instantly share code, notes, and snippets.

@OndrejSlamecka
Last active April 1, 2016 14:40
Show Gist options
  • Save OndrejSlamecka/2287725 to your computer and use it in GitHub Desktop.
Save OndrejSlamecka/2287725 to your computer and use it in GitHub Desktop.
jQuery plugin for turning select boxes to look-alike lists
<!--
Sets the value back to select
Understands selected attribute
Arrow control works
TODO: optgroup, size,… (I haven't had need for those yet – if you had and want to share please contact me)
-->
<select class="selectlike">
<option data-html="<b>Fancy text with HTML and styles</b>">Not so fancy fallback text</option>
</select>
<script>
// Simple
$('.selectlike').selectLike();
// Advanced
$('.selectlike').selectLike({
onSelect: function (selected) { // selected item passed as parameter to callback function
console.log(selected);
}
});
</script>
/* SelectLike */
.selectlike_box{ display: inline-block; border: 1px #828790 solid; margin: 0 0 9px }
.selectlike_box li { padding: .2em .4em; position: relative; list-style-type: none }
.selectlike_box li.selected { background: #3399ff; color: white }
.hidden-selectlike-input { position: absolute; top: -9999px; left: -9999px }
/* Custom styles: */
.selectlike_box { width: 240px }
.selectlike_box li img { margin:0 .8em 0 0; float: left; border: 1px solid #999 }
.selectlike_box li div { margin: .6em 0 0 }
/**
* SelectLike - jQuery plugin for turning select boxes to look-alike lists
*
* Author: Ondrej Slamecka 2012, BSD-3 license
* Thanks to http://jqueryboilerplate.com/
*/
;(function($)
{
"use strict";
var SelectLike = function (element, options)
{
/* --- Options --- */
this.defaultopts = {
onSelect: function(selected){}
};
/* --- Constructor --- */
this.options = $.extend({}, this.defaultopts, options);
this.$element = $(element);
this.$list = $('<ul class="selectlike_box"></ul>');
// Hidden text input for arrow control
this.$hidden_txt_input = $('<input type="text" class="hidden">');
$(this.$element).after(this.$hidden_txt_input);
this.$selected = $('selected', this.$element).index();
this.init();
};
SelectLike.prototype.init = function ()
{
var that = this;
// Generate list
var selected_id = null;
that.$list.html('');
this.$element.children().each(function (i) {
var item = '<li data-value="' + this.getAttribute('value') + '" ';
if (this.getAttribute('selected') !== null) {
item += 'class="selected" ';
selected_id = i;
}
item += '>' + this.getAttribute('data-html') + '</li>';
that.$list.append(item);
});
if (selected_id !== null) {
this.$selected = $('li:nth-child(' + (selected_id + 1) + ')', this.$list);
this.options.onSelect(this.$selected);
}
this.$element.after(this.$list);
this.$element.css('display', 'none');
// Set up selecting by clicking
this.$list.on('click', 'li', function() {
var $this = $(this);
if (that.$selected.length) {
that.$selected.removeClass('selected');
}
$this.addClass('selected');
that.select($this.attr('data-value'));
that.$selected = $this;
// Set focus to hidden input (for arrow browsing) but prevent browser from scrolling
that.$hidden_txt_input.css('position', 'fixed').focus().css('position', 'absolute');
that.options.onSelect(that.$selected);
});
// Set up selecting by arrow keys
$(this.$hidden_txt_input).keyup(function (event) {
if (event.keyCode === 40) {
that.next();
}
if (event.keyCode === 38) {
that.prev();
}
that.options.onSelect(that.$selected);
});
};
SelectLike.prototype.prev = function()
{
if(this.$selected.prev().index() === -1) {
return;
}
this.$selected.removeClass('selected');
var $previous = this.$selected.prev();
$previous.addClass('selected');
this.select($previous.attr('data-value'));
this.$selected = $previous;
};
SelectLike.prototype.next = function()
{
if (this.$selected.next().index() === -1) {
return;
}
this.$selected.removeClass('selected');
var $next = this.$selected.next();
$next.addClass('selected');
this.select($next.attr('data-value'));
this.$selected = $next;
};
SelectLike.prototype.select = function(id)
{
$('option[value=' + id + ']', this.$element).attr('selected', 'selected');
};
/* --- Extend jQuery DOM functions --- */
$.fn.selectLike = function (options)
{
return this.each(function(){
if (!$.data(this, 'plugin_selectLike')) {
$.data(this, 'plugin_selectLike', new SelectLike(this, options));
} else {
$.data(this, 'plugin_selectLike').init();
}
});
};
})(jQuery);
@OndrejSlamecka
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment