(function($){
window.SelectBoxManager=function(options){
var sbs=[],
self=this;
$(document).click(function(e){
if($(e.target).parents(".customSelect").size()===0){
self.close();
}});
this.add=function(sb){
sbs.push(sb);
};
this.close=function(){
$(sbs).each(function(){
this.close();
});
};};
var sb_manager=new SelectBoxManager();
window.SelectBox=function(options){
var self=this,
cfg=$.extend(true, {
manager: sb_manager,
customScrollbar: true,
zIndex: 100,
changeCallback: function(val){ },
truncate: function(str){return str;},
scrollOptions: {}}, options);
var $customSelect, $selectedValue, $selectValueWrap, $selectList, $dl, $options,
FOCUSED_CLASS="focused",
SELECTED_CLASS="selected",
SELECT_OPEN_CLASS="select-open",
DISABLED_CLASS="disabled",
HOVERED_CLASS="hovered",
_useDefaultBehavior=false,
_isOpen=false,
_isEnabled=true,
_isFocused=false,
_selectedValue="";
function init(){
_useDefaultBehavior=navigator.userAgent.match(/iPad|iPhone|Android|IEMobile|BlackBerry/i) ? true:false;
if(_useDefaultBehavior){
cfg.selectbox.addClass("use-default");
}
var selectId="",
selectedClass=cfg.selectbox.attr("class");
if(typeof cfg.selectbox.attr("id")!=="undefined"){
selectId='id="select-'+cfg.selectbox.attr("id")+'"';
}
cfg.selectbox.wrap('<div class="customSelect '+selectedClass+'" '+selectId+' />');
$customSelect=cfg.selectbox.parents(".customSelect");
$options=cfg.selectbox.find("option");
var selectListHTML=['<div class="selectList"><div class="selectListOuterWrap"><div class="selectListInnerWrap"><div class="selectListTop"></div><dl>'];
selectListHTML.push(_renderOptions());
selectListHTML.push('</dl><div class="selectListBottom"></div></div></div></div>');
$customSelect.append('<div class="selectValueWrap"><div class="selectedValue">'+_selectedValue+'</div> <span class="caret"></span> </div>' + selectListHTML.join(""));
$dl=$customSelect.find("dl");
$selectedValue=$customSelect.find(".selectedValue");
$selectValueWrap=$customSelect.find(".selectValueWrap");
$selectList=$customSelect.find(".selectList");
$customSelect.width(cfg.width);
$dl.width(cfg.width - 2);
_bindEvents();
sb_manager.add(self);
}
function _bindEvents(){
$selectValueWrap.click(function(){
if(_isOpen){
cfg.selectbox.focus();
self.close();
}else if(_isEnabled){
if(_useDefaultBehavior){
cfg.selectbox.focus();
}else{
self.open();
}}
});
$dl.click(function(e){
var $target=$(e.target);
if($target.is("dd")||$target.parents("dd")){
if(e.target.tagName.toLowerCase()!="dd"){
$target=$target.parents("dd");
}
if(!$target.hasClass(DISABLED_CLASS)&&$target.get(0)){
self.jumpToIndex($target.get(0).className.split(" ")[0].split("-")[1]);
self.close();
if(! _useDefaultBehavior){
cfg.selectbox.focus();
}}
}});
cfg.selectbox.focus(function(e){
_isFocused=true;
$customSelect.addClass(FOCUSED_CLASS);
}).blur(function(e){
_isFocused=false;
$customSelect.removeClass(FOCUSED_CLASS);
});
if(_useDefaultBehavior){
cfg.selectbox.change(function(e){
_updateValue($(this).find("option:selected").html());
});
}
cfg.selectbox.keyup(function(e){
self.close();
$options.each(function(i, itm){
if(itm.selected){
self.jumpToIndex(i);
return false;
}});
});
_bindHover();
}
function _bindHover(){
var $dds=$(".customSelect dd");
$dds.off("mouseover");
$dds.off("mouseout");
$dds.on("mouseover", function(e){
var $target=$(e.target);
if(e.target.tagName.toLowerCase()!="dd"){
$target=$target.parents("dd");
}
$target.addClass(HOVERED_CLASS);
});
$dds.on("mouseout", function(e){
var $target=$(e.target);
if(e.target.tagName.toLowerCase()!="dd"){
$target=$target.parents("dd");
}
$target.removeClass(HOVERED_CLASS);
});
}
function _updateValue(val){
if($selectedValue.html()!=val){
$selectedValue.html(_truncate(val));
cfg.changeCallback(cfg.selectbox.val());
}}
function _renderOptions(){
var optionHTML=[];
$options.each(function(i, itm){
var $this=$(this),
optgroup=$this.parents('optgroup'),
addlOptClasses="",
iconMarkup="";
if(optgroup.length > 0&&$this.prev().length===0){
optionHTML.push('<dt>'+optgroup.attr('label')+'</dt>');
}
if(itm.className!==""){
$(itm.className.split(" ")).each(function(){
iconMarkup +='<span class="' + this + '"></span>';
});
}
if(itm.selected&&!itm.disabled){
_selectedValue=iconMarkup + _truncate($(itm).html());
addlOptClasses=" " + SELECTED_CLASS;
}
if(itm.disabled){
addlOptClasses +=" " + DISABLED_CLASS;
}
optionHTML.push('<dd class="itm-'+i+' ' + addlOptClasses + '">' + iconMarkup + itm.innerHTML + '</dd>');
});
if($selectedValue&&$selectedValue.get(0)!==null){
$selectedValue.html(_selectedValue);
}
return optionHTML.join("");
}
function _setupScrollbar(){
$dl.css("height","auto");
if(cfg.height&&$dl.height() > cfg.height){
$dl.css("height", cfg.height);
if(cfg.customScrollbar){
self.scrollpane=$dl.jScrollPane($.extend({
contentWidth: 200
}, cfg.scrollOptions));
}else{
$dl.addClass("defaultScrollbar");
}}else{
$dl.css({overflow: "hidden"});
}}
function _truncate(str){
var arr=str.split("</span>");
var valToTrunc=arr[arr.length - 1];
arr[arr.length - 1]="";
var spans=arr.join("</SPAN>");
return spans + cfg.truncate(valToTrunc);
}
this.sync=function(){
$options=cfg.selectbox.find("option");
$dl.html(_renderOptions());
_bindHover();
_setupScrollbar();
};
this.disable=function(){
_isEnabled=false;
$customSelect.addClass(DISABLED_CLASS);
cfg.selectbox.attr("disabled", "disabled");
};
this.enable=function(){
_isEnabled=true;
$customSelect.removeClass(DISABLED_CLASS);
cfg.selectbox.removeAttr("disabled");
};
this.close=function(){
$customSelect.removeClass(SELECT_OPEN_CLASS);
$customSelect.css({"z-index": cfg.zIndex});
_isOpen=false;
};
this.open=function(){
_setupScrollbar();
if(cfg.manager){
cfg.manager.close();
}
$customSelect.addClass(SELECT_OPEN_CLASS);
if(self.scrollpane){
self.scrollpane.data('jsp').scrollToY($customSelect.find(".selected").position().top);
}
$customSelect.css({"z-index": cfg.zIndex + 1});
_isOpen=true;
};
this.jumpToIndex=function(index){
cfg.selectbox.get(0).selectedIndex=index;
$customSelect.find(".selected").removeClass(SELECTED_CLASS);
$customSelect.find(".itm-" + index).addClass(SELECTED_CLASS);
_updateValue($customSelect.find(".itm-" + index).html());
};
this.jumpToValue=function(value){
var index=-1;
$options.each(function(i){
if(this.innerHTML==value){
index=i;
return false;
}});
if(index!=-1){
self.jumpToIndex(index);
}
return index;
};
init();
};})(jQuery);