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