PageSourceSearch

https://www.ipko.com/wp-content/uploads/ac_assets/ue_ajax_search/ue_ajax_search.js

js ipko.com collected 2026-09-24 09:38:14 UTC 29,942 bytes, 1,242 lines download raw bytes

1function UEAjaxSearch(){
2  
3  var g_objWrapper, g_urlBase, g_cache = {}, g_objInput, g_searchItemIndex, g_objSearchBtn, g_pageNumber, g_paginationList, g_paginationInner, g_paginationHeader, g_postItem, g_activeItemClass, g_inActiveItemClass, g_arrowLeft, g_arrowRight, g_selectedItemClass, g_activePageIndex, g_homeUrl, g_objSuggested, g_objSuggestedLinks;
4  var g_objItemsWrapper, g_objError;
5  
6  var g_vars = {
7    CLASS_DIV_DEBUG:"uc-div-ajax-debug"
8  };
9  
10  var g_temp = {
11    handle: null,
12    trashold:500,
13    lastRequest:null
14  };
15  
16  
17  /**
18  * console log
19  */
20  function trace(str){
21    
22    console.log(str);
23  }
24  
25  /**
26  * run function with trashold
27  */
28  function runWithTrashold(func, trashold){
29    
30    if(g_temp.handle)
31    clearTimeout(g_temp.handle);
32    
33    g_temp.handle = setTimeout(func, g_temp.trashold);
34    
35  };
36  
37  /**
38  * replace all occurances
39  */
40  function replaceAll(text, from, to){
41    
42    return text.split(from).join(to);		
43  };
44  
45  
46  /**
47  * add url param
48  */
49  function addUrlParam(url, param, value){
50    
51    if(url.indexOf("?") == -1)
52    url += "?";
53    else
54    url += "&";
55    
56    if(typeof value == "undefined")
57    url += param;
58    else	
59    url += param + "=" + value;
60    
61    return(url);
62  }
63  
64  
65  /**
66  * get object property
67  */
68  function getVal(obj, name, defaultValue){
69    
70    if(!defaultValue)
71    var defaultValue = "";
72    
73    var val = "";
74    
75    if(!obj || typeof obj != "object")
76    val = defaultValue;
77    else if(obj.hasOwnProperty(name) == false){
78      val = defaultValue;
79    }else{
80      val = obj[name];			
81    }
82    
83    return(val);
84  }
85  
86  function ___________AJAX____________(){}
87  
88  /**
89  * show ajax error, should be something visible
90  */
91  function showAjaxError(message){
92    
93    g_objWrapper.removeClass("uc-loading");
94    
95    g_objError.show();
96    g_objError.html(message);
97    
98  }
99  
100  /**
101  * get the debug object
102  */
103  
104  function getDebugObject(){
105    
106    var objDebug = g_objWrapper.siblings("."+g_vars.CLASS_DIV_DEBUG);
107    
108    if(objDebug.length)
109    return(objDebug);
110    
111    //insert if not exists
112    
113    g_objWrapper.after("<div class='"+g_vars.CLASS_DIV_DEBUG+"' style='padding:10px;display:none;background-color:#D8FCC6'></div>");
114    
115    var objDebug = jQuery("body").find("."+g_vars.CLASS_DIV_DEBUG);
116    
117    return(objDebug);
118  }
119  
120  /**
121  * show ajax debug
122  */
123  function showAjaxDebug(str){
124    
125    trace("Ajax Error! - Check the debug");
126    
127    str = jQuery.trim(str);
128    
129    if(!str || str.length == 0)
130    return(false);
131    
132    var objStr = jQuery(str);
133    
134    if(objStr.find("header").length || objStr.find("body").length){
135      str = "Wrong ajax response!";
136    }
137    
138    var objDebug = getDebugObject();
139    
140    if(!objDebug || objDebug.length == 0){
141      
142      alert(str);
143      
144      throw new Error("debug not found");
145    }
146    
147    g_objItemsWrapper.hide();
148    
149    objDebug.show();
150    objDebug.html(str);
151    
152    
153  }
154  
155  /**
156  * get response from ajax cache
157  */
158  function getResponseFromAjaxCache(ajaxUrl, action, objData){
159    
160    var cacheKey = getAjaxCacheKey(ajaxUrl, action, objData);
161    
162    if(!cacheKey)
163    return(false);
164    
165    var response = getVal(g_cache, cacheKey);
166    
167    return(response);
168  }
169  
170  /**
171  * get ajax url
172  */
173  function getAjaxCacheKeyFromUrl(ajaxUrl){
174    
175    var key = ajaxUrl;
176    
177    key = key.replace(g_urlBase, "");
178    
179    //replace special signs
180    key = replaceAll(key, "/","");
181    key = replaceAll(key, "?","_");
182    key = replaceAll(key, "&","_");
183    key = replaceAll(key, "=","_");
184    
185    return(key);
186  }
187  
188  
189  /**
190  * get ajax cache key
191  */
192  function getAjaxCacheKey(ajaxUrl, action, objData){
193    
194    //cache only by url meanwhile
195    
196    if(jQuery.isEmptyObject(objData) == false)
197    return(false);
198    
199    if(action)
200    return(false);
201    
202    var cacheKey = getAjaxCacheKeyFromUrl(ajaxUrl);
203    
204    if(!cacheKey)
205    return(false);
206    
207    return(cacheKey);
208  }
209  
210  
211  /**
212  * cache ajax response
213  */
214  function cacheAjaxResponse(ajaxUrl, action, objData, response){
215    
216    var cacheKey = getAjaxCacheKey(ajaxUrl, action, objData);
217    
218    if(!cacheKey)
219    return(false);
220    
221    //some precoutions for overload
222    if(g_cache.length > 100)
223    return(false);
224    
225    g_cache[cacheKey] = response;
226    
227  }
228  
229  
230  /**
231  * small ajax request
232  */
233  function ajaxRequest(ajaxUrl, action, objData, onSuccess){
234    
235    if(!objData)
236    var objData = {};
237    
238    if(typeof objData != "object")
239    throw new Error("wrong ajax param");
240    
241    //check response from cache
242    var responseFromCache = getResponseFromAjaxCache(ajaxUrl, action, objData);
243    
244    if(responseFromCache){
245      
246      //simulate ajax request
247      setTimeout(function(){
248        onSuccess(responseFromCache);
249      }, 300);
250      
251      return(false);
252    }		
253    
254    var ajaxData = {};
255    ajaxData["action"] = "unlimitedelements_ajax_action";
256    ajaxData["client_action"] = action;
257    
258    var ajaxtype = "get";
259    
260    if(jQuery.isEmptyObject(objData) == false){
261      ajaxData["data"] = objData;
262      ajaxtype = "post";
263    }
264    
265    var ajaxOptions = {
266      type:ajaxtype,
267      url:ajaxUrl,
268      success:function(response){
269        
270        if(!response){
271          showAjaxError("Empty ajax response!");
272          return(false);					
273        }
274        
275        if(typeof response != "object"){
276          
277          try{
278            
279            response = jQuery.parseJSON(response);
280            
281          }catch(e){
282            
283            showAjaxDebug(response);
284            
285            showAjaxError("Ajax Error!!! not ajax response");
286            return(false);
287          }
288        }
289        
290        if(response == -1){
291          showAjaxError("ajax error!!!");
292          return(false);
293        }
294        
295        if(response == 0){
296          showAjaxError("ajax error, action: <b>"+action+"</b> not found");
297          return(false);
298        }
299        
300        if(response.success == undefined){
301          showAjaxError("The 'success' param is a must!");
302          return(false);
303        }
304        
305        
306        if(response.success == false){
307          showAjaxError(response.message);
308          return(false);
309        }
310        
311        cacheAjaxResponse(ajaxUrl, action, objData, response);
312        
313        if(typeof onSuccess == "function"){
314          
315          onSuccess(response);
316        }
317        
318      },
319      error:function(jqXHR, textStatus, errorThrown){
320        
321        switch(textStatus){
322          case "parsererror":
323          case "error":
324          
325          //showAjaxError("parse error");
326          
327          showAjaxDebug(jqXHR.responseText);
328          
329          break;
330        }
331      }
332    }
333    
334    if(ajaxtype == "post"){
335      ajaxOptions.dataType = 'json';
336      ajaxOptions.data = ajaxData
337    }
338    
339    if(g_temp.currentRequest)
340    g_temp.currentRequest.abort();
341    
342    g_temp.currentRequest = jQuery.ajax(ajaxOptions);
343    
344  }
345  
346  function ____________ACTIONS___________(){}
347  
348  /**
349  * clear all parts
350  */
351  function clearAll(){
352    
353    g_objItemsWrapper.hide();
354    g_objError.hide();
355  }
356  
357  
358  /**
359  * get the request url
360  */
361  function getAjaxRequestUrl(){
362    
363    var searchValue = g_objInput.val();
364    searchValue = encodeURIComponent(searchValue);
365    
366    if(!searchValue){
367      clearAll();
368      return(false);
369    }
370    
371    var objWidget = g_objWrapper.parents(".elementor-widget");
372    
373    if(objWidget.length == 0)
374    throw new Error("widget not found");
375    
376    var elementID = objWidget.data("id");
377    
378    if(!elementID)
379    throw new Error("element id not found");
380    
381    var objLayout = g_objWrapper.parents(".elementor");
382    
383    if(objLayout.length == 0)
384    throw new Error("Layout not found");
385    
386    var layoutID = objLayout.data("elementor-id");
387    
388    if(!layoutID)
389    throw new Error("Layout ID not found");
390    
391    
392    var url = g_urlBase;
393    url = addUrlParam(url, "ucfrontajaxaction", "ajaxsearch");
394    url = addUrlParam(url, "ucs", searchValue);
395    url = addUrlParam(url, "layoutid", layoutID);
396    url = addUrlParam(url, "elid", elementID);
397    
398    var addUrlFilters = g_objWrapper.triggerHandler("uc_get_filters_url");
399    
400    if(addUrlFilters)
401    url += "&"+addUrlFilters;
402    
403    
404    return(url);
405  }
406  
407  /**
408  * replace the grid debug
409  */
410  function operateAjax_setHtmlDebug(response, objGrid){
411    
412    //replace the debug
413    var htmlDebug = getVal(response, "html_debug");
414    
415    if(!htmlDebug)
416    return(false);
417    
418    var objDebug = objGrid.siblings(".uc-debug-query-wrapper");
419    
420    if(objDebug.length == 0)
421    return(false);
422    
423    objDebug.replaceWith(htmlDebug);
424  }
425  
426  /**
427  * handle the response
428  */
429  function handleResponse(response){
430    
431    var htmlItems = getVal(response,"html_items");
432    
433    g_objItemsWrapper.html(htmlItems);
434    
435    g_objItemsWrapper.show();
436    
437    operateAjax_setHtmlDebug(response, g_objWrapper);
438    
439  }
440  
441  /**
442  * format suggested searches
443  */
444  function placeSuggestedSearches(){
445    
446    if(!g_objSuggested.length)
447    return(false);
448    
449    //create an array of suggested searches
450    var suggestedItemsArray = g_objSuggested.text().split(/\r?\n/);
451    var suggestedItemsLength = suggestedItemsArray.length;
452    
453    //empty container
454    g_objSuggested.html("");
455    
456    for(let i=0; i<suggestedItemsLength; i++){    
457      
458      //trim each search
459      suggestedItemsArray[i] = jQuery.trim(suggestedItemsArray[i]);
460      
461      //create html for each search item
462      g_objSuggested.append("<a class='uc-ajax-search__suggested-link' href='javascript:void(0)'>"+suggestedItemsArray[i]+"</a>");
463      
464    }
465    
466    g_objSuggestedLinks = g_objSuggested.find(".uc-ajax-search__suggested-link");
467    
468    //add comma and space after each search item except last one
469    for(let i=0; i<suggestedItemsLength-1; i++){
470      
471      g_objSuggestedLinks.eq(i).append(", ");
472      
473    }
474    
475  }
476  
477  /*
478  * create pagination
479  */ 
480  function createPaginationElement(){
481    
482    var isPaginationExist = g_objItemsWrapper.data('pagination');
483    
484    if(isPaginationExist == false)
485    return(false);
486    
487    if(!g_objItemsWrapper.is(":visible"))
488    return(false);
489    
490    //create main wrapper
491    g_objItemsWrapper.prepend('<div class="uc-pagination-panel"></div>');
492    
493    var paginationPanel = g_objWrapper.find('.uc-pagination-panel');
494    var itemsNumber = g_objItemsWrapper.children().length - 1;
495    
496    //create child elements for main wrapper
497    paginationPanel.append('<div class="uc-pagination-list"></div>');
498    paginationPanel.append('<div class="uc-pagination-footer"></div>');
499    
500    var paginationPosition = g_objItemsWrapper.data('pagination-position');
501    
502    if(paginationPosition == 'before')
503    paginationPanel.prepend('<div class="uc-pagination-header"></div>');
504    
505    if(paginationPosition == 'after')
506    paginationPanel.append('<div class="uc-pagination-header"></div>');
507    
508    
509    g_paginationHeader = g_objWrapper.find('.uc-pagination-header');
510    g_paginationList = g_objWrapper.find('.uc-pagination-list');      
511    var paginationFooter = g_objWrapper.find('.uc-pagination-footer');
512    
513    var itemsPerPage = g_objItemsWrapper.data('num-items');
514    
515    var resultsText = g_objItemsWrapper.data('results-text');
516    
517    //display number of all results
518    if(itemsNumber == 0){
519      
520      var noResultsText = g_objItemsWrapper.data('no-results-text');
521      
522      g_paginationHeader.prepend('<div class="uc-ajax-search-results">' + noResultsText + '</div>');
523      
524    }else if(itemsNumber == 1){
525      
526      g_paginationHeader.prepend('<div class="uc-ajax-search-results">' + itemsNumber + ' ' + resultsText + '</div>');
527      
528    }else{
529      
530      g_paginationHeader.prepend('<div class="uc-ajax-search-results"></div>');
531      
532      var resultsElement = g_objWrapper.find('.uc-ajax-search-results');
533      
534      //count current / total results
535      var firstNum = itemsPerPage * (g_activePageIndex + 1) - itemsPerPage + 1;
536      var lastNum = itemsPerPage * (g_activePageIndex + 1);
537      
538      if(lastNum > itemsNumber && itemsPerPage < itemsNumber)
539      lastNum = itemsNumber
540      
541      if(firstNum == itemsNumber && itemsPerPage < itemsNumber)
542      resultsElement.text(firstNum + '/' + itemsNumber);
543      else if(itemsPerPage >= itemsNumber )
544      resultsElement.text(itemsNumber + ' ' + resultsText);
545      else
546      resultsElement.text(firstNum + '-' + lastNum + '/' + itemsNumber);
547      
548    }
549    
550    //create navigation
551    g_paginationHeader.append('<div class="uc-ajax-search-navigation-panel"></div>');
552    
553    //create navigation panel for pages and arrows
554    var paginationPanel = g_objWrapper.find('.uc-ajax-search-navigation-panel');
555    
556    //create pages and arrows wrapper elements
557    paginationPanel.append('<div class="uc-ajax-search-pages"></div>');
558    paginationPanel.append('<div class="uc-ajax-arrows"></div>');
559    
560    //if amount of search items is less or equal to amount of items per page then append search items to only one wrapper element 
561    //and stop any furter function execution
562    if(itemsNumber <= itemsPerPage){
563      
564      g_paginationList.append('<div class="uc-pagination-list-inner"></div>');
565      
566      g_paginationInner = g_objItemsWrapper.find('.uc-pagination-list-inner');
567      var searchItems = g_objItemsWrapper.find('.uc-search-item');
568      
569      g_paginationInner.append(searchItems);
570      
571      //add active class to the list of results
572      g_paginationInner.addClass(g_activeItemClass);
573      
574      return(false);
575      
576    }
577    
578    var pageNumber = Math.ceil(itemsNumber / itemsPerPage);
579    var pageWrapper = g_objWrapper.find('.uc-ajax-search-pages');
580    var arrowsWrapper = g_objWrapper.find('.uc-ajax-arrows');
581    
582    //create arrows
583    arrowsWrapper.append('<div class="uc-ajax-arrow-left"></div>');
584    arrowsWrapper.append('<div class="uc-ajax-arrow-right"></div>');
585    
586    g_arrowLeft = g_objWrapper.find('.uc-ajax-arrow-left');
587    g_arrowRight = g_objWrapper.find('.uc-ajax-arrow-right');
588    
589    //add inactive class to left arrow
590    if(g_activePageIndex <= 0 && g_arrowLeft)
591    g_arrowLeft.addClass(g_inActiveItemClass);
592    
593    //create pages
594    for (let page = 1; page <= pageNumber; page++){
595      
596      pageWrapper.append('<a class="uc-page-number" href="javascript:void(0)">' + page + '</a>');
597      g_paginationList.append('<div class="uc-pagination-list-inner"></div>');
598      
599    }
600    
601    g_pageNumber = g_objItemsWrapper.find('.uc-page-number');
602    
603    //add active class to first page
604    g_pageNumber.eq(0).addClass(g_activeItemClass);      
605    
606    g_paginationInner = g_objItemsWrapper.find('.uc-pagination-list-inner');
607    
608    //add active class to the first list of results
609    g_paginationInner.eq(0).addClass(g_activeItemClass);
610    
611    var searchItem = g_objItemsWrapper.find('.uc-search-item');
612    
613    //append result items to created list elements
614    for (let i = itemsPerPage; i <= itemsNumber; i = i + itemsPerPage){
615      
616      var searchItemRange = searchItem.slice(i - itemsPerPage, i);
617      
618      g_paginationInner.eq((i / itemsPerPage) - 1).append(searchItemRange);
619      
620    }
621    
622    //trigger custom event to connect vars to click function
623    g_objItemsWrapper.trigger('pages_created');
624    
625    //apend items to the last page
626    if(itemsNumber % itemsPerPage == 0)
627    return(false);
628    
629    var firstItemIndex = itemsNumber - (itemsNumber % itemsPerPage);
630    var lastItemIndex = itemsNumber;
631    
632    //if only one search item left, then append it and stop function execution
633    if(firstItemIndex == lastItemIndex){
634      
635      g_paginationInner.eq(-1).append(searchItem.eq(lastItemIndex));
636      
637      return(false);
638      
639    }
640    
641    //append the rest of search items to the last wrapper element
642    var searchItemLastRange = searchItem.slice(firstItemIndex, lastItemIndex);
643    
644    g_paginationInner.eq(-1).append(searchItemLastRange);
645    
646  }
647  
648  /*
649  * focus on input click
650  */
651  function onInputClick(){
652    
653    focusOnInput();
654    
655  }
656  
657  /*
658  * translate list page list wrapper on page number click
659  */
660  function onPageNumberClick(){
661    
662    var objNumber = jQuery(this);
663    var objNumberIndex = objNumber.index();
664    
665    //sync active page index
666    g_activePageIndex = objNumberIndex;
667    
668    if(g_pageNumber)
669    var pageNumber = g_pageNumber.length - 1;
670    
671    //set inactive class to navigation arrows
672    if(g_arrowLeft)
673    g_arrowLeft.removeClass(g_inActiveItemClass);
674    
675    if(g_arrowRight)
676    g_arrowRight.removeClass(g_inActiveItemClass);
677    
678    if(g_activePageIndex >= pageNumber && g_arrowRight)
679    g_arrowRight.addClass(g_inActiveItemClass);
680    
681    if(g_activePageIndex <= 0 && g_arrowLeft)
682    g_arrowLeft.addClass(g_inActiveItemClass);
683    
684    setActive();
685    
686  }
687  
688  /*
689  * set active item
690  */
691  function setActive(){
692    
693    var totalPageNumber = g_paginationInner.length;
694    
695    if(totalPageNumber <= 1)
696    return(false);
697    
698    //set active class to current page
699    g_pageNumber.removeClass(g_activeItemClass);
700    g_pageNumber.eq(g_activePageIndex).addClass(g_activeItemClass);
701    
702    //set active class to current list item
703    g_paginationInner.removeClass(g_activeItemClass);
704    g_paginationInner.eq(g_activePageIndex).addClass(g_activeItemClass);
705    
706    //reset search item index
707    g_searchItemIndex = 0;
708    
709    //translate list considering page direction
710    var isDirectionRtl = jQuery("body").hasClass("rtl");
711    
712    if(isDirectionRtl == false){
713      g_paginationList.css({
714        'transform': 'translate(-' + g_activePageIndex + '00%, 0)'
715      });
716    }
717    
718    if(isDirectionRtl == true){
719      g_paginationList.css({
720        'transform': 'translate(' + g_activePageIndex + '00%, 0)'
721      });
722    }
723    
724    var totalItems = g_objWrapper.find('.uc-search-item').length;
725    
726    if(totalItems == 1)
727    return(false);
728    
729    var resultsElement = g_objWrapper.find('.uc-ajax-search-results');
730    var itemsPerPage = g_objItemsWrapper.data('num-items');
731    
732    //count current / total results
733    var firstNum = itemsPerPage * (g_activePageIndex + 1) - itemsPerPage + 1;
734    var lastNum = itemsPerPage * (g_activePageIndex + 1);
735    
736    if(lastNum > totalItems)
737    lastNum = totalItems;
738    
739    if(firstNum == totalItems)
740    resultsElement.text(firstNum + '/' + totalItems);
741    else
742    resultsElement.text(firstNum + '-' + lastNum + '/' + totalItems);
743    
744  }
745  
746  /*
747  * translate list page list wrapper on arrows number click
748  */
749  function onArrowLeftClick(){
750    
751    if(g_arrowRight)
752    g_arrowRight.removeClass(g_inActiveItemClass);
753    
754    g_activePageIndex--; 
755    
756    if(g_activePageIndex <= 0){
757      
758      g_activePageIndex = 0;
759      
760      if(g_arrowLeft)
761      g_arrowLeft.addClass(g_inActiveItemClass);
762      
763    }
764    
765    setActive();   
766    
767  }
768  
769  /*
770  * translate list page list wrapper on arrows number click
771  */
772  function onArrowRightClick(){
773    
774    if(g_arrowLeft)
775    g_arrowLeft.removeClass(g_inActiveItemClass);
776    
777    g_activePageIndex++; 
778    
779    if(g_pageNumber)
780    var pageNumber = g_pageNumber.length - 1;
781    
782    if(g_activePageIndex >= pageNumber){
783      
784      g_activePageIndex = pageNumber;
785      
786      if(g_arrowRight)
787      g_arrowRight.addClass(g_inActiveItemClass);
788      
789    }
790    
791    setActive();
792    
793  }
794  
795  /**
796  * do the search itself
797  */
798  function doSearch(){
799    
800    //combine the url
801    var url = getAjaxRequestUrl();
802    
803    //if search phrase is empty then do not search
804    if(g_objInput.val() == '')
805    return(false);
806    
807    if(!url)
808    throw new Error("Error in ajax url");
809    
810    //ajax search
811    g_objError.hide();
812    g_objItemsWrapper.hide();
813    
814    g_objWrapper.addClass("uc-loading");
815    
816    ajaxRequest(url, null, null, function(response){
817      
818      g_objWrapper.removeClass("uc-loading");
819      
820      handleResponse(response);
821      
822      g_objInput.data('lastphrase', g_objInput.val());
823      
824      createPaginationElement();
825      
826      highlightSearchTerm(g_objInput.val());
827      
828    });
829    
830    
831  }
832  
833  /**
834  * focus on input
835  */
836  function focusOnInput(){
837    
838    g_objInput.addClass(g_activeItemClass);
839    
840  }
841  
842  function markSubstring(objResultText, text, substring) {
843
844    let regex = new RegExp(substring, "gi");
845    
846    //capitalize protection
847    var isCapitalized = objResultText.css('text-transform') == 'capitalize';
848
849    return text.replace(regex, (match) => {
850
851      if(isCapitalized == false)
852      return "<b>" + match + "</b>"
853      
854      if(isCapitalized == true)
855      return "<b class='uc-capitalized'>" + match + "</b>"
856
857    });
858
859  }
860  
861  /*
862  * highlight searct term in results
863  */
864  function highlightSearchTerm(searchTerm){
865    
866    var boldSearchPhrase = g_objItemsWrapper.data("bold-phrase");
867    
868    if(boldSearchPhrase == false)
869    return(false);
870    
871    var resultTitles = g_objItemsWrapper.find(".uc-search-item__link-title");
872    
873    resultTitles.each(function(){
874      
875      var objResultText = jQuery(this);
876      var resultTitleText = objResultText.text();
877      
878      var highlightedText = markSubstring(objResultText, resultTitleText, searchTerm);      
879      
880      objResultText.html(highlightedText);
881      
882    });
883    
884  }
885  
886  /**
887  * on keyup - run the search with treshold
888  */
889  function onInputChange(){
890    
891    var newPhrase = g_objInput.val();
892    var lastPhrase = g_objInput.data('lastphrase');
893    
894    checkInput();
895    
896    var isSearchWindowClosed = !g_objItemsWrapper.is(":visible");
897    
898    //if dropdown is visible then do not search same results
899    if(isSearchWindowClosed == false){
900      
901      if(jQuery.trim(lastPhrase) == jQuery.trim(newPhrase))
902      return(false);
903      
904    } 
905    
906    g_objItemsWrapper.hide();
907    
908    runWithTrashold(doSearch);
909    
910    g_searchItemIndex = -1;
911    
912    
913  }
914  
915  /*
916  ** navigate dropdown
917  */
918  function onKeyDown(e){
919    
920    if(!g_objInput.is(":focus"))
921    return(false);
922    
923    var isKeysActivated = g_objItemsWrapper.data('keys');
924    
925    if(isKeysActivated == false)
926    return(true);
927    
928    if(!g_objItemsWrapper.is(":visible"))
929    return(true);
930    
931    if(e.keyCode == 37 || e.keyCode == 39){
932      
933      if(g_objInput.hasClass(g_activeItemClass))
934      return(true);
935      
936      if(e.keyCode == 37)
937      g_activePageIndex--; 
938      
939      if(e.keyCode == 39)
940      g_activePageIndex++; 
941      
942      if(g_pageNumber)
943      var pageNumber = g_pageNumber.length - 1;
944      
945      if(g_arrowLeft)
946      g_arrowLeft.removeClass(g_inActiveItemClass);
947      
948      if(g_arrowRight)
949      g_arrowRight.removeClass(g_inActiveItemClass);
950      
951      if(g_activePageIndex >= pageNumber){
952        
953        g_activePageIndex = pageNumber;
954        
955        if(g_arrowRight)
956        g_arrowRight.addClass(g_inActiveItemClass);
957        
958      }
959      
960      if(g_activePageIndex <= 0){
961        
962        g_activePageIndex = 0;
963        
964        if(g_arrowLeft)
965        g_arrowLeft.addClass(g_inActiveItemClass);
966        
967      }
968      
969      setActive();
970      
971    }
972    
973    var itemsMaxNumber;
974    
975    g_postItem = g_objItemsWrapper.find('.uc-pagination-list-inner.uc-active .uc-search-item');
976    itemsMaxNumber = g_objItemsWrapper.find('.uc-pagination-list-inner.uc-active').children().length;
977    
978    var postItemNumber = g_postItem.length;
979    
980    if(e.keyCode == 40 || e.keyCode == 38 || e.keyCode == 13 || e.keyCode == 8 && !g_objInput.hasClass(g_activeItemClass) || e.keyCode == 27 || e.keyCode == 37 || e.keyCode == 39){
981      
982      e.preventDefault();
983      
984    }else{
985      
986      g_searchItemIndex = postItemNumber;
987      
988      focusOnInput();
989      
990    }
991    
992    if(e.keyCode != 37 || e.keyCode != 39)
993    g_postItem.removeClass(g_selectedItemClass); 
994    
995    if(e.keyCode == 40)
996    g_searchItemIndex++;   
997    
998    if(e.keyCode == 38)
999    g_searchItemIndex--;
1000    
1001    if(g_searchItemIndex < -1)
1002    g_searchItemIndex = itemsMaxNumber - 1;
1003    
1004    if(g_searchItemIndex == -1)        
1005    g_searchItemIndex = itemsMaxNumber;
1006    
1007    if(g_searchItemIndex > postItemNumber || g_searchItemIndex > itemsMaxNumber)
1008    g_searchItemIndex = 0;      
1009    
1010    if(g_searchItemIndex >= itemsMaxNumber && e.keyCode == 38 || g_searchItemIndex >= itemsMaxNumber && e.keyCode == 40){
1011      
1012      focusOnInput();
1013      
1014    }
1015    
1016    if(g_searchItemIndex < itemsMaxNumber && e.keyCode == 38 || g_searchItemIndex < itemsMaxNumber && e.keyCode == 40){
1017      
1018      g_objInput.removeClass(g_activeItemClass);
1019      
1020    }    
1021    
1022    var selectedItem = g_postItem.eq(g_searchItemIndex);
1023    
1024    selectedItem.addClass(g_selectedItemClass);
1025    
1026    var selectedItemLink = selectedItem.find('.uc-search-item__link');
1027    var selectedItemLinkUrl = selectedItemLink.attr('href');
1028    
1029    var goToSearchPageOnEnter = g_objItemsWrapper.data("goto-on-enter");
1030    
1031    if(e.keyCode == 13 && goToSearchPageOnEnter == true && !g_objInput.hasClass(g_activeItemClass))
1032    window.open(selectedItemLinkUrl, '_blank');
1033    
1034    if(e.keyCode == 13 && goToSearchPageOnEnter == true && g_objInput.hasClass(g_activeItemClass)){
1035      
1036      var searchPhrase = g_objInput.val();
1037      var homeUrlTarget = g_objInput.data('open-homeurl');
1038      
1039      window.open(g_homeUrl + '?s=' + searchPhrase, homeUrlTarget);
1040      
1041    }
1042    
1043    if(e.keyCode == 27){
1044      
1045      g_objItemsWrapper.hide();
1046      
1047      focusOnInput();
1048      
1049    } 
1050    
1051    if(e.keyCode == 8 && !g_objInput.hasClass(g_activeItemClass)){
1052      
1053      g_objItemsWrapper.hide();
1054      
1055      focusOnInput();
1056      
1057    }
1058    
1059    if(e.keyCode == 9){
1060      
1061      g_objItemsWrapper.hide();
1062      
1063      g_objInput.removeClass(g_activeItemClass);
1064      
1065    }   
1066    
1067    
1068  }
1069  
1070  /*
1071  * handle click on body event
1072  */
1073  function closeDropdownOnBodyClick(event){
1074    
1075    if(jQuery(event.target).parents().hasClass('uc-ajax-search__items'))
1076    return(false);
1077    
1078    if(jQuery(event.target).parents().hasClass('uc-ajax-search__suggested'))
1079    return(false);
1080    
1081    if (!jQuery(event.target).closest(g_objInput).length){
1082      
1083      g_objInput.blur();
1084      
1085      g_objItemsWrapper.hide();
1086      
1087      g_objInput.removeClass(g_activeItemClass);
1088      
1089    }else{
1090      
1091      g_objInput.focus();
1092      
1093    }
1094    
1095  }
1096  
1097  /*
1098  * seach on search button click
1099  */
1100  function onSearchButtonClick(){
1101    
1102    var searchPhrase = g_objInput.val();
1103    var homeUrlTarget = g_objInput.data('open-homeurl');
1104
1105    var dataPageUrl = g_objSearchBtn.data('page-url');
1106
1107    if(dataPageUrl == '')
1108    window.open(g_homeUrl + '?s=' + searchPhrase, homeUrlTarget);
1109    else
1110    window.open(g_homeUrl + '/' + dataPageUrl+ '/s=' + searchPhrase, homeUrlTarget);
1111
1112    
1113    
1114  }
1115  
1116  /**
1117  * search when on suggested search link click
1118  */
1119  function onSuggestedLinkClick(){
1120    
1121    var objSuggestedItem = jQuery(this);
1122    var objSuggestedItemText = objSuggestedItem.text();
1123    
1124    objSuggestedItemText = jQuery.trim(objSuggestedItemText);
1125    
1126    objSuggestedItemText = objSuggestedItemText.replace(",", "");
1127    
1128    focusOnInput();
1129    
1130    g_objInput.val(objSuggestedItemText);
1131    
1132    g_objInput.trigger("input");
1133    
1134  }
1135  
1136  /**
1137  * disable button when search field is empty
1138  */
1139  function checkInput(){
1140    
1141    if(!g_objSearchBtn.length)
1142    return(false);
1143    
1144    var isSearchFieldEmpty = g_objInput.val() == "";
1145    
1146    if(isSearchFieldEmpty == false){
1147      g_objSearchBtn.removeClass(g_inActiveItemClass);
1148      return(false);
1149    }
1150    
1151    g_objSearchBtn.addClass(g_inActiveItemClass);
1152    
1153  }
1154  
1155  /**
1156  * init events
1157  */
1158  function initEvents(){
1159    
1160    g_objInput.on("input", onInputChange);
1161    
1162    g_objInput.on("keydown", onKeyDown);
1163    
1164    g_objInput.on('click', onInputClick);
1165    
1166    g_objSearchBtn.on('click', onSearchButtonClick);
1167    
1168    g_objSuggestedLinks.on('click', onSuggestedLinkClick);
1169    
1170    jQuery(document).on('click', function(event) {
1171      
1172      closeDropdownOnBodyClick(event);
1173      
1174    });
1175    
1176    g_objItemsWrapper.on('pages_created', function(){     
1177      
1178      g_pageNumber.on('click', onPageNumberClick);
1179      
1180      g_arrowLeft.on('click', onArrowLeftClick);
1181      
1182      g_arrowRight.on('click', onArrowRightClick);
1183      
1184    });
1185    
1186  }
1187  
1188  
1189  /**
1190  * init class
1191  */
1192  this.init = function(urlAjax, id, homeUrl){
1193    
1194    g_objWrapper = jQuery("#"+id);
1195    
1196    if(g_objWrapper.length == 0)
1197    throw new Error("Widget not found by ID: "+id);
1198    
1199    g_urlBase = urlAjax;
1200    g_homeUrl = homeUrl;
1201    
1202    if(!g_urlBase)
1203    throw new Error("ajax url not found");
1204    
1205    g_objInput = g_objWrapper.find(".uc-ajax-search__input");
1206    if(g_objInput.length == 0)
1207    throw new Error("ajax input not found");
1208    
1209    g_objItemsWrapper = g_objWrapper.find(".uc-ajax-search__items");
1210    if(g_objItemsWrapper.length == 0)
1211    throw new Error("items wrapper not found");
1212    
1213    g_objSearchBtn = g_objWrapper.find('.uc-ajax-search__btn');
1214    
1215    g_activeItemClass = 'uc-active';
1216    g_inActiveItemClass = 'uc-inactive';
1217    g_selectedItemClass = 'uc-selected';
1218    
1219    g_searchItemIndex = -1;
1220    g_activePageIndex = 0;
1221    
1222    g_objError = g_objWrapper.find(".uc-ajax-search__error");
1223    g_objSuggested = g_objWrapper.find(".uc-ajax-search__suggested");
1224    g_objSuggestedLinks = g_objWrapper.find(".uc-ajax-search__suggested-link");
1225    
1226    g_objInput.val("");
1227    
1228    checkInput();
1229    placeSuggestedSearches();
1230    
1231    var isInEditor = g_objItemsWrapper.data('editor');
1232    var dataDebugList = g_objItemsWrapper.data('debug-list');
1233    
1234    if(isInEditor == 'yes' && dataDebugList == true)
1235    createPaginationElement();
1236    
1237    if(isInEditor == 'no')
1238    initEvents();
1239    
1240  }
1241  
1242}

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.