Skip to content

Instantly share code, notes, and snippets.

@jsongerber
Last active November 3, 2017 14:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jsongerber/27ca2d21d309bba721b69ef8fdd8fd11 to your computer and use it in GitHub Desktop.
Save jsongerber/27ca2d21d309bba721b69ef8fdd8fd11 to your computer and use it in GitHub Desktop.
Fully customizable html select using jQuery
.select-html{
/* Wrapper */
}
.select-html .select-label{
/* Label (value showed when closed) */
}
.select-html .options{
/* Options wrapper */
}
.select-html .option{
/* Option */
}
.select-html .option.active{
/* Option selected */
}
/*
Use (label tag not mandatory):
<label for="foo">Lorem Ipsum</label>
<select id="foo" name="bar">
<option value="foobar">…</option>
<option value="foobar">…</option>
</select>
$('select').selectHtml(true|false);
Parameter is wether or not show the selected option in the dropdown
*/
jQuery.fn.selectHtml = function(showSelectedInDropdown){
this.each(function(i){
var label = '';
var id = $(this).attr('id');
if (!id)
id = 'select-'+i;
var option = [];
$('option', this).each(function(i){
option[i] = {};
option[i].value = $(this).val();
option[i].label = $(this).text();
var selected = $(this).attr('selected');
option[i].selected = typeof selected !== typeof undefined && selected !== false ? 1 : 0;
if (option[i].selected)
label = option[i].label;
})
if (label == ''){
label = option[0].label;
}
if ($('label[for='+id+']').length === 0){
$(this).before('<label for="'+id+'">'+label+'</label>');
}
$(this).hide();
var options = $('<div class="options"></div>');
for (var i = 0; i <= option.length - 1; i++) {
// Write options, check if selected option must be in the dropdown
if (showSelectedInDropdown){
options.append($('<div class="option'+(option[i].selected == 1 ? ' active' : '')+'" data-value="'+option[i].value+'">'+option[i].label+'</div>'));
}else if (option[i].selected != 1){
options.append($('<div class="option" data-value="'+option[i].value+'">'+option[i].label+'</div>'));
}
}
options.hide();
$('label[for='+id+']').wrapInner('<span class="select-label"></span>').addClass('select-html').append(options);
$('label[for='+id+'] .select-label').text(label);
})
// Close
$(document).on('click', function(){
// Close every select, except the one we're trying to open, if we try to open one
var clickedLabel = 'LABEL' == event.target.tagName ? event.target : false;
if (!clickedLabel && $(event.target).closest('.select-html'))
clickedLabel = $(event.target).closest('.select-html');
$('.select-html').not(clickedLabel).find('.options').slideUp(200).closest('label').removeClass('open');
})
// Open
$('.select-html').on('click', function(event){
event.preventDefault();
var options = $('.options', this);
// Check if there's place below the label
var windowB = $(document).scrollTop() + $(window).height();
var labelH = $(this)[0].getBoundingClientRect().height;
var labelT = $(this).offset().top;
if (labelT + labelH + options.outerHeight() > windowB){
options.css({
top: 'auto',
bottom: labelH
});
}else{
options.css({
top: labelH,
bottom: 'auto'
});
}
options.stop().slideToggle(200).closest('label').toggleClass('open');
})
// Select option
$('.options .option').on('click', function(){
// Set active class
$(this).addClass('active').siblings().removeClass('active')
var label = $(this).closest('.select-html');
// Put default text in data attribute
if (!label.data('txt')){
label.data('txt', $('.text', label).text());
}
// Change label text
$('.text', label).text($(this).text());
var select = label.next('select');
var value = $(this).data('value');
select.val(value).change();
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment