PageSourceSearch

https://www.icpsolution.com/wp-content/themes/langwitch/design/js/libs/jquery.selectbox-0.2.js?ver=6.9.9

js icpsolution.com collected 2026-10-04 13:24:36 UTC 15,198 bytes, 514 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			}).on("mouseover", "a", function (e) {
294				$(this).addClass(inst.settings.classFocus);
295			}).on("mouseout", "a", 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", "a", function(e) {
304				e.stopPropagation();          
305				$("select").selectbox('close'); 
306			});
307			
308			$([".", inst.settings.classHolder, ", .", inst.settings.classSelector].join("")).mousedown(function(e) {    
309				e.stopPropagation();
310			});
311		},
312		/**
313		 * Remove the selectbox functionality completely. This will return the element back to its pre-init state.
314		 * 
315		 * @param {HTMLElement} target
316		 */
317		_detachSelectbox: function (target) {
318			var inst = this._getInst(target);
319			if (!inst) {
320				return FALSE;
321			}
322			$("#sbHolder_" + inst.uid).remove();
323			$.data(target, PROP_NAME, null);
324			$(target).show();			
325		},
326		/**
327		 * Change selected attribute of the selectbox.
328		 * 
329		 * @param {HTMLElement} target
330		 * @param {String} value
331		 * @param {String} text
332		 */
333		_changeSelectbox: function (target, value, text) {
334			var onChange,
335				inst = this._getInst(target);
336			if (inst) {
337				onChange = this._get(inst, 'onChange');
338				$("#sbSelector_" + inst.uid).text(text);
339			}
340			value = value.replace(/\'/g, "\\'");
341			$(target).find("option[value='" + value + "']").attr("selected", TRUE);
342			if (inst && onChange) {
343				onChange.apply((inst.input ? inst.input[0] : null), [value, inst]);
344			} else if (inst && inst.input) {
345				inst.input.trigger('change');
346			}
347		},
348		/**
349		 * Enable the selectbox.
350		 * 
351		 * @param {HTMLElement} target
352		 */
353		_enableSelectbox: function (target) {
354			var inst = this._getInst(target);
355			if (!inst || !inst.isDisabled) {
356				return FALSE;
357			}
358			$("#sbHolder_" + inst.uid).removeClass(inst.settings.classHolderDisabled);
359			inst.isDisabled = FALSE;
360			$.data(target, PROP_NAME, inst);
361		},
362		/**
363		 * Disable the selectbox.
364		 * 
365		 * @param {HTMLElement} target
366		 */
367		_disableSelectbox: function (target) {
368			var inst = this._getInst(target);
369			if (!inst || inst.isDisabled) {
370				return FALSE;
371			}
372			$("#sbHolder_" + inst.uid).addClass(inst.settings.classHolderDisabled);
373			inst.isDisabled = TRUE;
374			$.data(target, PROP_NAME, inst);
375		},
376		/**
377		 * Get or set any selectbox option. If no value is specified, will act as a getter.
378		 * 
379		 * @param {HTMLElement} target
380		 * @param {String} name
381		 * @param {Object} value
382		 */
383		_optionSelectbox: function (target, name, value) {
384			var inst = this._getInst(target);
385			if (!inst) {
386				return FALSE;
387			}
388			//TODO check name
389			inst[name] = value;
390			$.data(target, PROP_NAME, inst);
391		},
392		/**
393		 * Call up attached selectbox
394		 * 
395		 * @param {HTMLElement} target
396		 */
397		_openSelectbox: function (target) {
398			var inst = this._getInst(target);
399			//if (!inst || this._state[inst.uid] || inst.isDisabled) {
400			if (!inst || inst.isOpen || inst.isDisabled) {
401				return;
402			}
403			var	el = $("#sbOptions_" + inst.uid),
404				viewportHeight = parseInt($(window).height(), 10),
405				offset = $("#sbHolder_" + inst.uid).offset(),
406				scrollTop = $(window).scrollTop(),
407				height = el.prev().height(),
408				diff = viewportHeight - (offset.top - scrollTop) - height / 2,
409				onOpen = this._get(inst, 'onOpen');
410			el.css({
411				"top": height + "px",
412				"maxHeight": (diff - height) + "px"
413			});
414			inst.settings.effect === "fade" ? el.fadeIn(inst.settings.speed) : el.slideDown(inst.settings.speed);
415			$("#sbToggle_" + inst.uid).addClass(inst.settings.classToggleOpen);
416			this._state[inst.uid] = TRUE;
417			inst.isOpen = TRUE;
418			if (onOpen) {
419				onOpen.apply((inst.input ? inst.input[0] : null), [inst]);
420			}
421			$.data(target, PROP_NAME, inst);
422		},
423		/**
424		 * Close opened selectbox
425		 * 
426		 * @param {HTMLElement} target
427		 */
428		_closeSelectbox: function (target) {
429			var inst = this._getInst(target);
430			//if (!inst || !this._state[inst.uid]) {
431			if (!inst || !inst.isOpen) {
432				return;
433			}
434			var onClose = this._get(inst, 'onClose');
435			inst.settings.effect === "fade" ? $("#sbOptions_" + inst.uid).fadeOut(inst.settings.speed) : $("#sbOptions_" + inst.uid).slideUp(inst.settings.speed);
436			$("#sbToggle_" + inst.uid).removeClass(inst.settings.classToggleOpen);
437			this._state[inst.uid] = FALSE;
438			inst.isOpen = FALSE;
439			if (onClose) {
440				onClose.apply((inst.input ? inst.input[0] : null), [inst]);
441			}
442			$.data(target, PROP_NAME, inst);
443		},
444		/**
445		 * Create a new instance object
446		 * 
447		 * @param {HTMLElement} target
448		 * @return {Object}
449		 */
450		_newInst: function(target) {
451			var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1');
452			return {
453				id: id, 
454				input: target, 
455				uid: Math.floor(Math.random() * 99999999),
456				isOpen: FALSE,
457				isDisabled: FALSE,
458				settings: {}
459			}; 
460		},
461		/**
462		 * Retrieve the instance data for the target control.
463		 * 
464		 * @param {HTMLElement} target
465		 * @return {Object} - the associated instance data
466		 * @throws error if a jQuery problem getting data
467		 */
468		_getInst: function(target) {
469			try {
470				return $.data(target, PROP_NAME);
471			}
472			catch (err) {
473				throw 'Missing instance data for this selectbox';
474			}
475		},
476		/**
477		 * Get a setting value, defaulting if necessary
478		 * 
479		 * @param {Object} inst
480		 * @param {String} name
481		 * @return {Mixed}
482		 */
483		_get: function(inst, name) {
484			return inst.settings[name] !== undefined ? inst.settings[name] : this._defaults[name];
485		}
486	});
487
488	/**
489	 * Invoke the selectbox functionality.
490	 * 
491	 * @param {Object|String} options
492	 * @return {Object}
493	 */
494	$.fn.selectbox = function (options) {
495		
496		var otherArgs = Array.prototype.slice.call(arguments, 1);
497		if (typeof options == 'string' && options == 'isDisabled') {
498			return $.selectbox['_' + options + 'Selectbox'].apply($.selectbox, [this[0]].concat(otherArgs));
499		}
500		
501		if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string') {
502			return $.selectbox['_' + options + 'Selectbox'].apply($.selectbox, [this[0]].concat(otherArgs));
503		}
504		
505		return this.each(function() {
506			typeof options == 'string' ?
507				$.selectbox['_' + options + 'Selectbox'].apply($.selectbox, [this].concat(otherArgs)) :
508				$.selectbox._attachSelectbox(this, options);
509		});
510	};
511	
512	$.selectbox = new Selectbox(); // singleton instance
513	$.selectbox.version = "0.2";
514})(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.