PageSourceSearch

https://www.happycampus.com/js/jquery/plugins/jquery.autoSuggest.js?jsVer=20260921.1

js happycampus.com collected 2026-09-24 09:09:07 UTC 16,135 bytes, 465 lines download raw bytes

1 /*
2 * AutoSuggest
3 * Copyright 2009-2010 Drew Wilson
4 * www.drewwilson.com
5 * code.drewwilson.com/entry/autosuggest-jquery-plugin
6 *
7 * Version 1.4   -   Updated: Mar. 23, 2010
8 *
9 * This Plug-In will auto-complete or auto-suggest completed search queries
10 * for you as you type. You can add multiple selections and remove them on
11 * the fly. It supports keybord navigation (UP + DOWN + RETURN), as well
12 * as multiple AutoSuggest fields on the same page.
13 *
14 * Inspied by the Autocomplete plugin by: J?rn Zaefferer
15 * and the Facelist plugin by: Ian Tearle (iantearle.com)
16 *
17 * This AutoSuggest jQuery plug-in is dual licensed under the MIT and GPL licenses:
18 *   http://www.opensource.org/licenses/mit-license.php
19 *   http://www.gnu.org/licenses/gpl.html
20 */
21
22(function($){
23	$.fn.autoSuggest = function(data, options) {
24		var originKeyword = $('#inputQu').val();
25		var defaults = {
26			startText: "", //Enter Name Here
27			emptyText: "No Results Found",
28			preFill: {},
29			limitText: "No More Selections Are Allowed",
30			selectedItemProp: "keyword", //value //name of object property
31			selectedValuesProp: "keyword", //value //name of object property
32			searchObjProps: "keyword", //value //comma separated list of object property names
33			queryParam: "keywords", // q
34			retrieveLimit: 10, //false //number for 'limit' param on ajax request
35			extraParams: "",
36			matchCase: false,
37			matchGlobal: false,
38			minChars: 1,
39			keyDelay: 200,
40			resultsMargin: "0",
41			resultsHighlight: true,
42			neverSubmit: false,
43			selectionLimit: false,
44			showResultList: true,
45			start: function(){},
46			wrapStyle: "",
47			selectionClick: function(elem){},
48			selectionAdded: function(elem){},
49			selectionRemoved: function(elem){ elem.remove(); },
50			beforeRetrieve: function(string){ return string; },
51			retrieveComplete: function(data){ return data; },
52			resultClick: function(data){},
53			formatList: function(this_data, formatted) {
54				return formatted.html('<span style="float: left">' + this_data['keyword'] + '</span><span style="font-size: 11px; color: #1f83cf; float: right">' + this_data['cntString'] + 'ê²°ê³¼</span>');
55			},
56			recomBookList: null,
57			recomDocList: null,
58			resultsComplete: function(results_holder) {
59				$(results_holder).prepend("<p>검색어 추천</p>");
60			},
61			newDesign: false
62		};
63	 	var opts = $.extend(defaults, options);
64		var d_type = "object";
65		var d_count = 0;
66		var lastKeyPressCode = 0;
67		var isSubmit = false;
68		var isMainPage = false;
69
70		if($('#mainIndex').length > 0) { // 메인페이지 전용
71			isMainPage = true;
72		}
73
74		if(typeof data == "string") {
75			d_type = "string";
76			var req_string = data;
77		} else {
78			var org_data = data;
79			for (k in data) if (data.hasOwnProperty(k)) d_count++;
80		}
81
82		if((d_type == "object" && d_count > 0) || d_type == "string"){
83			return this.each(function(x){
84				var input = $(this);
85				var input_focus = false;
86				
87				opts.start.call(this);
88				input.attr("autocomplete","off").addClass("as-input");
89				if (opts.startText) input.val(opts.startText);
90				
91				// Setup basic elements and render them to the DOM
92				input.wrap('<div style="position:relative;z-index:100;' + opts.wrapStyle + '"></div>').wrap('<ul class="as-selections" id="as-selections-'+x+'"></ul>').wrap('<li class="as-original" id="as-original-'+x+'"></li>');
93				var selections_holder = $("#as-selections-"+x);
94				var org_li = $("#as-original-"+x);
95
96				if(isMainPage){
97					var results_holder = $('<div class="autokeyword_v4 as-results" id="as-results-'+x+'"></div>').hide();
98				} else if(opts.newDesign) {
99                    var results_holder = $('<div class="autokeyword as-results" id="as-results-'+x+'"></div>').hide();
100				} else{
101					var results_holder = $('<div class="as-results" id="as-results-'+x+'"></div>').hide();
102				}
103
104				var results_ul =  $('<ul class="as-list"></ul>');
105				var values_input = "";
106				var prefill_value = "";
107				results_ul.css({"width": selections_holder.outerWidth()+opts.browserGap});
108
109				results_holder.css({"margin": opts.resultsMargin});
110
111				opts.divWidth = parseInt(opts.divWidth);
112				if(!isNaN(opts.divWidth) && opts.divWidth > 0) {
113					results_holder.css({"width":opts.divWidth});
114				}
115				opts.divTop = parseInt(opts.divTop);
116				if(!isNaN(opts.divTop) && opts.divTop > 0) {
117					results_holder.css({"top":opts.divTop});
118				}
119
120				if(typeof opts.preFill == "string"){
121					var vals = opts.preFill.split(",");
122					for(var i=0; i < vals.length; i++){
123						var v_data = {};
124						v_data[opts.selectedValuesProp] = vals[i];
125						if(vals[i] != ""){
126							add_selected_item(v_data, "000"+i);
127						}
128					}
129					prefill_value = opts.preFill;
130				} else {
131					prefill_value = "";
132					var prefill_count = 0;
133					for (k in opts.preFill) if (opts.preFill.hasOwnProperty(k)) prefill_count++;
134					if(prefill_count > 0){
135						for(var i=0; i < prefill_count; i++){
136							var new_v = opts.preFill[i][opts.selectedValuesProp];
137							if(new_v == undefined){ new_v = ""; }
138							prefill_value = prefill_value+new_v+",";
139							if(new_v != ""){
140								add_selected_item(opts.preFill[i], "000"+i);
141							}
142						}
143					}
144				}
145				
146				if(prefill_value != ""){
147					input.val("");
148					var lastChar = prefill_value.substring(prefill_value.length-1);
149					if(lastChar != ","){ prefill_value = prefill_value+","; }
150					values_input = ","+prefill_value;
151					$("li.as-selection-item", selections_holder).addClass("blur").removeClass("selected");
152				}
153				
154				selections_holder.click(function(){
155					input_focus = true;
156					input.focus();
157				}).mousedown(function(){ input_focus = false; }).after(results_holder);
158
159				var timeout = null;
160				var prev = "";
161				var totalSelections = 0;
162				var tab_press = false;
163				
164				// Handle input field events
165				input.focus(function(){
166					if($(this).val() == opts.startText && values_input == ""){
167						$(this).val("");
168					} else if(input_focus){
169						$("li.as-selection-item", selections_holder).removeClass("blur");
170						if($(this).val() != ""){
171							if ($("li:first", results_holder).text() == opts.emptyText) {
172								results_holder.hide();
173							} else {
174								if (input.val() != values_input) {
175									if (!isSubmit) keyChange();
176								} else {
177									results_holder.show();
178								}
179							}
180						}
181					}
182					input_focus = true;
183					return true;
184				}).blur(function(){
185					if($(this).val() == "" && values_input == "" && prefill_value == ""){
186						if (opts.startText) $(this).val(opts.startText);
187					} else if(input_focus){
188						$("li.as-selection-item", selections_holder).addClass("blur").removeClass("selected");
189						results_holder.hide();
190					}
191				}).keydown(function(e) {
192					// track last key pressed
193					lastKeyPressCode = e.keyCode;
194					first_focus = false;
195					switch(e.keyCode) {
196						case 37: // left
197							break;
198						case 39: // right
199							break;
200						case 38: // up
201							e.preventDefault();
202							e.stopPropagation();
203							// 작성중인 한글 문제 때문에 현재 값을 다시한번 기록을 해준다.
204							$('#inputQu').val($('#inputQu').val());
205							moveSelection("up");
206							break;
207						case 40: // down
208							e.preventDefault();
209							e.stopPropagation();
210							// 작성중인 한글 문제 때문에 현재 값을 다시한번 기록을 해준다.
211							$('#inputQu').val($('#inputQu').val());
212							moveSelection("down");
213							break;
214						case 8:  // delete
215							if(input.val() == ""){
216								var last = values_input.split(",");
217								last = last[last.length - 2];
218								selections_holder.children().not(org_li.prev()).removeClass("selected");
219								if(org_li.prev().hasClass("selected")){
220									values_input = values_input.val().replace(","+last+",",",");
221									opts.selectionRemoved.call(this, org_li.prev());
222								} else {
223									opts.selectionClick.call(this, org_li.prev());
224									org_li.prev().addClass("selected");
225								}
226							}
227							if(input.val().length <= 1){
228								results_holder.hide();
229								 prev = "";
230							}
231							else {
232								if (timeout){ clearTimeout(timeout); }
233								timeout = setTimeout(function(){ keyChange(); }, opts.keyDelay);
234							}
235							break;
236						case 13: // return
237							tab_press = false;
238							var active = $("li.active:first", results_holder);
239							if(active.length > 0){
240								// active.click();
241								results_holder.hide();
242							}
243
244							if(false && (opts.neverSubmit || active.length > 0)){
245								e.preventDefault();
246							}
247							break;
248						default:
249							if(opts.showResultList){
250								if(opts.selectionLimit && $("li.as-selection-item", selections_holder).length >= opts.selectionLimit){
251									results_ul.html('<li class="as-message">'+opts.limitText+'</li>');
252									if ($("li:first", results_holder).text() == opts.emptyText) {
253										results_holder.hide();
254									} else {
255										results_holder.show();
256									}
257								} else {
258									if (timeout){ clearTimeout(timeout); }
259									timeout = setTimeout(function(){ keyChange(); }, opts.keyDelay);
260								}
261							}
262
263							originKeyword = $('#inputQu').val();
264							break;
265					}
266				});
267				
268				function keyChange() {
269					// ignore if the following keys are pressed: [del] [shift] [capslock]
270					if( lastKeyPressCode == 46 || (lastKeyPressCode > 8 && lastKeyPressCode < 32) ){ return results_holder.hide(); }
271					var string = convertHangul(input.val().replace(/[\\]+|[\/]+/g,""));
272					
273					if (string == prev) return;
274					prev = string;
275					if (string.length >= opts.minChars) {
276						if(d_type == "string"){
277							var limit = "";
278							if(opts.retrieveLimit){
279								limit = "&limit="+encodeURIComponent(opts.retrieveLimit);
280							}
281							if(opts.beforeRetrieve){
282								string = opts.beforeRetrieve.call(this, string);
283							}
284							string = $.trim(string);
285							values_input = string;
286
287							if (string.length > 0) {
288								$.getJSON(req_string+"?"+opts.queryParam+"="+encodeURIComponent(string)+limit+opts.extraParams, function(data){
289									d_count = 0;
290									var new_data = opts.retrieveComplete.call(this, data.list);
291									for (k in new_data) if (new_data.hasOwnProperty(k)) d_count++;
292									processData(new_data, string);
293								});
294							}
295						} else {
296							if(opts.beforeRetrieve){
297								string = opts.beforeRetrieve.call(this, string);
298							}
299							processData(org_data, string);
300						}
301					} else {
302						results_holder.hide();
303					}
304				}
305				
306				var num_count = 0;
307				function processData(data, query, recommendBook, recommendDocs){
308					if (!opts.matchCase){ query = query.toLowerCase(); }
309					var matchCount = 0;
310					results_holder.html(results_ul.html("")).hide();
311					results_holder.prepend('<p style="border:none" class="as-list-title">추천검색어</p>');
312					for(var i=0;i<d_count;i++){
313						var num = i;
314						num_count++;
315						var forward = false;
316						if(opts.searchObjProps == "value") {
317							var str = data[num].value;
318						}
319						else {
320							var str = "";
321							var names = opts.searchObjProps.split(",");
322							for(var y=0;y<names.length;y++){
323								var name = $.trim(names[y]);
324								str = str+data[num][name]+" ";
325							}
326						}
327						if(str){
328							if (!opts.matchCase){ str = str.toLowerCase(); }
329								forward = true;
330						}
331						if(forward){
332							var formatted = $('<li class="as-result-item" id="as-result-item-'+num+'" data-text="' + data[num].keyword + '"></li>').click(function(){
333									var raw_data = $(this).data("data");
334									var number = raw_data.num;
335									if($("#as-selection-"+number, selections_holder).length <= 0 && !tab_press){
336										var data = raw_data.attributes;
337										prev = "";
338										add_selected_item(data, number);
339										opts.resultClick.call(this, raw_data);
340										results_holder.hide();
341									}
342									tab_press = false;
343								}).mousedown(function(){ input_focus = false; }).mouseover(function(){
344									$("li", results_ul).removeClass("active");
345									$(this).addClass("active");
346								}).data("data",{attributes: data[num], num: num_count});
347							var this_data = $.extend({},data[num]);
348							var regx = new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + query + ")(?![^<>]*>)(?![^&;]+;)", ((opts.matchCase)? "" : "i") + ((opts.matchGlobal)? "g" : ""));
349							
350							if(opts.resultsHighlight){
351								var highlightTag = "<em>$1</em>";
352								if(opts.newDesign){
353									highlightTag = "<strong>$1</strong>";
354								}
355								this_data[opts.selectedItemProp] = this_data[opts.selectedItemProp].replace(regx,highlightTag);
356							}
357							if(!opts.formatList){
358								formatted = formatted.html(this_data[opts.selectedItemProp]);
359							} else {
360								formatted = opts.formatList.call(this, this_data, formatted);
361							}
362							results_ul.append(formatted);
363							delete this_data;
364							matchCount++;
365							if(opts.retrieveLimit && opts.retrieveLimit == matchCount ){ break; }
366						}
367					}
368
369					if(matchCount <= 0){
370						results_ul.html('<li class="as-message">'+opts.emptyText+'</li>');
371					}
372					results_ul.css("width", selections_holder.outerWidth()+opts.browserGap);
373					if(isMainPage) {
374                        results_ul.css("width", 647);
375					}
376
377					if (
378						($("li:first", results_holder).text() == opts.emptyText)
379						&& matchCount <= 0
380					) {
381						results_holder.hide();
382					} else {
383						if (matchCount <= 0) {
384							results_holder.find('.as-list-title').hide();
385							results_ul.hide();
386						}
387						results_holder.show();
388						opts.resultsComplete.call(this, results_holder);
389					}
390					// if ($("li:first", results_holder).text() == opts.emptyText || matchCount <= 0) {
391					// 	results_holder.hide();
392					// } else {
393					// 	results_holder.show();
394					// 	opts.resultsComplete.call(this, results_holder);
395					// }
396				}
397				
398				function add_selected_item(data, num){
399					isSubmit = true;
400					input.val(data[opts.selectedValuesProp]);
401					$("form[name='search']").submit();
402				}
403				
404				function moveSelection(direction){
405					if($(":visible",results_holder).length > 0){
406						var lis = $("li[id^='as-result-item']", results_holder);
407						if(direction == "down"){
408							var start = lis.eq(0);
409						} else {
410							var start = lis.filter(":last");
411						}
412						var active = $("li.active:first", results_holder);
413						if(active.length > 0){
414							if(direction == "down"){
415							start = active.next();
416							} else {
417								start = active.prev();
418							}
419						}
420						lis.removeClass("active");
421						start.addClass("active");
422						
423						if (!$("li.active > span:first", results_holder).text()) {
424							input.val(values_input);
425						}
426						else {
427							if (timeout){ clearTimeout(timeout); }
428							input.val($("li.active > span:first", results_holder).text());
429							results_holder.show();
430						}
431						var selected = $('.as-list>li.active:eq(0)');
432						if(selected.length > 0) {
433							var _text = selected.attr('data-text');
434							$('#inputQu').val(_text);
435						} else {
436							$('#inputQu').val(originKeyword);
437						}
438					}
439				}
440				
441				function convertHangul(str) {
442					var initial = "rRseEfaqQtTdwWczxvg";
443					var regInitial = "[" + initial + "]";
444					var medial = {k:0,o:1,i:2,O:3,j:4,p:5,u:6,P:7,h:8,hk:9,ho:10,hl:11,y:12,n:13,nj:14,np:15,nl:16,b:1
4447,m:18,ml:19,l:20}
445					var regMedial = "hk|ho|hl|nj|np|nl|ml|k|o|i|O|j|p|u|P|h|y|n|b|m|l";
446					var final = {"":0,r:1,R:2,rt:3,s:4,sw:5,sg:6,e:7,f:8,fr:9,fa:10,fq:11,ft:12,fx:13,fv:14,fg:15,a:16,q:17,qt:18,t:19,T:20,d:21,w:22,c:23,z:24,x:25,v:26,g:27}
447					var regFinal = "rt|sw|sg|fr|fa|fq|ft|fx|fv|fg|qt|r|R|s|e|f|a|q|t|T|d|w|c|z|x|v|g|";
448					
449					var reg_exp = new RegExp("("+regInitial+")("+regMedial+")((?:"+regFinal+")(?=(?:"+regInitial+")(?:"+regMedial+"))|(?:"+regFinal+"))", "g");
450					
451					var regAlpha =/^[a-zA-Z]+$/;
452					var regHangul =/^[가-힣]+$/;
453					
454					temp = str.replace(reg_exp, function replace(str, h, b, f) { return String.fromCharCode(initial.indexOf(h)*21*28 + medial[b]*28 + final[f] + 44032); });
455					
456					if(temp && regHangul.test(temp) && !regAlpha.test(temp)) {
457						str = temp;
458					}
459					
460					return str;
461				}
462			});
463		}
464	}
465})(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.