/*
* jQuery Selectbox plugin 0.1.2
*
* Copyright 2011, Dimitar Ivanov (http://www.bulgaria-web-developers.com/projects/javascript/selectbox/)
* Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
* 
* Date: Fri Mar 18 22:28:49 2011 +0200
*/
(function ($, undefined) { var PROP_NAME = "selectbox", FALSE = false, TRUE = true; function Selectbox() { this._state = []; this._defaults = { classHolder: "sbHolder", classHolderDisabled: "sbHolderDisabled", classSelector: "sbSelector", classOptions: "sbOptions", classToggleOpen: "sbToggleOpen", classToggle: "sbToggle", effect: "slide", onChange: null, onOpen: null, onClose: null} } $.extend(Selectbox.prototype, { _isOpenSelectbox: function (target) { if (!target) { return FALSE } var inst = this._getInst(target); return inst.isOpen }, _isDisabledSelectbox: function (target) { if (!target) { return FALSE } var inst = this._getInst(target); return inst.isDisabled }, _attachSelectbox: function (target, settings) { if (this._getInst(target)) { return FALSE } var $target = $(target), self = this, inst = self._newInst($target), sbHolder, sbSelector, sbToggle, sbOptions, s = FALSE, opts = $target.find("option"), olen = opts.length; $target.attr("sb", inst.uid); $.extend(inst.settings, self._defaults, settings); self._state[inst.uid] = FALSE; $target.hide(); function closeOthers() { var key, uid = this.attr("id").split("_")[1]; for (key in self._state) { if (key !== uid) { if (self._state.hasOwnProperty(key)) { if ($(":input[sb='" + key + "']")[0]) { self._closeSelectbox($(":input[sb='" + key + "']")[0]) } } } } } sbHolder = $("<div>", { id: "sbHolder_" + inst.uid, "class": inst.settings.classHolder }); sbSelector = $("<a>", { id: "sbSelector_" + inst.uid, href: "#", "class": inst.settings.classSelector, click: function (e) { e.preventDefault(); closeOthers.apply($(this), []); var uid = $(this).attr("id").split("_")[1]; if (self._state[uid]) { self._closeSelectbox(target) } else { self._openSelectbox(target) } } }); sbToggle = $("<a>", { id: "sbToggle_" + inst.uid, href: "#", "class": inst.settings.classToggle, click: function (e) { e.preventDefault(); closeOthers.apply($(this), []); var uid = $(this).attr("id").split("_")[1]; if (self._state[uid]) { self._closeSelectbox(target) } else { self._openSelectbox(target) } } }); sbToggle.appendTo(sbHolder); sbOptions = $("<ul>", { id: "sbOptions_" + inst.uid, "class": inst.settings.classOptions, css: { display: "none"} }); opts.each(function (i) { var that = $(this), li = $("<li>"); if (that.is(":selected")) { sbSelector.text(that.text()); s = TRUE } if (i === olen - 1) { li.addClass("last") } $("<a>", { href: "#" + that.val(), rel: that.val(), text: that.text(), click: function (e) { e.preventDefault(); var t = sbToggle, uid = t.attr("id").split("_")[1]; self._changeSelectbox(target, $(this).attr("rel"), $(this).text()); self._closeSelectbox(target) } }).appendTo(li); li.appendTo(sbOptions) }); if (!s) { sbSelector.text(opts.first().text()) } $.data(target, PROP_NAME, inst); sbSelector.appendTo(sbHolder); sbOptions.appendTo(sbHolder); sbHolder.insertAfter($target) }, _detachSelectbox: function (target) { var inst = this._getInst(target); if (!inst) { return FALSE } $("#sbHolder_" + inst.uid).remove(); $.data(target, PROP_NAME, null); $(target).show() }, _changeSelectbox: function (target, value, text) { var inst = this._getInst(target), onChange = this._get(inst, "onChange"); $("#sbSelector_" + inst.uid).text(text); $(target).children("option[value='" + value + "']").attr("selected", TRUE); if (onChange) { onChange.apply((inst.input ? inst.input[0] : null), [value, inst]) } else { if (inst.input) { inst.input.trigger("change") } } }, _enableSelectbox: function (target) { var inst = this._getInst(target); if (!inst || !inst.isDisabled) { return FALSE } $("#sbHolder_" + inst.uid).removeClass(inst.settings.classHolderDisabled); inst.isDisabled = FALSE; $.data(target, PROP_NAME, inst) }, _disableSelectbox: function (target) { var inst = this._getInst(target); if (!inst || inst.isDisabled) { return FALSE } $("#sbHolder_" + inst.uid).addClass(inst.settings.classHolderDisabled); inst.isDisabled = TRUE; $.data(target, PROP_NAME, inst) }, _optionSelectbox: function (target, name, value) { var inst = this._getInst(target); if (!inst) { return FALSE } inst[name] = value; $.data(target, PROP_NAME, inst) }, _openSelectbox: function (target) { var inst = this._getInst(target); if (!inst || inst.isOpen || inst.isDisabled) { return } var el = $("#sbOptions_" + inst.uid), viewportHeight = parseInt($(window).height(), 10), offset = $("#sbHolder_" + inst.uid).offset(), scrollTop = $(window).scrollTop(), height = el.prev().height(), diff = viewportHeight - (offset.top - scrollTop) - height / 2, onOpen = this._get(inst, "onOpen"); el.css({ top: height + "px", maxHeight: (diff - height) + "px" }); inst.settings.effect === "fade" ? el.fadeIn() : el.slideDown(); $("#sbToggle_" + inst.uid).addClass(inst.settings.classToggleOpen); this._state[inst.uid] = TRUE; inst.isOpen = TRUE; if (onOpen) { onOpen.apply((inst.input ? inst.input[0] : null), [inst]) } $.data(target, PROP_NAME, inst) }, _closeSelectbox: function (target) { var inst = this._getInst(target); if (!inst || !inst.isOpen) { return } var onClose = this._get(inst, "onClose"); inst.settings.effect === "fade" ? $("#sbOptions_" + inst.uid).fadeOut() : $("#sbOptions_" + inst.uid).slideUp(); $("#sbToggle_" + inst.uid).removeClass(inst.settings.classToggleOpen); this._state[inst.uid] = FALSE; inst.isOpen = FALSE; if (onClose) { onClose.apply((inst.input ? inst.input[0] : null), [inst]) } $.data(target, PROP_NAME, inst) }, _newInst: function (target) { var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, "\\\\$1"); return { id: id, input: target, uid: Math.floor(Math.random() * 99999999), isOpen: FALSE, isDisabled: FALSE, settings: {}} }, _getInst: function (target) { try { return $.data(target, PROP_NAME) } catch (err) { throw "Missing instance data for this selectbox" } }, _get: function (inst, name) { return inst.settings[name] !== undefined ? inst.settings[name] : this._defaults[name] } }); $.fn.selectbox = function (options) { var otherArgs = Array.prototype.slice.call(arguments, 1); if (typeof options == "string" && options == "isDisabled") { return $.selectbox["_" + options + "Selectbox"].apply($.selectbox, [this[0]].concat(otherArgs)) } if (options == "option" && arguments.length == 2 && typeof arguments[1] == "string") { return $.selectbox["_" + options + "Selectbox"].apply($.selectbox, [this[0]].concat(otherArgs)) } return this.each(function () { typeof options == "string" ? $.selectbox["_" + options + "Selectbox"].apply($.selectbox, [this].concat(otherArgs)) : $.selectbox._attachSelectbox(this, options) }) }; $.selectbox = new Selectbox(); $.selectbox.version = "0.1.2" })(jQuery);
