1(function( $ ) { 2 3 'use strict'; 4 5 var JetSearch = { 6 7 addedScripts: [], 8 addedStyles: [], 9 addedPostCSS: [], 10 assetsPromises: [], 11 12 initElementor: function() { 13 14 var widgets = { 15 'jet-ajax-search.default': JetSearch.widgetAjaxSearch, 16 'jet-search-suggestions.default': JetSearch.widgetSearchSuggestions 17 }; 18 19 $.each( widgets, function( widget, callback ) { 20 window.elementorFrontend.hooks.addAction( 'frontend/element_ready/' + widget, callback ); 21 } ); 22 23 // Re-init widgets in nested tabs 24 window.elementorFrontend.elements.$window.on( 25 'elementor/nested-tabs/activate', 26 ( event, content ) => { 27 28 const $content = $( content ); 29 JetSearch.reinitSlickSlider( $content ); 30 JetSearch.initElementsHandlers( $content ); 31 } 32 ); 33 34 window.addEventListener( 'elementor/popup/show', ( event ) => { 35 const instance = event.detail.instance; 36 37 const interval = setInterval( () => { 38 39 if ( ! instance.keyboardHandler ) return; 40 41 const handler = instance.keyboardHandler; 42 const config = handler.config; 43 44 if ( ! config || ! config.$modalElements ) return; 45 46 if ( handler.changeFocusAfterAnimation !== true ) { 47 clearInterval( interval ); 48 return; 49 } 50 51 const $input = instance.$element.find('.jet-ajax-search__field'); 52 53 if ( $input.length ) { 54 handler.firstFocusableElement = $input[0]; 55 } 56 57 clearInterval( interval ); 58 59 }, 50) ; 60 61 setTimeout( () => clearInterval( interval ), 1000 ); 62 63 }); 64 65 /* 66 // Example of usage AJAX success trigger 67 $( document ).on( 'jet-ajax-search/show-results', function( event, searchResults ) { 68 searchResults.find( '.jet-ajax-search__results-item' ).css( 'border', '2px solid red' ); 69 } ); 70 */ 71 72 /* 73 * Example of usage `jet-ajax-search/results-area/listing-add-suggestion` trigger 74 * 75 * Parameters: 76 * - itemWrapper: A CSS selector that points to the element containing the wrapper of the search result item. 77 * - itemLink: Represents the element that contains the link of the search result item. 78 * - itemTitle: A CSS selector that points to the element containing the title of the search result item. 79 * - itemUrlAttr: Specifies the attribute used to extract the URL from the itemLink. 80 $( document ).on( "jet-ajax-search/results-area/listing-add-suggestion", function( event, itemWrapper, itemLink, itemTitle, itemUrlAttr ) { 81 itemWrapper = '.jet-ajax-search__results-item', 82 itemLink = $( '.jet-listing-dynamic-image__link', itemWrapper ); 83 itemTitle = '.jet-ajax-search-item-title .jet-listing-dynamic-field__content'; 84 itemUrlAttr = 'href'; 85 86 window.JetSearch.addSuggestionFromResultAreaItem( itemWrapper, itemLink, itemTitle, itemUrlAttr ); 87 } ); 88 */ 89 }, 90 91 initBricks: function( $scope ) { 92 93 if ( window.bricksIsFrontend ) { 94 return; 95 } 96 97 $scope = $scope || $( 'body' ); 98 99 JetSearch.initBlocks( $scope ); 100 101 }, 102 103 initBlocks: function( $scope ) { 104 105 $scope = $scope || $( 'body' ); 106 107 window.JetPlugins.init( $scope, [ 108 { 109 block: 'jet-search/ajax-search', 110 callback: JetSearch.widgetAjaxSearch 111 }, 112 { 113 block: 'jet-search/search-suggestions', 114 callback: JetSearch.widgetSearchSuggestions 115 } 116 ] ); 117 }, 118 119 widgetAjaxSearch: function( $scope ) { 120 121 var settings = { 122 searchClass: '.jet-ajax-search', 123 searchFormClass: '.jet-ajax-search__form', 124 fieldsHolderClass: '.jet-ajax-search__fields-holder', 125 inputClass: '.jet-ajax-search__field', 126 settingsInput: 'input[name="jet_ajax_search_settings"]', 127 submitClass: '.jet-ajax-search__submit', 128 chosenClass: '.jet-ajax-search__categories select[name="jet_ajax_search_categories"]', 129 resultsAreaClass: '.jet-ajax-search__results-area', 130 resultsHeaderClass: '.jet-ajax-search__results-header', 131 resultsFooterClass: '.jet-ajax-search__results-footer', 132 listHolderClass: '.jet-ajax-search__results-holder', 133 listClass: '.jet-ajax-search__results-list', 134 listInnerClass: '.jet-ajax-search__results-list-inner', 135 listSlideClass: '.jet-ajax-search__results-slide', 136 itemClass: '.jet-ajax-search__results-item', 137 inlineSuggestionsAreaClass: '.jet-ajax-search__suggestions-inline-area', 138 inlineSuggestionsItemClass: '.jet-ajax-search__suggestions-inline-area-item', 139 resultsSuggestionsAreaClass: '.jet-ajax-search__results-suggestions-area', 140 resultsSuggestionItemClass: '.jet-ajax-search__results-suggestions-area-item', 141 countClass: '.jet-ajax-search__results-count', 142 messageHolderClass: '.jet-ajax-search__message', 143 fullResultsClass: '.jet-ajax-search__full-results', 144 navigationClass: '.jet-ajax-search__navigation-holder', 145 navButtonClass: '.jet-ajax-search__navigate-button', 146 bulletClass: '.jet-ajax-search__bullet-button', 147 numberClass: '.jet-ajax-search__number-button', 148 prevClass: '.jet-ajax-search__prev-button', 149 nextClass: '.jet-ajax-search__next-button', 150 activeNavClass: '.jet-ajax-search__active-button', 151 disableNavClass: '.jet-ajax-search__navigate-button-disable', 152 spinnerClass: '.jet-ajax-search__spinner-holder', 153 handlerId: 'jetSearchSettings', 154 isRtl: ( window.elementorFrontend && window.elementorFrontend.config.is_rtl ) ? window.elementorFrontend.config.is_rtl : $( 'body' ).hasClass( 'rtl' ) 155 }; 156 157 if ( $scope.hasClass('jet-ajax-search-block') ) { 158 var resultAreaWidthBy = $scope.find( settings.searchClass ).data('settings')['results_area_width_by'], 159 resultAreaCustomWidth = $scope.find( settings.searchClass ).data('settings')['results_area_custom_width'], 160 resultAreaCustomWidthPosition = $scope.find( settings.searchClass ).data('settings')['results_area_custom_position'], 161 resultAreaContainer = $( '.jet-ajax-search__results-area', $scope ); 162 163 if ( "custom" === resultAreaWidthBy ) { 164 if ( "" !== resultAreaCustomWidth ) { 165 resultAreaContainer.width( resultAreaCustomWidth ); 166 } 167 168 switch( resultAreaCustomWidthPosition ) { 169 case 'left': 170 resultAreaContainer.css( "left", 0 ); 171 resultAreaContainer.css( "right", "auto" ); 172 break; 173 case 'center': 174 resultAreaContainer.css( "left", "50%" ); 175 resultAreaContainer.css( "right", "auto" ); 176 resultAreaContainer.css( "-webkit-transform", "translateX(-55%)" ); 177 resultAreaContainer.css( "transform", "translateX(-50%)" ); 178 break; 179 case 'right': 180 resultAreaContainer.css( "left", "auto" ); 181 resultAreaContainer.css( "right", 0 ); 182 break; 183 } 184 } 185 } 186 187 $scope.find( settings.searchClass ).jetAjaxSearch( settings ); 188 189 var $chosenSelect = $scope.find( settings.chosenClass ); 190 191 if ( $chosenSelect[0] ) { 192 $chosenSelect.chosen( { 193 disable_search: true, 194 placeholder_text: '', 195 placeholder_text_single: '' 196 } ); 197 } 198 }, 199 200 widgetSearchSuggestions: function( $scope ) { 201 202 let $target = $scope.find( '.jet-search-suggestions' ), 203 settings = { 204 searchClass: '.jet-search-suggestions', 205 searchFormClass: '.jet-search-suggestions__form', 206 fieldsHolderClass: '.jet-search-suggestions__fields-holder', 207 inputClass: '.jet-search-suggestions__field', 208 spinnerClass: '.jet-search-suggestions__spinner-holder', 209 messageHolderClass: '.jet-search-suggestions__message', 210 settingsInput: 'input[name="jet_search_suggestions_settings"]', 211 submitClass: '.jet-search-suggestions__submit', 212 chosenClass: '.jet-search-suggestions__categories select[name="jet_search_suggestions_categories"]', 213 inlineClass: '.jet-search-suggestions__inline-area', 214 inlineItemClass: '.jet-search-suggestions__inline-area-item', 215 focusClass: '.jet-search-suggestions__focus-area', 216 focusHolderClass: '.jet-search-suggestions__focus-results-holder', 217 focusItemClass: '.jet-search-suggestions__focus-area-item', 218 handlerId: 'jetSearchSettings', 219 isRtl: ( window.elementorFrontend && window.elementorFrontend.config.is_rtl ) ? window.elementorFrontend.config.is_rtl : $( 'body' ).hasClass( 'rtl' ) 220 }, 221 $chosenSelect = $scope.find( settings.chosenClass ); 222 223 $target.jetAjaxSearchSuggestions( settings ); 224 225 if ( $chosenSelect[0] ) { 226 $chosenSelect.chosen( { 227 disable_search: true, 228 placeholder_text: '', 229 placeholder_text_single: '' 230 } ); 231 } 232 }, 233 234 setFormSuggestion: function( name, form, url = '' ) { 235 const ajaxSettings = window['jetSearchSettings']['searchSuggestions'] || {}, 236 sendData = { 237 name: name 238 }, 239 nonce = ajaxSettings.nonce_rest; 240 241 const ajaxData = { 242 action: ajaxSettings.add_action, 243 data: sendData || {}, 244 nonce: ajaxSettings.nonce 245 }; 246 247 $.ajax( { 248 type: 'POST', 249 url: ajaxSettings.add_suggestions_rest_api_url, 250 data: ajaxData, 251 dataType: 'json', 252 beforeSend: function( jqXHR ) { 253 jqXHR.setRequestHeader( 'X-WP-Nonce', nonce ); 254 }, 255 complete: function() { 256 if ( false != form ) {
257 if ( '' != url ) { 258 url = JetSearch.getResultsUrl( form, url ); 259 260 window.location.href = url; 261 } else { 262 form.submit(); 263 } 264 } else { 265 window.location.href = url; 266 } 267 } 268 } ); 269 }, 270 getResultsUrl: function( form, url = '' ) { 271 let redirectUrl = ''; 272 273 if ( '' != url ) { 274 redirectUrl = url; 275 } else { 276 redirectUrl = form.attr( 'action' ); 277 } 278 279 let formData = {}, 280 result = ''; 281 282 formData = form.serializeArray().reduce( function( obj, item ) { 283 if ( item.name === 's' ) { 284 item.value = item.value.replace(/\u3000/g, ' '); 285 } 286 287 obj[item.name] = item.value; 288 289 return obj; 290 }, {} ); 291 292 if ( Object.keys( formData ).length > 0 ) { 293 result = redirectUrl + '?' + $.param( formData ).replace(/=&/g, '&' ).replace(/=$/, '');; 294 } else { 295 result = redirectUrl; 296 } 297 298 return result; 299 }, 300 suggestionsPreloader: function( is_active, state, preloader ) { 301 if ( ! is_active ) { 302 return; 303 } 304 305 if ( '' != preloader ) { 306 if ( 'show' === state ) { 307 preloader.addClass( 'show' ); 308 } else if ( 'hide' === state ) { 309 preloader.removeClass( 'show' ); 310 } 311 } 312 }, 313 getUrlParams: function() { 314 let params = {}, 315 queryString = window.location.search.slice(1); 316 317 if ( queryString ) { 318 let pairs = queryString.split( '&' ); 319 320 for ( let i = 0; i < pairs.length; i++ ) { 321 let pair = pairs[i].split( '=' ); 322 323 params[pair[0]] = decodeURIComponent( pair[1] || '' ); 324 } 325 } 326 327 return params; 328 }, 329 md5: function(str) { 330 let hash = ''; 331 332 for (let i = 0; i < str.length; i++) { 333 let char = str.charCodeAt(i); 334 hash += char; 335 } 336 return hash; 337 }, 338 generateHash: function( string, length = 6 ) { 339 let md5Hash = JetSearch.md5( string ), 340 hash = ''; 341 342 for ( let i = 0; i < length; i++ ) { 343 hash += md5Hash.charAt( Math.floor( Math.random() * md5Hash.length ) ); 344 } 345 346 hash = hash.toLowerCase(); 347 348 return hash; 349 }, 350 generateRandomId: function() { 351 let hash = JetSearch.generateHash( Math.random().toString() ); 352 353 return hash; 354 }, 355 initElementsHandlers: function( $selector ) { 356 // Actual init 357 window.JetPlugins.init( $selector ); 358 359 // Legacy Elementor-only init 360 $selector.find( '[data-element_type]' ).each( function() { 361 var excludeWidgets = [ 362 'nav-menu.default', 363 'jet-woo-product-gallery-slider.default', 364 'accordion.default' 365 ]; 366 367 var $this = $( this ), 368 elementType = $this.data( 'element_type' ); 369 370 if ( !elementType ) { 371 return; 372 } 373 374 if ( 'widget' === elementType ) { 375 elementType = $this.data( 'widget_type' ); 376 377 if ( excludeWidgets.includes( elementType ) ) { 378 return; 379 } 380 381 window.elementorFrontend.hooks.doAction( 'frontend/element_ready/widget', $this, $ ); 382 } 383 384 window.elementorFrontend.hooks.doAction( 'frontend/element_ready/global', $this, $ ); 385 window.elementorFrontend.hooks.doAction( 'frontend/element_ready/' + elementType, $this, $ ); 386 } ); 387 388 if ( window.elementorFrontend ) { 389 const elementorLazyLoad = new Event( "elementor/lazyload/observe" ); 390 document.dispatchEvent( elementorLazyLoad ); 391 } 392 393 if ( window.JetPopupFrontend && window.JetPopupFrontend.initAttachedPopups ) { 394 window.JetPopupFrontend.initAttachedPopups( $selector ); 395 } 396 }, 397 reinitSlickSlider: function( $scope ) { 398 var $slider = $scope.find('.slick-initialized'); 399 400 if ( $slider.length ) { 401 402 $slider.each( function() { 403 $( this ).slick('unslick'); 404 } ); 405 } 406 }, 407 enqueueAssetsFromResponse: function( response ) { 408 if ( response.data.scripts ) { 409 JetSearch.enqueueScripts( response.data.scripts ); 410 } 411 412 if ( response.data.styles ) { 413 JetSearch.enqueueStyles( response.data.styles ); 414 } 415 }, 416 417 enqueueScripts: function( scripts ) { 418 $.each( scripts, function( handle, scriptHtml ) { 419 JetSearch.enqueueScript( handle, scriptHtml ) 420 } ); 421 }, 422 423 enqueueStyles: function( styles ) { 424 $.each( styles, function( handle, styleHtml ) { 425 JetSearch.enqueueStyle( handle, styleHtml ) 426 } ); 427 }, 428 429 enqueueScript: function( handle, scriptHtml ) { 430 431 if ( -1 !== JetSearch.addedScripts.indexOf( handle ) ) { 432 return; 433 } 434 435 if ( ! scriptHtml ) { 436 return; 437 } 438 439 var selector = 'script[id="' + handle + '-js"]'; 440 441 if ( $( selector ).length ) { 442 return; 443 } 444 445 var scriptsTags = scriptHtml.match( /<script[\s\S]*?<\/script>/gm ); 446 447 if ( scriptsTags.length ) { 448 449 for ( var i = 0; i < scriptsTags.length; i++ ) { 450 451 JetSearch.assetsPromises.push( 452 new Promise( function( resolve, reject ) { 453 454 var $tag = $( scriptsTags[i] ); 455 456 if ( $tag[0].src ) { 457 458 var tag = document.createElement( 'script' ); 459 460 tag.type = $tag[0].type; 461 tag.src = $tag[0].src; 462 tag.id = $tag[0].id; 463 tag.async = false;
464 tag.onload = function() { 465 resolve(); 466 }; 467 468 document.body.append( tag ); 469 } else { 470 $( 'body' ).append( scriptsTags[i] ); 471 resolve(); 472 } 473 } ) 474 ); 475 } 476 } 477 478 JetSearch.addedScripts.push( handle ); 479 }, 480 481 enqueueStyle: function( handle, styleHtml ) { 482 483 if ( -1 !== handle.indexOf( 'google-fonts' ) ) { 484 JetSearch.enqueueGoogleFonts( handle, styleHtml ); 485 return; 486 } 487 488 if ( -1 !== JetSearch.addedStyles.indexOf( handle ) ) { 489 return; 490 } 491 492 var selector = 'link[id="' + handle + '-css"],style[id="' + handle + '"]'; 493 494 if ( $( selector ).length ) { 495 return; 496 } 497 498 $( 'head' ).append( styleHtml ); 499 500 JetSearch.addedStyles.push( handle ); 501 502 if ( -1 !== handle.indexOf( 'elementor-post' ) ) { 503 var postID = handle.replace( 'elementor-post-', '' ); 504 JetSearch.addedPostCSS.push( postID ); 505 } 506 }, 507 508 enqueueGoogleFonts: function( handle, styleHtml ) { 509 510 var selector = 'link[id="' + handle + '-css"]'; 511 512 if ( $( selector ).length ) {} 513 514 $( 'head' ).append( styleHtml ); 515 }, 516 517 reinitBricksScripts: function( _this ) { 518 519 if ( !$( 'body' ).hasClass( 'theme-bricks' ) && !$( 'body' ).hasClass( 'bricks-is-frontend') ) { 520 return; 521 } 522 523 const resultsArea = $( '.jet-ajax-search__results-list', _this ); 524 const sourcesHolder = $( '.jet-ajax-search__source-results-holder', _this ); 525 526 //Results Area 527 resultsArea.find( '[data-script-id]' ).each( function() { 528 const newId = JetSearch.generateRandomId(); 529 530 $( this ).attr( 'data-script-id', newId ); 531 } ); 532 533 resultsArea.find( '[id^="brxe-"]' ).each( function() { 534 var id = $( this ).attr( 'id' ); 535 536 $( this ).addClass( id ); 537 } ); 538 539 const bricksScripts = { 540 ".bricks-lightbox": 'bricksPhotoswipe', 541 ".brxe-accordion, .brxe-accordion-nested": 'bricksAccordion', 542 ".brxe-animated-typing": 'bricksAnimatedTyping', 543 ".brxe-audio": 'bricksAudio', 544 ".brxe-countdown": 'bricksCountdown', 545 ".brxe-counter": 'bricksCounter', 546 ".brxe-video": 'bricksVideo', 547 ".bricks-lazy-hidden": 'bricksLazyLoad', 548 ".brx-animated": 'bricksAnimation', 549 ".brxe-pie-chart": 'bricksPieChart', 550 ".brxe-progress-bar .bar span": 'bricksProgressBar', 551 ".brxe-form": 'bricksForm', 552 ".brx-query-trail": 'bricksInitQueryLoopInstances', 553 "[data-interactions]": 'bricksInteractions', 554 ".brxe-alert svg": 'bricksAlertDismiss', 555 ".brxe-tabs, .brxe-tabs-nested": 'bricksTabs', 556 ".bricks-video-overlay, .bricks-video-overlay-icon, .bricks-video-preview-image": 'bricksVideoOverlayClickDetector', 557 ".bricks-background-video-wrapper": 'bricksBackgroundVideoInit', 558 ".brxe-toggle": 'bricksToggle', 559 ".brxe-offcanvas": 'bricksOffcanvas', 560 '.brxe-slider': 'bricksSwiper', 561 '.brxe-slider-nested': 'bricksSplide', 562 '.brxe-image': 'bricksSwiper' 563 }; 564 565 const contentWrapper = resultsArea[0]; 566 567 //Result Area 568 for ( const key in bricksScripts ) { 569 const widget = contentWrapper.querySelector(key); 570 571 if ( widget && typeof window[bricksScripts[key]] === "function" && bricksScripts[key] ) { 572 window[bricksScripts[key]](); 573 } 574 } 575 576 //Sources Holder 577 if ( sourcesHolder.length ) { 578 sourcesHolder.find( '[data-script-id]' ).each( function() { 579 const newId = JetSearch.generateRandomId(); 580 581 $( this ).attr( 'data-script-id', newId ); 582 } ); 583 584 sourcesHolder.find( '[id^="brxe-"]' ).each( function() { 585 var id = $( this ).attr( 'id' ); 586 587 $( this ).addClass( id ); 588 } ); 589 590 const sourcesWrapper = sourcesHolder[0]; 591 592 for ( const key in bricksScripts ) { 593 const widget = sourcesWrapper.querySelector( key ); 594 595 if ( widget && typeof window[bricksScripts[key]] === "function" && bricksScripts[key] ) { 596 window[bricksScripts[key]](); 597 } 598 } 599 } 600 }, 601 602 getCurrentDeviceMode: function() { 603 const width = window.innerWidth; 604 605 if ( width > 1024 ) { 606 return 'desktop'; 607 } else if ( width <= 1024 && width > 767 ) { 608 return 'tablet'; 609 } else { 610 return 'mobile'; 611 } 612 }, 613 614 trimString: function( str, numWords ) { 615 if ( typeof str !== 'string' ) { 616 return str; 617 } 618 619 let wordsArray = str.split( ' ' ); 620 621 if ( wordsArray.length <= numWords ) { 622 return str; 623 } 624 625 let truncatedString = wordsArray.slice( 0, numWords ).join( ' ' ); 626 627 return truncatedString + '...'; 628 }, 629 630 escapeHTML: function( str ) { 631 return str.replace(/[&<>"']/g, function ( match ) { 632 const escapeMap = { 633 '&': '&', 634 '<': '<', 635 '>': '>', 636 '"': '"', 637 "'": ''' 638 }; 639 640 return escapeMap[match]; 641 } ); 642 }, 643
644 addSuggestionFromResultAreaItem: function( itemWrapper, itemLink, itemTitle, itemUrlAttr ) { 645 itemLink.on( 'click', function( e ) { 646 e.stopImmediatePropagation(); 647 e.preventDefault(); 648 649 let item = $( this ).closest( itemWrapper ), 650 value = $( itemTitle, item ).text(), 651 url = $( this ).attr( itemUrlAttr ); 652 653 JetSearch.setFormSuggestion( value, false, url ); 654 } ); 655 } 656 }; 657 658 $.fn.getSuggestionsList = function( options, settings, showSpinner, hightlightText = false, callback = () => {} ) { 659 let self = this[0], 660 outputHtml = '', 661 listPosition = options.list_position, 662 inlineItemTemplate = wp.template( 'jet-search-inline-suggestion-item' ), 663 focusItemTemplate = wp.template( 'jet-search-focus-suggestion-item' ), 664 spinner = $( settings.spinnerClass, self ), 665 manualList = []; 666 667 const ajaxSettings = window['jetSearchSettings']['searchSuggestions'] || {}; 668 669 function highlightMatches( item ) { 670 let searched = options.value.trim(); 671 672 if ( searched !== "" ) { 673 let reg = new RegExp("[\>][^\<]*"+searched+"[^\<]*[\<]","gi"), 674 reg2 = new RegExp( searched, "gi" ), 675 regHtml = new RegExp("<\/?[a-z](.*?)[\s\S]*>", "gi"); 676 677 if ( reg.test( item ) ) { 678 item = item.replace( reg, function( item ) { 679 let subRegex = new RegExp( searched, "gi" ); 680 return item.replace( subRegex,`<mark>${searched}</mark>` ); 681 } ); 682 } 683 684 if ( regHtml.test( item ) ) { 685 return item; 686 } else { 687 item = item.replace( reg2, str => `<mark>${str}</mark>` ); 688 } 689 } 690 691 return item; 692 } 693 694 if ( 'manual' === options.list_type ) { 695 696 if ( options['manual_list'].length ) { 697 let list = options['manual_list'].split( "," ); 698 699 list.map( function( suggestion, i ) { 700 manualList[i] = { name: suggestion }; 701 } ); 702 703 if ( 'inline' === listPosition ) { 704 manualList.map( function( suggestion ) { 705 outputHtml += inlineItemTemplate( suggestion ); 706 } ); 707 708 $( self ).html( outputHtml ); 709 } else if ( 'focus' === listPosition ) { 710 manualList.map( function( suggestion ) { 711 outputHtml += focusItemTemplate( suggestion ); 712 } ); 713 714 $( settings.focusHolderClass ,self ).html( outputHtml ); 715 716 if ( typeof callback === 'function' ) { 717 callback(); 718 } 719 720 JetSearch.suggestionsPreloader( showSpinner, 'hide', spinner ); 721 } 722 } 723 724 return; 725 } 726 727 let sendData = { 728 list_type: options.list_type || '', 729 value: options.value || '', 730 limit: options.limit 731 }, 732 ajaxData = { 733 action: ajaxSettings.get_action, 734 data: sendData || {}, 735 }; 736 737 jQuery.ajax( { 738 type: 'GET', 739 url: ajaxSettings.get_suggestions_rest_api_url, 740 data: ajaxData, 741 dataType: 'json', 742 cache: false, 743 processData: true, 744 error: function( jqXHR, textStatus, errorThrown ) { 745 errorCallback( jqXHR ); 746 }, 747 success: function( response, textStatus, jqXHR ) { 748 successCallback( response ); 749 if ( typeof callback === 'function' ) { 750 callback(); 751 } 752 } 753 } ); 754 755 const successCallback = function( response ) { 756 757 if ( response ) { 758 JetSearch.suggestionsPreloader( showSpinner, 'hide', spinner ); 759 760 if ( 'inline' === listPosition ) { 761 response.map( function( suggestion ) { 762 suggestion['name'] = JetSearch.escapeHTML( suggestion['name'] ); 763 suggestion['fullName'] = JetSearch.escapeHTML( suggestion['name'] ); 764 765 if ( 0 < options.maxLength ) { 766 suggestion['name'] = JetSearch.trimString( suggestion['name'], options.maxLength ); 767 } 768 769 outputHtml += inlineItemTemplate( suggestion ); 770 } ); 771 772 $( self ).html( outputHtml ); 773 } else if ( 'focus' === listPosition ) { 774 775 response.map( function( suggestion ) { 776 suggestion['name'] = JetSearch.escapeHTML( suggestion['name'] ); 777 suggestion['fullName'] = JetSearch.escapeHTML( suggestion['name'] ); 778 779 if ( 0 < options.maxLength ) { 780 suggestion['name'] = JetSearch.trimString( suggestion['name'], options.maxLength ); 781 } 782 783 if ( options.value && ( "yes" === hightlightText || true === hightlightText ) ) {
784 suggestion['name'] = highlightMatches( suggestion['name'] ); 785 } 786 787 outputHtml += focusItemTemplate( suggestion ); 788 } ); 789 790 $( settings.focusHolderClass, self ).html( outputHtml ); 791 } 792 } 793 } 794 795 const errorCallback = function( jqXHR ) { 796 if ( 'abort' !== jqXHR.statusText ) { 797 JetSearch.suggestionsPreloader( showSpinner, 'hide', spinner ); 798 } 799 }; 800 }; 801 802 /** 803 * jetAjaxSearchSuggestions jQuery Plugin 804 * 805 * @param args 806 */ 807 $.fn.jetAjaxSearchSuggestions = function( args ) { 808 let self = this[0], 809 settings = args, 810 options = $( self ).data( 'settings' ) || {}, 811 timer = null, 812 showformList = options['show_search_suggestions_list_inline'] || false, 813 showfocusList = options['show_search_suggestions_list_on_focus'] || false, 814 formListType = options['search_suggestions_list_inline'] || false, 815 focusListType = options['search_suggestions_list_on_focus'] || false, 816 searchSuggestionsLimit = options['search_suggestions_quantity_limit'] || 10, 817 inlineLimit = options['search_suggestions_list_inline_quantity'] || 5, 818 focusLimit = options['search_suggestions_list_on_focus_quantity'] || 5, 819 showSpinner = options['show_search_suggestions_list_on_focus_preloader'] || '', 820 hightlightText = options['highlight_searched_text'] || '', 821 spinner = $( settings.spinnerClass, self ), 822 formFocusClass = settings.searchFormClass.replace( '.', '' ) + '--focus', 823 form = $( settings.searchFormClass, self ), 824 focusTarget = $( settings.focusHolderClass, self ), 825 disableInputs = false, 826 customResultUrl = options['search_results_url'] || '', 827 useSession = 'false', 828 focusItem; 829 830 if ( window.elementorFrontend ) { 831 var editMode = Boolean( window.elementorFrontend.isEditMode() ) 832 } else { 833 var editMode = false; 834 } 835 836 if ( !self.isInit ) { 837 self.isInit = true; 838 839 /** 840 * Ajax settings from localized global variable 841 */ 842 self.ajaxSettings = window[ settings.handlerId ]['searchSuggestions'] || {}; 843 844 customResultUrl = $.trim( customResultUrl ); 845 useSession = self.ajaxSettings.use_session; 846 847 self.selectSuggestion = function( event ) { 848 const keyCode = event.keyCode || event.which; 849 850 let value = event.target.parentElement.getAttribute('aria-label').trim(); 851 852 if ( false === disableInputs && !editMode ) { 853 854 if ( 'keydown' === event.type ) { 855 if ( 13 === keyCode ) { 856 disableInputs = true; 857 858 $( settings.inputClass, self )[0].value = value; 859 860 JetSearch.setFormSuggestion( value, form, customResultUrl ); 861 } 862 } else if ( 'click' === event.type ) { 863 disableInputs = true; 864 865 $( settings.inputClass, self )[0].value = value; 866 JetSearch.setFormSuggestion( value, form, customResultUrl ); 867 } 868 } 869 } 870 871 self.focusItemsNav = function() { 872 focusItem = $( '.jet-search-suggestions__focus-area-item', self ); 873 874 if ( 0 < focusItem.length ) { 875 focusItem.on( 'keydown', function( e ) { 876 const keyCode = e.keyCode || e.which; 877 878 switch ( keyCode ) { 879 case 40: // Down arrow 880 e.preventDefault(); 881 882 var next = $( this ).next(); 883 884 if ( next.length > 0 ) { 885 focusItem.removeClass( 'focused' ); 886 next.addClass( 'focused' ); 887 next.focus(); 888 } 889 break; 890 891 case 38: // Up arrow 892 e.preventDefault(); 893 894 var prev = $( this ).prev(); 895 896 if ( prev.length > 0 ) { 897 focusItem.removeClass( 'focused' ); 898 prev.addClass( 'focused' ); 899 prev.focus(); 900 } else { 901 focusItem.removeClass( 'focused' ); 902 $( settings.inputClass, self ).focus(); 903 } 904 break; 905 case 13: 906 e.preventDefault(); 907 let value = e.target.innerText.trim(); 908 $( settings.inputClass, self )[0].value = value; 909 910 JetSearch.setFormSuggestion( value, form, customResultUrl ); 911 break; 912 } 913 914 if ( $( this ).is( ':focus-visible' ) ) { 915 focusItem.removeClass( 'focused' ); 916 } 917 } ); 918 } 919 } 920 921 if ( formListType || focusListType ) { 922
923 if ( '' != formListType && ( "yes" === showformList || true === showformList ) ) { 924 let listOptions = { 925 list_position: 'inline', 926 list_type: formListType, 927 limit: inlineLimit, 928 maxLength: options.search_suggestions_list_inline_item_title_length, 929 }; 930 931 if ( 'manual' === formListType ) { 932 listOptions.manual_list = options['search_suggestions_list_inline_manual']; 933 } 934 935 $( settings.inlineClass, self ).getSuggestionsList( listOptions, settings, showSpinner, false, () => { 936 let inlineItem = $( '.jet-search-suggestions__inline-area-item', self ); 937 938 if ( 0 < inlineItem.length ) { 939 inlineItem.on( 'focus', function () { 940 if ( $( this ).is( ':focus-visible' ) ) { 941 self.hideList(); 942 } 943 } ); 944 } 945 946 inlineItem.on( 'keydown', function( e ) { 947 const keyCode = e.keyCode || e.which; 948 949 let value = e.target.parentElement.getAttribute('aria-label').trim(); 950 951 if ( 13 === keyCode ) { 952 $( settings.inputClass, self )[0].value = value; 953 954 JetSearch.setFormSuggestion( value, form, customResultUrl ); 955 } 956 } ); 957 } ); 958 } 959 960 if ( '' != focusListType && ( "yes" === showfocusList || true === showfocusList ) ) { 961 let listOptions = { 962 list_position: 'focus', 963 list_type: focusListType, 964 limit: focusLimit, 965 maxLength: options.search_suggestions_list_on_focus_item_title_length || 0, 966 }; 967 968 if ( 'manual' === focusListType ) { 969 listOptions.manual_list = options['search_suggestions_list_on_focus_manual']; 970 } 971 972 $( settings.focusClass, self ).getSuggestionsList( listOptions, settings, showSpinner, false, () => { 973 self.focusItemsNav(); 974 } ); 975 } 976 } 977 978 self.inputChangeHandler = function( event ) { 979 980 let value = $( event.target ).val(), 981 listOptions = { 982 list_position: 'focus', 983 value: value, 984 limit: searchSuggestionsLimit, 985 maxLength: options.search_suggestions_list_on_focus_item_title_length || 0, 986 }; 987 988 if ( '' != value ) { 989 focusTarget.empty(); 990 self.showList(); 991 JetSearch.suggestionsPreloader( showSpinner, 'show', spinner ); 992 993 clearTimeout( timer ); 994 timer = setTimeout( function() { 995 $( settings.focusClass, self ).getSuggestionsList( listOptions, settings, showSpinner, hightlightText, () => { 996 self.focusItemsNav(); 997 } ); 998 }, 450 ); 999 } else { 1000 clearTimeout( timer ); 1001 focusTarget.empty(); 1002 JetSearch.suggestionsPreloader( showSpinner, 'hide', spinner ); 1003 1004 if ( false != focusListType && ( "yes" === showfocusList || true === showfocusList ) ) { 1005 JetSearch.suggestionsPreloader( showSpinner, 'show', spinner ); 1006 1007 listOptions.limit = focusLimit; 1008 1009 if ( 'manual' === focusListType ) { 1010 listOptions.list_type = focusListType; 1011 listOptions.manual_list = options['search_suggestions_list_on_focus_manual']; 1012 } 1013 1014 $( settings.focusClass, self ).getSuggestionsList( listOptions, settings, showSpinner, false, () => { 1015 self.focusItemsNav(); 1016 } ); 1017 } 1018 } 1019 }; 1020 1021 self.hideList = function(event) { 1022 $( settings.focusClass, self ).removeClass( 'show' ); 1023 $( '.chosen-single', self ).removeClass( 'focused' ); 1024 1025 if ( focusItem && 0 < focusItem.length ) { 1026 focusItem.removeClass( 'focused' ); 1027 } 1028 }; 1029 1030 self.showList = function() { 1031 $( settings.focusClass, self ).addClass( 'show' ); 1032 }; 1033 1034 self.focusHandler = function( event ) { 1035 $( settings.searchFormClass, self ).addClass( formFocusClass ); 1036 self.showList(); 1037 }; 1038 1039 self.chosenFocusHandler = function() { 1040 self.hideList(); 1041 }; 1042 1043 self.formClick = function( event ) { 1044 event.stopPropagation(); 1045 }; 1046 1047 self.changeHandler = function( event ) { 1048 let target = $( event.target ), 1049 settingsInput = $( settings.settingsInput, self ), 1050 querySettings = JSON.parse( settingsInput.val() ), 1051 globalQuerySettings = $( self ).data( 'settings' ); 1052 1053 querySettings.category__in = target.val(); 1054 globalQuerySettings.category__in = target.val(); 1055 1056 settingsInput.val( JSON.stringify( querySettings ) ); 1057 $( self ).data( 'settings', globalQuerySettings ); 1058 1059 self.inputChangeHandler( { target: $( settings.inputClass, self ) } ) 1060 }; 1061 1062 self.formSubmit = function( event ) { 1063 let keyCode = event.keyCode || event.which; 1064 1065 if ( false === disableInputs ) { 1066 let value = event.target.value; 1067 1068 if ( 13 === keyCode && value.length != 0 ) { 1069 disableInputs = true; 1070 event.preventDefault(); 1071 1072 JetSearch.setFormSuggestion( value, form, customResultUrl ); 1073 } 1074 } 1075 1076 if ( 40 === keyCode ) {
1077 if ( focusItem && 0 < focusItem.length ) { 1078 event.preventDefault(); 1079 focusItem.removeClass( 'focused' ); 1080 focusItem.first().addClass( 'focused' ); 1081 focusItem.first().focus(); 1082 } 1083 } 1084 } 1085 1086 self.blurHandler = function( event ) { 1087 $( settings.searchFormClass, self ).removeClass( formFocusClass ); 1088 }; 1089 1090 self.clickFullResults = function( event ) { 1091 if ( false === disableInputs ) { 1092 disableInputs = true; 1093 1094 var searchInput = $( settings.inputClass, self ), 1095 value = searchInput.val(); 1096 1097 event.preventDefault(); 1098 1099 JetSearch.setFormSuggestion( value, form, customResultUrl ); 1100 } 1101 }; 1102 1103 $( settings.inputClass, self ) 1104 .on( 'input' + settings.searchClass, self.inputChangeHandler ) 1105 .on( 'focus' + settings.searchClass, self.focusHandler ) 1106 .on( 'blur' + settings.searchClass, self.blurHandler ) 1107 .on( 'keydown' + settings.searchClass, self.formSubmit ); 1108 1109 $( settings.submitClass, self ).on( 'click' + settings.searchClass, self.clickFullResults ); 1110 1111 $( self ) 1112 .on( 'click' + settings.searchClass, settings.focusItemClass, self.selectSuggestion ) 1113 .on( 'click keydown' + settings.searchClass, settings.inlineItemClass, self.selectSuggestion ) 1114 .on( 'click' + settings.searchClass, self.formClick ) 1115 .on( 'change', settings.chosenClass, self.changeHandler ) 1116 .on( 'touchend' + settings.searchClass, self.formClick ) 1117 .on( 'chosen:showing_dropdown', settings.chosenClass, self.chosenFocusHandler ); 1118 1119 $( self ).on( 'keydown', function( e ) { 1120 const keyCode = e.keyCode || e.which; 1121 1122 if ( 9 === keyCode ) { 1123 setTimeout( () => { 1124 const focusedElement = document.activeElement; 1125 1126 if ( $( focusedElement ).is( '.chosen-search-input' ) ) { 1127 $( '.chosen-single', self ).addClass( 'focused' ); 1128 } else { 1129 $( '.chosen-single', self ).removeClass( 'focused' ); 1130 } 1131 1132 if ( $( focusedElement ).is( '.jet-search-suggestions__inline-area-item' ) ) { 1133 self.hideList(); 1134 } 1135 }, 50 ); 1136 } 1137 } ); 1138 1139 $( settings.inputClass, self ).on( 'click' + settings.searchClass, () => { 1140 $( '.chosen-single', self ).removeClass( 'focused' ); 1141 } ); 1142 1143 $( 'body' ) 1144 .on( 'click' + settings.searchClass, self.hideList ) 1145 .on( 'touchend' + settings.searchClass, self.hideList ); 1146 1147 // If after reloading the page the value of the select is not '0'. 1148 if ( '0' !== $( settings.chosenClass, self ).val() ) { 1149 $( settings.chosenClass, self ).trigger( 'change' ); 1150 } 1151 } 1152 }; 1153 1154 /** 1155 * JetAjaxSearch jQuery Plugin 1156 * 1157 * @param args 1158 */ 1159 $.fn.jetAjaxSearch = function( args ) { 1160 1161 var self = this[0], 1162 settings = args, 1163 timer = null, 1164 itemTemplate = null, 1165 resultsArea = $( settings.resultsAreaClass, self ), 1166 resultsHolder = $( settings.listHolderClass, resultsArea ), 1167 resultsHeader = $( settings.resultsHeaderClass, resultsArea ), 1168 resultsFooter = $( settings.resultsFooterClass, resultsArea ), 1169 countHolder = $( settings.countClass, resultsArea ), 1170 fullResults = $( settings.fullResultsClass, resultsArea ), 1171 resultsList = $( settings.listClass, resultsArea ), 1172 resultsListInner = $( settings.listInnerClass, resultsArea ), 1173 resultsHeaderNav = $( settings.navigationClass, resultsHeader ), 1174 resultsFooterNav = $( settings.navigationClass, resultsFooter ), 1175 messageHolder = $( settings.messageHolderClass, resultsArea ), 1176 spinner = $( settings.spinnerClass, resultsArea ), 1177 form = $( settings.searchFormClass, self ), 1178 resultsSuggestions = $( settings.resultsSuggestionsAreaClass, self ), 1179 inlineSuggestions = $( settings.inlineSuggestionsAreaClass, self ), 1180 data = $( self ).data( 'settings' ) || [], 1181 customResultUrl = data['search_results_url'] || '', 1182 hightlightText = data['highlight_searched_text'] || '', 1183 formFocusClass = settings.searchFormClass.replace( '.', '' ) + '--focus', 1184 customResultUrl = data['search_results_url'] || '', 1185 searchLogging = data['search_logging'] || '', 1186 currentPosition = 1, 1187 lang = '', 1188 disableInputs = false, 1189 allowEmptyString = false, 1190 allowSubmitOnEnter = 1,
1191 urlParams = JetSearch.getUrlParams(), 1192 listingID = data['listing_id'] || '', 1193 categoryIndex = urlParams.jet_ajax_search_categories || '', 1194 getResultsOnFocus = true, 1195 maxUserSearches = 20, 1196 showSearchSuggestions = data['show_search_suggestions'] || false, 1197 suggestionsTitle = '', 1198 suggestionsType = data['search_suggestions_source'] || false, 1199 suggestionsPosition = data['search_suggestions_position'] || false, 1200 searchSuggestionsLimits = data['search_suggestions_limits'] || 20, 1201 storedUserSearches = JSON.parse( localStorage.getItem('jetUserSearches') ) || [], 1202 suggestionsList = []; 1203 1204 if ( 'yes' === data.search_by_empty_value || true === data.search_by_empty_value ) { 1205 allowEmptyString = true; 1206 } 1207 1208 if ( !self.isInit ) { 1209 self.isInit = true; 1210 1211 /** 1212 * Ajax request instance 1213 */ 1214 self.ajaxRequest = null; 1215 1216 self.suggestionsListLoaded = false; 1217 1218 if ( data.hasOwnProperty('lang') ) { 1219 lang = data.lang; 1220 delete data.lang; 1221 } 1222 1223 /** 1224 * Ajax settings from localized global variable 1225 */ 1226 self.ajaxSettings = window[ settings.handlerId ] || {}; 1227 self.suggestionsSettings = window['jetSearchSettings']['searchSuggestions'] || {}; 1228 1229 if ( self.ajaxSettings['ajaxSearchSuggestionsLimits'] ) { 1230 maxUserSearches = self.ajaxSettings['ajaxSearchSuggestionsLimits']; 1231 } 1232 1233 if ( 'yes' === data.submit_on_enter || true === data.submit_on_enter ) { 1234 allowSubmitOnEnter = false; 1235 } else { 1236 allowSubmitOnEnter = true; 1237 } 1238 1239 if ( '' === self.ajaxSettings.sumbitOnEnter ) { 1240 allowSubmitOnEnter = false; 1241 } 1242 1243 if ( window.elementorFrontend ) { 1244 var editMode = Boolean( window.elementorFrontend.isEditMode() ) 1245 } else { 1246 var editMode = false; 1247 } 1248 1249 self.suggestionsListHTML = function( suggestionsList ) { 1250 1251 let resultsSuggestionsTemplate = wp.template('jet-ajax-search-results-suggestion-item'), 1252 inlineSuggestionsTemplate = wp.template('jet-ajax-search-inline-suggestion-item'), 1253 inlineOutputHtml = '', 1254 resultsOutputHtml = ''; 1255 1256 1257 suggestionsList.forEach( item => { 1258 let inlineListItemHtml = '', 1259 resultsListItemHtml = '', 1260 maxLength = data.search_suggestions_item_title_length || 0, 1261 suggestionItem = {}; 1262 1263 suggestionItem['fullName'] = JetSearch.escapeHTML( item ); 1264 suggestionItem['name'] = JetSearch.escapeHTML( item ); 1265 1266 if ( 0 < maxLength ) { 1267 suggestionItem['name'] = JetSearch.trimString( item, maxLength ); 1268 } 1269 1270 if ( 'under_form' === suggestionsPosition ) { 1271 inlineListItemHtml = inlineSuggestionsTemplate( suggestionItem ); 1272 } else if ( 'inside_results_area' === suggestionsPosition ) { 1273 resultsListItemHtml = resultsSuggestionsTemplate( suggestionItem ); 1274 } 1275 1276 inlineOutputHtml += inlineListItemHtml; 1277 resultsOutputHtml += resultsListItemHtml; 1278 } ); 1279 1280 if ( 'under_form' === suggestionsPosition ) { 1281 suggestionsTitle = inlineSuggestions.html(); 1282 1283 inlineSuggestions.html( inlineOutputHtml ).prepend( suggestionsTitle ); 1284 } else if ( 'inside_results_area' === suggestionsPosition ) { 1285 suggestionsTitle = resultsSuggestions.html(); 1286 1287 resultsSuggestions.html( resultsOutputHtml ).prepend( suggestionsTitle ); 1288 } 1289 }; 1290 1291 self.showSuggestions = function() { 1292 1293 if ( suggestionsType ) { 1294 if ( 'popular' === suggestionsType ) { 1295 1296 if ( false === window.bricksIsFrontend ) { 1297 1298 let sendData = { 1299 list_type: 'popular', 1300 value: '', 1301 limit: searchSuggestionsLimits 1302 }, 1303 ajaxData = { 1304 action: self.ajaxSettings['searchSuggestions'].get_action, 1305 data: sendData || {}, 1306 }; 1307 1308 $.ajax( { 1309 type: 'GET', 1310 url: self.ajaxSettings['searchSuggestions'].get_suggestions_rest_api_url, 1311 data: ajaxData, 1312 dataType: 'json', 1313 cache: false, 1314 processData: true, 1315 error: function( jqXHR, textStatus, errorThrown ) { 1316 errorCallback( jqXHR ); 1317 }, 1318 success: function( response, textStatus, jqXHR ) { 1319 if ( response.length ) { 1320 suggestionsList = $.map( response, function( obj ) { 1321 return obj.name; 1322 } ); 1323 1324 self.suggestionsListLoaded = true; 1325 1326 if ( suggestionsList.length ) { 1327 suggestionsList = suggestionsList.slice( 0, searchSuggestionsLimits ); 1328 1329 self.suggestionsListHTML( suggestionsList ); 1330 } else { 1331 resultsSuggestions.hide(); 1332 inlineSuggestions.hide(); 1333 } 1334 } 1335 } 1336 } ); 1337 } else { 1338 suggestionsList = self.ajaxSettings['ajaxSearchPopularSuggestions'] || []; 1339 1340 if ( suggestionsList.length ) { 1341 suggestionsList = suggestionsList.slice( 0, searchSuggestionsLimits ); 1342 1343 self.suggestionsListHTML( suggestionsList ); 1344 } else { 1345 resultsSuggestions.hide(); 1346 inlineSuggestions.hide(); 1347 } 1348 } 1349 } else if ( 'user' === suggestionsType ) { 1350 let userSearches = localStorage.getItem('jetUserSearches'); 1351 1352 if ( userSearches ) { 1353 suggestionsList = JSON.parse( userSearches ) || []; 1354 1355 suggestionsList.reverse(); 1356 1357 suggestionsList = suggestionsList.slice( 0, searchSuggestionsLimits ); 1358 1359 self.suggestionsListHTML( suggestionsList ); 1360 } else { 1361 resultsSuggestions.hide(); 1362 inlineSuggestions.hide(); 1363 } 1364 } 1365 } 1366 }; 1367 1368 if ( 'yes' === showSearchSuggestions || true === showSearchSuggestions ) { 1369 self.showSuggestions(); 1370 } 1371 1372 self.inputChangeHandler = function( event ) { 1373 var value = $( event.target ).val(), 1374 symbolNumberForStart = 'number' === $.type( data.symbols_for_start_searching ) ? data.symbols_for_start_searching : 2; 1375 1376 value = value.replace(/\u3000/g, ' '); 1377 1378 if ( 'number' === $.type( symbolNumberForStart ) && symbolNumberForStart > value.length ) { 1379 if ( 'inside_results_area' === suggestionsPosition && suggestionsList.length ) { 1380 resultsHeader.hide(); 1381 resultsFooter.hide(); 1382 resultsList.hide(); 1383 resultsSuggestions.show(); 1384 resultsSuggestions.addClass( 'active' ); 1385 resultsHolder.addClass( 'show' ); 1386 self.showList(); 1387 } else { 1388 self.hideList(); 1389 } 1390 1391 return false;
1392 } 1393 1394 if ( 'inside_results_area' === suggestionsPosition && suggestionsList.length ) { 1395 resultsSuggestions.removeClass( 'active' ); 1396 resultsHeader.show(); 1397 resultsFooter.show(); 1398 resultsList.show(); 1399 } 1400 1401 resultsHolder.removeClass( 'show' ); 1402 self.outputMessage( '', '' ); 1403 resultsListInner.css( 'transform', 'translateX(0)' ); 1404 resultsList.css( 'height', 'auto' ); 1405 1406 if ( value ) { 1407 self.showList(); 1408 spinner.addClass( 'show' ); 1409 1410 clearTimeout( timer ); 1411 timer = setTimeout( function() { 1412 data.value = value; 1413 data.deviceMode = window.elementorFrontend && window.elementorFrontend.getCurrentDeviceMode() ? window.elementorFrontend.getCurrentDeviceMode() : JetSearch.getCurrentDeviceMode(); 1414 self.ajaxSendData( data, lang ); 1415 }, 450 ); 1416 } else { 1417 self.hideList(); 1418 } 1419 }; 1420 1421 self.successCallback = function( response ) { 1422 1423 if ( response.error ) { 1424 spinner.removeClass( 'show' ); 1425 self.outputMessage( data.server_error, 'error show' ); 1426 return; 1427 } 1428 1429 JetSearch.enqueueAssetsFromResponse( response ); 1430 1431 var responseData = response.data, 1432 error = responseData.error, 1433 message = responseData.message, 1434 posts = responseData.posts, 1435 listingItems = responseData.listing_items, 1436 post = null, 1437 outputHtml = '', 1438 listItemHtml = '', 1439 listHtml = '<div class="' + settings.listSlideClass.replace( '.', '' ) + '">%s</div>', 1440 searchSources = responseData.sources, 1441 searchSourcesBeforePosts = null, 1442 searchSourcesAfterPosts = null, 1443 countAllResults = null, 1444 searchSourcesHolder = $( '.jet-ajax-search__source-results-holder', self ); 1445 1446 resultsHolder.removeClass( 'show' ); 1447 spinner.removeClass( 'show' ); 1448 currentPosition = 1; 1449 1450 searchSourcesHolder.remove(); 1451 1452 resultsListInner.html( '' ); 1453 resultsHeaderNav.html( '' ); 1454 resultsFooterNav.html( '' ); 1455 1456 searchSourcesBeforePosts = searchSources 1457 .filter( item => item.priority < 0 && '' != item.content ) 1458 .sort( ( a, b ) => a.priority - b.priority ); 1459 1460 searchSourcesAfterPosts = searchSources 1461 .filter( item => item.priority > 0 && '' != item.content ) 1462 .sort( ( a, b ) => a.priority - b.priority ); 1463 1464 if ( '' != listingID && 0 !== responseData.post_count && !error ) { 1465 var outputHtml = '', 1466 listItemHtml = '', 1467 listHtml = '<div class="jet-listing-grid__items jet-listing-base ' + settings.listSlideClass.replace( '.', '' ) + '">%s</div>'; 1468 1469 if ( listingItems.length ) { 1470 $.each( listingItems, ( i, item ) => { 1471 listItemHtml += item; 1472 1473 if ( ( parseInt( i ) + 1 ) % responseData.limit_query == 0 || parseInt( i ) === listingItems.length - 1 ) { 1474 outputHtml += listHtml.replace( '%s', listItemHtml ); 1475 listItemHtml = ''; 1476 } 1477 } ); 1478 } 1479 1480 messageHolder.removeClass( 'show' ); 1481 1482 countAllResults = responseData.post_count; 1483 1484 if ( responseData.sources_results_count && 0 < responseData.sources_results_count ) { 1485 countAllResults += responseData.sources_results_count; 1486 } 1487 1488 $( 'span', countHolder ).html( countAllResults ); 1489 resultsListInner 1490 .html( outputHtml ) 1491 .data( 'columns', responseData.columns ); 1492 1493 Promise.all( JetSearch.assetsPromises ).then( function() { 1494 JetSearch.initElementsHandlers( resultsListInner ); 1495 JetSearch.reinitBricksScripts( self ); 1496 JetSearch.assetsPromises = []; 1497 } ); 1498 1499 resultsHeaderNav.html( responseData.results_navigation.in_header ); 1500 resultsFooterNav.html( responseData.results_navigation.in_footer ); 1501 1502 if ( !countHolder[0] && !responseData.results_navigation.in_header ) { 1503 resultsHeader.addClass( 'is-empty' ); 1504 } else { 1505 resultsHeader.removeClass( 'is-empty' ); 1506 } 1507 1508 if ( !fullResults[0] && !responseData.results_navigation.in_footer ) { 1509 resultsFooter.addClass( 'is-empty' ); 1510 } else { 1511 resultsFooter.removeClass( 'is-empty' ); 1512 } 1513 1514 resultsList.css( 'height', 'auto' ); 1515 1516 $( document ).trigger( 'jet-ajax-search/show-results/listing', [ resultsListInner ] ); 1517 1518 resultsHolder.addClass( 'show' ); 1519 1520 if ( 'yes' === searchLogging || true === searchLogging ) { 1521 let itemWrapper = settings.itemClass, 1522 itemLink = $( '.jet-engine-listing-overlay-wrap', itemWrapper ), 1523 itemTitle = '.jet-ajax-search-item-title .jet-listing-dynamic-field__content', 1524 itemUrlAttr = 'data-url'; 1525 1526 $( document ).trigger( 'jet-ajax-search/results-area/listing-ad
1526d-suggestion', [ self, itemWrapper, itemLink, itemTitle, itemUrlAttr ] ); 1527 1528 JetSearch.addSuggestionFromResultAreaItem( itemWrapper, itemLink, itemTitle, itemUrlAttr ); 1529 } 1530 } 1531 1532 const allowedHighlightFields = [ 'title', 'after_content', 'after_title', 'before_content', 'before_title', 'content', 'price' ]; 1533 1534 function highlightMatches( item ) { 1535 let searched = responseData.search_value.trim(); 1536 1537 if ( searched !== "" ) { 1538 let reg = new RegExp("[\>][^\<]*"+searched+"[^\<]*[\<]","gi"), 1539 reg2 = new RegExp( searched, "gi" ), 1540 regHtml = new RegExp("<\/?[a-z](.*?)[\s\S]*>", "gi"); 1541 1542 if ( reg.test( item ) ) { 1543 item = item.replace( reg, function( item ) { 1544 let subRegex = new RegExp( searched, "gi" ); 1545 return item.replace( subRegex,`<mark>${searched}</mark>` ); 1546 } ); 1547 } 1548 1549 if ( regHtml.test( item ) ) { 1550 return item; 1551 } else { 1552 item = item.replace( reg2, str => `<mark>${str}</mark>` ); 1553 } 1554 } 1555 1556 return item; 1557 } 1558 1559 function highlightFields( fields, allowHighlightFields ) { 1560 1561 $.each( fields, function( key, value ) { 1562 if ( -1 != $.inArray( key, allowHighlightFields ) && ( null != value && '' != value ) ) { 1563 fields[key] = highlightMatches( value ); 1564 } 1565 } ); 1566 1567 return fields; 1568 } 1569 1570 if ( 0 !== responseData.post_count && !error && '' === listingID) { 1571 1572 messageHolder.removeClass( 'show' ); 1573 itemTemplate = wp.template( 'jet-ajax-search-results-item' ); 1574 1575 for ( post in posts ) { 1576 if ( responseData.search_highlight && true === responseData.search_highlight ) { 1577 if ( '' != hightlightText && ( "yes" === hightlightText || true === hightlightText ) ) { 1578 highlightFields( posts[post], allowedHighlightFields ); 1579 } 1580 } 1581 1582 if ( posts[post].is_product ) { 1583 let productType = posts[post].product_type, 1584 productTypeClass = 'add-to-cart-button'; 1585 1586 if ( 'product_type_variable' === productType ) { 1587 productTypeClass = 'select-options-button'; 1588 } 1589 1590 posts[post].add_to_cart = '<div class="jet-ajax-search__item-add-to-cart"><button data-quantity="1" class="jet-ajax-search__results-item-cart-button ' + productTypeClass + '" data-product_id="' + posts[post].product_id + '" data-product_sku="' + posts[post].product_sku + '" aria-label="' + posts[post].product_label + '" data-product_url="' + posts[post].product_url + '" rel="nofollow" target="_blank">' + posts[post].product_add_text + '</button></div>'; 1591 } 1592 1593 let templateResult = itemTemplate( posts[post] ); 1594 1595 listItemHtml += templateResult; 1596 1597 if ( (parseInt( post ) + 1) % responseData.limit_query == 0 || parseInt( post ) === posts.length - 1 ) { 1598 outputHtml += listHtml.replace( '%s', listItemHtml ); 1599 listItemHtml = ''; 1600 } 1601 } 1602 1603 countAllResults = responseData.post_count; 1604 1605 if ( responseData.sources_results_count && 0 < responseData.sources_results_count ) { 1606 countAllResults += responseData.sources_results_count; 1607 } 1608 1609 $( 'span', countHolder ).html( countAllResults ); 1610 resultsListInner 1611 .html( outputHtml ) 1612 .data( 'columns', responseData.columns ); 1613 1614 $( '.jet-ajax-search__results-item-cart-button.add-to-cart-button', self ).on( 'click', function( e ) { 1615 e.preventDefault(); 1616 1617 let _this = $( this); 1618 1619 if ( _this.attr( 'data-product_id' ) ) { 1620 let addToCartData = {}; 1621 1622 $.each( _this[0].dataset, function( key, value ) { 1623 addToCartData[ key ] = value; 1624 } ); 1625 1626 _this.prop( 'disabled', true ); 1627 1628 $.ajax( { 1629 type: 'POST', 1630 url: wc_add_to_cart_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'add_to_cart' ), 1631 dataType: 'json', 1632 data: addToCartData, 1633 success: function( response ) { 1634 $( document.body ).trigger( 'wc_fragment_refresh' ); 1635 $( document.body ).trigger( 'added_to_cart' ); 1636 1637 _this.prop( 'disabled', false ); 1638 }, 1639 error: function(xhr, status, error) { 1640 _this.prop( 'disabled', false ); 1641 } 1642 } ); 1643 } 1644 } ); 1645 1646 $( '.jet-ajax-search__results-item-cart-button.select-options-button', self ).on( 'click', function( e ) { 1647 e.preventDefault(); 1648 1649 const productUrl = $( this ).data( 'product_url' ); 1650 1651 window.open( productUrl, '_blank' ); 1652 } ); 1653 1654 resultsHeaderNav.html( responseData.results_navigation.in_header ); 1655 resultsFooterNav.html( responseData.results_navigation.in_footer ); 1656 1657 if ( !countHolder[0] && !responseData.results_navigation.in_header ) { 1658 resultsHeader.addClass( 'is-empty' ); 1659 } else { 1660 resultsHeader.removeClass( 'is-empty' ); 1661 } 1662 1663 if ( !fullResults[0] && !responseData.results_navigation.in_footer ) { 1664 resultsFooter.addClass( 'is-empty' ); 1665 } else { 1666 resultsFooter.removeClass( 'is-empty' ); 1667 } 1668 1669 resultsHolder.addClass( 'show' ); 1670 1671 $( document ).trigger( 'jet-ajax-search/show-results', [ resultsHolder ] ); 1672 1673 var inputField = $( '.jet-ajax-search__field', self ), 1674 resultsItem = $( '.jet-ajax-search__item-link', self ), 1675 focusedItem = resultsItem.filter( ':focus' ); 1676 1677 inputField.on( 'keydown', function( e ) {
1678 const keyCode = e.keyCode || e.which; 1679 1680 if ( 40 === keyCode ) { // Down arrow 1681 e.preventDefault(); 1682 1683 var position = currentPosition - 1, 1684 activeSlide = $( settings.listSlideClass, resultsListInner ).eq( position ), 1685 next = activeSlide.find( '.jet-ajax-search__item-link' ).first(); 1686 1687 if ( focusedItem.length === 0 ) { 1688 setTimeout( () => { 1689 resultsItem.removeClass( 'focused' ); 1690 next.addClass( 'focused' ); 1691 next.focus(); 1692 }, 0 ); 1693 } 1694 } 1695 } ); 1696 1697 resultsItem.on( 'keydown', function( e ) { 1698 const keyCode = e.keyCode || e.which; 1699 1700 switch ( keyCode ) { 1701 case 40: // Down arrow 1702 e.preventDefault(); 1703 1704 var next = $( this ).parent().next().find( '.jet-ajax-search__item-link' ).first(); 1705 1706 if ( 0 < next.length ) { 1707 resultsItem.removeClass( 'focused' ); 1708 next.addClass( 'focused' ); 1709 next.focus(); 1710 } 1711 break; 1712 1713 case 38: // Up arrow 1714 e.preventDefault(); 1715 1716 var prev = $( this ).parent().prev().find( '.jet-ajax-search__item-link' ).first(); 1717 1718 if ( 0 < prev.length ) { 1719 resultsItem.removeClass( 'focused' ); 1720 prev.addClass( 'focused' ); 1721 prev.focus(); 1722 } else { 1723 resultsItem.removeClass( 'focused' ); 1724 inputField.focus(); 1725 } 1726 break; 1727 1728 case 37: // Left arrow 1729 var prevSlide = $( this ).closest( '.jet-ajax-search__results-slide' ).prev(); 1730 1731 if ( 0 < prevSlide.length ) { 1732 1733 $( settings.prevClass + ':not( ' + settings.disableNavClass + ' )' ).click(); 1734 1735 resultsItem.removeClass( 'focused' ); 1736 1737 setTimeout( () => { 1738 $( settings.listSlideClass, resultsListInner ).eq( currentPosition - 1 ).find( '.jet-ajax-search__item-link' ).first().focus().addClass( 'focused' ); 1739 }, 350 ); 1740 } 1741 break; 1742 1743 case 39: // Right arrow 1744 var nextSlide = $( this ).closest( '.jet-ajax-search__results-slide' ).next(); 1745 1746 if ( 0 < nextSlide.length ) { 1747 1748 $( settings.nextClass + ':not( ' + settings.disableNavClass + ' )' ).click(); 1749 1750 resultsItem.removeClass( 'focused' ); 1751 1752 setTimeout( () => { 1753 $( settings.listSlideClass, resultsListInner ).eq( currentPosition - 1 ).find( '.jet-ajax-search__item-link' ).first().focus().addClass( 'focused' ); 1754 }, 350 ); 1755 } 1756 break; 1757 case 9: 1758 resultsItem.removeClass( 'focused' ); 1759 break; 1760 } 1761 } ); 1762 1763 if ( 'yes' === searchLogging || true === searchLogging ) { 1764 let itemWrapper = settings.itemClass, 1765 resultAreaItemLink = $( '.jet-ajax-search__item-link', itemWrapper ), 1766 resultAreaItemTitle = '.jet-ajax-search__item-title', 1767 resultAreaItemUrlAttr = 'href'; 1768 1769 JetSearch.addSuggestionFromResultAreaItem( itemWrapper, resultAreaItemLink, resultAreaItemTitle, resultAreaItemUrlAttr ); 1770 } 1771 1772 searchSourcesBeforePosts.forEach( function( item ) { 1773 self.maybeHasListing( item ); 1774 1775 resultsListInner.before( item.content ); 1776 resultsHolder.addClass( 'show' ); 1777 } ); 1778 1779 searchSourcesAfterPosts.forEach( function( item ) { 1780 self.maybeHasListing( item ); 1781 1782 resultsListInner.after( item.content ); 1783 resultsHolder.addClass( 'show' ); 1784 } ); 1785 } else { 1786 1787 if ( searchSourcesBeforePosts.length || searchSourcesAfterPosts.length ) { 1788 searchSourcesBeforePosts.forEach( function( item ) { 1789 self.maybeHasListing( item ); 1790 1791 resultsListInner.before( item.content ); 1792 resultsHolder.addClass( 'show' ); 1793 } ); 1794 1795 searchSourcesAfterPosts.forEach( function( item ) { 1796 self.maybeHasListing( item ); 1797 1798 resultsListInner.after( item.content ); 1799 resultsHolder.addClass( 'show' ); 1800 } ); 1801 1802 countAllResults = responseData.post_count; 1803 1804 if ( responseData.sources_results_count && 0 < responseData.sources_results_count ) { 1805 countAllResults += responseData.sources_results_count; 1806 } 1807 1808 $( 'span', countHolder ).html( countAllResults ); 1809 1810 } else { 1811 self.outputMessage( message, 'show' ); 1812 } 1813 } 1814 }; 1815 1816 self.maybeHasListing = function( item ) { 1817 if ( typeof item.listing_template !== 'undefined' && true === item.listing_template ) { 1818 Promise.all( JetSearch.assetsPromises ).then( function() { 1819 JetSearch.initElementsHandlers( resultsListInner ); 1820 JetSearch.reinitBricksScripts( self ); 1821 JetSearch.assetsPromises = []; 1822 } ); 1823 } 1824 } 1825 1826 self.errorCallback = function( jqXHR ) { 1827 if ( 'abort' !== jqXHR.statusText ) { 1828 spinner.removeClass( 'show' ); 1829 self.outputMessage( data.server_error, 'error show' ); 1830 } 1831 }; 1832 1833 self.ajaxSendData = function( sendData, lang = '' ) { 1834 let filteredData = {}; 1835 1836 Object.keys( sendData ).forEach( key => { 1837 if ( 1838 sendData[key] !== '' && 1839 sendData[key] !== null && 1840 sendData[key] !== undefined && 1841 !( Array.isArray( sendData[key] ) && sendData[key].length === 0 ) 1842 ) { 1843 filteredData[key] = sendData[key]; 1844 } 1845 } ); 1846 1847 var ajaxData = { 1848 action: self.ajaxSettings.action, 1849 nonce: self.ajaxSettings.nonce, 1850 data: filteredData || {} 1851 }; 1852
1853 if ( '' != lang ) { 1854 ajaxData.lang = lang; 1855 } 1856 1857 const isRestAPI = self.ajaxSettings.rest_api_url && self.ajaxSettings.rest_api_url.includes( '/wp-json/' ); 1858 1859 self.ajaxRequest = jQuery.ajax( { 1860 type: 'GET', 1861 url: self.ajaxSettings.rest_api_url, 1862 data: ajaxData, 1863 dataType: 'json', 1864 cache: false, 1865 processData: true, 1866 beforeSend: function( jqXHR, ajaxSettings ) { 1867 1868 if ( null !== self.ajaxRequest ) { 1869 self.ajaxRequest.abort(); 1870 } 1871 1872 if ( isRestAPI ) { 1873 jqXHR.setRequestHeader( 'X-WP-Nonce', self.ajaxSettings.nonce ); 1874 } 1875 1876 }, 1877 error: function( jqXHR, textStatus, errorThrown ) { 1878 self.errorCallback( jqXHR ); 1879 }, 1880 success: function( response, textStatus, jqXHR ) { 1881 self.successCallback( response ); 1882 } 1883 } ); 1884 }; 1885 1886 self.hideList = function() { 1887 resultsArea.removeClass( 'show' ); 1888 $( '.chosen-single', self ).removeClass( 'focused' ); 1889 }; 1890 1891 self.showList = function() { 1892 resultsArea.addClass( 'show' ); 1893 }; 1894 1895 self.focusHandler = function( event ) { 1896 var value = event.target.value, 1897 symbolNumberForStart = 'number' === $.type( data.symbols_for_start_searching ) ? data.symbols_for_start_searching : 2; 1898 1899 $( settings.searchFormClass, self ).addClass( formFocusClass ); 1900 1901 if ( 'inside_results_area' === suggestionsPosition && suggestionsList.length ) { 1902 if ( value && getResultsOnFocus ) { 1903 spinner.addClass( 'show' ); 1904 1905 data.value = value; 1906 data.deviceMode = window.elementorFrontend && window.elementorFrontend.getCurrentDeviceMode() ? window.elementorFrontend.getCurrentDeviceMode() : JetSearch.getCurrentDeviceMode(); 1907 1908 self.ajaxSendData( data, lang ); 1909 1910 getResultsOnFocus = false; 1911 } 1912 1913 if ( '' === value ) { 1914 resultsHeader.hide(); 1915 resultsFooter.hide(); 1916 resultsList.hide(); 1917 resultsSuggestions.addClass( 'active' ); 1918 resultsHolder.addClass( 'show' ); 1919 self.showList(); 1920 } 1921 } 1922 1923 if ( 'number' === $.type( symbolNumberForStart ) && symbolNumberForStart > value.length ) { 1924 return; 1925 } 1926 1927 self.showList(); 1928 }; 1929 1930 self.blurHandler = function( event ) { 1931 $( settings.searchFormClass, self ).removeClass( formFocusClass ); 1932 }; 1933 1934 self.outputMessage = function( message, messageClass ) { 1935 message = message.replace( /\\/g, '' ); // remove slashes 1936 //message = $( "<div/>" ).html( message ).text(); 1937 message = message.replace( /\\*"/g, '' ); 1938 messageHolder.removeClass( 'error show' ).addClass( messageClass ).html( message ); 1939 }; 1940 1941 self.formClick = function( event ) { 1942 event.stopPropagation(); 1943 }; 1944 1945 self.clickFullResults = function( event ) { 1946 1947 var searchInput = $( settings.inputClass, self ), 1948 value = searchInput.val(), 1949 url = JetSearch.getResultsUrl( form ); 1950 1951 event.preventDefault(); 1952 1953 if ( value.length != 0 || true === allowEmptyString ) { 1954 if ( false === disableInputs ) { 1955 disableInputs = true; 1956 1957 value = value.replace(/\u3000/g, ' '); 1958 1959 searchInput.val( value ); 1960 1961 if ( '' != customResultUrl ) { 1962 customResultUrl = $.trim( customResultUrl ); 1963 1964 url = JetSearch.getResultsUrl( form, customResultUrl ); 1965 } 1966 1967 if ( 'yes' === showSearchSuggestions || true === showSearchSuggestions ) { 1968 self.addUserSearch( value ); 1969 } 1970 1971 if ( 'yes' === searchLogging || true === searchLogging ) { 1972 JetSearch.setFormSuggestion( value, form, url ); 1973 } else { 1974 window.location.href = url; 1975 } 1976 } 1977 } 1978 }; 1979 1980 self.changeSlide = function( number ) { 1981 var currentSlide = $( settings.listSlideClass, resultsListInner ).eq( number ), 1982 direction = settings.isRtl ? 1 : -1, 1983 position = number * 100 * direction; 1984 1985 currentSlide.scrollTop( 0 ); 1986 resultsListInner.css( 'transform', 'translateX(' + position + '%)' ); 1987 resultsList.css( 'height', 'auto' ); 1988 }; 1989 1990 self.clickBulletHandler = function( event ) { 1991 var target = $( event.target ); 1992 1993 currentPosition = target.data( 'number' ); 1994 self.syncNavigation(); 1995 1996 self.changeSlide( currentPosition - 1 ); 1997 }; 1998 1999 self.clickNavigationButtonHandler = function( event ) { 2000 var target = $( event.target ), 2001 direction = target.data( 'direction' ); 2002 2003 currentPosition = currentPosition + direction; 2004 self.syncNavigation(); 2005 2006 self.changeSlide( currentPosition - 1 ); 2007 }; 2008 2009 self.syncNavigation = function() { 2010 var lastPosition = resultsListInner.data( 'columns' ), 2011 disableClass = settings.disableNavClass.replace( '.', '' ), 2012 activeClass = settings.activeNavClass.replace( '.', '' ); 2013 2014 $( settings.activeNavClass, self ).removeClass( activeClass ); 2015 $( settings.disableNavClass, self ).removeClass( disableClass ); 2016 2017 $( settings.navButtonClass + '[data-number="' + currentPosition +'"]', self ).addClass( activeClass ); 2018 2019 if ( 1 === currentPosition ) { 2020 $( settings.prevClass, self ).addClass( disableClass ); 2021 } 2022 2023 if ( lastPosition === currentPosition ) { 2024 $( settings.nextClass, self ).addClass( disableClass ); 2025 } 2026 }; 2027 2028 self.formSubmit = function( event ) { 2029 var value = event.target.value, 2030 url = JetSearch.getResultsUrl( form ); 2031 2032 if ( ( 1 > value.length && false === allowEmptyString ) && ( 13 === event.keyCode || 'click' === event.type ) ) { 2033 return false;
2034 } else { 2035 if ( 13 === event.keyCode && allowSubmitOnEnter ) { 2036 if ( false === disableInputs ) { 2037 disableInputs = true; 2038 2039 event.preventDefault(); 2040 2041 if ( '' != customResultUrl ) { 2042 customResultUrl = $.trim( customResultUrl ); 2043 2044 url = JetSearch.getResultsUrl( form, customResultUrl ); 2045 } 2046 2047 self.addUserSearch( value ); 2048 2049 if ( 'yes' === searchLogging || true === searchLogging ) { 2050 JetSearch.setFormSuggestion( value, form, url ); 2051 } else { 2052 window.location.href = url; 2053 } 2054 } 2055 } 2056 } 2057 }; 2058 2059 self.changeHandler = function( event ) { 2060 var target = $( event.target ), 2061 globalQuerySettings = $( self ).data( 'settings' ); 2062 2063 globalQuerySettings.category__in = target.val(); 2064 data.category__in = target.val(); 2065 2066 $( self ).data( 'settings', globalQuerySettings ); 2067 2068 self.inputChangeHandler( { target: $( settings.inputClass, self ) } ) 2069 }; 2070 2071 self.chosenFocusHandler = function() { 2072 self.hideList(); 2073 }; 2074 2075 self.setResultsAreaWidth = function() { 2076 2077 if ( 'fields_holder' !== data.results_area_width_by ) { 2078 return; 2079 } 2080 2081 resultsArea.css( 'width', $( settings.fieldsHolderClass, self ).outerWidth() ); 2082 }; 2083 2084 self.addUserSearch = function( newSearchRequest ) { 2085 if ( 'user' === suggestionsType ) { 2086 newSearchRequest = newSearchRequest.trim(); 2087 2088 if ( ! storedUserSearches.some( search => search === newSearchRequest ) ) { 2089 if ( storedUserSearches.length >= maxUserSearches ) { 2090 storedUserSearches.shift(); 2091 } 2092 2093 storedUserSearches.push( newSearchRequest ); 2094 2095 localStorage.setItem( 'jetUserSearches', JSON.stringify( storedUserSearches ) ); 2096 } 2097 } 2098 } 2099 2100 self.selectSuggestion = function( event ) { 2101 const keyCode = event.keyCode || event.which; 2102 2103 let value = event.target.parentElement.getAttribute('aria-label').trim(), 2104 url = null; 2105 2106 if ( false === disableInputs && !editMode ) { 2107 2108 if ( 'keydown' === event.type ) { 2109 if ( 13 === keyCode ) { 2110 disableInputs = true; 2111 2112 $( settings.inputClass, self )[0].value = value; 2113 2114 self.addUserSearch( value ); 2115 2116 url = JetSearch.getResultsUrl( form ); 2117 2118 if ( '' != customResultUrl ) { 2119 customResultUrl = $.trim( customResultUrl ); 2120 2121 url = JetSearch.getResultsUrl( form, customResultUrl ); 2122 } 2123 2124 if ( 'yes' === searchLogging || true === searchLogging ) { 2125 JetSearch.setFormSuggestion( value, false, url ); 2126 } else { 2127 window.location.href = url; 2128 } 2129 } 2130 } else if ( 'click' === event.type ) { 2131 disableInputs = true; 2132 2133 $( settings.inputClass, self )[0].value = value; 2134 2135 self.addUserSearch( value ); 2136 2137 url = JetSearch.getResultsUrl( form ); 2138 2139 if ( '' != customResultUrl ) { 2140 customResultUrl = $.trim( customResultUrl ); 2141 2142 url = JetSearch.getResultsUrl( form, customResultUrl ); 2143 } 2144 2145 if ( 'yes' === searchLogging || true === searchLogging ) { 2146 JetSearch.setFormSuggestion( value, false, url ); 2147 } else { 2148 window.location.href = url; 2149 } 2150 } 2151 } 2152 } 2153 2154 self.customUrlActions = { 2155 selectorOnClick: 'a[href^="#jet-engine-action"][href*="event=click"]', 2156 selectorOnHover: 'a[href^="#jet-engine-action"][href*="event=hover"], [data-url^="#jet-engine-action"][data-url*="event=hover"]', 2157 2158 init: function() { 2159 var timeout = null; 2160 2161 $( document ).on( 'click.JetSearch', this.selectorOnClick, function( event ) { 2162 event.preventDefault(); 2163 self.customUrlActions.actionHandler( event ) 2164 } ); 2165 2166 $( document ).on( 'click.JetSearch', this.selectorOnHover, function( event ) { 2167 if ( 'A' === event.currentTarget.nodeName ) { 2168 event.preventDefault(); 2169 } 2170 } ); 2171 2172 $( document ).on( { 2173 'mouseenter.JetSearch': function( event ) { 2174 2175 if ( timeout ) { 2176 clearTimeout( timeout ); 2177 } 2178 2179 timeout = setTimeout( function() { 2180 self.customUrlActions.actionHandler( event ) 2181 }, window.JetEngineSettings.hoverActionTimeout ); 2182 }, 2183 'mouseleave.JetSearch': function() { 2184 if ( timeout ) { 2185 clearTimeout( timeout ); 2186 timeout = null; 2187 } 2188 }, 2189 }, this.selectorOnHover ); 2190 }, 2191 2192 actions: {}, 2193 2194 addAction: function( name, callback ) { 2195 this.actions[ name ] = callback; 2196 }, 2197 2198 actionHandler: function( event ) { 2199 var url = $( event.currentTarget ).attr( 'href' ) || $( event.currentTarget ).attr( 'data-url' ); 2200 2201 this.runAction( url ); 2202 }, 2203 2204 runAction: function( url ) { 2205 var queryParts = url.split( '&' ), 2206 settings = {}; 2207
2208 queryParts.forEach( function( item ) { 2209 if ( -1 !== item.indexOf( '=' ) ) { 2210 var pair = item.split( '=' ); 2211 2212 settings[ pair[0] ] = decodeURIComponent( pair[1] ); 2213 } 2214 } ); 2215 2216 if ( ! settings.action ) { 2217 return; 2218 } 2219 2220 var actionCb = this.actions[ settings.action ]; 2221 2222 if ( ! actionCb ) { 2223 return; 2224 } 2225 2226 actionCb( settings ); 2227 } 2228 }; 2229 2230 self.handleListingItemClick = function( event ) { 2231 var url = $( this ).data( 'url' ), 2232 target = $( this ).data( 'target' ) || false; 2233 2234 if ( url ) { 2235 2236 event.preventDefault(); 2237 2238 if ( window.elementorFrontend && window.elementorFrontend.isEditMode() ) { 2239 return; 2240 } 2241 2242 if ( -1 !== url.indexOf( '#jet-engine-action' ) ) { 2243 2244 self.customUrlActions.runAction( url ); 2245 2246 } else { 2247 2248 if ( '_blank' === target ) { 2249 window.open( url ); 2250 return; 2251 } 2252 2253 window.location = url; 2254 } 2255 } 2256 }; 2257 2258 $( settings.inputClass, self ) 2259 .on( 'input' + settings.searchClass, self.inputChangeHandler ) 2260 .on( 'focus' + settings.searchClass, self.focusHandler ) 2261 .on( 'blur' + settings.searchClass, self.blurHandler ) 2262 .on( 'keydown' + settings.searchClass, self.formSubmit ); 2263 2264 $( settings.submitClass, self ).on( 'click' + settings.searchClass, self.clickFullResults ); 2265 2266 $( self ) 2267 .on( 'click' + settings.searchClass, self.formClick ) 2268 .on( 'touchend' + settings.searchClass, self.formClick ) 2269 .on( 'click' + settings.searchClass, settings.fullResultsClass, self.clickFullResults ) 2270 .on( 'click' + settings.searchClass, settings.countClass, self.clickFullResults ) 2271 .on( 'click' + settings.searchClass, settings.bulletClass, self.clickBulletHandler ) 2272 .on( 'click' + settings.searchClass, settings.numberClass, self.clickBulletHandler ) 2273 .on( 'click' + settings.searchClass, settings.prevClass + ':not( ' + settings.disableNavClass + ' )', self.clickNavigationButtonHandler ) 2274 .on( 'click' + settings.searchClass, settings.nextClass + ':not( ' + settings.disableNavClass + ' )', self.clickNavigationButtonHandler ) 2275 .on( 'click keydown' + settings.searchClass, settings.inlineSuggestionsItemClass, self.selectSuggestion ) 2276 .on( 'click keydown' + settings.searchClass, settings.resultsSuggestionItemClass, self.selectSuggestion ) 2277 .on( 'change', settings.chosenClass, self.changeHandler ) 2278 .on( 'chosen:showing_dropdown', settings.chosenClass, self.chosenFocusHandler ) 2279 .on( 'click' + settings.searchClass, '.jet-engine-listing-overlay-wrap:not([data-url*="event=hover"])', self.handleListingItemClick ); 2280 2281 if ( ! allowSubmitOnEnter ){ 2282 $( window ).keydown( function( event ) { 2283 if ( 13 === event.keyCode && event.target.className.includes( 'jet-ajax-search' ) ) { 2284 event.preventDefault(); 2285 return false; 2286 } 2287 }); 2288 } 2289 2290 $( self ).on( 'keydown', function( e ) { 2291 const keyCode = e.keyCode || e.which; 2292 2293 if ( 9 === keyCode ) { 2294 setTimeout( () => { 2295 const focusedElement = document.activeElement; 2296 2297 if ( $( focusedElement ).is( '.chosen-search-input' ) ) { 2298 $( '.chosen-single', self ).addClass( 'focused' ); 2299 } else { 2300 $( '.chosen-single', self ).removeClass( 'focused' ); 2301 } 2302 }, 50 ); 2303 } 2304 } ); 2305 2306 $( settings.inputClass, self ).on( 'click' + settings.searchClass, () => { 2307 $( '.chosen-single', self ).removeClass( 'focused' ); 2308 } ); 2309 2310 if ( '' != categoryIndex ) { 2311 let target = $( settings.chosenClass, self ), 2312 globalQuerySettings = $( self ).data( 'settings' ), 2313 categorySelect = $( '.jet-ajax-search__categories-select', self ), 2314 currentCategory = ''; 2315 2316 categorySelect.find( 'option' ).each( function() { 2317 var value = $( this ).val(); 2318 2319 if ( value === categoryIndex ) { 2320 currentCategory = $( this ).text(); 2321 } 2322 } ); 2323 2324 categorySelect.find( 'option:contains("' + currentCategory + '")' ).attr( 'selected', 'selected' ); 2325 2326 globalQuerySettings.category__in = target.val(); 2327 data.category__in = target.val(); 2328 2329 $( self ).data( 'settings', globalQuerySettings ); 2330 } else { 2331 // If after reloading the page the value of the select is not '0'. 2332 2333 if ( '0' !== $( settings.chosenClass, self ).val() ) { 2334 $( settings.chosenClass, self ).trigger( 'change' ); 2335 } 2336 } 2337 2338 $( 'body' ) 2339 .on( 'click' + settings.searchClass, self.hideList ) 2340 .on( 'touchend' + settings.searchClass, self.hideList ); 2341 2342 self.setResultsAreaWidth(); 2343 $( window ).on( 'resize' + settings.searchClass, self.setResultsAreaWidth ); 2344 2345 $( window ).on( 'orientationchange resize', function () { 2346 resultsListInner.imagesLoaded( function() { 2347 resultsList.css( 'height', $( settings.listSlideClass, resultsListInner ).eq(0).outerHeight() ); 2348 } ); 2349 } ); 2350 2351 } else { 2352 return 'is init: true'; 2353 } 2354 }; 2355 2356 // initialize after all is defined 2357 $( window ).on( 'elementor/frontend/init', JetSearch.initElementor ); 2358 JetSearch.initBlocks(); 2359 2360 window.jetSearchBricks = function() { 2361 JetSearch.initBricks(); 2362 } 2363 2364 window.JetSearch = JetSearch; 2365 2366}( jQuery ));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.