PageSourceSearch

https://www.mojatvrtka.net/js/jqac.js

js mojatvrtka.net collected 2026-10-02 23:07:43 UTC 14,338 bytes, 477 lines download raw bytes

1
2(function($) {
3
4// some key codes
5 var RETURN = 13;
6 var TAB = 9;
7 var ESC = 27;
8 var ARRLEFT = 37;
9 var ARRUP = 38;
10 var ARRRIGHT = 39;
11 var ARRDOWN = 40;
12 var BACKSPACE = 8;
13 var DELETE = 46;
14 
15function debug(s){
16  $('#info').append(htmlspecialchars(s)+'<br>');
17}
18// getting caret position obj: {start,end}
19function getCaretPosition(obj){
20  var start = -1;
21  var end = -1;
22  if(typeof obj.selectionStart != "undefined"){
23    start = obj.selectionStart;
24    end = obj.selectionEnd;
25  }
26  else if(document.selection&&document.selection.createRange){
27    var M=document.selection.createRange();
28    var Lp;
29    try{
30      Lp = M.duplicate();
31      Lp.moveToElementText(obj);
32    }catch(e){
33      Lp=obj.createTextRange();
34    }
35    Lp.setEndPoint("EndToStart",M);
36    start=Lp.text.length;
37    if(start>obj.value.length)
38      start = -1;
39    
40    Lp.setEndPoint("EndToStart",M);
41    end=Lp.text.length;
42    if(end>obj.value.length)
43      end = -1;
44  }
45  return {'start':start,'end':end};
46}
47// set caret to
48function setCaret(obj,l){
49  obj.focus();
50  if (obj.setSelectionRange){
51    obj.setSelectionRange(l,l);
52  }
53  else if(obj.createTextRange){
54    m = obj.createTextRange();      
55    m.moveStart('character',l);
56    m.collapse();
57    m.select();
58  }
59}
60// prepare array with velued objects
61// required properties are id and value
62// rest of properties remaines
63function prepareArray(jsondata){
64  var new_arr = [];
65  for(var i=0;i<jsondata.length;i++){
66    if(jsondata[i].id != undefined && jsondata[i].value != undefined){
67      jsondata[i].id = jsondata[i].id+"";
68      jsondata[i].value = jsondata[i].value+"";
69      if(jsondata[i].info != undefined)
70        jsondata[i].info = jsondata[i].info+"";
71      new_arr.push(jsondata[i]);
72    }
73  }
74  return new_arr;
75}
76// php analogs
77function escapearg(s){
78  if(s == undefined || !s) return '';
79  return s.replace('\\','\\\\').
80           replace('*','\\*').
81           replace('.','\\.').
82           replace('/','\\/');
83}
84function htmlspecialchars(s){
85  if(s == undefined || !s) return '';
86  return s.replace('&','&amp;').
87           replace('<','&lt;').
88           replace('>','&gt;');
89}
90function ltrim(s){
91  if(s == undefined || !s) return '';
92  return s.replace(/^\s+/g,'');
93}
94
95// extending jQuery
96$.fn.autocomplete = function(options){ return this.each(function(){
97  // take me
98  var me = $(this);
99  var me_this = $(this).get(0);
100
101  // test for supported text elements
102  if(!me.is('input:text,input:password,textarea'))
103  return;
104
105  // get or ajax_get required!
106  if(!options && (!$.isFunction(options.get) || !options.ajax_get)){
107  return;
108  }  
109  // check plugin enabled
110  if(me.attr('jqac') == 'on') return;
111
112  // plugin on!
113  me.attr('jqac','on');
114
115  // no browser's autocomplete!
116  me.attr('autocomplete','off');
117
118  // default options
119  options = $.extend({ 
120                      delay     : 250 ,
121                      timeout   : 15000 ,
122                      minchars  : 3 ,
123                      multi     : false ,
124                      cache     : true , 
125                      height    : 250 ,
126                      autowidth : false ,
127                      noresults : 'no result'
128                      },
129                      options);
130
131  // bind key events
132  // handle special keys here
133  me.keydown(function(ev){
134    switch(ev.which){
135      // return choose highlighted item or default propogate
136      case RETURN:
137        if(!suggestions_menu) return true;
138        else setHighlightedValue();
139        return false;
140      // escape clears menu
141      case ESC:
142        clearSuggestions();
143        return false;
144    }
145    return true;
146  });
147  me.keypress(function(ev){
148    // ev.which doesn't work here - it always returns 0
149    switch(ev.keyCode){
150      case RETURN: case ESC:
151        return false;
152      // up changes highlight
153      case ARRUP:
154        changeHighlight(ev.keyCode);
155        return false;
156      // down changes highlight or open new menu
157      case ARRDOWN:
158        if(!suggestions_menu) getSuggestions(getUserInput());
159        else changeHighlight(ev.keyCode);
160        return false;
161     }
162     return true;
163  });
164  // handle normal characters here
165  me.keyup(function(ev) {
166      switch(ev.which) {
167        case RETURN: case ESC: case ARRLEFT: case ARRRIGHT: case ARRUP: case ARR
167DOWN:
168          return false;
169        default:
170          getSuggestions(getUserInput());
171      }
172      return true;
173  });
174
175  // init variables
176  var user_input = "";
177  var input_chars_size  = 0;
178  var suggestions = [];
179  var current_highlight = 0;
180  var suggestions_menu = false;
181  var suggestions_list = false;
182  var loading_indicator = false;
183  var clearSuggestionsTimer = false;
184  var getSuggestionsTimer = false;
185  var showLoadingTimer = false;
186  var zIndex = me.css('z-index');
187
188  // get user input
189  function getUserInput(){
190    var val = me.val();
191    if(options.multi){
192      var pos = getCaretPosition(me_this);
193      var start = pos.start;
194      for(;start>0 && val.charAt(start-1) != ',';start--){}
195      var end = pos.start;
196      for(;end<val.length && val.charAt(end) != ',';end++){}
197      var val = val.substr(start,end-start);
198    }
199    return ltrim(val);
200  }
201  // set suggestion
202  function setSuggestion(val){
203    user_input = val;
204    if(options.multi){
205      var orig = me.val();
206      var pos = getCaretPosition(me_this);
207      var start = pos.start;
208      for(;start>0 && orig.charAt(start-1) != ',';start--){}
209      var end = pos.start;
210      for(;end<orig.length && orig.charAt(end) != ',';end++){}
211      var new_val = orig.substr(0,start) + (start>0?' ':'') + val + orig.substr(end);
212      me.val(new_val);
213      setCaret(me_this,start + val.length + (start>0?1:0));
214    }
215    else{
216      me_this.focus();
217      me.val(val);
218    }
219  }
220  // get suggestions
221  function getSuggestions(val){
222    // input length is less than the min required to trigger a request
223    // reset input string
224    // do nothing
225    if (val.length < options.minchars){
226      clearSuggestions();
227      return false;
228    }
229    // if caching enabled, and user is typing (ie. length of input is increasing)
230    // filter results out of suggestions from last request
231    if (options.cache && val.length > input_chars_size && suggestions.length){
232      var arr = [];
233      for (var i=0;i<suggestions.length;i++){
234        var re = new RegExp("("+escapearg(val)+")",'ig');
235        if(re.exec(suggestions[i].value))
236          arr.push( suggestions[i] );
237      }
238      user_input = val;
239      input_chars_size = val.length;
240      suggestions = arr;
241      createList(suggestions);
242      return false;
243    }
244    else{// do new request
245      clearTimeout(getSuggestionsTimer);
246      user_input = val;
247      input_chars_size = val.length;
248      getSuggestionsTimer = setTimeout( 
249        function(){ 
250          suggestions = [];
251          // call pre callback, if exists
252          if($.isFunction(options.pre_callback))
253            options.pre_callback();
254          // call get
255          if($.isFunction(options.get)){
256            suggestions = prepareArray(options.get(val));
257            createList(suggestions);
258          }
259          // call AJAX get
260          else if($.isFunction(options.ajax_get)){
261            clearSuggestions();
262            showLoadingTimer = setTimeout(show_loading,options.delay);
263            options.ajax_get(val,ajax_continuation);
264          }
265        },
266        options.delay );
267    }
268    return false;
269  };
270  // AJAX continuation
271  function ajax_continuation(jsondata){
272    hide_loading();
273    suggestions = prepareArray(jsondata);
274    createList(suggestions);
275  }
276  // shows loading indicator
277  function show_loading(){
278    if(!loading_indicator){
279      loading_indicator = $('<div class="jqac-menu"><div class="jqac-loading"></div></div>').get(0);
280      $(loading_indicator).css('position','absolute');
281      var pos = me.offset();
282      $(loading_indicator).css('left', pos.left + "px");
283      $(loading_indicator).css('top', ( pos.top + me.height() + 2 ) + "px");
284      if(!options.autowidth)
285        $(loading_indicator).width(me.width());
286      $('body').append(loading_indicator);
287    }
288    $(loading_indicator).show();
289    setTimeout(hide_loading,10000);
290  }
291  // hides loading indicator 
292  function hide_loading(){
293    if(loading_indicator)
294      $(loading_indicator).hide();
295    clearTimeout(showLoadingTimer);
296  }
297  // create suggestions list
298  function createList(arr){
299    if(suggestions_menu)
300      $(suggestions_menu).remove();
301    hide_loading();
302    killTimeout();
303
304    // create holding div
305    suggestions_menu = $('<div class="jqac-menu"></div>').get(0);
306
307    // ovveride some necessary CSS properties 
308    $(suggestions_menu).css({'position':'absolute',
309                             'z-index':zIndex,
310                             'max-height':options.height+'px',
311                             'overflow-y':'auto'});
312
313    // create and populate ul
314    suggestions_list = $('<ul class="dropdown"></ul>').get(0);
315    // set some CSS's
316    $(suggestions_list).
317      css('list-style','none').
318      css('margin','0px').
319      css('padding','2px').
320      css('overflow','hidden');
321    // regexp for replace 
322    var re = new RegExp("("+escapearg(htmlspecialchars(user_input))+")",'ig');
323    // loop throught arr of suggestions creating an LI element for each suggestion
324    for (var i=0;i<arr.length;i++){
325      var val = new String(arr[i].value);
326      // using RE
327      var output = htmlspecialchars(val).replace(re,'<em>$1</em>');
328      // using substr
329      //var st = val.toLowerCase().indexOf( user_input.toLowerCase() );
330      //var len = user_input.length;
331      //var output = val.substring(0,st)+"<em>"+val.substring(st,st+len)+"</em>"+val.substring(st+len);
332
333      var span = $('<span class="jqac-link">'+output+'</span>').get(0);
334      if (arr[i].info != undefined && arr[i].info != ""){
335        $(span).append($('<div class="jqac-info">'+arr[i].info+'</div>'));
336      }
337
338      $(span).attr('name',i+1);
339      $(span).click(function () { setHighlightedValue(); });
340      $(span).mouseover(function () { setHighlight($(this).attr('name'),true); });
341
342      var li = $('<li></li>').get(0);
343      $(li).append(span);
344
345      $(suggestions_list).append(li);
346    }
347
348    // no results
349    if (arr.length == 0){
350      $(suggestions_list).append('<li class="jqac-warning">'+options.noresults+'</li>');
351    }
352
353    $(suggestions_menu).append(suggestions_list);
354
355    // get position of target textfield
356    // position holding div below it
357    // set width of holding div to width of field
358    var pos = me.offset();
359
360    $(suggestions_menu).css('left', pos.left + "px");
361    $(suggestions_menu).css('top', ( pos.top + me.height() + 2 ) + "px");
362    if(!options.autowidth)
363      $(suggestions_menu).width(me.width());
364
365    // set mouseover functions for div
366    // when mouse pointer leaves div, set a timeout to remove the list after an interval
367    // when mouse enters div, kill the timeout so the list won't be removed
368    $(suggestions_menu).mouseover(function(){ killTimeout() });
369    $(suggestions_menu).mouseout(function(){ resetTimeout() });
370
371    // add DIV to document
372    $('body').append(suggestions_menu);
373
374    // bgIFRAME support
375    if($.fn.bgiframe)
376      $(suggestions_menu).bgiframe({height: suggestions_menu.scrollHeight});
377
378
379    // adjust height: add +20 for scrollbar
380    if(suggestions_menu.scrollHeight > options.height){
381      $(suggestions_menu).height(options.height);
382      $(suggestions_menu).width($(suggestions_menu).width()+20);
383    }
384	
385    // currently no item is highlighted
386    current_highlight = 0;
387
388    // remove list after an interval
389    clearSuggestionsTimer = setTimeout(function () { clearSuggestions() }, options.timeout);
390  };
391  // set highlighted value
392  function setHighlightedValue(){
393    if(current_highlight && suggestions[current_highlight-1]){
394      var sugg = suggestions[ current_highlight-1 ];
395      if(sugg.affected_value != undefined && sugg.affected_value != '')
396        setSuggestion(sugg.affected_value);
397      else
398        setSuggestion(sugg.value);
399      // pass selected object to callback function, if exists
400      if ($.isFunction(options.callback))
401        options.callback( suggestions[current_highlight-1] );
402
403      clearSuggestions();
404    }
405  };
406  // change highlight according to key
407  function changeHighlight(key){	
408    if(!suggestions_list || suggestions.length == 0) return false;
409    var n;
410    if (key == ARRDOWN)
411      n = current_highlight + 1;
412    else if (key == ARRUP)
413      n = current_highlight - 1;
414
415    if (n > $(suggestions_list).children().size())
416      n = 1;
417    if (n < 1)
418      n = $(suggestions_list).children().size();
419    setHighlight(n);
420  };
421  // change highlight
422  function setHighlight(n,mouse_mode){
423    if (!suggestions_list) return false;
424    if (current_highlight > 0) clearHighlight();
425    current_highlight = Number(n);
426    var li = $(suggestions_list).children().get(current_highlight-1);
427    li.className = 'jqac-highlight';
428    // for mouse mode don't adjust scroll! prevent scrolling jumps
429    if(!mouse_mode) adjustScroll(li);
430    killTimeout();
431  };
432  // clear highlight
433  function clearHighlight(){
434    if (!suggestions_list)return false;
435    if (current_highlight > 0){
436      $(suggestions_list).children().get(current_highlight-1).className = '';
437      current_highlight = 0;
438    }
439  };
440  // clear suggestions list
441  function clearSuggestions(){
442    killTimeout();
443    if(suggestions_menu){
444      $(suggestions_menu).remove();
445      suggestions_menu = false;
446      suggestions_list = false;
447      current_highlight = 0;
448    }
449  };
450  // set scroll
451  function adjustScroll(el){
452    if(!suggestions_menu) return false;
453    var viewportHeight = suggestions_menu.clientHeight;        
454    var wholeHeight = suggestions_menu.scrollHeight;
455    var scrolled = suggestions_menu.scrollTop;
456    var elTop = el.offsetTop;
457    var elBottom = elTop + el.offsetHeight;
458    if(elBottom > scrolled + viewportHeight){
459      suggestions_menu.scrollTop = elBottom - viewportHeight;
460    }
461    else if(elTop < scrolled){
462      suggestions_menu.scrollTop = elTop;
463    }
464    return true; 
465  }
466  // timeout funcs
467  function killTimeout(){
468    clearTimeout(clearSuggestionsTimer);
469  };
470  function resetTimeout(){
471    clearTimeout(clearSuggestionsTimer);
472    clearSuggestionsTimer = setTimeout(function () { clearSuggestions() }, 1000);
473  };
474
475})};
476
477})($);

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.