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