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