/*
jquery selectbox (version 1.0.7)
a cosmetic, styleable replacement for select elements.
homepage: http://abeautifulsite.net/blog/2011/01/jquery-selectbox-plugin/
demo page: http://labs.abeautifulsite.net/projects/js/jquery/selectbox/
copyright 2011 cory laviska for a beautiful site, llc.
features:
- supports optgroups
- supports standard dropdown controls
- supports multi-select controls (i.e. multiple="multiple")
- supports inline controls (i.e. size="5")
- fully accessible via keyboard
- shift + click (or shift + enter) to select a range of options in multi-select controls
- type to search when the control has focus
- auto-height based on the size attribute (to use, omit the height property in your css!)
- tested in ie7-ie9, firefox 3-4, recent webkit browsers, and opera
license:
licensed under both the mit license and the gnu gplv2 (same as jquery: http://jquery.org/license)
usage:
link to the js file:
add the css file (or append contents to your own stylesheet):
to create:
$("select").selectbox([settings]);
settings:
to specify settings, use this syntax: $("select").selectbox('settings', { settingname: value, ... });
menutransition: ['default', 'slide', 'fade'] - the show/hide transition for dropdown menus
menuspeed: [integer, 'slow', 'normal', 'fast'] - the show/hide transition speed
methods:
to call a method use this syntax: $("select").selectbox('methodname', [options]);
create - creates the control (default method)
destroy - destroys the selectbox control and reverts back to the original form control
disable - disables the control (i.e. disabled="disabled")
enable - enables the control
value - if passed with a value, sets the control to that value; otherwise returns the current value
options - pass in either a string of html or a json object to replace the existing options
control - returns the selectbox control element (an anchor tag) for working with directly
events:
events are fired on the original select element. you can bind events like this:
$("select").selectbox().change( function() { alert( $(this).val() ); } );
focus - fired when the control gains focus
blur - fired when the control loses focus
change - fired when the value of a control changes
change log:
v1.0.0 (2011-04-03) - complete rewrite with added support for inline and multi-select controls
v1.0.1 (2011-04-04) - fixed options method so it doesn't destroy/recreate the control when called.
- added a check for ios devices (their native controls are much better for
touch-based devices; you can still use selectbox api methods for theme)
- fixed issue where ie window would lose focus on xp
- fixed premature selection issue in webkit browsers
v1.0.2 (2011-04-13) - fixed auto-height for inline controls when control is invisible on load
- removed auto-width for dropdown and inline controls; now relies 100% on css
for setting the width
- added 'control' method for working directly with the selectbox control
v1.0.3 (2011-04-22) - fixed bug in value method that errored if the control didn't exist
v1.0.4 (2011-04-22) - fixed bug where controls without any options would render with incorrect heights
v1.0.5 (2011-04-22) - removed 'tick' image in lieu of background colors to indicate selection
- clicking no longer toggles selected/unselected in multi-selects; use ctrl/cmd and
shift like in normal browser controls
- fixed bug where inline controls would not receive focus unless tabbed into
v1.0.6 (2011-04-29) - fixed bug where inline controls could be "dragged" when selecting an empty area
v1.0.7 (2011-05-18) - expanded ios check to include android devices as well
- added autowidth option; set to false on init to use css widths for dropdown menus
known issues:
- the blur and focus callbacks are not very reliable in ie7. the change callback works fine.
*/
if(jquery) (function($) {
$.extend($.fn, {
selectbox: function(method, data) {
var typetimer, typesearch = '';
//
// private methods
//
var init = function(select, data) {
// disable for ios devices (their native controls are more suitable for a touch device)
if( navigator.useragent.match(/ipad|iphone|android/i) ) return false;
// element must be a select control
if( select.tagname.tolowercase() !== 'select' ) return false;
select = $(select);
if( select.data('selectbox-control') ) return false;
var control = $(''),
inline = select.attr('multiple') || parseint(select.attr('size')) > 1;
var settings = data || {};
if( settings.autowidth === undefined ) settings.autowidth = true;
// inherit class names, style, and title attributes
control
.addclass(select.attr('class'))
.attr('style', select.attr('style') || '')
.attr('title', select.attr('title') || '')
.attr('tabindex', parseint(select.attr('tabindex')))
.css('display', 'inline-block')
.bind('focus.selectbox', function() {
if( this !== document.activeelement ) $(document.activeelement).blur();
if( control.hasclass('selectbox-active') ) return;
control.addclass('selectbox-active');
select.trigger('focus');
})
.bind('blur.selectbox', function() {
if( !control.hasclass('selectbox-active') ) return;
control.removeclass('selectbox-active');
select.trigger('blur');
});
if( select.attr('disabled') ) control.addclass('selectbox-disabled');
// generate control
if( inline ) {
//
// inline controls
//
var options = getoptions(select, 'inline');
control
.append(options)
.data('selectbox-options', options)
.addclass('selectbox-inline')
.addclass('selectbox-menushowing')
.bind('keydown.selectbox', function(event) {
handlekeydown(select, event);
})
.bind('keypress.selectbox', function(event) {
handlekeypress(select, event);
})
.bind('mousedown.selectbox', function(event) {
if( $(event.target).is('a.selectbox-inline') ) event.preventdefault();
if( !control.hasclass('selectbox-focus') ) control.focus();
})
.insertafter(select);
// auto-height based on size attribute
if( !select[0].style.height ) {
var size = select.attr('size') ? parseint(select.attr('size')) : 5;
// draw a dummy control off-screen, measure, and remove it
var tmp = control
.clone()
.removeattr('id')
.css({
position: 'absolute',
top: '-9999em'
})
.show()
.appendto('body');
tmp.find('.selectbox-options').html('