/*
HeapBox 0.9.2
(c) 2013 Filip Bartos
*/
;(function ( $, window, document, undefined ) {
var pluginName = "heapbox",
defaults = {
effect: {
"type": "slide",
"speed": "slow"
},
insert: "before",
heapsize: undefined,
emptyMessage: 'Empty',
tabindex: 'undefined',
openStart: function(){},
openComplete: function(){},
closeStart: function(){},
closeComplete: function(){},
onChange: function(){}
};
function Plugin( element, options ) {
/* Settings */
this.element = element;
this.options = $.extend( {}, defaults, options );
this._defaults = defaults;
this._name = pluginName;
this.instance;
this.callbackManager = new Array();
this.init();
}
Plugin.prototype = {
/*
* Heapbox init
*/
init: function() {
this._hideSourceElement();
this._isSourceSelectbox();
this.instance = this.createInstance();
this._createElements();
this._setDefaultValues();
},
/*
* Generate new ID for selectbox
*/
createInstance: function() {
return {
heapId: Math.round(Math.random() * 99999999),
state: false
};
},
/*
* Set events
*/
_setEvents: function() {
var self = this;
this._setControlsEvents();
$(document).on("click", "html", function(e){ e.stopPropagation();self._closeheap(true,function(){},function(){});});
},
_setSliderEvents: function() {
var self = this;
this.scrollingStatus = false;
heap = $("#heapbox_"+this.instance.heapId+" .heap");
heap.find(".sliderDown").click(function(e){e.preventDefault();e.stopPropagation();self._setHeapboxFocus();});
heap.find(".sliderDown").mousedown(function(e){
self.scrollingStatus = true;
self._keyArrowDownHandler($("#heapbox_"+self.instance.heapId));
self.interval = setInterval(function(){self._keyArrowDownHandler($("#heapbox_"+self.instance.heapId));},300);
}).mouseup(function(e){
clearInterval(self.interval);
self.scrollingStatus = false;
}).mouseout(function(e){
clearInterval(self.interval);
self.scrollingStatus = false;
});
heap.find(".sliderUp").click(function(e){e.preventDefault();e.stopPropagation();self._setHeapboxFocus();});
heap.find(".sliderUp").mousedown(function(e){
self.scrollingStatus = true;
self._keyArrowUpHandler($("#heapbox_"+self.instance.heapId));
self.interval = setInterval(function(){self._keyArrowUpHandler($("#heapbox_"+self.instance.heapId));},300);
}).mouseup(function(e){
clearInterval(self.interval);
self.scrollingStatus = false;
}).mouseout(function(e){
clearInterval(self.interval);
self.scrollingStatus = false;
});
},
_setViewPosition: function(heapbox) {
heap = $("div#heapbox_"+this.instance.heapId+" .heap");
heap.show();
var self = this;
selected = heapbox.find(".heapOptions li a.selected");
firstTop = heapbox.find(".heapOptions li a").first().offset().top;
actTop = $(selected).offset().top;
newTop = firstTop - actTop + this.sliderUpHeight;
heapHeight = $("div#heapbox_"+this.instance.heapId+" .heapOptions").height();
maxPosition = heapHeight-parseInt(this.options.heapsize,10)+this.sliderDownHeight;
minPosition = 0+this.sliderUpHeight;
if((-1*newTop) > maxPosition) newTop = -1*(maxPosition);
heapbox.find(".heapOptions").css("top",newTop);
if(!this.instance.state) heap.hide();
},
_setKeyboardEvents: function() {
var self = this;
heapbox = $("#heapbox_"+this.instance.heapId);
heapbox.keydown(function(e) {
switch(e.which)
{
case 13: self._handlerClicked();
return false;
break;
case 27: self._closeheap();
break;
case 37: self._keyArrowUpHandler($("#heapbox_"+self.instance.heapId));
e.preventDefault();
break;
case 39: self._keyArrowDownHandler($("#heapbox_"+self.instance.heapId));
e.preventDefault();
break;
case 38: self._keyArrowUpHandler($("#heapbox_"+self.instance.heapId));
e.preventDefault();
break;
case 40: self._keyArrowDownHandler($("#heapbox_"+self.instance.heapId));
e.preventDefault();
break;
}
});
},
_keyArrowUpHandler:function(heapboxEl){
var self = this;
heapboxEl.find("div.heap ul li").each(function(){
if(($(this).find("a").hasClass("selected")))
{
selectItem = self._findPrev($(this));
if(selectItem) {
self._heapChanged(self,selectItem,true);
return false;
}
}
});
self._setViewPosition($("#heapbox_"+self.instance.heapId));
},
_keyArrowDownHandler:function(heapboxEl){
var self = this;
heapboxEl.find("div.heap ul li").each(function(){
if(($(this).find("a").hasClass("selected")))
{
selectItem = self._findNext($(this));
if(selectItem) {
self._heapChanged(self,selectItem,true);
return false;
}
}
});
self._setViewPosition($("#heapbox_"+self.instance.heapId));
},
/*
* Find prev selectable heapbox option (ignore disabled)
*/
_findPrev:function(startItem){
if(startItem.prev().length > 0){
if(!startItem.prev().find("a").hasClass("disabled")) {
return startItem.prev().find("a");
}else{
return this._findPrev(startItem.prev());
}
}
},
/*
* Find next selectable heapbox option (ignore disabled)
*/
_findNext:function(startItem){
if(startItem.next().length > 0){
if(!startItem.next().find("a").hasClass("disabled")) {
return startItem.next().find("a");
}else{
return this._findNext(startItem.next());
}
}
},
/*
* Create heapbox html structure
*/
_createElements: function() {
var self = this;
heapBoxEl = $('
', {
id: 'heapbox_'+this.instance.heapId,
'class': 'heapBox',
data: {'sourceElement':this.element}
});
heapBoxHolderEl = $('', {
href: '',
'class': 'holder'
});
heapBoxHandlerEl = $('', {
href: '',
'class': 'handler'
});
heapBoxheapEl = $('', {
'class': 'heap'
});
heapBoxEl.append(heapBoxHolderEl);
heapBoxEl.append(heapBoxHandlerEl);
heapBoxEl.append(heapBoxheapEl);
this.heapBoxEl = heapBoxEl;
this._insertHeapbox(this.heapBoxEl);
},
/*
* Insert heapbox
*/
_insertHeapbox: function(heapbox) {
if(this.isSourceElementSelect && this.options.insert == "inside")
this.options.insert = "before";
switch(this.options.insert) {
case "before":
$(this.element).before(heapbox);
break;
case "after":
$(this.element).after(heapbox);
break;
case "inside":
$(this.element).html(heapbox);
this._showSourceElement();
break;
default:
$(this.element).before(heapbox);
break;
}
},
/*
* Fill heapbox with init data
*/
_setDefaultValues: function()
{
this._initHeap();
this._initView(heapBoxEl);
this._setHolderTitle();
this._setTabindex();
this._setEvents();
},
_setHeapboxFocus: function()
{
heapbox = $("div#heapbox_"+this.instance.heapId+" .holder");
heapbox.focus();
},
_setHeapSize: function() {
if(this.options.heapsize) {
if(heapBoxheapEl.height() < parseInt(this.options.heapsize,10)) {
delete this.options.heapsize;
return;
} else {
heapBoxheapEl.css("height",this.options.heapsize);
}
}
},
/*
* Fill heapbox with init data
*/
_initHeap: function(){
var initData;
if(this.isSourceElementSelect){
initData = this._optionsToJson();
this._setData(initData);
}
},
/*
* Init view with right position
*/
_initView: function(heapbox){
if(this._isHeapEmpty()){
return;
}else{
this._setViewPosition(heapbox);
}
},
/*
* Set title of holder
*/
_setHolderTitle: function()
{
var self = this;
holderEl = $("#heapbox_"+this.instance.heapId).find(".holder");
selectedEl = $("#heapbox_"+this.instance.heapId).find(".heap ul li a.selected").last();
if(selectedEl.length != 0)
{
holderEl.text(selectedEl.text());
holderEl.attr("rel",selectedEl.attr("rel"));
if(selectedEl.attr("data-icon-src")) {
iconEl = this._createIconElement(selectedEl.attr("data-icon-src"));
holderEl.append(iconEl);
}
}
else
{
holderEl.text(this.options.emptyMessage);
this._removeHeapboxHolderEvents();
this._removeHeapboxHandlerEvents();
}
},
/*
* Set tabindex to heapbox element
*/
_setTabindex: function(){
var tabindex;
tabindex = this.options.tabindex != "undefined" ? this.options.tabindex : $(this.element).attr("tabindex");
if(tabindex != "undefined") {
$("#heapbox_"+this.instance.heapId).attr("tabindex",tabindex);
}
},
/*
* Set data to heap
*/
_setData: function(data)
{
var self = this;
var _data = jQuery.parseJSON(data);
var selected = false;
if(this.isSourceElementSelect) this._refreshSourceSelectbox(_data);
heapBoxheapOptionsEl = $('', {
'class': 'heapOptions'
});
$.each(_data,function(){
if(this.selected) { selected = true; }
heapBoxOptionLiEl = $('', {
'class': 'heapOption'
});
heapBoxheapOptionAEl = $('', {
href: '',
rel: this.value,
title: this.text,
text: this.text,
'class': this.selected ? 'selected':'',
click: function(e){
e.preventDefault();
e.stopPropagation();
self._heapChanged(self,this);
}
});
if(this.disabled) {
heapBoxheapOptionAEl.unbind("click");
heapBoxheapOptionAEl.addClass("disabled");
heapBoxheapOptionAEl.click(function(e){
e.preventDefault();
e.stopPropagation();
});
}
if(this.icon)
{
heapBoxheapOptionAEl.attr('data-icon-src',this.icon);
heapBoxOptionIcon = self._createIconElement(this.icon);
heapBoxheapOptionAEl.append(heapBoxOptionIcon);
}
heapBoxOptionLiEl.append(heapBoxheapOptionAEl);
heapBoxheapOptionsEl.append(heapBoxOptionLiEl);
});
$("div#heapbox_"+this.instance.heapId+" .heap ul").remove();
$("div#heapbox_"+this.instance.heapId+" .heap").append(heapBoxheapOptionsEl);
this._setHeapSize();
if(this._isHeapsizeSet()) {
this._createSliderUpElement();
this._createSliderDownElement();
}
if(selected != true){
$("div#heapbox_"+this.instance.heapId+" .heap ul li a").first().addClass("selected");
}
},
/*
* Create sliderUp element
*/
_createSliderUpElement: function() {
slideUp = $('', {
'class': 'sliderUp',
'href': ''
});
$("div#heapbox_"+this.instance.heapId+" .heap .heapOptions").before(slideUp);
sliderUp = $("#heapbox_"+this.instance.heapId+" .sliderUp");
this.sliderUpHeight = parseInt(sliderUp.css("height"),10)+parseInt(sliderUp.css("border-top-width"),10)+parseInt(sliderUp.css("border-bottom-width"),10);
$("#heapbox_"+this.instance.heapId+" .heapOptions").css("top",this.sliderUpHeight);
},
/*
* Create sliderDown element
*/
_createSliderDownElement: function() {
slideDown = $('', {
'class': 'sliderDown',
'href': ''
});
$("div#heapbox_"+this.instance.heapId+" .heap .heapOptions").after(slideDown);
sliderDown = $("#heapbox_"+this.instance.heapId+" .sliderDown");
this.sliderDownHeight = parseInt(sliderDown.css("height"),10)+parseInt(sliderDown.css("border-top-width"))+parseInt(sliderDown.css("border-bottom-width"));
},
/*
* Creat img element for icon
*/
_createIconElement: function(iconSrc) {
heapBoxOptionIcon = $('
', {
src: iconSrc,
alt: iconSrc
});
return heapBoxOptionIcon;
},
/*
* If source element is