Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
359 changes: 183 additions & 176 deletions js/jquery.nice-select.js
Original file line number Diff line number Diff line change
@@ -1,190 +1,197 @@
/* jQuery Nice Select - v1.1.0
https://github.com/hernansartorio/jquery-nice-select
Made by Hernán Sartorio */

(function($) {
Made by Hernán Sartorio and improved by Godjo */

$.fn.niceSelect = function(method) {
(function ($) {

$.fn.niceSelect = function (method) {

// Methods
if (typeof method == 'string') {
if (method == 'update') {
this.each(function() {
var $select = $(this);
var $dropdown = $(this).next('.nice-select');
var open = $dropdown.hasClass('open');

if ($dropdown.length) {
$dropdown.remove();
create_nice_select($select);

if (open) {
$select.next().trigger('click');
// Methods
if (typeof method == 'string') {
if (method == 'update') {
this.each(function () {
var $select = $(this);
var $dropdown = $(this).next('.nice-select');
var open = $dropdown.hasClass('open');

if ($dropdown.length) {
$dropdown.remove();
create_nice_select($select);

if (open) {
$select.next().trigger('click');
}
}
});
} else if (method == 'destroy') {
this.each(function () {
var $select = $(this);
var $dropdown = $(this).next('.nice-select');

if ($dropdown.length) {
$dropdown.remove();
$select.css('display', '');
}
});
if ($('.nice-select').length == 0) {
$(document).off('.nice_select');
}
} else {
console.log('Method "' + method + '" does not exist.')
}
});
} else if (method == 'destroy') {
this.each(function() {
return this;
}

// Hide native select
this.hide();

// Create custom markup
this.each(function () {
var $select = $(this);
var $dropdown = $(this).next('.nice-select');

if ($dropdown.length) {
$dropdown.remove();
$select.css('display', '');

if (!$select.next().hasClass('nice-select')) {
create_nice_select($select);
}
});
if ($('.nice-select').length == 0) {
$(document).off('.nice_select');
}
} else {
console.log('Method "' + method + '" does not exist.')
}
return this;
}

// Hide native select
this.hide();

// Create custom markup
this.each(function() {
var $select = $(this);

if (!$select.next().hasClass('nice-select')) {
create_nice_select($select);
}
});

function create_nice_select($select) {
$select.after($('<div></div>')
.addClass('nice-select')
.addClass($select.attr('class') || '')
.addClass($select.attr('disabled') ? 'disabled' : '')
.attr('tabindex', $select.attr('disabled') ? null : '0')
.html('<span class="current"></span><ul class="list"></ul>')
);

var $dropdown = $select.next();
var $options = $select.find('option');
var $selected = $select.find('option:selected');

$dropdown.find('.current').html($selected.data('display') || $selected.text());

$options.each(function(i) {
var $option = $(this);
var display = $option.data('display');

$dropdown.find('ul').append($('<li></li>')
.attr('data-value', $option.val())
.attr('data-display', (display || null))
.addClass('option' +
($option.is(':selected') ? ' selected' : '') +
($option.is(':disabled') ? ' disabled' : ''))
.html($option.text())
);
});
}

/* Event listeners */

// Unbind existing events in case that the plugin has been initialized before
$(document).off('.nice_select');

// Open/close
$(document).on('click.nice_select', '.nice-select', function(event) {
var $dropdown = $(this);

$('.nice-select').not($dropdown).removeClass('open');
$dropdown.toggleClass('open');

if ($dropdown.hasClass('open')) {
$dropdown.find('.option');
$dropdown.find('.focus').removeClass('focus');
$dropdown.find('.selected').addClass('focus');
} else {
$dropdown.focus();
}
});

// Close when clicking outside
$(document).on('click.nice_select', function(event) {
if ($(event.target).closest('.nice-select').length === 0) {
$('.nice-select').removeClass('open').find('.option');
}
});

// Option click
$(document).on('click.nice_select', '.nice-select .option:not(.disabled)', function(event) {
var $option = $(this);
var $dropdown = $option.closest('.nice-select');

$dropdown.find('.selected').removeClass('selected');
$option.addClass('selected');

var text = $option.data('display') || $option.text();
$dropdown.find('.current').text(text);

$dropdown.prev('select').val($option.data('value')).trigger('change');
});

// Keyboard events
$(document).on('keydown.nice_select', '.nice-select', function(event) {
var $dropdown = $(this);
var $focused_option = $($dropdown.find('.focus') || $dropdown.find('.list .option.selected'));

// Space or Enter
if (event.keyCode == 32 || event.keyCode == 13) {
if ($dropdown.hasClass('open')) {
$focused_option.trigger('click');
} else {
$dropdown.trigger('click');

function create_nice_select($select) {
$select.after($('<div></div>')
.addClass('nice-select')
.addClass($select.attr('class') || '')
.addClass($select.attr('disabled') ? 'disabled' : '')
.attr('tabindex', $select.attr('disabled') ? null : '0')
.html('<span class="current"></span><ul class="list"></ul>')
);

var $dropdown = $select.next();
var $options = $select.find('option');
var $selected = $select.find('option:selected');
var $selected_image = $select.find('option:selected').data('image') ? '<img src="' + $select.find('option:selected').data('image') + '"/ >' : '';


$dropdown.find('.current').html($selected.data('display') || $selected_image + $selected.text());

$options.each(function (i) {
var $option = $(this);
var display = $option.data('display');
var image = $option.data('image') ? '<img src="' + $option.data('image') + '"/ >' : '';

$dropdown.find('ul').append($('<li></li>')
.attr('data-value', $option.val())
.attr('data-display', (display || null))
.addClass('option' +
($option.is(':selected') ? ' selected' : '') +
($option.is(':disabled') ? ' disabled' : ''))
.html(image + $option.text())
);
});
}
return false;
// Down
} else if (event.keyCode == 40) {
if (!$dropdown.hasClass('open')) {
$dropdown.trigger('click');
} else {
var $next = $focused_option.nextAll('.option:not(.disabled)').first();
if ($next.length > 0) {

/* Event listeners */

// Unbind existing events in case that the plugin has been initialized before
$(document).off('.nice_select');

// Open/close
$(document).on('click.nice_select', '.nice-select', function (event) {
var $dropdown = $(this);

$('.nice-select').not($dropdown).removeClass('open');
$dropdown.toggleClass('open');

if ($dropdown.hasClass('open')) {
$dropdown.find('.option');
$dropdown.find('.focus').removeClass('focus');
$next.addClass('focus');
$dropdown.find('.selected').addClass('focus');
} else {
$dropdown.focus();
}
}
return false;
// Up
} else if (event.keyCode == 38) {
if (!$dropdown.hasClass('open')) {
$dropdown.trigger('click');
} else {
var $prev = $focused_option.prevAll('.option:not(.disabled)').first();
if ($prev.length > 0) {
$dropdown.find('.focus').removeClass('focus');
$prev.addClass('focus');
});

// Close when clicking outside
$(document).on('click.nice_select', function (event) {
if ($(event.target).closest('.nice-select').length === 0) {
$('.nice-select').removeClass('open').find('.option');
}
});

// Option click
$(document).on('click.nice_select', '.nice-select .option:not(.disabled)', function (event) {
var $option = $(this);
var $dropdown = $option.closest('.nice-select');

$dropdown.find('.selected').removeClass('selected');
$option.addClass('selected');

var text = $option.data('display') || $option.html();
var image = $option.find('img');
console.log(this);

$dropdown.find('.current').html(text);

$dropdown.prev('select').val($option.data('value')).trigger('change');
});

// Keyboard events
$(document).on('keydown.nice_select', '.nice-select', function (event) {
var $dropdown = $(this);
var $focused_option = $($dropdown.find('.focus') || $dropdown.find('.list .option.selected'));

// Space or Enter
if (event.keyCode == 32 || event.keyCode == 13) {
if ($dropdown.hasClass('open')) {
$focused_option.trigger('click');
} else {
$dropdown.trigger('click');
}
return false;
// Down
} else if (event.keyCode == 40) {
if (!$dropdown.hasClass('open')) {
$dropdown.trigger('click');
} else {
var $next = $focused_option.nextAll('.option:not(.disabled)').first();
if ($next.length > 0) {
$dropdown.find('.focus').removeClass('focus');
$next.addClass('focus');
}
}
return false;
// Up
} else if (event.keyCode == 38) {
if (!$dropdown.hasClass('open')) {
$dropdown.trigger('click');
} else {
var $prev = $focused_option.prevAll('.option:not(.disabled)').first();
if ($prev.length > 0) {
$dropdown.find('.focus').removeClass('focus');
$prev.addClass('focus');
}
}
return false;
// Esc
} else if (event.keyCode == 27) {
if ($dropdown.hasClass('open')) {
$dropdown.trigger('click');
}
// Tab
} else if (event.keyCode == 9) {
if ($dropdown.hasClass('open')) {
return false;
}
}
});

// Detect CSS pointer-events support, for IE <= 10. From Modernizr.
var style = document.createElement('a').style;
style.cssText = 'pointer-events:auto';
if (style.pointerEvents !== 'auto') {
$('html').addClass('no-csspointerevents');
}
return false;
// Esc
} else if (event.keyCode == 27) {
if ($dropdown.hasClass('open')) {
$dropdown.trigger('click');
}
// Tab
} else if (event.keyCode == 9) {
if ($dropdown.hasClass('open')) {
return false;
}
}
});

// Detect CSS pointer-events support, for IE <= 10. From Modernizr.
var style = document.createElement('a').style;
style.cssText = 'pointer-events:auto';
if (style.pointerEvents !== 'auto') {
$('html').addClass('no-csspointerevents');
}

return this;

};

}(jQuery));

return this;

};

}(jQuery));