PageSourceSearch

https://www.biogama.eu/wp-content/uploads/ac_assets/ue_ajax_search/ue_ajax_search.js?ver=1.5.114

js biogama.eu collected 2026-10-10 00:57:39 UTC 31,678 bytes, 1,220 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    var suggestionObj = getVal(response, "search_suggestion");
433    var dataAutocorrect = g_objItemsWrapper.data('autocorrect');
434    
435    if(dataAutocorrect == true && htmlItems == "" && suggestionObj && suggestionObj.suggestion){
436        
437        var suggestion = suggestionObj.suggestion;
438        var textBefore = g_objItemsWrapper.data('autocorrect-beforetext');;
439        var textAfter = g_objItemsWrapper.data('autocorrect-aftertext');;
440        
441        htmlItems = "<div class='uc-ajax-search__suggested-item'>" + textBefore + "<a href='javascript:void(0)' class='uc-ajax-search__suggested-link'>" + suggestion + "</a>" + textAfter  + "</div>";
442    }
443    
444    g_objItemsWrapper.html(htmlItems);
445    
446    g_objItemsWrapper.show();
447    
448    operateAjax_setHtmlDebug(response, g_objWrapper);
449    
450  }
451  
452  /**
453  * format suggested searches
454  */
455  function placeSuggestedSearches(){
456    
457    if(!g_objSuggested.length)
458      return(false);
459    
460    //create an array of suggested searches
461    var suggestedItemsArray = g_objSuggested.text().split(/\r?\n/);
462    var suggestedItemsLength = suggestedItemsArray.length;
463    
464    //empty container
465    g_objSuggested.html("");
466    
467    for(let i=0; i<suggestedItemsLength; i++){    
468      
469      //trim each search
470      suggestedItemsArray[i] = jQuery.trim(suggestedItemsArray[i]);
471      
472      //create html for each search item
473      g_objSuggested.append("<a class='uc-ajax-search__suggested-link' href='javascript:void(0)'>"+suggestedItemsArray[i]+"</a>");
474      
475    }
476    
477    g_objSuggestedLinks = g_objSuggested.find(".uc-ajax-search__suggested-link");
478    
479    //add comma and space after each search item except last one
480    for(let i=0; i<suggestedItemsLength-1; i++){
481      
482      g_objSuggestedLinks.eq(i).append(", ");
483      
484    }
485    
486  }
487  
488  /*
489  * create pagination
490  */ 
491  function createPaginationElement(){
492    
493    var isPaginationExist = g_objItemsWrapper.data('pagination');
494    
495    if(isPaginationExist == false)
496      return(false);
497    
498    if(!g_objItemsWrapper.is(":visible"))
499      return(false);
500    
501    //create main wrapper
502    g_objItemsWrapper.prepend('<div class="uc-pagination-panel"></div>');
503    
504    var paginationPanel = g_objWrapper.find('.uc-pagination-panel');
505    var itemsNumber = g_objItemsWrapper.children().not(".uc-ajax-search__suggested-item").length - 1;
506    
507    //create child elements for main wrapper
508    paginationPanel.append('<div class="uc-pagination-list"></div>');
509    paginationPanel.append('<div class="uc-pagination-footer"></div>');
510    
511    var paginationPosition = g_objItemsWrapper.data('pagination-position');
512    
513    if(paginationPosition == 'before')
514      paginationPanel.prepend('<div class="uc-pagination-header"></div>');
515    
516    if(paginationPosition == 'after')
517      paginationPanel.append('<div class="uc-pagination-header"></div>');
518    
519    
520    g_paginationHeader = g_objWrapper.find('.uc-pagination-header');
521    g_paginationList = g_objWrapper.find('.uc-pagination-list');      
522    var paginationFooter = g_objWrapper.find('.uc-pagination-footer');
523    
524    var itemsPerPage = g_objItemsWrapper.data('num-items');
525    
526    var resultsText = g_objItemsWrapper.data('results-text');
527    
528    //display number of all results
529    if(itemsNumber == 0){
530      
531      var noResultsText = g_objItemsWrapper.data('no-results-text');
532      
533      g_paginationHeader.prepend('<div class="uc-ajax-search-results">' + noResultsText + '</div>');
534      
535    }else if(itemsNumber == 1){
536      
537      g_paginationHeader.prepend('<div class="uc-ajax-search-results">' + itemsNumber + ' ' + resultsText + '</div>');
538      
539    }else{
540      
541      g_paginationHeader.prepend('<div class="uc-ajax-search-results"></div>');
542      
543      var resultsElement = g_objWrapper.find('.uc-ajax-search-results');
544      
545      //count current / total results
546      var firstNum = itemsPerPage * (g_activePageIndex + 1) - itemsPerPage + 1;
547      var lastNum = itemsPerPage * (g_activePageIndex + 1);
548      
549      if(lastNum > itemsNumber && itemsPerPage < itemsNumber)
550        lastNum = itemsNumber
551      
552      if(firstNum == itemsNumber && itemsPerPage < itemsNumber)
553        resultsElement.text(firstNum + '/' + itemsNumber);
554      else if(itemsPerPage >= itemsNumber )
555        resultsElement.text(itemsNumber + ' ' + resultsText);
556      else
557        resultsElement.text(firstNum + '-' + lastNum + '/' + itemsNumber);      
558    }
559    
560    //create navigation
561    g_paginationHeader.append('<div class="uc-ajax-search-navigation-panel"></div>');
562    
563    //create navigation panel for pages and arrows
564    var paginationPanel = g_objWrapper.find('.uc-ajax-search-navigation-panel');
565    
566    //create pages and arrows wrapper elements
567    paginationPanel.append('<div class="uc-ajax-search-pages"></div>');
568    paginationPanel.append('<div class="uc-ajax-arrows"></div>');
569    
570    //if amount of search items is less or equal to amount of items per page then append search items to only one wrapper element 
571    //and stop any furter function execution
572    if(itemsNumber <= itemsPerPage){
573      
574      g_paginationList.append('<div class="uc-pagination-list-inner"></div>');
575      
576      g_paginationInner = g_objItemsWrapper.find('.uc-pagination-list-inner');
577      var searchItems = g_objItemsWrapper.find('.uc-search-item');
578      
579      g_paginationInner.append(searchItems);
580      
581      //add active class to the list of results
582      g_paginationInner.addClass(g_activeItemClass);
583      
584      return(false);
585      
586    }
587    
588    var pageNumber = Math.ceil(itemsNumber / itemsPerPage);
589    var pageWrapper = g_objWrapper.find('.uc-ajax-search-pages');
590    var arrowsWrapper = g_objWrapper.find('.uc-ajax-arrows');
591    
592    //create arrows
593    arrowsWrapper.append('<div class="uc-ajax-arrow-left"></div>');
594    arrowsWrapper.append('<div class="uc-ajax-arrow-right"></div>');
595    
596    g_arrowLeft = g_objWrapper.find('.uc-ajax-arrow-left');
597    g_arrowRight = g_objWrapper.find('.uc-ajax-arrow-right');
598    
599    //add inactive class to left arrow
600    if(g_activePageIndex <= 0 && g_arrowLeft)
601      g_arrowLeft.addClass(g_inActiveItemClass);
602    
603    //create pages
604    for (let page = 1; page <= pageNumber; page++){
605      
606      pageWrapper.append('<a class="uc-page-number" href="javascript:void(0)">' + page + '</a>');
607      g_paginationList.append('<div class="uc-pagination-list-inner"></div>');
608      
609    }
610    
611    g_pageNumber = g_objItemsWrapper.find('.uc-page-number');
612    
613    //add active class to first page
614    g_pageNumber.eq(0).addClass(g_activeItemClass);      
615    
616    g_paginationInner = g_objItemsWrapper.find('.uc-pagination-list-inner');
617    
618    //add active class to the first list of results
619    g_paginationInner.eq(0).addClass(g_activeItemClass);
620    
621    var searchItem = g_objItemsWrapper.find('.uc-search-item');
622    
623    //append result items to created list elements
624    for (let i = itemsPerPage; i <= itemsNumber; i = i + itemsPerPage){
625      
626      var searchItemRange = searchItem.slice(i - itemsPerPage, i);
627      
628      g_paginationInner.eq((i / itemsPerPage) - 1).append(searchItemRange);
629      
630    }
631    
632    //trigger custom event to connect vars to click function
633    g_objItemsWrapper.trigger('pages_created');
634    
635    //apend items to the last page
636    if(itemsNumber % itemsPerPage == 0)
637      return(false);
638    
639    var firstItemIndex = itemsNumber - (itemsNumber % itemsPerPage);
640    var lastItemIndex = itemsNumber;
641    
642    //if only one search item left, then append it and stop function execution
643    if(firstItemIndex == lastItemIndex){
644      
645      g_paginationInner.eq(-1).append(searchItem.eq(lastItemIndex));
646      
647      return(false);
648      
649    }
650    
651    //append the rest of search items to the last wrapper element
652    var searchItemLastRange = searchItem.slice(firstItemIndex, lastItemIndex);
653    
654    g_paginationInner.eq(-1).append(searchItemLastRange);
655    
656  }
657  
658  /*
659  * focus on input click
660  */
661  function onInputClick(){
662    
663    focusOnInput();
664    
665  }
666  
667  /*
668  * translate list page list wrapper on page number click
669  */
670  function onPageNumberClick(){
671    
672    var objNumber = jQuery(this);
673    var objNumberIndex = objNumber.index();
674    
675    //sync active page index
676    g_activePageIndex = objNumberIndex;
677    
678    if(g_pageNumber)
679      var pageNumber = g_pageNumber.length - 1;
680    
681    //set inactive class to navigation arrows
682    if(g_arrowLeft)
683      g_arrowLeft.removeClass(g_inActiveItemClass);
684    
685    if(g_arrowRight)
686      g_arrowRight.removeClass(g_inActiveItemClass);
687    
688    if(g_activePageIndex >= pageNumber && g_arrowRight)
689      g_arrowRight.addClass(g_inActiveItemClass);
690    
691    if(g_activePageIndex <= 0 && g_arrowLeft)
692      g_arrowLeft.addClass(g_inActiveItemClass);
693    
694    setActive();
695    
696  }
697  
698  /*
699  * set active item
700  */
701  function setActive(){
702    
703    var totalPageNumber = g_paginationInner.length;
704    
705    if(totalPageNumber <= 1)
706      return(false);
707    
708    //set active class to current page
709    g_pageNumber.removeClass(g_activeItemClass);
710    g_pageNumber.eq(g_activePageIndex).addClass(g_activeItemClass);
711    
712    //set active class to current list item
713    g_paginationInner.removeClass(g_activeItemClass);
714    g_paginationInner.eq(g_activePageIndex).addClass(g_activeItemClass);
715    
716    //reset search item index
717    g_searchItemIndex = 0;
718    
719    //translate list considering page direction
720    var isDirectionRtl = jQuery("body").hasClass("rtl");
721    
722    if(isDirectionRtl == false){
723      g_paginationList.css({
724        'transform': 'translate(-' + g_activePageIndex + '00%, 0)'
725      });
726    }
727    
728    if(isDirectionRtl == true){
729      g_paginationList.css({
730        'transform': 'translate(' + g_activePageIndex + '00%, 0)'
731      });
732    }
733    
734    var totalItems = g_objWrapper.find('.uc-search-item').length;
735    
736    if(totalItems == 1)
737      return(false);
738    
739    var resultsElement = g_objWrapper.find('.uc-ajax-search-results');
740    var itemsPerPage = g_objItemsWrapper.data('num-items');
741    
742    //count current / total results
743    var firstNum = itemsPerPage * (g_activePageIndex + 1) - itemsPerPage + 1;
744    var lastNum = itemsPerPage * (g_activePageIndex + 1);
745    
746    if(lastNum > totalItems)
747      lastNum = totalItems;
748    
749    if(firstNum == totalItems)
750      resultsElement.text(firstNum + '/' + totalItems);
751    else
752      resultsElement.text(firstNum + '-' + lastNum + '/' + totalItems);
753    
754  }
755  
756  /*
757  * translate list page list wrapper on arrows number click
758  */
759  function onArrowLeftClick(){    
760    if(g_arrowRight)
761      g_arrowRight.removeClass(g_inActiveItemClass);
762    
763    g_activePageIndex--; 
764    
765    if(g_activePageIndex <= 0){
766      
767      g_activePageIndex = 0;
768      
769      if(g_arrowLeft)
770        g_arrowLeft.addClass(g_inActiveItemClass);
771      
772    }
773    
774    setActive();       
775  }
776  
777  /*
778  * translate list page list wrapper on arrows number click
779  */
780  function onArrowRightClick(){
781    
782    if(g_arrowLeft)
783      g_arrowLeft.removeClass(g_inActiveItemClass);
784    
785    g_activePageIndex++; 
786    
787    if(g_pageNumber)
788      var pageNumber = g_pageNumber.length - 1;
789    
790    if(g_activePageIndex >= pageNumber){
791      
792      g_activePageIndex = pageNumber;
793      
794      if(g_arrowRight)
795        g_arrowRight.addClass(g_inActiveItemClass);
796      
797    }
798    
799    setActive();
800    
801  }
802  
803  /**
804  * append custom links ending
805  */
806  function appendCustomLinksEnding(){
807    var dataLinksEnding = g_objItemsWrapper.data("linksending");
808    
809    if(dataLinksEnding == false)
810      return(false);
811    
812    var dataLinksEndingText = g_objItemsWrapper.data("linksendingtext");
813    var objLinks = g_objItemsWrapper.find("a");
814    
815    if(!objLinks || objLinks.length == 0)
816      return(false);
817    
818    objLinks.each(function(){
819      var objLink = jQuery(this);
820      var linkHref = objLink.attr("href");
821      
822      if(!linkHref)
823        return(true);
824      
825      var islinkClickable = linkHref != "javascript:void(0);";
826      
827      if(islinkClickable == false)
828        return(true);
829      
830      var newLink = linkHref+"?ue-search-phrase="+dataLinksEndingText;
831      
832      objLink.attr("href", newLink);
833    });
834  }
835  
836  /**
837  * do the search itself
838  */
839  function doSearch(){
840    
841    //combine the url
842    var url = getAjaxRequestUrl();
843    
844    //if search phrase is empty then do not search
845    if(g_objInput.val() == '')
846      return(false);
847    
848    if(!url)
849      throw new Error("Error in ajax url");
850    
851    //ajax search
852    g_objError.hide();
853    g_objItemsWrapper.hide();
854    
855    g_objWrapper.addClass("uc-loading");
856    
857    ajaxRequest(url, null, null, function(response){
858      
859      g_objWrapper.removeClass("uc-loading");
860      
861      handleResponse(response);
862      
863      g_objInput.data('lastphrase', g_objInput.val());
864      
865      createPaginationElement();
866      
867      highlightSearchTerm(g_objInput.val());
868      
869      appendCustomLinksEnding();      
870    });    
871  }
872  
873  /**
874  * focus on input
875  */
876  function focusOnInput(){    
877    g_objInput.addClass(g_activeItemClass);    
878  }
879  
880  /**
881  * mark substing 
882  */
883  function markSubstring(objResultText, text, substring) {    
884    let regex = new RegExp(substring, "gi");
885    
886    //capitalize protection
887    var isCapitalized = objResultText.css('text-transform') == 'capitalize';
888    
889    return text.replace(regex, (match) => {
890      
891      if(isCapitalized == false)
892        return "<b>" + match + "</b>"
893      
894      if(isCapitalized == true)
895        return "<b class='uc-capitalized'>" + match + "</b>"      
896    });    
897  }
898  
899  /*
900  * highlight searct term in results
901  */
902  function highlightSearchTerm(searchTerm){    
903    var boldSearchPhrase = g_objItemsWrapper.data("bold-phrase");
904    
905    if(boldSearchPhrase == false)
906      return(false);
907    
908    var resultTitles = g_objItemsWrapper.find(".uc-search-item__link-title");
909    
910    resultTitles.each(function(){      
911      var objResultText = jQuery(this);
912      var resultTitleText = objResultText.text();
913      
914      var highlightedText = markSubstring(objResultText, resultTitleText, searchTerm);      
915      
916      objResultText.html(highlightedText);      
917    });    
918  }
919  
920  /**
921  * on keyup - run the search with treshold
922  */
923  function onInputChange(){    
924    var newPhrase = g_objInput.val();
925    var lastPhrase = g_objInput.data('lastphrase');
926    
927    checkInput();
928    
929    var isSearchWindowClosed = !g_objItemsWrapper.is(":visible");
930    
931    //if dropdown is visible then do not search same results
932    if(isSearchWindowClosed == false){
933      
934      if(jQuery.trim(lastPhrase) == jQuery.trim(newPhrase))
935        return(false);      
936    } 
937    
938    g_objItemsWrapper.hide();
939    
940    runWithTrashold(doSearch);
941    
942    g_searchItemIndex = -1;    
943  }
944  
945  /*
946  ** navigate dropdown
947  */
948  function onKeyDown(e){    
949    if(!g_objInput.is(":focus"))
950      return(false);
951    
952    var isKeysActivated = g_objItemsWrapper.data('keys');
953    
954    if(isKeysActivated == false)
955      return(true);
956    
957    if(!g_objItemsWrapper.is(":visible"))
958      return(true);
959    
960    if(e.keyCode == 37 || e.keyCode == 39){
961      
962      if(g_objInput.hasClass(g_activeItemClass))
963        return(true);
964      
965      if(e.keyCode == 37)
966        g_activePageIndex--; 
967      
968      if(e.keyCode == 39)
969        g_activePageIndex++; 
970      
971      if(g_pageNumber)
972        var pageNumber = g_pageNumber.length - 1;
973      
974      if(g_arrowLeft)
975        g_arrowLeft.removeClass(g_inActiveItemClass);
976      
977      if(g_arrowRight)
978        g_arrowRight.removeClass(g_inActiveItemClass);
979      
980      if(g_activePageIndex >= pageNumber){
981        
982        g_activePageIndex = pageNumber;
983        
984        if(g_arrowRight)
985          g_arrowRight.addClass(g_inActiveItemClass);
986        
987      }
988      
989      if(g_activePageIndex <= 0){
990        
991        g_activePageIndex = 0;
992        
993        if(g_arrowLeft)
994          g_arrowLeft.addClass(g_inActiveItemClass);
995        
996      }
997      
998      setActive();      
999    }
1000    
1001    var itemsMaxNumber;
1002    
1003    g_postItem = g_objItemsWrapper.find('.uc-pagination-list-inner.uc-active .uc-search-item');
1004    itemsMaxNumber = g_objItemsWrapper.find('.uc-pagination-list-inner.uc-active').children().length;
1005    
1006    var postItemNumber = g_postItem.length;
1007    
1008    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){
1009      
1010      e.preventDefault();
1011      
1012    }else{      
1013      g_searchItemIndex = postItemNumber; 
1014      
1015      focusOnInput();      
1016    }
1017    
1018    if(e.keyCode != 37 || e.keyCode != 39)
1019      g_postItem.removeClass(g_selectedItemClass); 
1020    
1021    if(e.keyCode == 40)
1022      g_searchItemIndex++;   
1023    
1024    if(e.keyCode == 38)
1025      g_searchItemIndex--;
1026    
1027    if(g_searchItemIndex < -1)
1028      g_searchItemIndex = itemsMaxNumber - 1;
1029    
1030    if(g_searchItemIndex == -1)        
1031      g_searchItemIndex = itemsMaxNumber;
1032    
1033    if(g_searchItemIndex > postItemNumber || g_searchItemIndex > itemsMaxNumber)
1034      g_searchItemIndex = 0;      
1035    
1036    if(g_searchItemIndex >= itemsMaxNumber && e.keyCode == 38 || g_searchItemIndex >= itemsMaxNumber && e.keyCode == 40){      
1037      focusOnInput();      
1038    }
1039    
1040    if(g_searchItemIndex < itemsMaxNumber && e.keyCode == 38 || g_searchItemIndex < itemsMaxNumber && e.keyCode == 40){      
1041      g_objInput.removeClass(g_activeItemClass);      
1042    }    
1043    
1044    var selectedItem = g_postItem.eq(g_searchItemIndex);
1045    
1046    selectedItem.addClass(g_selectedItemClass);
1047    
1048    var selectedItemLink = selectedItem.find('.uc-search-item__link');
1049    var selectedItemLinkUrl = selectedItemLink.attr('href');    
1050    var goToSearchPageOnEnter = g_objItemsWrapper.data("goto-on-enter");
1051    
1052    if(e.keyCode == 13 && goToSearchPageOnEnter == true && !g_objInput.hasClass(g_activeItemClass))
1053      window.open(selectedItemLinkUrl, '_blank');
1054    
1055    if(e.keyCode == 13 && goToSearchPageOnEnter == true && g_objInput.hasClass(g_activeItemClass)){      
1056      var searchPhrase = g_objInput.val();
1057      var homeUrlTarget = g_objInput.data('open-homeurl');
1058      
1059      window.open(g_homeUrl + '?s=' + searchPhrase, homeUrlTarget);      
1060    }
1061    
1062    if(e.keyCode == 27){      
1063      g_objItemsWrapper.hide();      
1064      focusOnInput();      
1065    } 
1066    
1067    if(e.keyCode == 8 && !g_objInput.hasClass(g_activeItemClass)){      
1068      g_objItemsWrapper.hide();      
1069      focusOnInput();      
1070    }
1071    
1072    if(e.keyCode == 9){      
1073      g_objItemsWrapper.hide();      
1074      g_objInput.removeClass(g_activeItemClass);      
1075    }   
1076  }
1077  
1078  /*
1079  * handle click on body event
1080  */
1081  function closeDropdownOnBodyClick(event){    
1082    if(jQuery(event.target).parents().hasClass('uc-ajax-search__items'))
1083      return(false);
1084    
1085    if(jQuery(event.target).parents().hasClass('uc-ajax-search__suggested'))
1086      return(false);
1087    
1088    if (!jQuery(event.target).closest(g_objInput).length){
1089      
1090      g_objInput.blur();      
1091      g_objItemsWrapper.hide();      
1092      g_objInput.removeClass(g_activeItemClass);
1093      
1094    }else{      
1095      g_objInput.focus();      
1096    }    
1097  }
1098  
1099  /*
1100  * seach on search button click
1101  */
1102  function onSearchButtonClick(){
1103    
1104    var searchPhrase = g_objInput.val();
1105    var homeUrlTarget = g_objInput.data('open-homeurl');
1106    
1107    var dataPageUrl = g_objSearchBtn.data('page-url');
1108    
1109    if(dataPageUrl == '')
1110      window.open(g_homeUrl + '?s=' + searchPhrase, homeUrlTarget);
1111    else
1112      window.open(g_homeUrl + '/' + dataPageUrl+ '/s=' + searchPhrase, homeUrlTarget);    
1113  }
1114  
1115  /**
1116  * search when on suggested search link click
1117  */
1118  function onSuggestedLinkClick(){    
1119    var objSuggestedItem = jQuery(this);
1120    var objSuggestedItemText = objSuggestedItem.text();
1121    
1122    objSuggestedItemText = jQuery.trim(objSuggestedItemText);    
1123    objSuggestedItemText = objSuggestedItemText.replace(",", "");
1124    
1125    focusOnInput();
1126    
1127    g_objInput.val(objSuggestedItemText);
1128    
1129    g_objInput.trigger("input");    
1130  }
1131  
1132  /**
1133  * disable button when search field is empty
1134  */
1135  function checkInput(){    
1136    if(!g_objSearchBtn.length)
1137      return(false);
1138    
1139    var isSearchFieldEmpty = g_objInput.val() == "";
1140    
1141    if(isSearchFieldEmpty == false){
1142      g_objSearchBtn.removeClass(g_inActiveItemClass);
1143      return(false);
1144    }
1145    
1146    g_objSearchBtn.addClass(g_inActiveItemClass);    
1147  }
1148  
1149  /**
1150  * init events
1151  */
1152  function initEvents(){    
1153    g_objInput.on("input", onInputChange);    
1154    g_objInput.on("keydown", onKeyDown);    
1155    g_objInput.on('click', onInputClick);    
1156    g_objSearchBtn.on('click', onSearchButtonClick);    
1157    g_objWrapper.on('click', '.uc-ajax-search__suggested-link', onSuggestedLinkClick);
1158    
1159    jQuery(document).on('click', function(event) {      
1160      closeDropdownOnBodyClick(event);      
1161    });
1162    
1163    g_objItemsWrapper.on('pages_created', function(){           
1164      g_pageNumber.on('click', onPageNumberClick);      
1165      g_arrowLeft.on('click', onArrowLeftClick);      
1166      g_arrowRight.on('click', onArrowRightClick);      
1167    });    
1168  }
1169  
1170  /**
1171  * init class
1172  */
1173  this.init = function(urlAjax, id, homeUrl){    
1174    g_objWrapper = jQuery("#"+id);
1175    
1176    if(g_objWrapper.length == 0)
1177      throw new Error("Widget not found by ID: "+id);
1178    
1179    g_urlBase = urlAjax;
1180    g_homeUrl = homeUrl;
1181    
1182    if(!g_urlBase)
1183      throw new Error("ajax url not found");
1184    
1185    g_objInput = g_objWrapper.find(".uc-ajax-search__input");
1186    if(g_objInput.length == 0)
1187      throw new Error("ajax input not found");
1188    
1189    g_objItemsWrapper = g_objWrapper.find(".uc-ajax-search__items");
1190    if(g_objItemsWrapper.length == 0)
1191      throw new Error("items wrapper not found");
1192    
1193    g_objSearchBtn = g_objWrapper.find('.uc-ajax-search__btn');
1194    
1195    g_activeItemClass = 'uc-active';
1196    g_inActiveItemClass = 'uc-inactive';
1197    g_selectedItemClass = 'uc-selected';
1198    
1199    g_searchItemIndex = -1;
1200    g_activePageIndex = 0;
1201    
1202    g_objError = g_objWrapper.find(".uc-ajax-search__error");
1203    g_objSuggested = g_objWrapper.find(".uc-ajax-search__suggested");
1204    g_objSuggestedLinks = g_objWrapper.find(".uc-ajax-search__suggested-link");
1205    
1206    g_objInput.val("");
1207    
1208    checkInput();
1209    placeSuggestedSearches();
1210    
1211    var isInEditor = g_objItemsWrapper.data('editor');
1212    var dataDebugList = g_objItemsWrapper.data('debug-list');
1213    
1214    if(isInEditor == 'yes' && dataDebugList == true)
1215      createPaginationElement();
1216    
1217    if(isInEditor == 'no')
1218      initEvents();    
1219  }
1220}

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.