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 * append custom links ending 797 */ 798 function appendCustomLinksEnding(){ 799 var dataLinksEnding = g_objItemsWrapper.data("linksending"); 800 801 if(dataLinksEnding == false) 802 return(false); 803 804 var dataLinksEndingText = g_objItemsWrapper.data("linksendingtext"); 805 var objLinks = g_objItemsWrapper.find("a"); 806 807 if(!objLinks || objLinks.length == 0) 808 return(false); 809 810 objLinks.each(function(){ 811 var objLink = jQuery(this); 812 var linkHref = objLink.attr("href"); 813 814 if(!linkHref) 815 return(true); 816 817 var islinkClickable = linkHref != "javascript:void(0);"; 818 819 if(islinkClickable == false) 820 return(true); 821 822 var newLink = linkHref+"?ue-search-phrase="+dataLinksEndingText; 823 824 objLink.attr("href", newLink); 825 }); 826 } 827 828 /** 829 * do the search itself 830 */ 831 function doSearch(){ 832 833 //combine the url 834 var url = getAjaxRequestUrl(); 835 836 //if search phrase is empty then do not search
837 if(g_objInput.val() == '') 838 return(false); 839 840 if(!url) 841 throw new Error("Error in ajax url"); 842 843 //ajax search 844 g_objError.hide(); 845 g_objItemsWrapper.hide(); 846 847 g_objWrapper.addClass("uc-loading"); 848 849 ajaxRequest(url, null, null, function(response){ 850 851 g_objWrapper.removeClass("uc-loading"); 852 853 handleResponse(response); 854 855 g_objInput.data('lastphrase', g_objInput.val()); 856 857 createPaginationElement(); 858 859 highlightSearchTerm(g_objInput.val()); 860 861 appendCustomLinksEnding(); 862 }); 863 864 865 } 866 867 /** 868 * focus on input 869 */ 870 function focusOnInput(){ 871 872 g_objInput.addClass(g_activeItemClass); 873 874 } 875 876 function markSubstring(objResultText, text, substring) { 877 878 let regex = new RegExp(substring, "gi"); 879 880 //capitalize protection 881 var isCapitalized = objResultText.css('text-transform') == 'capitalize'; 882 883 return text.replace(regex, (match) => { 884 885 if(isCapitalized == false) 886 return "<b>" + match + "</b>" 887 888 if(isCapitalized == true) 889 return "<b class='uc-capitalized'>" + match + "</b>" 890 891 }); 892 893 } 894 895 /* 896 * highlight searct term in results 897 */ 898 function highlightSearchTerm(searchTerm){ 899 900 var boldSearchPhrase = g_objItemsWrapper.data("bold-phrase"); 901 902 if(boldSearchPhrase == false) 903 return(false); 904 905 var resultTitles = g_objItemsWrapper.find(".uc-search-item__link-title"); 906 907 resultTitles.each(function(){ 908 909 var objResultText = jQuery(this); 910 var resultTitleText = objResultText.text(); 911 912 var highlightedText = markSubstring(objResultText, resultTitleText, searchTerm); 913 914 objResultText.html(highlightedText); 915 916 }); 917 918 } 919 920 /** 921 * on keyup - run the search with treshold 922 */ 923 function onInputChange(){ 924 925 var newPhrase = g_objInput.val(); 926 var lastPhrase = g_objInput.data('lastphrase'); 927 928 checkInput(); 929 930 var isSearchWindowClosed = !g_objItemsWrapper.is(":visible"); 931 932 //if dropdown is visible then do not search same results 933 if(isSearchWindowClosed == false){ 934 935 if(jQuery.trim(lastPhrase) == jQuery.trim(newPhrase)) 936 return(false); 937 938 } 939 940 g_objItemsWrapper.hide(); 941 942 runWithTrashold(doSearch); 943 944 g_searchItemIndex = -1; 945 946 947 } 948 949 /* 950 ** navigate dropdown 951 */ 952 function onKeyDown(e){ 953 954 if(!g_objInput.is(":focus")) 955 return(false); 956 957 var isKeysActivated = g_objItemsWrapper.data('keys'); 958 959 if(isKeysActivated == false) 960 return(true); 961 962 if(!g_objItemsWrapper.is(":visible")) 963 return(true); 964 965 if(e.keyCode == 37 || e.keyCode == 39){ 966 967 if(g_objInput.hasClass(g_activeItemClass)) 968 return(true); 969 970 if(e.keyCode == 37) 971 g_activePageIndex--; 972 973 if(e.keyCode == 39) 974 g_activePageIndex++; 975 976 if(g_pageNumber) 977 var pageNumber = g_pageNumber.length - 1; 978 979 if(g_arrowLeft) 980 g_arrowLeft.removeClass(g_inActiveItemClass); 981 982 if(g_arrowRight) 983 g_arrowRight.removeClass(g_inActiveItemClass); 984 985 if(g_activePageIndex >= pageNumber){ 986 987 g_activePageIndex = pageNumber; 988 989 if(g_arrowRight) 990 g_arrowRight.addClass(g_inActiveItemClass); 991 992 } 993 994 if(g_activePageIndex <= 0){ 995 996 g_activePageIndex = 0; 997 998 if(g_arrowLeft) 999 g_arrowLeft.addClass(g_inActiveItemClass); 1000 1001 } 1002 1003 setActive(); 1004 1005 } 1006 1007 var itemsMaxNumber; 1008 1009 g_postItem = g_objItemsWrapper.find('.uc-pagination-list-inner.uc-active .uc-search-item'); 1010 itemsMaxNumber = g_objItemsWrapper.find('.uc-pagination-list-inner.uc-active').children().length; 1011 1012 var postItemNumber = g_postItem.length; 1013 1014 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){ 1015 1016 e.preventDefault(); 1017 1018 }else{ 1019 1020 g_searchItemIndex = postItemNumber; 1021 1022 focusOnInput(); 1023 1024 } 1025 1026 if(e.keyCode != 37 || e.keyCode != 39) 1027 g_postItem.removeClass(g_selectedItemClass); 1028 1029 if(e.keyCode == 40) 1030 g_searchItemIndex++; 1031 1032 if(e.keyCode == 38) 1033 g_searchItemIndex--; 1034 1035 if(g_searchItemIndex < -1) 1036 g_searchItemIndex = itemsMaxNumber - 1; 1037 1038 if(g_searchItemIndex == -1) 1039 g_searchItemIndex = itemsMaxNumber; 1040 1041 if(g_searchItemIndex > postItemNumber || g_searchItemIndex > itemsMaxNumber) 1042 g_searchItemIndex = 0; 1043 1044 if(g_searchItemIndex >= itemsMaxNumber && e.keyCode == 38 || g_searchItemIndex >= itemsMaxNumber && e.keyCode == 40){ 1045 1046 focusOnInput(); 1047 1048 } 1049 1050 if(g_searchItemIndex < itemsMaxNumber && e.keyCode == 38 || g_searchItemIndex < itemsMaxNumber && e.keyCode == 40){ 1051
1052 g_objInput.removeClass(g_activeItemClass); 1053 1054 } 1055 1056 var selectedItem = g_postItem.eq(g_searchItemIndex); 1057 1058 selectedItem.addClass(g_selectedItemClass); 1059 1060 var selectedItemLink = selectedItem.find('.uc-search-item__link'); 1061 var selectedItemLinkUrl = selectedItemLink.attr('href'); 1062 1063 var goToSearchPageOnEnter = g_objItemsWrapper.data("goto-on-enter"); 1064 1065 if(e.keyCode == 13 && goToSearchPageOnEnter == true && !g_objInput.hasClass(g_activeItemClass)) 1066 window.open(selectedItemLinkUrl, '_blank'); 1067 1068 if(e.keyCode == 13 && goToSearchPageOnEnter == true && g_objInput.hasClass(g_activeItemClass)){ 1069 1070 var searchPhrase = g_objInput.val(); 1071 var homeUrlTarget = g_objInput.data('open-homeurl'); 1072 1073 window.open(g_homeUrl + '?s=' + searchPhrase, homeUrlTarget); 1074 1075 } 1076 1077 if(e.keyCode == 27){ 1078 1079 g_objItemsWrapper.hide(); 1080 1081 focusOnInput(); 1082 1083 } 1084 1085 if(e.keyCode == 8 && !g_objInput.hasClass(g_activeItemClass)){ 1086 1087 g_objItemsWrapper.hide(); 1088 1089 focusOnInput(); 1090 1091 } 1092 1093 if(e.keyCode == 9){ 1094 1095 g_objItemsWrapper.hide(); 1096 1097 g_objInput.removeClass(g_activeItemClass); 1098 1099 } 1100 1101 1102 } 1103 1104 /* 1105 * handle click on body event 1106 */ 1107 function closeDropdownOnBodyClick(event){ 1108 1109 if(jQuery(event.target).parents().hasClass('uc-ajax-search__items')) 1110 return(false); 1111 1112 if(jQuery(event.target).parents().hasClass('uc-ajax-search__suggested')) 1113 return(false); 1114 1115 if (!jQuery(event.target).closest(g_objInput).length){ 1116 1117 g_objInput.blur(); 1118 1119 g_objItemsWrapper.hide(); 1120 1121 g_objInput.removeClass(g_activeItemClass); 1122 1123 }else{ 1124 1125 g_objInput.focus(); 1126 1127 } 1128 1129 } 1130 1131 /* 1132 * seach on search button click 1133 */ 1134 function onSearchButtonClick(){ 1135 1136 var searchPhrase = g_objInput.val(); 1137 var homeUrlTarget = g_objInput.data('open-homeurl'); 1138 1139 var dataPageUrl = g_objSearchBtn.data('page-url'); 1140 1141 if(dataPageUrl == '') 1142 window.open(g_homeUrl + '?s=' + searchPhrase, homeUrlTarget); 1143 else 1144 window.open(g_homeUrl + '/' + dataPageUrl+ '/s=' + searchPhrase, homeUrlTarget); 1145 1146 1147 1148 } 1149 1150 /** 1151 * search when on suggested search link click 1152 */ 1153 function onSuggestedLinkClick(){ 1154 1155 var objSuggestedItem = jQuery(this); 1156 var objSuggestedItemText = objSuggestedItem.text(); 1157 1158 objSuggestedItemText = jQuery.trim(objSuggestedItemText); 1159 1160 objSuggestedItemText = objSuggestedItemText.replace(",", ""); 1161 1162 focusOnInput(); 1163 1164 g_objInput.val(objSuggestedItemText); 1165 1166 g_objInput.trigger("input"); 1167 1168 } 1169 1170 /** 1171 * disable button when search field is empty 1172 */ 1173 function checkInput(){ 1174 1175 if(!g_objSearchBtn.length) 1176 return(false); 1177 1178 var isSearchFieldEmpty = g_objInput.val() == ""; 1179 1180 if(isSearchFieldEmpty == false){ 1181 g_objSearchBtn.removeClass(g_inActiveItemClass); 1182 return(false); 1183 } 1184 1185 g_objSearchBtn.addClass(g_inActiveItemClass); 1186 1187 } 1188 1189 /** 1190 * init events 1191 */ 1192 function initEvents(){ 1193 1194 g_objInput.on("input", onInputChange); 1195 1196 g_objInput.on("keydown", onKeyDown); 1197 1198 g_objInput.on('click', onInputClick); 1199 1200 g_objSearchBtn.on('click', onSearchButtonClick); 1201 1202 g_objSuggestedLinks.on('click', onSuggestedLinkClick); 1203 1204 jQuery(document).on('click', function(event) { 1205 1206 closeDropdownOnBodyClick(event); 1207 1208 }); 1209 1210 g_objItemsWrapper.on('pages_created', function(){ 1211 1212 g_pageNumber.on('click', onPageNumberClick); 1213 1214 g_arrowLeft.on('click', onArrowLeftClick); 1215 1216 g_arrowRight.on('click', onArrowRightClick); 1217 1218 }); 1219 1220 } 1221 1222 1223 /** 1224 * init class 1225 */ 1226 this.init = function(urlAjax, id, homeUrl){ 1227 1228 g_objWrapper = jQuery("#"+id); 1229 1230 if(g_objWrapper.length == 0) 1231 throw new Error("Widget not found by ID: "+id); 1232 1233 g_urlBase = urlAjax; 1234 g_homeUrl = homeUrl; 1235 1236 if(!g_urlBase) 1237 throw new Error("ajax url not found"); 1238 1239 g_objInput = g_objWrapper.find(".uc-ajax-search__input");
1240 if(g_objInput.length == 0) 1241 throw new Error("ajax input not found"); 1242 1243 g_objItemsWrapper = g_objWrapper.find(".uc-ajax-search__items"); 1244 if(g_objItemsWrapper.length == 0) 1245 throw new Error("items wrapper not found"); 1246 1247 g_objSearchBtn = g_objWrapper.find('.uc-ajax-search__btn'); 1248 1249 g_activeItemClass = 'uc-active'; 1250 g_inActiveItemClass = 'uc-inactive'; 1251 g_selectedItemClass = 'uc-selected'; 1252 1253 g_searchItemIndex = -1; 1254 g_activePageIndex = 0; 1255 1256 g_objError = g_objWrapper.find(".uc-ajax-search__error"); 1257 g_objSuggested = g_objWrapper.find(".uc-ajax-search__suggested"); 1258 g_objSuggestedLinks = g_objWrapper.find(".uc-ajax-search__suggested-link"); 1259 1260 g_objInput.val(""); 1261 1262 checkInput(); 1263 placeSuggestedSearches(); 1264 1265 var isInEditor = g_objItemsWrapper.data('editor'); 1266 var dataDebugList = g_objItemsWrapper.data('debug-list'); 1267 1268 if(isInEditor == 'yes' && dataDebugList == true) 1269 createPaginationElement(); 1270 1271 if(isInEditor == 'no') 1272 initEvents(); 1273 1274 } 1275}
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.