(function($) {
$.fn.sbCustomSelect = function(options) {
var iOS = (navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i)) || (navigator.userAgent.match(/iPad/i)),
android = (navigator.userAgent.match(/Android/i)),
UP = 38, DOWN = 40, SPACE = 32, RETURN = 13, TAB = 9,
matchString = '';
// Sync custom display with original select box and set selected class and the correct
var updateSelect = function() {
var $this = $(this),
$dropdown = $this.siblings('.sb-dropdown'),
$sbSelect = $this.siblings('.sb-select');
$sbSelect.val(this[this.selectedIndex].innerHTML);
$dropdown.children().removeClass('selected')
.filter(':contains(' + this[this.selectedIndex].innerHTML + ')').addClass('selected');
};
// Update original select box, hide
, and fire change event to keep everything in sync
var dropdownSelection = function(e) {
var $target = $(e.target),
$option = $target.closest('.sb-custom').find('option').filter(':contains(' + $target.text() + ')');
e.preventDefault();
$option[0].selected = true;
$target.closest('ul').fadeOut('fast');
$option.parent().trigger('change');
};
// Create the
that will be used to change the selection on a non iOS/Android browser
var createDropdown = function($select) {
var $options = $select.children(),
$dropdown = $('
');
});
$dropdown.bind('click', dropdownSelection);
return $dropdown;
};
// Clear keystroke matching string and show dropdown
var viewList = function(e) {
var $this = $(this);
clear();
$this.closest('.sb-custom').find('.sb-dropdown').fadeIn('fast');
e.preventDefault();
};
// Hide the custom dropdown
var hideDropdown = function(e) {
if (!$(e.target).closest('.sb-custom').length) {
$('.sb-dropdown').fadeOut('fast');
}
};
// Manage keypress to replicate browser functionality
var selectKeypress = function(e) {
var $this = $(this),
$current = $this.siblings('ul').find('.selected');
if ((e.keyCode == UP || e.keyCode == DOWN || e.keyCode == SPACE) && $current.is(':hidden')) {
$current.focus();
return;
}
if (e.keyCode == UP && $current.prev().length) {
e.preventDefault();
$current.removeClass('selected');
$current.prev().addClass('selected');
} else if (e.keyCode == DOWN && $current.next().length) {
e.preventDefault();
$current.removeClass('selected');
$current.next().addClass('selected');
}
if (e.keyCode == RETURN || e.keyCode == SPACE) {
$current.trigger('click');
return;
}
if (e.keyCode >= 48 && e.keyCode <= 90) {
matchString += String.fromCharCode(e.keyCode);
checkforMatch(e);
}
if (e.keyCode == TAB && $current.is(':visible')) {
e.preventDefault();
$current.trigger('click');
hideDropdown(e);
}
};
// Check keys pressed to see if there is a text match with one of the options
var checkforMatch = function(e) {
var re = '/' + matchString + '.*/';
$(e.target).siblings('ul').find('a').each(function() {
if (this.innerHTML.toUpperCase().indexOf(matchString) === 0) {
$(this).trigger('click');
return;
}
});
};
// Clear the string used for matching keystrokes to select options
var clear = function() {
matchString = '';
};
/* jQuery Plugin Loop
*
* Take the select box out of the tab order.
*
* Add the field that will show the currently selected item and attach the change event to update the .sb-select input.
*
* If this is iOS or Android then we want to use the browsers standard UI controls. Set the opacity of the select to 0
* and lay it over our custom display of the current value.
* Otherwise, we're going to create a custom
for the dropdown
*
* After all of the setup is complete, trigger the change event on the original select box to update the .sb-select input
*/
this.each(function() {
var $self = $(this);
$self.attr('tabindex', -1)
.wrap('')
.after('')
.bind('change', updateSelect);
if (iOS || android) {
$self.show().css({
'display': 'block',
'opacity': 0,
'position': 'absolute',
'width': '100%',
'z-index': 1000
});
} else {
$self.next().bind('click', viewList).after(createDropdown($self));
}
$self.trigger('change');
});
// Hide dropdown when click is outside of the input or dropdown
$(document).bind('click', hideDropdown);
$('.sb-custom').find('.sb-select').live('keydown', selectKeypress);
$('.sb-custom').bind('blur', clear);
$('.sb-dropdown').live('focus', viewList);
return this;
};
})(jQuery);