PageSourceSearch

https://www.inoxpa.com/themes/inoxpa/js/jquery.selectbox-0.2.js

js inoxpa.com collected 2026-10-04 11:20:57 UTC 15,249 bytes, 517 lines download raw bytes

1/*!
2 * jQuery Selectbox plugin 0.2
3 *
4 * Copyright 2011-2012, Dimitar Ivanov (http://www.bulgaria-web-developers.com/projects/javascript/selectbox/)
5 * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
6 *
7 * Date: Tue Jul 17 19:58:36 2012 +0300
8 */
9(function ($, undefined) {
10	var PROP_NAME = 'selectbox',
11		FALSE = false,
12		TRUE = true;
13	/**
14	 * Selectbox manager.
15	 * Use the singleton instance of this class, $.selectbox, to interact with the select box.
16	 * Settings for (groups of) select boxes are maintained in an instance object,
17	 * allowing multiple different settings on the same page
18	 */
19	function Selectbox() {
20		this._state = [];
21		this._defaults = { // Global defaults for all the select box instances
22			classHolder: "sbHolder",
23			classHolderDisabled: "sbHolderDisabled",
24			classSelector: "sbSelector",
25			classOptions: "sbOptions",
26			classGroup: "sbGroup",
27			classSub: "sbSub",
28			classDisabled: "sbDisabled",
29			classToggleOpen: "sbToggleOpen",
30			classToggle: "sbToggle",
31			classFocus: "sbFocus",
32			speed: 200,
33			effect: "slide", // "slide" or "fade"
34			onChange: null, //Define a callback function when the selectbox is changed
35			onOpen: null, //Define a callback function when the selectbox is open
36			onClose: null //Define a callback function when the selectbox is closed
37		};
38	}
39
40	$.extend(Selectbox.prototype, {
41		/**
42		 * Is the first field in a jQuery collection open as a selectbox
43		 *
44		 * @param {Object} target
45		 * @return {Boolean}
46		 */
47		_isOpenSelectbox: function (target) {
48			if (!target) {
49				return FALSE;
50			}
51			var inst = this._getInst(target);
52			return inst.isOpen;
53		},
54		/**
55		 * Is the first field in a jQuery collection disabled as a selectbox
56		 *
57		 * @param {HTMLElement} target
58		 * @return {Boolean}
59		 */
60		_isDisabledSelectbox: function (target) {
61			if (!target) {
62				return FALSE;
63			}
64			var inst = this._getInst(target);
65			return inst.isDisabled;
66		},
67		/**
68		 * Attach the select box to a jQuery selection.
69		 *
70		 * @param {HTMLElement} target
71		 * @param {Object} settings
72		 */
73		_attachSelectbox: function (target, settings) {
74			if (this._getInst(target)) {
75				return FALSE;
76			}
77			var $target = $(target),
78				self = this,
79				inst = self._newInst($target),
80				sbHolder, sbSelector, sbToggle, sbOptions,
81				s = FALSE, optGroup = $target.find("optgroup"), opts = $target.find("option"), olen = opts.length;
82
83			$target.attr("sb", inst.uid);
84
85			$.extend(inst.settings, self._defaults, settings);
86			self._state[inst.uid] = FALSE;
87			$target.hide();
88
89			function closeOthers() {
90				var key, sel,
91					uid = this.attr("id").split("_")[1];
92				for (key in self._state) {
93					if (key !== uid) {
94						if (self._state.hasOwnProperty(key)) {
95							sel = $("select[sb='" + key + "']")[0];
96							if (sel) {
97								self._closeSelectbox(sel);
98							}
99						}
100					}
101				}
102			}
103
104			sbHolder = $("<div>", {
105				"id": "sbHolder_" + inst.uid,
106				"class": inst.settings.classHolder,
107				"tabindex": $target.attr("tabindex")
108			});
109
110			sbSelector = $("<a>", {
111				"id": "sbSelector_" + inst.uid,
112				"href": "#",
113				"class": inst.settings.classSelector,
114				"click": function (e) {
115					e.preventDefault();
116					closeOthers.apply($(this), []);
117					var uid = $(this).attr("id").split("_")[1];
118					if (self._state[uid]) {
119						self._closeSelectbox(target);
120					} else {
121						self._openSelectbox(target);
122					}
123				}
124			});
125
126			sbToggle = $("<a>", {
127				"id": "sbToggle_" + inst.uid,
128				"href": "#",
129				"class": inst.settings.classToggle,
130				"click": function (e) {
131					e.preventDefault();
132					closeOthers.apply($(this), []);
133					var uid = $(this).attr("id").split("_")[1];
134					if (self._state[uid]) {
135						self._closeSelectbox(target);
136					} else {
137						self._openSelectbox(target);
138					}
139				}
140			});
141			sbToggle.appendTo(sbHolder);
142
143			sbOptions = $("<ul>", {
144				"id": "sbOptions_" + inst.uid,
145				"class": inst.settings.classOptions,
146				"css": {
147					"display": "none"
148				}
149			});
150
151			$target.children().each(function(i) {
152				var that = $(this), li, config = {};
153				if (that.is("option")) {
154					getOptions(that);
155				} else if (that.is("optgroup")) {
156					li = $("<li>");
157					$("<span>", {
158						"text": that.attr("label")
159					}
159).addClass(inst.settings.classGroup).appendTo(li);
160					li.appendTo(sbOptions);
161					if (that.is(":disabled")) {
162						config.disabled = true;
163					}
164					config.sub = true;
165					getOptions(that.find("option"), config);
166				}
167			});
168
169			function getOptions () {
170				var sub = arguments[1] && arguments[1].sub ? true : false,
171					disabled = arguments[1] && arguments[1].disabled ? true : false;
172				arguments[0].each(function (i) {
173					var that = $(this),
174						li = $("<li>"),
175						child;
176					if (that.is(":selected")) {
177						sbSelector.text(that.text());
178						s = TRUE;
179					}
180					if (i === olen - 1) {
181						li.addClass("last");
182					}
183					if (!that.is(":disabled") && !disabled) {
184						child = $("<a>", {
185							"href": "#" + that.val(),
186							"rel": that.val()
187						}).text(that.text()).bind("click.sb", function (e) {
188								if (e && e.preventDefault) {
189									e.preventDefault();
190								}
191								var t = sbToggle,
192									$this = $(this),
193									uid = t.attr("id").split("_")[1];
194								self._changeSelectbox(target, $this.attr("rel"), $this.text());
195								self._closeSelectbox(target);
196							}).bind("mouseover.sb", function () {
197								var $this = $(this);
198								$this.parent().siblings().find("a").removeClass(inst.settings.classFocus);
199								$this.addClass(inst.settings.classFocus);
200							}).bind("mouseout.sb", function () {
201								$(this).removeClass(inst.settings.classFocus);
202							});
203						if (sub) {
204							child.addClass(inst.settings.classSub);
205						}
206						if (that.is(":selected")) {
207							child.addClass(inst.settings.classFocus);
208						}
209						child.appendTo(li);
210					} else {
211						child = $("<span>", {
212							"text": that.text()
213						}).addClass(inst.settings.classDisabled);
214						if (sub) {
215							child.addClass(inst.settings.classSub);
216						}
217						child.appendTo(li);
218					}
219					li.appendTo(sbOptions);
220				});
221			}
222
223			if (!s) {
224				sbSelector.text(opts.first().text());
225			}
226
227			$.data(target, PROP_NAME, inst);
228
229			sbHolder.data("uid", inst.uid).bind("keydown.sb", function (e) {
230				var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0,
231					$this = $(this),
232					uid = $this.data("uid"),
233					inst = $this.siblings("select[sb='"+uid+"']").data(PROP_NAME),
234					trgt = $this.siblings(["select[sb='", uid, "']"].join("")).get(0),
235					$f = $this.find("ul").find("a." + inst.settings.classFocus);
236				switch (key) {
237					case 37: //Arrow Left
238					case 38: //Arrow Up
239						if ($f.length > 0) {
240							var $next;
241							$("a", $this).removeClass(inst.settings.classFocus);
242							$next = $f.parent().prevAll("li:has(a)").eq(0).find("a");
243							if ($next.length > 0) {
244								$next.addClass(inst.settings.classFocus).focus();
245								$("#sbSelector_" + uid).text($next.text());
246							}
247						}
248						break;
249					case 39: //Arrow Right
250					case 40: //Arrow Down
251						var $next;
252						$("a", $this).removeClass(inst.settings.classFocus);
253						if ($f.length > 0) {
254							$next = $f.parent().nextAll("li:has(a)").eq(0).find("a");
255						} else {
256							$next = $this.find("ul").find("a").eq(0);
257						}
258						if ($next.length > 0) {
259							$next.addClass(inst.settings.classFocus).focus();
260							$("#sbSelector_" + uid).text($next.text());
261						}
262						break;
263					case 13: //Enter
264						if ($f.length > 0) {
265							self._changeSelectbox(trgt, $f.attr("rel"), $f.text());
266						}
267						self._closeSelectbox(trgt);
268						break;
269					case 9: //Tab
270						if (trgt) {
271							var inst = self._getInst(trgt);
272							if (inst/* && inst.isOpen*/) {
273								if ($f.length > 0) {
274									self._changeSelectbox(trgt, $f.attr("rel"), $f.text());
275								}
276								self._closeSelectbox(trgt);
277							}
278						}
279						var i = parseInt($this.attr("tabindex"), 10);
280						if (!e.shiftKey) {
281							i++;
282						} else {
283							i--;
284						}
285						$("*[tabindex='" + i + "']").focus();
286						break;
287					case 27: //Escape
288						self._closeSelectbox(trgt);
289						break;
290				}
291				e.stopPropagation();
292				return false;
293			}).delegate("a", "mouseover", function (e) {
294					$(this).addClass(inst.settings.classFocus);
295				}).delegate("a", "mouseout", function (e) {
296					$(this).removeClass(inst.settings.classFocus);
297				});
298
299			sbSelector.appendTo(sbHolder);
300			sbOptions.appendTo(sbHolder);
301			sbHolder.insertAfter($target);
302
303			$("html").on('mousedown', function(e) {
304				e.stopPropagation();
305				$("select").selectbox('close');
306			});
307			$([".", inst.settings.classHolder, ", .", inst.settings.classSelector].join("")).mousedown(function(e) {
308				e.stopPropagation();
309			});
310		},
311		/**
312		 * Remove the selectbox functionality completely. This will return the element back to its pre-init state.
313		 *
314		 * @param {HTMLElement} target
315		 */
316		_detachSelectbox: function (target) {
317			var inst = this._getInst(target);
318			if (!inst) {
319				return FALSE;
320			}
321			$("#sbHolder_" + inst.uid).remove();
322			$.data(target, PROP_NAME, null);
323			$(target).show();
324		},
325		/**
326		 * Change selected attribute of the selectbox.
327		 *
328		 * @param {HTMLElement} target
329		 * @param {String} value
330		 * @param {String} text
331		 */
332		_changeSelectbox: function (target, value, text) {
333			var onChange,
334				inst = this._getInst(target);
335			if (inst) {
336				onChange = this._get(inst, 'onChange');
337				$("#sbSelector_" + inst.uid).text(text);
338			}
339			value = value.replace(/\'/g, "\\'");
340			var $targetOption = $(target).find("option").filter(function() {
341				var $this = $(this);
342				return value == ($this.val() || $this.text());
343			});
344			$targetOption.prop("selected", true);
345			if (inst && onChange) {
346				onChange.apply((inst.input ? inst.input[0] : null), [value, inst]);
347			} else if (inst && inst.input) {
348				inst.input.trigger('change');
349			}
350		},
351		/**
352		 * Enable the selectbox.
353		 *
354		 * @param {HTMLElement} target
355		 */
356		_enableSelectbox: function (target) {
357			var inst = this._getInst(target);
358			if (!inst || !inst.isDisabled) {
359				return FALSE;
360			}
361			$("#sbHolder_" + inst.uid).removeClass(inst.settings.classHolderDisabled);
362			inst.isDisabled = FALSE;
363			$.data(target, PROP_NAME, inst);
364		},
365		/**
366		 * Disable the selectbox.
367		 *
368		 * @param {HTMLElement} target
369		 */
370		_disableSelectbox: function (target) {
371			var inst = this._getInst(target);
372			if (!inst || inst.isDisabled) {
373				return FALSE;
374			}
375			$("#sbHolder_" + inst.uid).addClass(inst.settings.classHolderDisabled);
376			inst.isDisabled = TRUE;
377			$.data(target, PROP_NAME, inst);
378		},
379		/**
380		 * Get or set any selectbox option. If no value is specified, will act as a getter.
381		 *
382		 * @param {HTMLElement} target
383		 * @param {String} name
384		 * @param {Object} value
385		 */
386		_optionSelectbox: function (target, name, value) {
387			var inst = this._getInst(target);
388			if (!inst) {
389				return FALSE;
390			}
391			//TODO check name
392			inst[name] = value;
393			$.data(target, PROP_NAME, inst);
394		},
395		/**
396		 * Call up attached selectbox
397		 *
398		 * @param {HTMLElement} target
399		 */
400		_openSelectbox: function (target) {
401			var inst = this._getInst(target);
402			//if (!inst || this._state[inst.uid] || inst.isDisabled) {
403			if (!inst || inst.isOpen || inst.isDisabled) {
404				return;
405			}
406			var	el = $("#sbOptions_" + inst.uid),
407				viewportHeight = parseInt($(window).height(), 10),
408				offset = $("#sbHolder_" + inst.uid).offset(),
409				scrollTop = $(window).scrollTop(),
410				height = el.prev().height(),
411				diff = viewportHeight - (offset.top - scrollTop) - height / 2,
412				onOpen = this._get(inst, 'onOpen');
413			el.css({
414				"top": height + "px",
415				"maxHeight": (diff - height) + "px"
416			});
417			inst.settings.effect === "fade" ? el.fadeIn(inst.settings.speed) : el.slideDown(inst.settings.speed);
418			$("#sbToggle_" + inst.uid).addClass(inst.settings.classToggleOpen);
419			this._state[inst.uid] = TRUE;
420			inst.isOpen = TRUE;
421			if (onOpen) {
422				onOpen.apply((inst.input ? inst.input[0] : null), [inst]);
423			}
424			$.data(target, PROP_NAME, inst);
425		},
426		/**
427		 * Close opened selectbox
428		 *
429		 * @param {HTMLElement} target
430		 */
431		_closeSelectbox: function (target) {
432			var inst = this._getInst(target);
433			//if (!inst || !this._state[inst.uid]) {
434			if (!inst || !inst.isOpen) {
435				return;
436			}
437			var onClose = this._get(inst, 'onClose');
438			inst.settings.effect === "fade" ? $("#sbOptions_" + inst.uid).fadeOut(inst.settings.speed) : $("#sbOptions_" + inst.uid).slideUp(inst.settings.speed);
439			$("#sbToggle_" + inst.uid).removeClass(inst.settings.classToggleOpen);
440			this._state[inst.uid] = FALSE;
441			inst.isOpen = FALSE;
442			if (onClose) {
443				onClose.apply((inst.input ? inst.input[0] : null), [inst]);
444			}
445			$.data(target, PROP_NAME, inst);
446		},
447		/**
448		 * Create a new instance object
449		 *
450		 * @param {HTMLElement} target
451		 * @return {Object}
452		 */
453		_newInst: function(target) {
454			var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1');
455			return {
456				id: id,
457				input: target,
458				uid: Math.floor(Math.random() * 99999999),
459				isOpen: FALSE,
460				isDisabled: FALSE,
461				settings: {}
462			};
463		},
464		/**
465		 * Retrieve the instance data for the target control.
466		 *
467		 * @param {HTMLElement} target
468		 * @return {Object} - the associated instance data
469		 * @throws error if a jQuery problem getting data
470		 */
471		_getInst: function(target) {
472			try {
473				return $.data(target, PROP_NAME);
474			}
475			catch (err) {
476				throw 'Missing instance data for this selectbox';
477			}
478		},
479		/**
480		 * Get a setting value, defaulting if necessary
481		 *
482		 * @param {Object} inst
483		 * @param {String} name
484		 * @return {Mixed}
485		 */
486		_get: function(inst, name) {
487			return inst.settings[name] !== undefined ? inst.settings[name] : this._defaults[name];
488		}
489	});
490
491	/**
492	 * Invoke the selectbox functionality.
493	 *
494	 * @param {Object|String} options
495	 * @return {Object}
496	 */
497	$.fn.selectbox = function (options) {
498
499		var otherArgs = Array.prototype.slice.call(arguments, 1);
500		if (typeof options == 'string' && options == 'isDisabled') {
501			return $.selectbox['_' + options + 'Selectbox'].apply($.selectbox, [this[0]].concat(otherArgs));
502		}
503
504		if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string') {
505			return $.selectbox['_' + options + 'Selectbox'].apply($.selectbox, [this[0]].concat(otherArgs));
506		}
507
508		return this.each(function() {
509			typeof options == 'string' ?
510				$.selectbox['_' + options + 'Selectbox'].apply($.selectbox, [this].concat(otherArgs)) :
511				$.selectbox._attachSelectbox(this, options);
512		});
513	};
514
515	$.selectbox = new Selectbox(); // singleton instance
516	$.selectbox.version = "0.2";
517})(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.