PageSourceSearch

https://www.univaq.it/js/bsnAutoSuggest.js

js univaq.it collected 2026-09-24 08:51:41 UTC 14,882 bytes, 842 lines download raw bytes

1/**
2 *  author:		Timothy Groves - http://www.brandspankingnew.net
3 *	version:	1.2 - 2006-11-17
4 *              1.3 - 2006-12-04
5 *              2.0 - 2007-02-07
6 *              2.1.1 - 2007-04-13
7 *              2.1.2 - 2007-07-07
8 *              2.1.3 - 2007-07-19
9 *
10 */
11
12 var global_iHigh = 0;
13 
14
15if (typeof(bsn) == "undefined")
16	_b = bsn = {};
17
18if (typeof(_b.Autosuggest) == "undefined")
19	_b.Autosuggest = {};
20else
21	alert("Autosuggest is already set!");
22
23_b.AutoSuggest = function (id, param)
24{
25	// no DOM - give up!
26	//
27	if (!document.getElementById)
28		return 0;
29	
30	// get field via DOM
31	//
32	this.fld = _b.DOM.gE(id);
33
34	if (!this.fld)
35		return 0;
36	
37	// init variables
38	//
39	this.sInp 	= "";
40	this.nInpC 	= 0;
41	this.aSug 	= [];
42	this.iHigh 	= 0;
43	
44	
45	
46	
47	// parameters object
48	//
49	this.oP = param ? param : {};
50	
51	// defaults	
52	//
53	var k, def = {minchars:1, meth:"get", varname:"input", className:"autosuggest", timeout:2500, delay:500, offsety:-5, shownoresults: true, noresults: "No results!", maxheight: 250, cache: true, maxentries: 25};
54	for (k in def)
55	{
56		if (typeof(this.oP[k]) != typeof(def[k]))
57			this.oP[k] = def[k];
58	}
59	
60	// set keyup handler for field
61	// and prevent autocomplete from client
62	//
63	var p = this;
64	
65	// NOTE: not using addEventListener because UpArrow fired twice in Safari
66	//_b.DOM.addEvent( this.fld, 'keyup', function(ev){ return pointer.onKeyPress(ev); } );
67	
68	this.fld.onkeypress 	= function(ev){ return p.onKeyPress(ev); };
69	this.fld.onkeyup 		= function(ev){ return p.onKeyUp(ev); };
70	
71	this.fld.setAttribute("autocomplete","off");
72};
73
74_b.AutoSuggest.prototype.onKeyPress = function(ev)
75{
76	var key = (window.event) ? window.event.keyCode : ev.keyCode;
77
78	// set responses to keydown events in the field
79	// this allows the user to use the arrow keys to scroll through the results
80	// ESCAPE clears the list
81	// TAB sets the current highlighted value
82	//
83	var RETURN = 13;
84	var TAB = 9;
85	var ESC = 27;
86	
87	var bubble = 1;
88
89	switch(key)
90	{
91		case RETURN:
92			this.setHighlightedValue();
93			bubble = 0;
94			break;
95
96		case ESC:
97			this.clearSuggestions();
98			break;
99	}
100
101	return bubble;
102};
103
104_b.AutoSuggest.prototype.onKeyUp = function(ev)
105{
106	var key = (window.event) ? window.event.keyCode : ev.keyCode;
107	
108	// set responses to keydown events in the field
109	// this allows the user to use the arrow keys to scroll through the results
110	// ESCAPE clears the list
111	// TAB sets the current highlighted value
112	//
113
114	var ARRUP = 38;
115	var ARRDN = 40;
116	
117	var bubble = 1;
118
119	switch(key)
120	{
121		case ARRUP:
122			this.changeHighlight(key);
123			bubble = 0;
124			break;
125
126		case ARRDN:
127			this.changeHighlight(key);
128			bubble = 0;
129			break;
130		
131		default:
132			this.getSuggestions(this.fld.value);
133	}
134
135	return bubble;
136	
137
138};
139
140_b.AutoSuggest.prototype.getSuggestions = function (val)
141{
142	// if input stays the same, do nothing
143	//
144	if (val == this.sInp)
145		return 0;
146	
147	// kill list
148	//
149	_b.DOM.remE(this.idAs);
150	
151	this.sInp = val;
152	
153	// input length is less than the min required to trigger a request
154	// do nothing
155	//
156	if (val.length < this.oP.minchars)
157	{
158		this.aSug = [];
159		this.nInpC = val.length;
160		return 0;
161	}
162	
163	var ol = this.nInpC; // old length
164	this.nInpC = val.length ? val.length : 0;
165	
166	// if caching enabled, and user is typing (ie. length of input is increasing)
167	// filter results out of aSuggestions from last request
168	//
169	var l = this.aSug.length;
170	if (this.nInpC > ol && l && l<this.oP.maxentries && this.oP.cache)
171	{
172		var arr = [];
173		for (var i=0;i<l;i++)
174		{
175			if(this.aSug[i].value.toLowerCase().indexOf(val.toLowerCase()) != -1)
176				arr.push( this.aSug[i] );
177		}
178		this.aSug = arr;
179		
180		this.createList(this.aSug);
181			
182		return false;
183	}
184	else
185	// do new request
186	//
187	{
188		var pointer = this;
189		var input = this.sInp;
190		clearTimeout(this.ajID);
191		this.ajID = setTimeout( function() { pointer.doAjaxRequest(input) }, this.oP.delay );
192	}
193
194	return false;
195};
196
197
198
199
200
201_b.AutoSuggest.prototype.doAjaxRequest = function (input)
202{
203	// check that saved input is still the value of the field
204	//
205	if (input != this.fld.value)
206		return false;
207	
208	
209	var pointer = this;
210	
211	
212	// create ajax request
213	//
214	if (typeof(this.oP.script) == "function")
215		var url = this.oP.script(encodeURIComponent(this.sInp));
216	else
217		var url = this.oP.script+this.oP.varname+"="+encodeURIComponent(this.sInp);
218	
219	if (!url)
220		return false;
221	
222	var meth = this.oP.meth;
223	var input = this.sInp;
224	
225	var onSuccessFunc = function (req) { pointer.setSuggestions(req, input) };
226	var onErrorFunc = function (status) { alert("AJAX error: "+status); };
227
228	var myAjax = new _b.Ajax();
229	myAjax.makeRequest( url, meth, onSuccessFunc, onErrorFunc );
230};
231
232
233
234
235
236_b.AutoSuggest.prototype.setSuggestions = function (req, input)
237{
238	// if field input no longer matches what was passed to the request
239	// don't show the suggestions
240	//
241	if (input != this.fld.value)
242		return false;
243	
244	
245	this.aSug = [];
246	
247	
248	if (this.oP.json)
249	{
250		var jsondata = eval('(' + req.responseText + ')');
251		
252		for (var i=0;i<jsondata.results.length;i++)
253		{
254			this.aSug.push(  { 'id':jsondata.results[i].id, 'value':jsondata.results[i].value, 'info':jsondata.results[i].info }  );
255		}
256	}
257	else
258	{
259
260		var xml = req.responseXML;
261	
262		// traverse xml
263		//
264		var results = xml.getElementsByTagName('results')[0].childNodes;
265
266		for (var i=0;i<results.length;i++)
267		{
268			if (results[i].hasChildNodes())
269				this.aSug.push(  { 'id':results[i].getAttribute('id'), 'value':results[i].childNodes[0].nodeValue, 'info':results[i].getAttribute('info') }  );
270		}
271	
272	}
273	
274	this.idAs = "as_"+this.fld.id;
275	
276
277	this.createList(this.aSug);
278
279};
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294_b.AutoSuggest.prototype.createList = function(arr)
295{
296	var pointer = this;
297	
298	
299	
300	
301	// get rid of old list
302	// and clear the list removal timeout
303	//
304	_b.DOM.remE(this.idAs);
305	this.killTimeout();
306	
307	
308	// if no results, and shownoresults is false, do nothing
309	//
310	if (arr.length == 0 && !this.oP.shownoresults)
311		return false;
312	
313	
314	// create holding div
315	//
316	var div = _b.DOM.cE("div", {id:this.idAs, className:this.oP.className});	
317	
318	var hcorner = _b.DOM.cE("div", {className:"as_corner"});
319	var hbar = _b.DOM.cE("div", {className:"as_bar"});
320	var header = _b.DOM.cE("div", {className:"as_header"});
321	header.appendChild(hcorner);
322	header.appendChild(hbar);
323	div.appendChild(header);
324	
325	
326	
327	
328	// create and populate ul
329	//
330	var ul = _b.DOM.cE("ul", {id:"as_ul"});
331	
332	
333	
334	
335	// loop throught arr of suggestions
336	// creating an LI element for each suggestion
337	//
338	for (var i=0;i<arr.length;i++)
339	{
340		// format output with the input enclosed in a EM element
341		// (as HTML, not DOM)
342		//
343		var val = arr[i].value;
344		var st = val.toLowerCase().indexOf( this.sInp.toLowerCase() );
345		var output = val.substring(0,st) + "<em>" + val.substring(st, st+this.sInp.length) + "</em>" + val.substring(st+this.sInp.length);
346		
347		
348		var span 		= _b.DOM.cE("span", {}, output, true);
349		if (arr[i].info != "")
350		{
351			var br			= _b.DOM.cE("br", {});
352			span.appendChild(br);
353			var small		= _b.DOM.cE("small", {}, arr[i].info);
354			span.appendChild(small);
355		}
356		
357		var a 			= _b.DOM.cE("a", { href:"#" });
358		
359		var tl 		= _b.DOM.cE("span", {className:"tl"}, " ");
360		var tr 		= _b.DOM.cE("span", {className:"tr"}, " ");
361		a.appendChild(tl);
362		a.appendChild(tr);
363		
364		a.appendChild(span);
365		
366		a.name = i+1;
367		a.onclick = function () { pointer.setHighlightedValue(); return false; };
368		a.onmouseover = function () { pointer.setHighlight(this.name); };
369		
370		var li = _b.DOM.cE(  "li", {}, a  );
371		
372		ul.appendChild( li );
373	}
374	
375	
376	// no results
377	//
378	if (arr.length == 0 && this.oP.shownoresults)
379	{
380		var li = _b.DOM.cE(  "li", {className:"as_warning"}, this.oP.noresults  );
381		ul.appendChild( li );
382	}
383	
384	
385	div.appendChild( ul );
386	
387	
388	var fcorner = _b.DOM.cE("div", {className:"as_corner"});
389	var fbar = _b.DOM.cE("div", {className:"as_bar"});
390	var footer = _b.DOM.cE("div", {className:"as_footer"});
391	footer.appendChild(fcorner);
392	footer.appendChild(fbar);
393	div.appendChild(footer);
394	
395	
396	
397	// get position of target textfield
398	// position holding div below it
399	// set width of holding div to width of field
400	//
401	var pos = _b.DOM.getPos(this.fld);
402	
403	div.style.left 		= pos.x + "px";
404	div.style.top 		= ( pos.y + this.fld.offsetHeight + this.oP.offsety ) + "px";
405	div.style.left=(this.oP.offsetx)+"px";
406	div.style.width=this.oP.boxwidth+"px";
407	
408	// set mouseover functions for div
409	// when mouse pointer leaves div, set a timeout to remove the list after an interval
410	// when mouse enters div, kill the timeout so the list won't be removed
411	//
412	div.onmouseover 	= function(){ pointer.killTimeout() };
413	div.onmouseout 		= function(){ pointer.resetTimeout() };
414
415
416	// add DIV to document
417	//
418	document.getElementsByTagName("body")[0].appendChild(div);
419	
420	
421	
422	// currently no item is highlighted
423	//
424	this.iHigh = 0;
425	
426	
427	
428	
429	
430	
431	// remove list after an interval
432	//
433	var pointer = this;
434	this.toID = setTimeout(function () { pointer.clearSuggestions() }
434, this.oP.timeout);
435};
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451_b.AutoSuggest.prototype.changeHighlight = function(key)
452{	
453	var list = _b.DOM.gE("as_ul");
454	
455	if (!list)
456		return false;
457		
458	var n;
459
460	if (key == 40)
461		n = this.iHigh + 1;
462	else if (key == 38)
463		n = this.iHigh - 1;
464	
465	if (n > list.childNodes.length)
466		n = list.childNodes.length;
467	if (n < 1)
468		n = 0;
469	
470	this.setHighlight(n);
471};
472
473
474
475_b.AutoSuggest.prototype.setHighlight = function(n)
476{
477	var list = _b.DOM.gE("as_ul");
478	if (!list)
479		return false;
480	
481	if (this.iHigh > 0)
482		this.clearHighlight();
483	
484	this.iHigh = Number(n);
485	
486	// MOD: variabile globale per far funzionare 'onEnter' sul form di ricerca	
487	global_iHigh = this.iHigh;
488	
489	list.childNodes[this.iHigh-1].className = "as_highlight";
490
491	this.killTimeout();
492};
493
494
495_b.AutoSuggest.prototype.clearHighlight = function()
496{
497	var list = _b.DOM.gE("as_ul");
498	if (!list)
499		return false;
500	
501	if (this.iHigh > 0)
502	{
503		list.childNodes[this.iHigh-1].className = "";
504		this.iHigh = 0;
505	}
506};
507
508
509_b.AutoSuggest.prototype.setHighlightedValue = function ()
510{
511	if (this.iHigh)
512	{
513		//this.sInp = this.fld.value = this.aSug[ this.iHigh-1 ].value;
514		
515		// move cursor to end of input (safari)
516		//
517		this.fld.focus();
518		if (this.fld.selectionStart)
519			this.fld.setSelectionRange(this.sInp.length, this.sInp.length);
520		
521		this.clearSuggestions();
522		
523		// pass selected object to callback function, if exists
524		//
525		if (typeof(this.oP.callback) == "function")
526			this.oP.callback( this.aSug[this.iHigh-1] );
527	}
528};
529
530
531
532
533
534
535
536
537
538
539
540
541
542_b.AutoSuggest.prototype.killTimeout = function()
543{
544	clearTimeout(this.toID);
545};
546
547_b.AutoSuggest.prototype.resetTimeout = function()
548{
549	clearTimeout(this.toID);
550	var pointer = this;
551	this.toID = setTimeout(function () { pointer.clearSuggestions() }, 1000);
552};
553
554
555
556
557
558
559
560_b.AutoSuggest.prototype.clearSuggestions = function ()
561{
562	
563	this.killTimeout();
564	
565	var ele = _b.DOM.gE(this.idAs);
566	var pointer = this;
567	if (ele)
568	{
569		var fade = new _b.Fader(ele,1,0,250,function () { _b.DOM.remE(pointer.idAs) });
570	}
571};
572
573
574
575
576
577
578
579
580
581
582// AJAX PROTOTYPE _____________________________________________
583
584
585if (typeof(_b.Ajax) == "undefined")
586	_b.Ajax = {};
587
588
589
590_b.Ajax = function ()
591{
592	this.req = {};
593	this.isIE = false;
594};
595
596
597
598_b.Ajax.prototype.makeRequest = function (url, meth, onComp, onErr)
599{
600	
601	if (meth != "POST")
602		meth = "GET";
603	
604	this.onComplete = onComp;
605	this.onError = onErr;
606	
607	var pointer = this;
608	
609	// branch for native XMLHttpRequest object
610	if (window.XMLHttpRequest)
611	{
612		this.req = new XMLHttpRequest();
613		this.req.onreadystatechange = function () { pointer.processReqChange() };
614		this.req.open("GET", url, true); //
615		this.req.send(null);
616	// branch for IE/Windows ActiveX version
617	}
618	else if (window.ActiveXObject)
619	{
620		this.req = new ActiveXObject("Microsoft.XMLHTTP");
621		if (this.req)
622		{
623			this.req.onreadystatechange = function () { pointer.processReqChange() };
624			this.req.open(meth, url, true);
625			this.req.send();
626		}
627	}
628};
629
630
631_b.Ajax.prototype.processReqChange = function()
632{
633	
634	// only if req shows "loaded"
635	if (this.req.readyState == 4) {
636		// only if "OK"
637		if (this.req.status == 200)
638		{
639			this.onComplete( this.req );
640		} else {
641			this.onError( this.req.status );
642		}
643	}
644};
645
646
647
648
649
650
651
652
653
654
655// DOM PROTOTYPE _____________________________________________
656
657
658if (typeof(_b.DOM) == "undefined")
659	_b.DOM = {};
660
661
662
663/* create element */
664_b.DOM.cE = function ( type, attr, cont, html )
665{
666	var ne = document.createElement( type );
667	if (!ne)
668		return 0;
669		
670	for (var a in attr)
671		ne[a] = attr[a];
672	
673	var t = typeof(cont);
674	
675	if (t == "string" && !html)
676		ne.appendChild( document.createTextNode(cont) );
677	else if (t == "string" && html)
678		ne.innerHTML = cont;
679	else if (t == "object")
680		ne.appendChild( cont );
681
682	return ne;
683};
684
685
686
687/* get element */
688_b.DOM.gE = function ( e )
689{
690	var t=typeof(e);
691	if (t == "undefined")
692		return 0;
693	else if (t == "string")
694	{
695		var re = document.getElementById( e );
696		if (!re)
697			return 0;
698		else if (typeof(re.appendChild) != "undefined" )
699			return re;
700		else
701			return 0;
702	}
703	else if (typeof(e.appendChild) != "undefined")
704		return e;
705	else
706		return 0;
707};
708
709
710
711/* remove element */
712_b.DOM.remE = function ( ele )
713{
714	var e = this.gE(ele);
715	
716	if (!e)
717		return 0;
718	else if (e.parentNode.removeChild(e))
719		return true;
720	else
721		return 0;
722};
723
724
725
726/* get position */
727_b.DOM.getPos = function ( e )
728{
729	var e = this.gE(e);
730
731	var obj = e;
732
733	var curleft = 0;
734	if (obj.offsetParent)
735	{
736		while (obj.offsetParent)
737		{
738			curleft += obj.offsetLeft;
739			obj = obj.offsetParent;
740		}
741	}
742	else if (obj.x)
743		curleft += obj.x;
744	
745	var obj = e;
746	
747	var curtop = 0;
748	if (obj.offsetParent)
749	{
750		while (obj.offsetParent)
751		{
752			curtop += obj.offsetTop;
753			obj = obj.offsetParent;
754		}
755	}
756	else if (obj.y)
757		curtop += obj.y;
758
759	return {x:curleft, y:curtop};
760};
761
762
763
764
765
766
767
768
769
770
771// FADER PROTOTYPE _____________________________________________
772
773
774
775if (typeof(_b.Fader) == "undefined")
776	_b.Fader = {};
777
778
779
780
781
782_b.Fader = function (ele, from, to, fadetime, callback)
783{	
784	if (!ele)
785		return 0;
786	
787	this.e = ele;
788	
789	this.from = from;
790	this.to = to;
791	
792	this.cb = callback;
793	
794	this.nDur = fadetime;
795		
796	this.nInt = 50;
797	this.nTime = 0;
798	
799	var p = this;
800	this.nID = setInterval(function() { p._fade() }, this.nInt);
801};
802
803
804
805
806_b.Fader.prototype._fade = function()
807{
808	this.nTime += this.nInt;
809	
810	var ieop = Math.round( this._tween(this.nTime, this.from, this.to, this.nDur) * 100 );
811	var op = ieop / 100;
812	
813	if (this.e.filters) // internet explorer
814	{
815		try
816		{
817			this.e.filters.item("DXImageTransform.Microsoft.Alpha").opacity = ieop;
818		} catch (e) { 
819			// If it is not set initially, the browser will throw an error.  This will set it if it is not set yet.
820			this.e.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity='+ieop+')';
821		}
822	}
823	else // other browsers
824	{
825		this.e.style.opacity = op;
826	}
827	
828	
829	if (this.nTime == this.nDur)
830	{
831		clearInterval( this.nID );
832		if (this.cb != undefined)
833			this.cb();
834	}
835};
836
837
838
839_b.Fader.prototype._tween = function(t,b,c,d)
840{
841	return b + ( (c-b) * (t/d) );
842};

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.