https://www.phsinc.com/wp-content/plugins/ajax-search-for-woocommerce/assets/js/search.js?ver=1.33.0
1/** 2 * Ajax Autocomplete for jQuery, version 1.2.27 3 * (c) 2015 Tomas Kirda 4 * 5 * Ajax Autocomplete for jQuery is freely distributable under the terms of an MIT-style license. 6 * For details, see the web site: https://github.com/devbridge/jQuery-Autocomplete 7 * 8 * Modified by Damian Góra: http://damiangora.com 9 * Minify: https://www.toptal.com/developers/javascript-minifier/ 10 */ 11 12/*jslint browser: true, white: true, single: true, this: true, multivar: true */ 13/*global define, window, document, jQuery, exports, require */ 14 15// Expose plugin as an AMD module if AMD loader is present: 16(function (factory) { 17 "use strict"; 18 if (typeof define === 'function' && define.amd) { 19 // AMD. Register as an anonymous module. 20 define(['jquery'], factory); 21 } else if (typeof exports === 'object' && typeof require === 'function') { 22 // Browserify 23 factory(require('jquery')); 24 } else { 25 // Browser globals 26 factory(jQuery); 27 } 28}(function ($) { 29 'use strict'; 30 31 var utils = (function () { 32 return { 33 escapeRegExChars: function (value) { 34 return value.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&"); 35 }, 36 formatHtml: function (string) { 37 return string.replace(/&/g, '&') // Edge case: "&" >> "&amp;". 38 .replace(/&amp;/g, '&') // Fix for above case: "&amp;" >> "&". 39 .replace(/</g, '<') 40 .replace(/>/g, '>') 41 .replace(/"/g, '"') 42 .replace(/'/g, ''') 43 .replace(/<sup/g, '<sup') 44 .replace(/<\/sup/g, '</sup') 45 .replace(/sup>/g, 'sup>') 46 .replace(/<sub/g, '<sub') 47 .replace(/<\/sub/g, '</sub') 48 .replace(/sub>/g, 'sub>') 49 .replace(/<br\s?\/?>/g, '<br/>') 50 .replace(/<(\/?(strong|b|br|span|i))>/g, '<$1>') 51 .replace(/<(strong|span|i)\s+class\s*=\s*"([^&]+)">/g, '<$1 class="$2">'); 52 }, 53 createNode: function (containerClass) { 54 var div = document.createElement('div'); 55 div.className = containerClass; 56 div.style.position = 'absolute'; 57 div.style.display = 'none'; 58 div.setAttribute('unselectable', 'on'); 59 return div; 60 }, 61 matchGreekAccents: function (phrase) { 62 // Break early if the phrase does not contain Greek characters. 63 if (!/[\u0370-\u03FF\u1F00-\u1FFF]+/.test(phrase)) { 64 return phrase; 65 } 66 67 // Remove Greek accents. 68 phrase = phrase.normalize('NFD').replace(/[\u0300-\u036f]/g, ""); 69 70 var accents = { 71 'Î': 'Î', 72 'α': 'ά', 73 'Î': 'Î', 74 'ε': 'Î', 75 'Î': 'Î', 76 'ι': 'ί', 77 'Ï': 'Î', 78 'Î¥': 'Î', 79 'Ï ': 'Ï', 80 'Ï': 'ΰ', 81 'Î': 'Î', 82 'η': 'ή', 83 'Î': 'Î', 84 'ο': 'Ï', 85 'Ω': 'Î', 86 'Ï': 'Ï' 87 }; 88 // Replace eg. "ε" >> "[εÎ]". 89 for (let [key, value] of Object.entries(accents)) { 90 if (phrase.indexOf(key) > -1) { 91 phrase = phrase.replaceAll(key, '[' + key + value + ']'); 92 } 93 } 94 95 return phrase; 96 }, 97 highlight: function (suggestionValue, phrase) { 98 var i, 99 tokens = phrase.split(/ /), 100 highlighted = false, 101 last = ''; 102 103 if (tokens) { 104 last = tokens[tokens.length - 1]; 105 tokens = tokens.sort(function (a, b) { 106 return b.length - a.length; 107 }); 108 109 for (i = 0; i < tokens.length; i++) { 110 if (tokens[i] && tokens[i].length >= 1) { 111 112 var token = tokens[i].replace(/[\^\@]/g, ''); 113 114 if (token.length > 0) { 115 if (token.trim().length === 1 && tokens[i] !== last) { 116 var pattern = '((\\s|^)' + utils.escapeRegExChars(token.trim()) + '\\s)'; 117 pattern = utils.matchGreekAccents(pattern); 118 } else if (token.trim().length === 1 && tokens[i] === last) { 119 var pattern = '((\\s|^)' + utils.escapeRegExChars(token.trim()) + ')'; 120 pattern = utils.matchGreekAccents(pattern); 121 } else { 122 var pattern = '(' + utils.escapeRegExChars(token.trim()) + ')'; 123 pattern = utils.matchGreekAccents(pattern); 124 } 125 126 suggestionValue = suggestionValue.replace(new RegExp(pattern, 'gi'), '\^\^$1\@\@'); 127 highlighted = true; 128 } 129 } 130 } 131 } 132 133 if (highlighted) { 134 suggestionValue = suggestionValue.replace(/\^\^/g, '<strong>'); 135 suggestionValue = suggestionValue.replace(/@@/g, '<\/strong>'); 136 } 137 138 return suggestionValue; 139 }, 140 debounce: function (func, wait) { 141 var timeout, 142 debounceID = new Date().getUTCMilliseconds(); 143 144 // First query in the chain 145 if (ajaxDebounceState.id.length === 0) { 146 ajaxDebounceState.id = debounceID; 147 func(); 148 return; 149 } 150 151 ajaxDebounceState.id = debounceID; 152 153 timeout = setTimeout(function () { 154 155 if (debounceID !== ajaxDebounceState.id) { 156 clearTimeout(timeout); 157 return; 158 } 159 160 // Last query in the chain 161 func(); 162 ajaxDebounceState.id = ''; 163 164 }, wait); 165 }, 166 mouseHoverDebounce: function (func, selector, wait) { 167 var timeout; 168 169 timeout = setTimeout(function () { 170 171 if ($(selector + ':hover').length > 0) { 172 func(); 173 } else { 174 clearTimeout(timeout); 175 return; 176 } 177 178 179 }, wait); 180 }, 181 isTextSelected: function () { 182 var selected = false, 183 selObj = document.getSelection(); 184 185 if (typeof selObj == 'object') { 186 if (selObj.toString().length > 0) { 187 selected = true; 188 } 189 } 190 return selected 191 }, 192 getActiveInstance: function () { 193 var $el = $('.dgwt-wcas-search-wrapp.dgwt-wcas-active'), 194 instance; 195 if ($el.length > 0) { 196 $el.each(function () { 197 var $input = $(this).find('.dgwt-wcas-search-input'); 198 if (typeof $input.data('autocomplete') == 'object') { 199 instance = $input.data('autocomplete'); 200 return false;
201 } 202 }); 203 } 204 205 return instance; 206 }, 207 hashCode: function (s) { 208 var h = 0, i = s.length; 209 while (i > 0) { 210 h = (h << 5) - h + s.charCodeAt(--i) | 0; 211 } 212 return h < 0 ? h * -1 : h; 213 }, 214 isBrowser: function (browser) { 215 return navigator.userAgent.indexOf(browser) !== -1; 216 }, 217 isSafari: function () { 218 return this.isBrowser('Safari') && !this.isBrowser('Chrome'); 219 }, 220 isIOS: function () { 221 var platform = navigator?.userAgent || navigator?.platform || 'unknown'; 222 223 return /iPhone|iPod|iPad/.test(platform) 224 // iPad on iOS 13 detection 225 || (navigator.userAgent.includes("Mac") && "ontouchend" in document) 226 }, 227 isIE11: function () { 228 return !!navigator.userAgent.match(/Trident\/7\./); 229 }, 230 setLocalStorageItem: function (key, value) { 231 try { 232 window.localStorage.setItem( 233 key, 234 JSON.stringify(value) 235 ); 236 } catch (error) { 237 // A more advanced implementation would handle the error case 238 } 239 }, 240 getLocalStorageItem: function (key, defaultValue) { 241 try { 242 const item = window.localStorage.getItem(key); 243 return item ? JSON.parse(item) : defaultValue; 244 } catch (error) { 245 return defaultValue; 246 } 247 }, 248 removeLocalStorageItem: function (key) { 249 try { 250 window.localStorage.removeItem(key); 251 } catch (error) { 252 } 253 } 254 }; 255 }()), 256 ajaxDebounceState = { 257 id: '', 258 callback: null, 259 ajaxSettings: null, 260 object: null, 261 }, 262 keys = { 263 ESC: 27, 264 TAB: 9, 265 RETURN: 13, 266 LEFT: 37, 267 UP: 38, 268 RIGHT: 39, 269 DOWN: 40 270 }, 271 noop = $.noop; 272 273 function DgwtWcasAutocompleteSearch(el, options) { 274 var that = this; 275 276 // Shared variables: 277 that.element = el; 278 that.el = $(el); 279 that.suggestions = []; 280 that.badQueries = []; 281 that.selectedIndex = -1; 282 that.currentValue = that.element.value; 283 that.timeoutId = null; 284 that.cachedResponse = {}; 285 that.cachedDetails = {}; 286 that.cachedPrices = {}; 287 that.detailsRequestsSent = []; 288 that.onChangeTimeout = null; 289 that.onChange = null; 290 that.isLocal = false;
291 that.suggestionsContainer = null; 292 that.detailsContainer = null; 293 that.autoAligmentprocess = null; 294 that.noSuggestionsContainer = null; 295 that.latestActivateSource = ''; 296 that.actionTriggerSource = ''; 297 that.options = $.extend(true, {}, DgwtWcasAutocompleteSearch.defaults, options); 298 that.classes = { 299 selected: 'dgwt-wcas-suggestion-selected', 300 suggestion: 'dgwt-wcas-suggestion', 301 suggestionsContainerOrientTop: 'dgwt-wcas-suggestions-wrapp--top', 302 inputFilled: 'dgwt-wcas-search-filled', 303 darkenOverlayMounted: 'js-dgwt-wcas-search-darkoverl-mounted', 304 fixed: 'dgwt-wcas-suggestions-wrapp-fixed', 305 initialized: 'dgwt-wcas-suggestions-wrapp-initialized' 306 }; 307 that.hint = null; 308 that.hintValue = ''; 309 that.selection = null; 310 that.overlayMobileState = 'off'; 311 that.overlayDarkenedState = 'off'; 312 that.isMouseDownOnSearchElements = false; 313 that.isPreSuggestionsMode = false; 314 315 // Voice search 316 that.voiceSearchRecognition = null; 317 that.voiceSearchStarted = null; 318 319 // Search history 320 that.recentlyViewedProductsKey = 'fibosearch_recently_viewed_products'; 321 that.recentlySearchedPhrasesKey = 'fibosearch_recently_searched_phrases'; 322 323 // Initialize and set options: 324 that.initialize(); 325 that.setOptions(options); 326 327 } 328 329 DgwtWcasAutocompleteSearch.utils = utils; 330 331 $.DgwtWcasAutocompleteSearch = DgwtWcasAutocompleteSearch; 332 333 DgwtWcasAutocompleteSearch.defaults = { 334 ajaxSettings: {}, 335 autoSelectFirst: false, 336 appendTo: 'body', 337 serviceUrl: null, 338 lookup: null, 339 onSelect: null, 340 containerDetailsWidth: 'auto', 341 showDetailsPanel: false, 342 showImage: false, 343 showPrice: false, 344 showSKU: false, 345 showDescription: false, 346 showSaleBadge: false, 347 showFeaturedBadge: false, 348 dynamicPrices: false, 349 saleBadgeText: 'sale', 350 featuredBadgeText: 'featured', 351 minChars: 3, 352 maxHeight: 600, 353 dpusbBreakpoint: 550, // (details panel under search bar - breakpoint) If search bar width is lower than this option, suggestions wrapper and details panel will show under search bar with the same width 354 deferRequestBy: 0, 355 params: {}, 356 formatResult: _formatResult, 357 delimiter: null, 358 zIndex: 999999999, 359 type: 'GET', 360 noCache: false, 361 isRtl: false, 362 onSearchStart: noop, 363 onSearchComplete: noop, 364 onSearchError: noop, 365 preserveInput: false, 366 searchFormClass: 'dgwt-wcas-search-wrapp', 367 containerClass: 'dgwt-wcas-suggestions-wrapp', 368 containerDetailsClass: 'dgwt-wcas-details-wrapp', 369 preSuggestionsWrappClass: 'dgwt-wcas-pre-suggestions-wrapp', 370 darkenedOverlayClass: 'dgwt-wcas-darkened-overlay', 371 searchInputClass: 'dgwt-wcas-search-input', 372 preloaderClass: 'dgwt-wcas-preloader', 373 closeTrigger: 'dgwt-wcas-close', 374 formClass: 'dgwt-wcas-search-form', 375 voiceSearchClass: 'dgwt-wcas-voice-search', 376 voiceSearchSupportedClass: 'dgwt-wcas-voice-search-supported', 377 voiceSearchActiveClass: 'dgwt-wcas-voice-search-active', 378 voiceSearchDisabledClass: 'dgwt-wcas-voice-search-disabled', 379 tabDisabled: false, 380 dataType: 'text', 381 currentRequest: null, 382 triggerSelectOnValidInput: true, 383 isPremium: false, 384 overlayMobile: false, 385 preventBadQueries: true, 386 lookupFilter: _lookupFilter, 387 paramName: 'query', 388 transformResult: _transformResult, 389 noSuggestionNotice: 'No results', 390 forceFixPosition: false, 391 positionFixed: false, 392 debounceWaitMs: 400, 393 sendGAEvents: true, 394 enableGASiteSearchModule: false, 395 showProductVendor: false, 396 disableHits: false, 397 disableSubmit: false, 398 voiceSearchEnabled: false, 399 voiceSearchLang: '', 400 showRecentlySearchedProducts: false, 401 showRecentlySearchedPhrases: false, 402 goToFirstVariationOnSubmit: true, 403 } 404 405 function _lookupFilter(suggestion, originalQuery, queryLowerCase) { 406 return suggestion.value.toLowerCase().indexOf(queryLowerCase) !== -1; 407 } 408 409 function _transformResult(response) { 410 return typeof response === 'string' ? JSON.parse(response)
410: response; 411 } 412 413 function _formatResult(suggestionValue, currentValue, highlight) { 414 if (currentValue.length > 0 && highlight) { 415 suggestionValue = utils.highlight(suggestionValue, currentValue); 416 } 417 418 return utils.formatHtml(suggestionValue); 419 } 420 421 DgwtWcasAutocompleteSearch.prototype = { 422 initialize: function () { 423 var that = this; 424 425 // Remove autocomplete attribute to prevent native suggestions: 426 that.element.setAttribute('autocomplete', 'off'); 427 428 that.options.params = that.applyCustomParams(that.options.params); 429 430 that.createContainers(); 431 432 that.registerEventsSearchBar(); 433 that.registerEventsSuggestions(); 434 that.registerEventsDetailsPanel(); 435 that.registerIconHandler(); 436 that.registerFlexibleLayout(); 437 that.initVoiceSearch(); 438 439 that.fixPosition = function () { 440 that.adjustContainerWidth(); 441 if (that.visible) { 442 that.fixPositionSuggestions(); 443 if (that.canShowDetailsPanel()) { 444 that.fixPositionDetailsPanel(); 445 } 446 } 447 that.positionOverlayDarkened(); 448 }; 449 450 // Fix position on resize 451 $(window).on('resize.autocomplete', function () { 452 var that = utils.getActiveInstance(); 453 clearTimeout(window.dgwt_wcas.resizeOnlyOnce); 454 if (typeof that != 'undefined') { 455 window.dgwt_wcas.resizeOnlyOnce = setTimeout(function () { 456 that.fixPosition(); 457 }, 100); 458 } 459 }); 460 461 // Fix position on scroll 462 $(window).on('scroll.autocomplete', function () { 463 var that = utils.getActiveInstance(); 464 clearTimeout(window.dgwt_wcas.scrollOnlyOnce); 465 if (typeof that != 'undefined') { 466 window.dgwt_wcas.scrollOnlyOnce = setTimeout(function () { 467 that.fixPosition(); 468 }, 100); 469 } 470 }); 471 472 // Trigger only when x axis is changed 473 var windowWidth = $(window).width(); 474 $(window).on('resize.autocomplete', function () { 475 var newWidth = $(window).width(); 476 if (newWidth != windowWidth) { 477 that.toggleMobileOverlayMode(); 478 windowWidth = newWidth; 479 } 480 }); 481 482 if (that.isBreakpointReached('mobile-overlay')) { 483 that.activateMobileOverlayMode(); 484 } 485 486 that.hideAfterClickOutsideListener(); 487 488 that.getFormWrapper().addClass(that.classes.initialized); 489 490 that.suggestionsContainer.addClass('js-dgwt-wcas-initialized'); 491 492 if (that.detailsContainer && that.detailsContainer.length > 0) { 493 that.detailsContainer.addClass('js-dgwt-wcas-initialized'); 494 } 495 }, 496 createContainers: function (type) { 497 var that = this, 498 options = that.options; 499 500 // Suggestions 501 if ($('.' + options.containerClass).length == 0) { 502 503 that.suggestionsContainer = $(DgwtWcasAutocompleteSearch.utils.createNode(options.containerClass)); 504 505 that.suggestionsContainer.appendTo(options.appendTo || 'body'); 506 507 that.suggestionsContainer.addClass('woocommerce'); 508 509 // Add conditional classes 510 if (options.showImage === true) { 511 that.suggestionsContainer.addClass('dgwt-wcas-has-img'); 512 } 513 514 // Price 515 if (options.showPrice === true) { 516 that.suggestionsContainer.addClass('dgwt-wcas-has-price'); 517 } 518 519 // Description 520 if (options.showDescription === true) { 521 that.suggestionsContainer.addClass('dgwt-wcas-has-desc'); 522 } 523 524 // SKU 525 if (options.showSKU === true) { 526 that.suggestionsContainer.addClass('dgwt-wcas-has-sku'); 527 } 528 529 // Headings 530 if (options.showHeadings === true) { 531 that.suggestionsContainer.addClass('dgwt-wcas-has-headings'); 532 } 533 534 } else { 535 536 that.suggestionsContainer = $('.' + that.options.containerClass); 537 538 } 539 540 // Details Panel
541 if (that.canShowDetailsPanel()) { 542 543 if ($('.' + options.containerDetailsClass).length == 0) { 544 that.detailsContainer = $(DgwtWcasAutocompleteSearch.utils.createNode(options.containerDetailsClass)); 545 that.detailsContainer.appendTo(options.appendTo || 'body'); 546 547 that.detailsContainer.addClass('woocommerce'); 548 } else { 549 550 that.detailsContainer = $('.' + options.containerDetailsClass); 551 552 } 553 554 } 555 }, 556 registerEventsSearchBar: function () { 557 var that = this; 558 559 // The Control event that checks if other listeners work 560 that.el.on('fibosearch/ping', function () { 561 that.el.addClass('fibosearch-pong'); 562 }); 563 564 // Extra tasks on submit 565 that.getForm().on('submit.autocomplete', function (e) { 566 567 if (that.options.disableSubmit) { 568 e.preventDefault(); 569 return false; 570 } 571 572 // Prevent submit empty form 573 var $input = $(this).find('.' + that.options.searchInputClass); 574 if ($input.length && $input.val().length === 0) { 575 e.preventDefault(); 576 return false; 577 } 578 579 // If variation suggestion exist, click it instead submit search results page 580 if (that.options.goToFirstVariationOnSubmit) { 581 if (that.suggestions.length > 0) { 582 $.each(that.suggestions, function (i, suggestion) { 583 if ( 584 typeof suggestion.type != 'undefined' 585 && suggestion.type == 'product_variation' 586 ) { 587 that.select(i); 588 e.preventDefault(); 589 return false; 590 } 591 }); 592 } 593 } 594 595 if (that.options.showRecentlySearchedPhrases) { 596 that.saveHistorySearches($input.val()); 597 } 598 599 // Clean before submit 600 that.closeOverlayMobile(); 601 }); 602 603 // Position preloader 604 that.positionPreloaderAndMic(); 605 $(window).on('load', function () { 606 that.positionPreloaderAndMic(); 607 }); 608 609 that.el.on('keydown.autocomplete', function (e) { 610 that.onKeyPress(e); 611 }); 612 that.el.on('keyup.autocomplete', function (e) { 613 that.onKeyUp(e); 614 }); 615 that.el.on('blur.autocomplete', function () { 616 that.onBlur(); 617 }); 618 that.el.on('focus.autocomplete', function (e) { 619 that.onFocus(e); 620 }); 621 that.el.on('change.autocomplete', function (e) { 622 that.onKeyUp(e); 623 }); 624 that.el.on('input.autocomplete', function (e) { 625 that.onKeyUp(e); 626 }); 627 628 }, 629 registerEventsSuggestions: function () { 630 var that = this, 631 suggestionSelector = '.' + that.classes.suggestion, 632 suggestionsContainer = that.getSuggestionsContainer(); 633 634 // Register these events only once 635 if (suggestionsContainer.hasClass('js-dgwt-wcas-initialized')) { 636 return; 637 } 638 639 // Select suggestion and enable details panel on hovering over it 640 $(document).on('mouseenter.autocomplete', suggestionSelector, function () { 641 var that = utils.getActiveInstance(); 642 643 if (typeof that == 'undefined') { 644 return; 645 } 646 647 var currentIndex = $(this).data('index'); 648 var selector = '.dgwt-wcas-suggestion[data-index="' + currentIndex + '"]'; 649 650 var timeOffset = that.canShowDetailsPanel() ? 100 : 1; 651 652 if (that.selectedIndex != currentIndex) { 653 654 if (that.suggestions[currentIndex].type == 'headline' 655 || that.suggestions[currentIndex].type == 'headline-v2') { 656 return; 657 } 658 659 utils.mouseHoverDebounce(function () { 660 if (that.selectedIndex !== currentIndex) { 661 that.latestActivateSource = 'mouse'; 662 that.getDetails(that.suggestions[currentIndex]); 663 that.activate(currentIndex); 664 } 665 }, selector, timeOffset); 666 667 } 668 }); 669 670 var alreadyClicked = false;
671 // Redirect to the new URL after click a suggestions 672 $(document).on('click.autocomplete', suggestionSelector, function (e) { 673 if (!alreadyClicked) { 674 var that = utils.getActiveInstance(); 675 that.actionTriggerSource = 'click'; 676 677 alreadyClicked = true; 678 setTimeout(function () { 679 alreadyClicked = false; 680 }, 500); 681 682 if (typeof e.ctrlKey === 'undefined' || e.ctrlKey === false) { 683 that.select($(this).data('index')); 684 e.preventDefault(); 685 } 686 } else { 687 e.preventDefault(); 688 } 689 }); 690 691 // FIX issue with touchpads for some laptops (marginal cases) 692 $(document).on('mousedown.autocomplete', suggestionSelector, function (e) { 693 var _this = this; 694 if (e.button === 0) { 695 setTimeout(function () { 696 if (!alreadyClicked) { 697 var that = utils.getActiveInstance(); 698 that.select($(_this).data('index')); 699 } 700 }, 250); 701 } 702 }); 703 704 // Mark cursor position for onBlur event 705 $('.' + that.options.containerClass).on('mousedown.autocomplete', function (e) { 706 var that = utils.getActiveInstance(); 707 that.isMouseDownOnSearchElements = true; 708 }); 709 710 $(document).on('click', '.js-dgwt-wcas-sugg-hist-clear', function () { 711 that.resetPreSuggestions(); 712 }); 713 }, 714 registerEventsDetailsPanel: function () { 715 var that = this, 716 detailsContainer = that.getDetailsContainer(); 717 718 if (!that.canShowDetailsPanel() || detailsContainer.hasClass('js-dgwt-wcas-initialized')) { 719 return; 720 } 721 722 // Update quantity 723 $(document).on('change.autocomplete', '[name="js-dgwt-wcas-quantity"]', function (e) { 724 var $input = $(this).closest('.js-dgwt-wcas-pd-addtc').find('[data-quantity]'); 725 $input.attr('data-quantity', $(this).val()); 726 }); 727 728 // Mark cursor position for onBlur event 729 $('.' + that.options.containerDetailsClass).on('mousedown.autocomplete', function (e) { 730 var that = utils.getActiveInstance(); 731 that.isMouseDownOnSearchElements = true; 732 }); 733 734 }, 735 registerIconHandler: function () { 736 var that = this, 737 $formWrapper = that.getFormWrapper(), 738 $form = that.getForm(); 739 740 $formWrapper.on('click.autocomplete', '.js-dgwt-wcas-search-icon-handler', function (e) { 741 742 var $input = $formWrapper.find('.' + that.options.searchInputClass); 743 744 if ($formWrapper.hasClass('dgwt-wcas-layout-icon-open')) { 745 that.hide(); 746 $form.hide(true); 747 748 $formWrapper.removeClass('dgwt-wcas-layout-icon-open'); 749 750 751 } else { 752 var $arrow = $formWrapper.find('.dgwt-wcas-search-icon-arrow'); 753 $form.hide(); 754 $arrow.hide(); 755 $formWrapper.addClass('dgwt-wcas-layout-icon-open'); 756 that.positionIconSearchMode($formWrapper); 757 758 $form.fadeIn(50, function () { 759 $arrow.show(); 760 that.positionPreloaderAndMic($formWrapper); 761 762 var textEnd = that.currentValue.length; 763 if (textEnd > 0) { 764 $input[0].setSelectionRange(textEnd, textEnd); 765 } 766 767 $input.trigger('focus'); 768 }); 769 770 setTimeout(function () { 771 that.fixPosition(); 772 }, 110); 773 774 } 775 return false;
776 }); 777 778 if ($('.js-dgwt-wcas-initialized').length == 0 && $('.js-dgwt-wcas-search-icon-handler').length > 0) { 779 780 $(document).on('click.autocomplete', function (event) { 781 782 if ($('.dgwt-wcas-layout-icon-open').length) { 783 784 var $target = $(event.target); 785 786 if (!($target.closest('.' + that.options.searchFormClass).length > 0 787 || $target.closest('.' + that.options.containerClass).length > 0 788 || $target.closest('.' + that.options.containerDetailsClass).length > 0 789 || $target.hasClass('js-dgwt-wcas-sugg-hist-clear') 790 )) { 791 that.hideIconModeSearch(); 792 } 793 794 } 795 }); 796 } 797 }, 798 registerFlexibleLayout: function () { 799 var that = this; 800 801 // Trigger only when x axis is changed 802 var windowWidth = $(window).width(); 803 $(window).on('resize.autocomplete', function () { 804 var newWidth = $(window).width(); 805 if (newWidth != windowWidth) { 806 that.reloadFlexibleLayout(); 807 windowWidth = newWidth; 808 } 809 }); 810 811 that.reloadFlexibleLayout(); 812 $(window).on('load.autocomplete', function () { 813 that.reloadFlexibleLayout(); 814 }); 815 816 }, 817 activateMobileOverlayMode: function () { 818 var that = this, 819 $formWrapper = that.getFormWrapper(), 820 $iconHandler = $formWrapper.find('.js-dgwt-wcas-search-icon-handler'); 821 822 if ( 823 $formWrapper.hasClass('js-dgwt-wcas-mobile-overlay-enabled') 824 && !$formWrapper.find('.js-dgwt-wcas-enable-mobile-form').length 825 ) { 826 827 var aria = typeof dgwt_wcas.labels.mob_overlay_label === 'string' ? dgwt_wcas.labels.mob_overlay_label : ''; 828 829 $formWrapper.prepend('<a href="#" aria-label="' + aria + '" class="js-dgwt-wcas-enable-mobile-form dgwt-wcas-enable-mobile-form"></a>'); 830 $formWrapper.addClass('dgwt-wcas-mobile-overlay-trigger-active'); 831 832 // Don't focus an icon handler when mobile overlay handler is displayed. 833 if ($iconHandler.length) { 834 $iconHandler.attr('tabindex', '-1'); 835 } 836 837 var $el = $formWrapper.find('.js-dgwt-wcas-enable-mobile-form'); 838 839 $el.on('click.autocomplete', function (e) { 840 841 if (that.options.mobileOverlayDelay > 0) { 842 setTimeout(function () { 843 that.showMobileOverlay(); 844 }, that.options.mobileOverlayDelay); 845 } else { 846 that.showMobileOverlay(); 847 } 848 849 return false; 850 }); 851 } 852 853 }, 854 deactivateMobileOverlayMode: function () { 855 var that = this, 856 $formWrapper = that.getFormWrapper(), 857 $iconHandler = $formWrapper.find('.js-dgwt-wcas-search-icon-handler'); 858 859 var $el = $formWrapper.find('.js-dgwt-wcas-enable-mobile-form'); 860 861 if ($formWrapper.hasClass('js-dgwt-wcas-mobile-overlay-enabled') 862 && $el.length 863 ) { 864 that.closeOverlayMobile(); 865 $el.remove(); 866 $formWrapper.removeClass('dgwt-wcas-mobile-overlay-trigger-active'); 867 868 // Focus an icon handler when mobile overlay is deactivated. 869 if ($iconHandler.length) { 870 $iconHandler.removeAttr('tabindex'); 871 } 872 } 873 874 }, 875 toggleMobileOverlayMode: function () { 876 var that = this, 877 $formWrapper = that.getFormWrapper(), 878 isMobOverlayEnabled = false; 879 880 // Break early if this search bar shouldn't open in overlay mobile mode 881 if (!$formWrapper.hasClass('js-dgwt-wcas-mobile-overlay-enabled')) { 882 return; 883 } 884 885 // Determine the search should open in mobile overlay 886 if ($formWrapper.find('.js-dgwt-wcas-enable-mobile-form').length) { 887 isMobOverlayEnabled = true; 888 } 889 890 // Toggled? 891 if ( 892 (!isMobOverlayEnabled && that.isBreakpointReached('mobile-overlay')) 893 || (isMobOverlayEnabled && !that.isBreakpointReached('mobile-overlay')) 894 ) { 895 896 var $suggestionsWrapper = that.getSuggestionsContainer(); 897 898 that.close(false); 899 900 if ($suggestionsWrapper.length) { 901 $suggestionsWrapper.html(''); 902 } 903 904 that.hideIconModeSearch(); 905 } 906 907 // Activate overlay on mobile feature 908 if (!isMobOverlayEnabled && that.isBreakpointReached('mobile-overlay')) { 909 that.activateMobileOverlayMode(); 910 } 911 912 // Deactivate overlay on mobile feature 913 if (isMobOverlayEnabled && !that.isBreakpointReached('mobile-overlay')) { 914 that.deactivateMobileOverlayMode(); 915 } 916 }, 917 showMobileOverlay: function () { 918 var that = this; 919 920 if (that.overlayMobileState === 'on') { 921 return; 922 } 923 924 that.overlayMobileState = 'on'; 925 926 var zIndex = 99999999999, 927 $wrapper = that.getFormWrapper(), 928 $suggestionsWrapp = that.getSuggestionsContainer(), 929 $overlayWrap, 930 html = ''; 931 932 $('html').addClass('dgwt-wcas-overlay-mobile-on'); 933 $('html').addClass('dgwt-wcas-open-' + that.getSearchStyle()); 934 html += '<div class="js-dgwt-wcas-overlay-mobile dgwt-wcas-overlay-mobile">'; 935 html += '<div class="dgwt-wcas-om-bar js-dgwt-wcas-om-bar">'; 936 html += '<button class="dgwt-wcas-om-return js-dgwt-wcas-om-return">' 937 if (typeof dgwt_wcas.back_icon == 'string') { 938 html += dgwt_wcas.back_icon; 939 } 940 html += '</button>'; 941 html += '</div>'; 942 html += '</div>'; 943 944 // Create overlay 945 $(that.options.mobileOverlayWrapper).append(html); 946 $overlayWrap = $('.js-dgwt-wcas-overlay-mobile'); 947 $overlayWrap.css('zIndex', zIndex); 948 949 $wrapper.after('<span class="js-dgwt-wcas-om-hook"></span>'); 950 $wrapper.appendTo('.js-dgwt-wcas-om-bar'); 951 $suggestionsWrapp.appendTo('.js-dgwt-wcas-om-bar'); 952 $wrapper.addClass('dgwt-wcas-search-wrapp-mobile'); 953 954 if ($wrapper.hasClass('dgwt-wcas-has-submit')) { 955 $wrapper.addClass('dgwt-wcas-has-submit-off'); 956 $wrapper.removeClass('dgwt-wcas-has-submit'); 957 } 958 959 $wrapper.find('.' + that.options.searchInputClass).trigger('focus'); 960 961 $(document).on('click.autocomplete', '.js-dgwt-wcas-om-return', function (e) { 962 that.closeOverlayMobile($overlayWrap); 963 }); 964 document.dispatchEvent(new CustomEvent('fibosearch/show-mobile-overlay', { 965 detail: that 966 })); 967 }, 968 closeOverlayMobile: function ($overlayWrap) { 969 var that = this; 970 971 if (!$('html').hasClass('dgwt-wcas-overlay-mobile-on')) { 972 that.overlayMobileState = 'off'; 973 return; 974 } 975 976 var $suggestionsWrapp = that.getSuggestionsContainer(); 977 978 var $clonedForm = $('.js-dgwt-wcas-om-bar').find('.' + that.options.searchFormClass); 979 980 if ($clonedForm.hasClass('dgwt-wcas-has-submit-off')) { 981 $clonedForm.removeClass('dgwt-wcas-has-submit-off'); 982 $clonedForm.addClass('dgwt-wcas-has-submit'); 983 } 984 985 $clonedForm.removeClass('dgwt-wcas-search-wrapp-mobile'); 986 $('html').removeClass('dgwt-wcas-overlay-mobile-on'); 987 $('html').removeClass('dgwt-wcas-open-' + that.getSearchStyle()); 988 $suggestionsWrapp.appendTo('body'); 989 $suggestionsWrapp.removeAttr('body-scroll-lock-ignore'); 990 $('.js-dgwt-wcas-om-hook').after($clonedForm); 991 $('.js-dgwt-wcas-overlay-mobile').remove(); 992 $('.js-dgwt-wcas-om-hook').remove(); 993 994 setTimeout(function () { 995 $clonedForm.find('.' + that.options.searchInputClass).val(''); 996 var $closeBtn = $clonedForm.find('.dgwt-wcas-close'); 997 if ($clonedForm.length > 0) { 998 $closeBtn.removeClass('dgwt-wcas-close'); 999 $closeBtn.html(''); 1000 } 1001 1002 that.hide(); 1003 1004 }, 150); 1005 1006 1007 that.overlayMobileState = 'off'; 1008 1009 document.dispatchEvent(new CustomEvent('fibosearch/hide-mobile-overlay', { 1010 detail: that 1011 })); 1012 }, 1013 reloadFlexibleLayout: function () { 1014 var that = this,
1015 $searchWrapp = that.getFormWrapper(), 1016 flexibleMode = 0, 1017 $iconPreloader = $searchWrapp.find('.dgwt-wcas-icon-preloader'); 1018 1019 /** 1020 * flexibleMode 1021 * 0 = not set 1022 * 1 = Icon on mobile, search bar on desktop 1023 * 2 = Icon on desktop, search bar on mobile 1024 */ 1025 1026 if ($searchWrapp.hasClass('js-dgwt-wcas-layout-icon-flexible')) { 1027 flexibleMode = 1; 1028 } 1029 1030 if ($searchWrapp.hasClass('js-dgwt-wcas-layout-icon-flexible-inv')) { 1031 flexibleMode = 2; 1032 } 1033 if (flexibleMode > 0) { 1034 1035 if ( 1036 (flexibleMode === 1 && that.isBreakpointReached('search-layout')) 1037 || (flexibleMode === 2 && !that.isBreakpointReached('search-layout')) 1038 ) { 1039 $searchWrapp.addClass('js-dgwt-wcas-layout-icon'); 1040 $searchWrapp.addClass('dgwt-wcas-layout-icon'); 1041 } else { 1042 $searchWrapp.removeClass('js-dgwt-wcas-layout-icon'); 1043 $searchWrapp.removeClass('dgwt-wcas-layout-icon'); 1044 } 1045 1046 $searchWrapp.addClass('dgwt-wcas-layout-icon-flexible-loaded'); 1047 if ($iconPreloader.length) { 1048 $iconPreloader.remove(); 1049 } 1050 } 1051 }, 1052 onFocus: function (e) { 1053 var that = this, 1054 $formWrapper = that.getFormWrapper(), 1055 options = that.options; 1056 // Mark as active 1057 $('.' + options.searchFormClass).removeClass('dgwt-wcas-active'); 1058 $formWrapper.addClass('dgwt-wcas-active'); 1059 1060 // Mark as focus 1061 $('body').addClass('dgwt-wcas-focused'); 1062 $formWrapper.addClass('dgwt-wcas-search-focused'); 1063 1064 if ($(e.target).closest('.dgwt-wcas-search-wrapp-mobile').length == 0) { 1065 that.enableOverlayDarkened(); 1066 } 1067 1068 that.fixPosition(); 1069 1070 if (that.el.val().length === 0) { 1071 if (that.canShowPreSuggestions()) { 1072 that.showPreSuggestions(); 1073 } 1074 } else if (that.el.val().length >= that.options.minChars) { 1075 that.onValueChange(); 1076 } 1077 }, 1078 onBlur: function () { 1079 var that = this, 1080 options = that.options, 1081 value = that.el.val(), 1082 query = that.getQuery(value), 1083 isMobileOverlayOnIPhone = false; 1084 1085 // Remove focused classes 1086 $('body').removeClass('dgwt-wcas-focused'); 1087 $('.' + options.searchFormClass).removeClass('dgwt-wcas-search-focused'); 1088 1089 if (utils.isIOS() && $('html').hasClass('dgwt-wcas-overlay-mobile-on')) { 1090 isMobileOverlayOnIPhone = true; 1091 } 1092 1093 if (!(that.isMouseDownOnSearchElements || isMobileOverlayOnIPhone)) { 1094 that.hide(); 1095 1096 if (that.selection && that.currentValue !== query) { 1097 (options.onInvalidateSelection || $.noop).call(that.element); 1098 } 1099 } 1100 1101 document.dispatchEvent(new CustomEvent('fibosearch/close', { 1102 detail: that 1103 })); 1104 }, 1105 abortAjax: function () { 1106 var that = this; 1107 if (that.currentRequest) { 1108 that.currentRequest.abort(); 1109 that.currentRequest = null; 1110 } 1111 }, 1112 setOptions: function (suppliedOptions) { 1113 var that = this, 1114 $suggestionsContainer = that.getSuggestionsContainer(), 1115 1116 options = $.extend({}, that.options, suppliedOptions); 1117 1118 that.isLocal = Array.isArray(options.lookup); 1119 1120 if (that.isLocal) { 1121 options.lookup = that.verifySuggestionsFormat(options.lookup); 1122 } 1123 1124 $suggestionsContainer.css({ 1125 'max-height': !that.canShowDetailsPanel() ? options.maxHeight + 'px' : 'none', 1126 'z-index': options.zIndex 1127 }); 1128 1129 // Add classes
1130 if (that.canShowDetailsPanel()) { 1131 var $detailsContainer = that.getDetailsContainer(); 1132 1133 $detailsContainer.css({ 1134 'z-index': (options.zIndex - 1) 1135 }); 1136 } 1137 1138 options.onSearchComplete = function () { 1139 var $searchForm = that.getFormWrapper(); 1140 $searchForm.removeClass('dgwt-wcas-processing'); 1141 that.preloader('hide', 'form', 'dgwt-wcas-inner-preloader'); 1142 that.showCloseButton(); 1143 }; 1144 1145 this.options = options; 1146 }, 1147 clearCache: function () { 1148 this.cachedResponse = {}; 1149 this.cachedDetails = {}; 1150 this.cachedPrices = {}; 1151 this.badQueries = []; 1152 }, 1153 clear: function (cache) { 1154 if (cache) { 1155 this.clearCache(); 1156 } 1157 this.currentValue = ''; 1158 this.suggestions = []; 1159 }, 1160 close: function (focus) { 1161 var that = this, 1162 $el = that.el.closest('.' + that.options.searchFormClass).find('.' + that.options.searchInputClass), 1163 $wrapp = that.getFormWrapper(); 1164 1165 that.hide(); 1166 that.clear(false); 1167 that.hideCloseButton(); 1168 $el.val(''); 1169 $wrapp.removeClass(that.classes.inputFilled); 1170 1171 if (focus) { 1172 $el.trigger('focus'); 1173 } 1174 }, 1175 fixPositionSuggestions: function () { 1176 var that = this, 1177 $suggestions = that.getSuggestionsContainer(), 1178 $formEl = that.getForm(), 1179 $input = that.el, 1180 formData = that.getElementInfo($formEl), 1181 inputData = that.getElementInfo($input), 1182 offset = { 1183 top: inputData.top + inputData.height, 1184 left: formData.left 1185 }; 1186 1187 // Set different vertical coordinates when the search bar is in the fixed position 1188 if (that.ancestorHasPositionFixed($formEl)) { 1189 offset.top = inputData.topViewPort + inputData.height; 1190 $suggestions.addClass(that.classes.fixed); 1191 } else { 1192 $suggestions.removeClass(that.classes.fixed); 1193 } 1194 1195 that.getSuggestionsContainer().css(offset); 1196 }, 1197 fixPositionDetailsPanel: function () { 1198 var that = this, 1199 $searchBar = that.getFormWrapper(), 1200 $suggestions = that.getSuggestionsContainer(), 1201 $detailsPanel = that.getDetailsContainer(), 1202 $formEl = that.getForm(), 1203 $input = that.el, 1204 formData = that.getElementInfo($formEl), 1205 inputData = that.getElementInfo($input), 1206 offset = { 1207 top: inputData.top + inputData.height, 1208 left: formData.left + $suggestions.outerWidth(false) 1209 }; 1210 1211 // Set different vertical coordinate when the search bar is in the fixed position 1212 if (that.ancestorHasPositionFixed($searchBar)) { 1213 offset.top = inputData.topViewPort + inputData.height; 1214 $detailsPanel.addClass(that.classes.fixed); 1215 } else { 1216 $detailsPanel.removeClass(that.classes.fixed) 1217 } 1218 1219 // Stick the details panel to the right side of the suggestion wrapper and to the bottom border of the search form 1220 $detailsPanel.css(offset); 1221 1222 $('body').removeClass('dgwt-wcas-full-width dgwt-wcas-details-outside dgwt-wcas-details-right dgwt-wcas-details-left dgwt-wcas-details-notfit'); 1223 1224 // Details Panel Mode 1: Both suggestions wrapper and details panel wrapper have the same width as the search bar 1225 if ($searchBar.outerWidth() >= that.options.dpusbBreakpoint) { 1226 $('body').addClass('dgwt-wcas-full-width'); 1227 1228 if (that.options.isRtl === true) { 1229 offset.left = formData.left + $detailsPanel.outerWidth(false); 1230 $suggestions.css('left', offset.left); 1231 $detailsPanel.css('left', formData.left); 1232 } 1233 1234 return; 1235 } 1236 1237 // Details Panel Mode 2: The suggestions' wrapper has the same width as the search bar. 1238 // Details panel clings to the left or right side of the suggestion wrapper. 1239 var windowWidth = $(window).width(), 1240 cDWidth = $detailsPanel.outerWidth(), 1241 cOffset = $detailsPanel.offset(); 1242
1243 $('body').addClass('dgwt-wcas-details-outside dgwt-wcas-details-right'); 1244 1245 // Is the details panel fits the space of the right side? 1246 // Not? Try to move to the left side 1247 if (windowWidth < (cOffset.left + cDWidth)) { 1248 $('body').removeClass('dgwt-wcas-details-right'); 1249 $('body').addClass('dgwt-wcas-details-left'); 1250 offset.left = $suggestions.offset().left - $detailsPanel.outerWidth(false); 1251 $detailsPanel.css('left', offset.left); 1252 cOffset = $detailsPanel.offset(); 1253 } 1254 1255 // Is the details' panel fits the space of the left side? 1256 // Not? Try to hide it by adding class "dgwt-wcas-details-notfit" 1257 if (cOffset.left < 1) { 1258 $('body').removeClass('dgwt-wcas-details-left dgwt-wcas-details-right'); 1259 $('body').addClass('dgwt-wcas-details-notfit'); 1260 } 1261 }, 1262 fixHeight: function () { 1263 var that = this; 1264 1265 var $suggestionsWrapp = that.getSuggestionsContainer(), 1266 $detailsWrapp = that.getDetailsContainer(); 1267 1268 $suggestionsWrapp.css('height', 'auto'); 1269 $detailsWrapp.css('height', 'auto'); 1270 1271 if (!that.canShowDetailsPanel()) { 1272 $suggestionsWrapp.css('height', 'auto'); 1273 return false; 1274 } 1275 1276 var sH = $suggestionsWrapp.outerHeight(false), 1277 dH = $detailsWrapp.outerHeight(false), 1278 minHeight = 340; 1279 1280 $suggestionsWrapp.find('.dgwt-wcas-suggestion:last-child').removeClass('dgwt-wcas-suggestion-no-border-bottom'); 1281 1282 if (sH <= minHeight && dH <= minHeight) { 1283 return false; 1284 } 1285 1286 $suggestionsWrapp.find('.dgwt-wcas-suggestion:last-child').addClass('dgwt-wcas-suggestion-no-border-bottom'); 1287 1288 if (dH < sH) { 1289 $detailsWrapp.css('height', (sH) + 'px'); 1290 } 1291 1292 if (sH < dH) { 1293 $suggestionsWrapp.css('height', dH + 'px'); 1294 } 1295 1296 return false; 1297 }, 1298 automaticAlignment: function () { 1299 var that = this, 1300 $input = that.getFormWrapper().find('.dgwt-wcas-search-input'), 1301 $suggestionsContainer = that.getSuggestionsContainer(), 1302 $detailsWrapp = that.getDetailsContainer(); 1303 1304 if (that.autoAligmentprocess != null) { 1305 return; 1306 } 1307 1308 var markers = [$input.width(), $suggestionsContainer.height()]; 1309 if (that.canShowDetailsPanel()) { 1310 markers[2] = $detailsWrapp.height(); 1311 } 1312 1313 that.autoAligmentprocess = setInterval(function () { 1314 1315 var newMarkers = [$input.width(), $suggestionsContainer.height()]; 1316 if (that.canShowDetailsPanel()) { 1317 newMarkers[2] = $detailsWrapp.height(); 1318 } 1319 1320 for (var i = 0; i < markers.length; i++) { 1321 1322 if (markers[i] != newMarkers[i]) { 1323 1324 that.fixHeight(); 1325 that.fixPosition(); 1326 markers = newMarkers; 1327 break; 1328 } 1329 } 1330 1331 1332 if (that.canShowDetailsPanel()) { 1333 1334 var innerDetailsHeight = $detailsWrapp.find('.dgwt-wcas-details-inner').height(); 1335 1336 1337 if ((innerDetailsHeight - $detailsWrapp.height()) > 2) { 1338 that.fixHeight(); 1339 } 1340 } 1341 1342 }, 10); 1343 1344 }, 1345 getElementInfo: function ($el) { 1346 var data = {}, 1347 viewPort, 1348 offset; 1349 1350 viewPort = $el[0].getBoundingClientRect(); 1351 offset = $el.offset(); 1352 1353 data.left = offset.left; 1354 data.top = offset.top; 1355 data.width = $el.outerWidth(false); 1356 data.height = $el.outerHeight(false); 1357 data.right = data.left + data.width; 1358 data.bottom = data.top + data.height; 1359 data.topViewPort = viewPort.top; 1360 data.bottomViewPort = viewPort.top + data.height; 1361 1362 return data; 1363 }, 1364 getFormWrapper: function () { 1365 var that = this; 1366 return that.el.closest('.' + that.options.searchFormClass); 1367 }, 1368 getForm: function () { 1369 var that = this; 1370 return that.el.closest('.' + that.options.formClass); 1371 }, 1372 getSuggestionsContainer: function () { 1373 var that = this; 1374 return $('.' + that.options.containerClass); 1375 }, 1376 getDetailsContainer: function () { 1377 var that = this; 1378 return $('.' + that.options.containerDetailsClass); 1379 }, 1380 scrollDownSuggestions: function () { 1381 var that = this, 1382 $el = that.getSuggestionsContainer(); 1383 $el[0].scrollTop = $el[0].scrollHeight; 1384 }, 1385 isCursorAtEnd: function () { 1386 var that = this, 1387 valLength = that.el.val().length, 1388 selectionStart = that.element.selectionStart, 1389 range; 1390 1391 if (typeof selectionStart === 'number') { 1392 return selectionStart === valLength; 1393 } 1394 if (document.selection) { 1395 range = document.selection.createRange(); 1396 range.moveStart('character', -valLength); 1397 return valLength === range.text.length; 1398 } 1399 return true; 1400 }, 1401 onKeyPress: function (e) { 1402 var that = this, 1403 $wrapp = that.getFormWrapper(); 1404 1405 that.addActiveClassIfMissing(); 1406 1407 // If suggestions are hidden and user presses arrow down, display suggestions: 1408 if (!that.visible && e.keyCode === keys.DOWN && that.currentValue) { 1409 that.suggest(); 1410 return; 1411 } 1412 1413 if (!that.visible) { 1414 // Hide the search icon mode on ESC when there are no suggestions 1415 if (e.keyCode === keys.ESC && $wrapp.hasClass('dgwt-wcas-layout-icon-open')) { 1416 that.hideIconModeSearch(); 1417 } 1418 1419 // Hide the darkened overlay on ESC when there are no suggestions 1420 if (e.keyCode === keys.ESC && that.isMountedOverlayDarkened()) { 1421 that.disableOverlayDarkened(); 1422 that.el.blur(); 1423 } 1424 1425 // Hide the mobile overlay on ESC. 1426 if (e.keyCode === keys.ESC && $('html').hasClass('dgwt-wcas-overlay-mobile-on')) { 1427 that.closeOverlayMobile(); 1428 } 1429 1430 return; 1431 } 1432 1433 // Open selected suggestion in new tab 1434 if ((e.ctrlKey || e.metaKey) && e.keyCode === keys.RETURN) { 1435 if (that.selectedIndex > -1) { 1436 that.openInNewTab(that.selectedIndex); 1437 } 1438 return; 1439 } 1440 1441 switch (e.keyCode) { 1442 case keys.ESC: 1443 that.close(); 1444 break; 1445 case keys.RIGHT: 1446 if (that.hint && that.options.onHint && that.isCursorAtEnd()) { 1447 that.selectHint(); 1448 break; 1449 } 1450 return; 1451 case keys.TAB: 1452 break; 1453 case keys.RETURN: 1454 1455 if (that.selectedIndex === -1) { 1456 if (that.options.disableSubmit) { 1457 return false;
1458 } 1459 that.hide(); 1460 return; 1461 } 1462 that.actionTriggerSource = 'enter'; 1463 that.select(that.selectedIndex); 1464 break; 1465 case keys.UP: 1466 that.moveUp(); 1467 break; 1468 case keys.DOWN: 1469 that.moveDown(); 1470 break; 1471 default: 1472 return; 1473 } 1474 1475 // Cancel event if function did not return: 1476 e.stopImmediatePropagation(); 1477 e.preventDefault(); 1478 }, 1479 onKeyUp: function (e) { 1480 var that = this; 1481 1482 switch (e.keyCode) { 1483 case keys.UP: 1484 case keys.DOWN: 1485 return; 1486 } 1487 1488 clearTimeout(that.onChangeTimeout); 1489 1490 if (that.currentValue !== that.el.val()) { 1491 if (that.options.deferRequestBy > 0) { 1492 // Defer lookup in case when value changes very quickly: 1493 that.onChangeTimeout = setTimeout(function () { 1494 that.onValueChange(); 1495 }, that.options.deferRequestBy); 1496 } else { 1497 that.onValueChange(); 1498 } 1499 } 1500 }, 1501 onValueChange: function () { 1502 if (this.ignoreValueChange) { 1503 this.ignoreValueChange = false; 1504 return; 1505 } 1506 1507 var that = this, 1508 options = that.options, 1509 value = that.el.val(), 1510 query = that.getQuery(value), 1511 $wrapp = that.getFormWrapper(); 1512 1513 if (that.selection && that.currentValue !== query) { 1514 that.selection = null; 1515 (options.onInvalidateSelection || $.noop).call(that.element); 1516 } 1517 1518 clearTimeout(that.onChangeTimeout); 1519 that.currentValue = value; 1520 that.selectedIndex = -1; 1521 1522 // Check existing suggestion for the match before proceeding: 1523 if (options.triggerSelectOnValidInput && that.isExactMatch(query)) { 1524 that.select(0); 1525 return; 1526 } 1527 1528 // Mark as filled 1529 if (query.length > 0) { 1530 if (!$wrapp.hasClass(that.classes.inputFilled)) { 1531 $wrapp.addClass(that.classes.inputFilled); 1532 } 1533 } else { 1534 $wrapp.removeClass(that.classes.inputFilled); 1535 } 1536 1537 if (query.length < options.minChars) { 1538 1539 that.hideCloseButton(); 1540 that.hide(); 1541 1542 if (that.canShowPreSuggestions() && query.length === 0) { 1543 that.showPreSuggestions(); 1544 } 1545 } else { 1546 1547 if (that.canShowPreSuggestions()) { 1548 that.hidePreSuggestions() 1549 } 1550 1551 that.getSuggestions(query); 1552 } 1553 }, 1554 isExactMatch: function (query) { 1555 var suggestions = this.suggestions; 1556 1557 return (suggestions.length === 1 && suggestions[0].value.toLowerCase() === query.toLowerCase()); 1558 }, 1559 isNoResults: function (suggestions) { 1560 var isNoResults = false; 1561 1562 if ( 1563 typeof suggestions != 'undefined' 1564 && suggestions.length === 1 1565 && typeof suggestions[0].type !== 'undefined' 1566 && suggestions[0].type === 'no-results' 1567 ) { 1568 isNoResults = true; 1569 } 1570 1571 return isNoResults; 1572 }, 1573 canShowDetailsPanel: function () { 1574 var that = this,
1575 show = that.options.showDetailsPanel; 1576 1577 if ($(window).width() < 768 || ('ontouchend' in document) || that.isPreSuggestionsMode || that.isNoResults(that.suggestions)) { 1578 show = false; 1579 } 1580 return show; 1581 }, 1582 isBreakpointReached: function (context) { 1583 var that = this, 1584 breakpoint = 0; 1585 1586 switch (context) { 1587 case 'search-layout': 1588 breakpoint = that.options.layoutBreakpoint; 1589 if (that.isSetParam('layout_breakpoint')) { 1590 breakpoint = Number.parseInt(that.getParam('layout_breakpoint')); 1591 } 1592 break; 1593 case 'mobile-overlay': 1594 breakpoint = that.options.mobileOverlayBreakpoint; 1595 if (that.isSetParam('mobile_overlay_breakpoint')) { 1596 breakpoint = Number.parseInt(that.getParam('mobile_overlay_breakpoint')); 1597 } 1598 break; 1599 } 1600 1601 return window.innerWidth <= breakpoint; 1602 }, 1603 getQuery: function (value) { 1604 var delimiter = this.options.delimiter, 1605 parts; 1606 1607 if (!delimiter) { 1608 return value.trim(); 1609 } 1610 parts = value.split(delimiter); 1611 return $.trim(parts[parts.length - 1]); 1612 }, 1613 getSuggestionsLocal: function (query) { 1614 var that = this, 1615 options = that.options, 1616 queryLowerCase = query.toLowerCase(), 1617 filter = options.lookupFilter, 1618 limit = parseInt(options.lookupLimit, 10), 1619 data; 1620 1621 data = { 1622 suggestions: $.grep(options.lookup, function (suggestion) { 1623 return filter(suggestion, query, queryLowerCase); 1624 }) 1625 }; 1626 1627 if (limit && data.suggestions.length > limit) { 1628 data.suggestions = data.suggestions.slice(0, limit); 1629 } 1630 1631 return data; 1632 }, 1633 getSuggestions: function (q) { 1634 var response, 1635 that = this, 1636 options = that.options, 1637 serviceUrl = options.serviceUrl, 1638 searchForm = that.getFormWrapper(), 1639 params, 1640 cacheKey, 1641 ajaxSettings, 1642 iconSearchActive = that.isActiveIconModeSearch(); 1643 1644 options.params[options.paramName] = q; 1645 1646 if (typeof dgwt_wcas.current_lang != 'undefined') { 1647 options.params['l'] = dgwt_wcas.current_lang; 1648 } 1649 1650 that.preloader('show', 'form', 'dgwt-wcas-inner-preloader'); 1651 searchForm.addClass('dgwt-wcas-processing'); 1652 1653 if (options.onSearchStart.call(that.element, options.params) === false) { 1654 return; 1655 } 1656 1657 params = options.ignoreParams ? null : options.params; 1658 1659 if (typeof options.lookup === 'function') { 1660 options.lookup(q, function (data) { 1661 that.suggestions = data.suggestions; 1662 that.suggest(); 1663 that.selectFirstSuggestion(data.suggestions); 1664 options.onSearchComplete.call(that.element, q, data.suggestions); 1665 }); 1666 return; 1667 } 1668 1669 if (!$('body').hasClass('dgwt-wcas-open')) { 1670 document.dispatchEvent(new CustomEvent('fibosearch/open', { 1671 detail: that 1672 })); 1673 } 1674 1675 if (that.isLocal) { 1676 response = that.getSuggestionsLocal(q); 1677 } else { 1678 if (typeof serviceUrl === 'function') { 1679 serviceUrl = serviceUrl.call(that.element, q); 1680 } 1681 cacheKey = serviceUrl + '?' + $.param(params || {}); 1682 response = that.cachedResponse[cacheKey]; 1683 } 1684 1685 if (response && Array.isArray(response.suggestions)) { 1686 that.suggestions = response.suggestions; 1687 that.suggest(); 1688 that.selectFirstSuggestion(response.suggestions); 1689 options.onSearchComplete.call(that.element, q, response.suggestions); 1690 1691 that.updatePrices(); 1692 1693 if (that.isNoResults(response.suggestions)) { 1694 document.dispatchEvent(new CustomEvent('fibosearch/no-results', { 1695 detail: that 1696 })); 1697 } else { 1698 document.dispatchEvent(new CustomEvent('fibosearch/show-suggestions', { 1699 detail: that 1700 })); 1701 } 1702 } else if (!that.isBadQuery(q)) { 1703 that.abortAjax(); 1704 1705 ajaxSettings = { 1706 url: serviceUrl, 1707 data: params, 1708 type: options.type, 1709 dataType: options.dataType 1710 }; 1711 1712 $.extend(ajaxSettings, options.ajaxSettings); 1713 1714 ajaxDebounceState.object = that; 1715 ajaxDebounceState.ajaxSettings = ajaxSettings; 1716 1717 utils.debounce(function () { 1718 1719 var that = ajaxDebounceState.object, 1720 ajaxSettings = ajaxDebounceState.ajaxSettings; 1721 1722 1723 that.currentRequest = $.ajax(ajaxSettings).done(function (data) { 1724 1725 // Interrupt if the icon mode was closed in the meantime
1726 if (iconSearchActive && !that.isActiveIconModeSearch()) { 1727 return; 1728 } 1729 1730 var result; 1731 that.currentRequest = null; 1732 result = that.options.transformResult(data, q); 1733 1734 if (typeof result.suggestions !== 'undefined') { 1735 that.processResponse(result, q, cacheKey); 1736 that.selectFirstSuggestion(result.suggestions); 1737 1738 if (that.isNoResults(result.suggestions)) { 1739 that.gaEvent(q, 'Autocomplete Search without results'); 1740 } else { 1741 that.gaEvent(q, 'Autocomplete Search with results'); 1742 } 1743 } 1744 1745 that.fixPosition(); 1746 1747 that.options.onSearchComplete.call(that.element, q, result.suggestions); 1748 1749 that.updatePrices(); 1750 1751 if (that.isNoResults(result.suggestions)) { 1752 document.dispatchEvent(new CustomEvent('fibosearch/no-results', { 1753 detail: that 1754 })); 1755 } else { 1756 document.dispatchEvent(new CustomEvent('fibosearch/show-suggestions', { 1757 detail: that 1758 })); 1759 } 1760 }).fail(function (jqXHR, textStatus, errorThrown) { 1761 that.options.onSearchError.call(that.element, q, jqXHR, textStatus, errorThrown); 1762 }); 1763 1764 1765 }, options.debounceWaitMs); 1766 1767 1768 } else { 1769 options.onSearchComplete.call(that.element, q, []); 1770 } 1771 1772 }, 1773 getDetails: function (suggestion) { 1774 var that = this; 1775 1776 // Disable details panel 1777 if (!that.canShowDetailsPanel()) { 1778 return false; 1779 } 1780 1781 // Brake if there are no suggestions 1782 if (suggestion == null || typeof suggestion.type == 'undefined') { 1783 return; 1784 } 1785 1786 // Disable on more product suggestion 1787 if (typeof suggestion.type == 'string' && suggestion.type === 'more_products') { 1788 return; 1789 } 1790 1791 that.fixHeight(); 1792 1793 var $containerDetails = that.getDetailsContainer(), 1794 currentObjectID = that.prepareSuggestionObjectID(suggestion), 1795 result; 1796 1797 // Check cache 1798 result = that.cachedDetails[currentObjectID]; 1799 1800 if (result != null) { 1801 1802 // Load response from cache 1803 that.detailsPanelSetScene(currentObjectID); 1804 that.fixHeight(); 1805 that.fixPosition(); 1806 1807 } else { 1808 1809 var data = { 1810 action: dgwt_wcas.action_result_details, 1811 items: [] 1812 }; 1813 1814 $.each(that.suggestions, function (i, suggestion) { 1815 1816 if ( 1817 typeof suggestion.type != 'undefined' 1818 && suggestion.type != 'more_products' 1819 && suggestion.type != 'headline' 1820 ) { 1821 var itemData = { 1822 objectID: that.prepareSuggestionObjectID(suggestion), 1823 value: suggestion.value != null ? suggestion.value : '' 1824 }; 1825 data.items.push(itemData); 1826 } 1827 }); 1828 1829 1830 that.detailsPanelClearScene(); 1831 that.preloader('show', 'details', ''); 1832 1833 // Prevent duplicate ajax requests 1834 if ($.inArray(currentObjectID, that.detailsRequestsSent) != -1) { 1835 return; 1836 } else { 1837 that.detailsRequestsSent.push(currentObjectID); 1838 } 1839 1840 $.ajax({ 1841 data: data, 1842 type: 'post', 1843 url: dgwt_wcas.ajax_details_endpoint, 1844 success: function (response) { 1845 1846 var result = typeof response === 'string' ? JSON.parse(response)
1846: response; 1847 1848 if (typeof result.items != 'undefined') { 1849 for (var i = 0; i < result.items.length; i++) { 1850 var cacheKey = result.items[i]['objectID']; 1851 that.cachedDetails[cacheKey] = {html: result.items[i]['html']} 1852 that.detailsPanelAddToScene(cacheKey); 1853 1854 if (typeof result.items[i]['price'] != 'undefined' && result.items[i]['price'].length > 0) { 1855 that.cachedPrices[cacheKey] = result.items[i]['price']; 1856 } 1857 } 1858 } 1859 1860 that.preloader('hide', 'details', ''); 1861 1862 var currentObjectID = that.prepareSuggestionObjectID(that.suggestions[that.selectedIndex]); 1863 1864 if (that.cachedDetails[currentObjectID] != null) { 1865 that.detailsPanelSetScene(currentObjectID); 1866 } else { 1867 // @TODO Maybe display some error or placeholder 1868 that.detailsPanelClearScene(); 1869 } 1870 that.fixPosition(); 1871 that.fixHeight(); 1872 1873 that.updatePrices(true); 1874 }, 1875 error: function (jqXHR, exception) { 1876 1877 that.preloader('hide', 'details', ''); 1878 1879 that.detailsPanelClearScene(); 1880 that.fixPosition(); 1881 that.fixHeight(); 1882 }, 1883 }); 1884 } 1885 1886 $(document).trigger('dgwtWcasDetailsPanelLoaded', that); 1887 1888 }, 1889 updatePrices: function (noAjax) { 1890 var that = this, 1891 i, 1892 productsToLoad = []; 1893 1894 if (!(that.options.showPrice && that.options.dynamicPrices)) { 1895 return; 1896 } 1897 1898 if (that.suggestions.length == 0) { 1899 return; 1900 } 1901 1902 for (i = 0; i < that.suggestions.length; i++) { 1903 1904 if ( 1905 typeof that.suggestions[i].type != 'undefined' 1906 && (that.suggestions[i].type == 'product' || that.suggestions[i].type == 'product_variation') 1907 ) { 1908 var key = ''; 1909 if (typeof that.suggestions[i].variation_id !== 'undefined') { 1910 // Variation as single product. 1911 key = 'product__' + that.suggestions[i].variation_id; 1912 } else { 1913 key = 'product__' + that.suggestions[i].post_id; 1914 } 1915 1916 if (typeof that.cachedPrices[key] != 'undefined') { 1917 1918 that.updatePrice(i, that.cachedPrices[key]); 1919 1920 } else { 1921 1922 that.applyPreloaderForPrice(i); 1923 if (typeof that.suggestions[i].variation_id !== 'undefined') { 1924 // Variation as single product. 1925 productsToLoad.push(that.suggestions[i].variation_id); 1926 } else { 1927 productsToLoad.push(that.suggestions[i].post_id); 1928 } 1929 } 1930 } 1931 1932 } 1933 1934 1935 if (!noAjax && productsToLoad.length > 0) { 1936 1937 var data = { 1938 action: typeof dgwt_wcas.action_get_prices == 'undefined' ? 'dgwt_wcas_get_prices' : dgwt_wcas.action_get_prices, 1939 items: productsToLoad 1940 }; 1941 1942 $.ajax({ 1943 data: data, 1944 type: 'post', 1945 url: dgwt_wcas.ajax_prices_endpoint, 1946 success: function (response) { 1947 if ( 1948 typeof response.success != 'undefined' 1949 && response.success 1950 && Object.keys(response.data).length > 0 1951 && that.suggestions.length > 0 1952 ) { 1953 for (i = 0; i < that.suggestions.length; i++) { 1954 if ( 1955 typeof that.suggestions[i].type !== 'undefined' 1956 && that.suggestions[i].type === 'product' 1957 && typeof response.data[that.suggestions[i].post_id] === 'string' 1958 ) { 1959 key = 'product__' + that.suggestions[i].post_id; 1960 that.cachedPrices[key] = response.data[that.suggestions[i].post_id]; 1961 that.updatePrice(i, response.data[that.suggestions[i].post_id]); 1962 } else if ( 1963 typeof that.suggestions[i].type !== 'undefined' 1964 && that.suggestions[i].type === 'product_variation' 1965 && typeof that.suggestions[i].variation_id !== 'undefined' 1966 && typeof response.data[that.suggestions[i].variation_id] === 'string' 1967 ) { 1968 key = 'product__' + that.suggestions[i].variation_id; 1969 that.cachedPrices[key] = response.data[that.suggestions[i].variation_id]; 1970 that.updatePrice(i, response.data[that.suggestions[i].variation_id]); 1971 } 1972 } 1973 } 1974 1975 }, 1976 error: function (jqXHR, exception) { 1977 1978 }, 1979 }); 1980 1981 } 1982 1983 }, 1984 updatePrice: function (index, price) { 1985 var that = this; 1986 1987 if (typeof that.suggestions[index] != 'undefined') { 1988 1989 that.suggestions[index].price = price; 1990 1991 var $price = $('.dgwt-wcas-suggestions-wrapp').find('[data-index="' + index + '"] .dgwt-wcas-sp'); 1992 1993 if ($price.length) { 1994 $price.html(price); 1995 } 1996 } 1997 1998 }, 1999 applyCustomParams: function (params) { 2000 var that = this; 2001 2002 // Custom params (global) 2003 if (typeof dgwt_wcas.custom_params == 'object') { 2004 var cp = dgwt_wcas.custom_params; 2005 for (var property in cp) { 2006 params[property] = cp[property]; 2007 } 2008 } 2009 2010 // Custom params (local) 2011 var inputCustomParams = that.el.data('custom-params'); 2012 2013 if (typeof inputCustomParams === 'object') { 2014 for (var property in inputCustomParams) { 2015 params[property] = inputCustomParams[property]; 2016 } 2017 } 2018 2019 return params; 2020 }, 2021 isSetParam: function (param) { 2022 var that = this; 2023 return typeof that.options.params[param] != 'undefined'; 2024 }, 2025 getParam: function (param) { 2026 var that = this; 2027 return that.isSetParam(param) ? that.options.params[param] : ''; 2028 }, 2029 applyPreloaderForPrice: function (index) { 2030 var that = this; 2031 2032 if (typeof that.suggestions[index] != 'undefined') { 2033 var $price = $('.dgwt-wcas-suggestions-wrapp').find('[data-index="' + index + '"] .dgwt-wcas-sp'); 2034 if ($price.length) { 2035 $price.html('<div class="dgwt-wcas-preloader-price"><div class="dgwt-wcas-preloader-price-inner"> <div></div><div></div><div></div></div></div>'); 2036 } 2037 } 2038 }, 2039 prepareSuggestionObjectID: function (suggestion) { 2040 var objectID = ''; 2041 2042 if (typeof suggestion != 'undefined' && typeof suggestion.type != 'undefined') { 2043 2044 //Products and post types 2045 if (suggestion.post_id != null) { 2046 objectID = suggestion.type + '__' + suggestion.post_id; 2047 2048 if (suggestion.type === 'product_variation') { 2049 objectID += '__' + suggestion.variation_id; 2050 } 2051 2052 // Post types 2053 if (typeof suggestion.post_type != 'undefined') { 2054 objectID = suggestion.type + '__' + suggestion.post_id + '__' + suggestion.post_type; 2055 } 2056 2057 } 2058 2059 //Terms 2060 if (suggestion.term_id != null && suggestion.taxonomy != null) { 2061 objectID = suggestion.type + '__' + suggestion.term_id + '__' + suggestion.taxonomy; 2062 } 2063 } 2064 2065 return objectID; 2066 }, 2067 detailsPanelSetScene: function (objectID) { 2068 var that = this, 2069 $containerDetails = that.getDetailsContainer(), 2070 objectHash = utils.hashCode(objectID),
2071 $el = $containerDetails.find('.dgwt-wcas-details-inner[data-object="' + objectHash + '"]'); 2072 2073 document.dispatchEvent(new CustomEvent('fibosearch/show-details-panel', { 2074 detail: that 2075 })); 2076 2077 if ($el.length) { 2078 that.preloader('hide', 'details', ''); 2079 that.detailsPanelClearScene(); 2080 $el.addClass('dgwt-wcas-details-inner-active'); 2081 } 2082 }, 2083 detailsPanelAddToScene: function (objectID) { 2084 var that = this, 2085 $containerDetails = that.getDetailsContainer(), 2086 object = that.cachedDetails[objectID], 2087 objectHash = utils.hashCode(objectID), 2088 html = ''; 2089 2090 if (typeof object != 'undefined' && typeof object.html == 'string') { 2091 html = object.html.replace('<div ', '<div data-object="' + objectHash + '" '); 2092 } 2093 2094 if ($containerDetails.find('.dgwt-wcas-details-inner[data-object="' + objectHash + '"]').length == 0) { 2095 $containerDetails.append(html); 2096 } 2097 }, 2098 detailsPanelClearScene: function () { 2099 var that = this, 2100 $containerDetails = that.getDetailsContainer(), 2101 $views = $containerDetails.find('.dgwt-wcas-details-inner'); 2102 2103 if ($views.length) { 2104 $views.removeClass('dgwt-wcas-details-inner-active'); 2105 } 2106 }, 2107 selectFirstSuggestion: function (suggestions) { 2108 var that = this, 2109 index = 0, 2110 noResults = false; 2111 2112 if (!that.canShowDetailsPanel()) { 2113 return; 2114 } 2115 2116 if (suggestions != 'undefined' && suggestions.length > 0) { 2117 $.each(that.suggestions, function (i, suggestion) { 2118 2119 if ( 2120 typeof suggestion.type != 'undefined' 2121 && suggestion.type != 'more_products' 2122 && suggestion.type != 'headline' 2123 && suggestion.type != 'headline-v2' 2124 && suggestion.type != 'no-results' 2125 ) { 2126 index = i; 2127 return false; 2128 } 2129 2130 if (typeof suggestion.type === 'undefined' || suggestion.type === 'no-results') { 2131 noResults = true; 2132 } 2133 2134 }); 2135 } 2136 2137 if (noResults) { 2138 return; 2139 } 2140 2141 that.latestActivateSource = 'system'; 2142 that.getDetails(suggestions[index]); 2143 that.activate(index); 2144 }, 2145 isBadQuery: function (q) { 2146 if (!this.options.preventBadQueries) { 2147 return false; 2148 } 2149 2150 var badQueries = this.badQueries, 2151 i = badQueries.length; 2152 2153 while (i--) { 2154 if (q.indexOf(badQueries[i]) === 0) { 2155 return true; 2156 } 2157 } 2158 2159 return false; 2160 }, 2161 hide: function (clear) { 2162 var that = this, 2163 $suggestions = that.getSuggestionsContainer(), 2164 $detailsPanel = that.getDetailsContainer(); 2165 2166 if (typeof that.options.onHide === 'function' && that.visible) { 2167 that.options.onHide.call(that.element, container); 2168 } 2169 2170 that.visible = false; 2171 that.selectedIndex = -1; 2172 clearTimeout(that.onChangeTimeout); 2173 $suggestions.hide(); 2174 $suggestions.removeClass(that.classes.suggestionsContainerOrientTop); 2175 $suggestions.removeClass(that.classes.fixed); 2176 2177 if (that.canShowDetailsPanel()) { 2178 $detailsPanel.hide(); 2179 $detailsPanel.removeClass(that.classes.fixed); 2180 } 2181 2182 that.hidePreSuggestions(); 2183 2184 $('body').removeClass('dgwt-wcas-open'); 2185 if (!$('html').hasClass('dgwt-wcas-overlay-mobile-on')) { 2186 var searchStyle = that.getSearchStyle(); 2187 $('html').removeClass('dgwt-wcas-open-' + searchStyle); 2188 if (searchStyle === 'pirx') { 2189 $('html').removeClass('dgwt-wcas-open-pirx-compact'); 2190 } 2191 } 2192 $('body').removeClass('dgwt-wcas-block-scroll');
2193 $('body').removeClass('dgwt-wcas-is-details'); 2194 $('body').removeClass('dgwt-wcas-full-width'); 2195 $('body').removeClass('dgwt-wcas-nores'); 2196 $('body').removeClass('dgwt-wcas-details-outside'); 2197 $('body').removeClass('dgwt-wcas-details-right'); 2198 $('body').removeClass('dgwt-wcas-details-left'); 2199 2200 if (that.autoAligmentprocess != null) { 2201 clearInterval(that.autoAligmentprocess); 2202 that.autoAligmentprocess = null; 2203 } 2204 2205 that.isMouseDownOnSearchElements = false; 2206 2207 if (typeof clear == 'boolean' && clear) { 2208 2209 that.hideCloseButton(); 2210 2211 that.currentValue = ''; 2212 that.suggestions = []; 2213 2214 } 2215 }, 2216 positionIconSearchMode: function ($formWrapper) { 2217 var that = this, 2218 formLeftValue = -20, 2219 $form = that.getForm(), 2220 formWidth = $form.width(), 2221 windowWidth = $(window).width(); 2222 2223 var iconLeftOffset = $formWrapper[0].getBoundingClientRect().left; 2224 2225 var iconLeftRatio = (iconLeftOffset + 10) / windowWidth; 2226 2227 formLeftValue = Math.floor(-1 * (formWidth * iconLeftRatio)); 2228 2229 // Prevent shifting to the left more than the icon position (also positioned from the left) 2230 formLeftValue = Math.max(formLeftValue, -1 * iconLeftOffset); 2231 2232 $form.css({'left': formLeftValue + 'px'}); 2233 2234 }, 2235 isActiveIconModeSearch: function () { 2236 var active = false, 2237 $openedElements = $('.dgwt-wcas-layout-icon-open'); 2238 if ($openedElements.length > 0) { 2239 active = true; 2240 } 2241 return active; 2242 }, 2243 hideIconModeSearch: function () { 2244 var that = this; 2245 2246 if (that.isActiveIconModeSearch() && !utils.isTextSelected()) { 2247 $('.dgwt-wcas-layout-icon-open').removeClass('dgwt-wcas-layout-icon-open'); 2248 } 2249 }, 2250 hideAfterClickOutsideListener: function () { 2251 var that = this; 2252 if (!('ontouchend' in document)) { 2253 2254 $(document).on('mouseup', function (e) { 2255 if (!that.visible) { 2256 return; 2257 } 2258 2259 var outsideForm = !($(e.target).closest('.' + that.options.searchFormClass).length > 0 || $(e.target).hasClass(that.options.searchFormClass)), 2260 outsideContainer = !($(e.target).closest('.' + that.options.containerClass).length > 0 || $(e.target).hasClass(that.options.containerClass)); 2261 2262 if (!that.canShowDetailsPanel()) { 2263 2264 if (outsideForm && outsideContainer) { 2265 that.hide(); 2266 } 2267 2268 } else { 2269 2270 var outsidecontainerDetails = !($(e.target).closest('.' + that.options.containerDetailsClass).length > 0 || $(e.target).hasClass(that.options.containerDetailsClass)); 2271 2272 if (outsideForm && outsideContainer && outsidecontainerDetails) { 2273 that.hide(); 2274 } 2275 2276 } 2277 2278 }); 2279 2280 } 2281 }, 2282 suggest: function () { 2283 if (!this.suggestions.length) { 2284 this.hide(); 2285 return; 2286 } 2287 2288 var that = this, 2289 options = that.options, 2290 groupBy = options.groupBy, 2291 formatResult = options.formatResult, 2292 value = that.getQuery(that.currentValue), 2293 className = that.classes.suggestion, 2294 classSelected = that.classes.selected, 2295 container = that.getSuggestionsContainer(), 2296 containerDetails = that.getDetailsContainer(), 2297 noSuggestionsContainer = $(that.noSuggestionsContainer), 2298 beforeRender = options.beforeRender, 2299 html = '', 2300 category, 2301 formatGroup = function (suggestion, index) { 2302 var currentCategory = suggestion.data[groupBy]; 2303 2304 if (category === currentCategory) { 2305 return ''; 2306 } 2307 2308 category = currentCategory; 2309 2310 return '<div class="autocomplete-group"><strong>' + category + '</strong></div>'; 2311 }; 2312 2313 if (options.triggerSelectOnValidInput && that.isExactMatch(value)) { 2314 that.select(0); 2315 return; 2316 } 2317 2318 $('body').removeClass('dgwt-wcas-nores'); 2319 2320 // Build suggestions inner HTML: 2321 $.each(that.suggestions, function (i, suggestion) { 2322 2323 var url = typeof suggestion.url == 'string' && suggestion.url.length ? suggestion.url : '#'; 2324 2325 if (groupBy) { 2326 html += formatGroup(suggestion, value, i); 2327 } 2328 2329 if (typeof suggestion.type == 'undefined' || (suggestion.type != 'product') && suggestion.type != 'product_variation') { 2330 2331 var classes = className, 2332 innerClass = 'dgwt-wcas-st', 2333 prepend = '', 2334 append = '', 2335 title = '', 2336 highlight = true, 2337 isImg, 2338 noResults = false;
2339 2340 if (suggestion.taxonomy === 'product_cat') { 2341 classes += ' dgwt-wcas-suggestion-tax dgwt-wcas-suggestion-cat'; 2342 if (!options.showHeadings) { 2343 prepend += '<span class="dgwt-wcas-st--direct-headline">' + dgwt_wcas.labels['tax_' + suggestion.taxonomy] + '</span>'; 2344 } 2345 if (typeof suggestion.breadcrumbs != 'undefined' && suggestion.breadcrumbs) { 2346 title = suggestion.breadcrumbs + ' > ' + suggestion.value; 2347 append += '<span class="dgwt-wcas-st-breadcrumbs"><span class="dgwt-wcas-st-label-in">' + dgwt_wcas.labels.in + ' </span>' + suggestion.breadcrumbs + '</span>'; 2348 //@TODO RTL support 2349 } 2350 2351 } else if (suggestion.taxonomy === 'product_tag') { 2352 classes += ' dgwt-wcas-suggestion-tax dgwt-wcas-suggestion-tag'; 2353 if (!options.showHeadings) { 2354 prepend += '<span class="dgwt-wcas-st--direct-headline">' + dgwt_wcas.labels['tax_' + suggestion.taxonomy] + '</span>'; 2355 } 2356 } else if (options.isPremium && suggestion.taxonomy === options.taxonomyBrands) { 2357 classes += ' dgwt-wcas-suggestion-tax dgwt-wcas-suggestion-brand'; 2358 if (!options.showHeadings) { 2359 prepend += '<span class="dgwt-wcas-st--direct-headline">' + dgwt_wcas.labels['tax_' + suggestion.taxonomy] + '</span>'; 2360 } 2361 } else if (options.isPremium && suggestion.type === 'taxonomy') { 2362 classes += ' dgwt-wcas-suggestion-tax dgwt-wcas-suggestion-tax-' + suggestion.taxonomy; 2363 if (!options.showHeadings) { 2364 prepend += '<span class="dgwt-wcas-st--direct-headline">' + dgwt_wcas.labels['tax_' + suggestion.taxonomy] + '</span>'; 2365 } 2366 } else if (options.isPremium && suggestion.type === 'vendor') { 2367 classes += ' dgwt-wcas-suggestion-vendor dgwt-wcas-suggestion-vendor'; 2368 if (!options.showHeadings) { 2369 prepend += '<span class="dgwt-wcas-st--direct-headline">' + dgwt_wcas.labels.vendor + '</span>'; 2370 } 2371 } else if (options.isPremium && suggestion.type === 'post' && typeof suggestion.post_type !== 'undefined') { 2372 classes += ' dgwt-wcas-suggestion-pt dgwt-wcas-suggestion-pt-' + suggestion.post_type; 2373 if (!options.showHeadings) { 2374 prepend += '<span class="dgwt-wcas-st--direct-headline">' + dgwt_wcas.labels['post_type_' + suggestion.post_type] + '</span>'; 2375 } 2376 } else if (suggestion.type === 'more_products') { 2377 classes += ' js-dgwt-wcas-suggestion-more dgwt-wcas-suggestion-more'; 2378 innerClass = 'dgwt-wcas-st-more'; 2379 suggestion.value = dgwt_wcas.labels.show_more + '<span class="dgwt-wcas-st-more-total"> (' + suggestion.total + ')</span>'; 2380 highlight = false; 2381 } else if (options.showHeadings && suggestion.type === 'headline') { 2382 classes += ' js-dgwt-wcas-suggestion-headline dgwt-wcas-suggestion-headline'; 2383 if (typeof dgwt_wcas.labels[suggestion.value + '_plu'] != 'undefined') { 2384 suggestion.value = dgwt_wcas.labels[suggestion.value + '_plu']; 2385 } 2386 highlight = false; 2387 } 2388 2389 if (suggestion.type === 'no-results') { 2390 2391 $('body').addClass('dgwt-wcas-nores'); 2392 if (containerDetails.length) { 2393 that.detailsPanelClearScene(); 2394 containerDetails.hide(); 2395 containerDetails.removeClass(that.classes.fixed); 2396 that.fixHeight(); 2397 } 2398 2399 suggestion.value = ''; 2400 html += that.createNoResultsContent(); 2401 2402 } else { 2403 // Image 2404 if ( 2405 (typeof suggestion.image_src != 'undefined' && suggestion.image_src) || 2406 (typeof suggestion.image != 'undefined' && suggestion.image) 2407 ) { 2408 isImg = true; 2409 } 2410 2411 // Custom content before title (3rd party) 2412 prepend += that.apply3rdPartyPlaceholder('title_before', suggestion); 2413 append += that.apply3rdPartyPlaceholder('title_after', suggestion); 2414 2415 title = title.length > 0 ? ' title="' + title.replace(/>/g, '>') + '"' : ''; 2416 2417 html += '<a href="' + url + '" class="' + classes + '" data-index="' + i + '">'; 2418 2419 if (isImg) { 2420 const imgSrc = suggestion.image_src ? suggestion.image_src : suggestion.image; 2421 html += '<span class="dgwt-wcas-si"><img src="' + imgSrc + '" /></span>'; 2422 html += '<div class="dgwt-wcas-content-wrapp">'; 2423 } 2424 2425 html += '<span' + title + ' class="' + innerClass + '">'; 2426 2427 if (suggestion.type === 'vendor') { 2428 html += '<span class="dgwt-wcas-st-title">' + prepend + formatResult(suggestion.value, value, highlight, options) + append + '</span>'; 2429 2430 // Vendor city 2431 if (suggestion.shop_city) { 2432 html += '<span class="dgwt-wcas-vendor-city"><span>
2432 - </span>' + formatResult(suggestion.shop_city, value, true, options) + '</span>'; 2433 } 2434 2435 // Description 2436 if (typeof suggestion.desc != 'undefined' && suggestion.desc) { 2437 html += '<span class="dgwt-wcas-sd">' + formatResult(suggestion.desc, value, true, options) + '</span>'; 2438 } 2439 2440 } else { 2441 html += prepend + formatResult(suggestion.value, value, highlight, options) + append; 2442 } 2443 2444 html += '</span>'; 2445 2446 html += isImg ? '</div>' : ''; 2447 html += '</a>'; 2448 } 2449 2450 } else { 2451 2452 html += that.createProductSuggestion(suggestion, i); 2453 2454 } 2455 }); 2456 2457 this.adjustContainerWidth(); 2458 2459 noSuggestionsContainer.detach(); 2460 container.html(html); 2461 2462 if (typeof beforeRender === 'function') { 2463 beforeRender.call(that.element, container, that.suggestions); 2464 } 2465 2466 container.show(); 2467 2468 // Add class on show 2469 $('body').addClass('dgwt-wcas-open'); 2470 var searchStyle = that.getSearchStyle(); 2471 $('html').addClass('dgwt-wcas-open-' + searchStyle); 2472 if (searchStyle === 'pirx') { 2473 $('html').addClass('dgwt-wcas-open-pirx-compact'); 2474 } 2475 2476 // Reset the latest mousedown position 2477 that.isMouseDownOnSearchElements = false; 2478 2479 that.automaticAlignment(); 2480 2481 if (that.canShowDetailsPanel()) { 2482 $('body').addClass('dgwt-wcas-is-details'); 2483 containerDetails.show(); 2484 that.fixHeight(); 2485 } 2486 2487 // Select first value by default: 2488 if (options.autoSelectFirst) { 2489 that.selectedIndex = 0; 2490 container.scrollTop(0); 2491 container.children('.' + className).first().addClass(classSelected); 2492 } 2493 2494 that.visible = true; 2495 that.fixPosition(); 2496 }, 2497 createNoResultsContent: function () { 2498 var html = '<div class="dgwt-wcas-suggestion-nores">', 2499 defaultHtml = typeof dgwt_wcas.labels.no_results_default != 'undefined' ? dgwt_wcas.labels.no_results_default : '', 2500 noResultsHtml = defaultHtml; 2501 2502 try { 2503 noResultsHtml = JSON.parse(dgwt_wcas.labels.no_results); 2504 // Fix invalid HTML 2505 var tmpEl = document.createElement('div'); 2506 tmpEl.innerHTML = noResultsHtml; 2507 noResultsHtml = tmpEl.innerHTML; 2508 2509 } catch (e) { 2510 2511 } 2512 2513 html += noResultsHtml; 2514 html += '</div>'; 2515 2516 return html; 2517 2518 }, 2519 createProductSuggestion: function (suggestion, index, extClassName) { 2520 var that = this, 2521 html = '', 2522 parent = '', 2523 dataAttrs = '', 2524 options = that.options, 2525 className = that.classes.suggestion, 2526 isImg = false, 2527 value = that.getQuery(that.currentValue), 2528 formatResult = options.formatResult, 2529 url = typeof suggestion.url == 'string' && suggestion.url.length ? suggestion.url : '#'; 2530 2531 if (typeof extClassName == 'string') { 2532 className += ' ' + extClassName; 2533 } 2534 2535 // Image 2536 if (options.showImage === true && typeof suggestion.thumb_html != 'undefined') { 2537 isImg = true; 2538 } 2539 2540 var sugVarClass = suggestion.type === 'product_variation' ? ' dgwt-wcas-suggestion-product-var' : ''; 2541 // One suggestion HTML 2542 dataAttrs += typeof suggestion.post_id != 'undefined' ? 'data-post-id="' + suggestion.post_id + '" ' : ''; 2543 dataAttrs += typeof suggestion.taxonomy != 'undefined' ? 'data-taxonomy="' + suggestion.taxonomy + '" ' : ''; 2544 dataAttrs += typeof suggestion.term_id != 'undefined' ? 'data-term-id="' + suggestion.term_id + '" ' : ''; 2545 html += '<a href="' + url + '" class="' + className + ' dgwt-wcas-suggestion-product' + sugVarClass + '" data-index="' + index + '" ' + dataAttrs + '>'; 2546 2547 // Image 2548 if (isImg) { 2549 html += '<span class="dgwt-wcas-si">' + suggestion.thumb_html + '</span>'; 2550 } 2551 2552 2553 html += isImg ? '<div class="dgwt-wcas-content-wrapp">' : ''; 2554 2555 2556 // Open Title wrapper 2557 html += '<div class="dgwt-wcas-st">'; 2558 2559 2560 2561 // Custom content before title (3rd party) 2562 html += that.apply3rdPartyPlaceholder('title_before', suggestion); 2563 2564 // Title 2565 html += '<span class="dgwt-wcas-st-title">' + formatResult(suggestion.value, value, true, options) + parent + '</span>'; 2566 2567 // Custom content after title (3rd party) 2568 html += that.apply3rdPartyPlaceholder('title_after', suggestion); 2569 2570 // SKU 2571 if (options.showSKU === true && typeof suggestion.sku != 'undefined' && suggestion.sku.length > 0) { 2572 html += '<span class="dgwt-wcas-sku">(' + dgwt_wcas.labels.sku_label + ' ' + formatResult(suggestion.sku, value, true, options) + ')</span>'; 2573 } 2574 2575 // Description 2576 if (options.showDescription === true && typeof suggestion.desc != 'undefined' && suggestion.desc) { 2577 html += '<span class="dgwt-wcas-sd">' + formatResult(suggestion.desc, value, true, options) + '</span>'; 2578 } 2579 2580 // Vendor 2581 if (options.showProductVendor === true && typeof suggestion.vendor != 'undefined' && suggestion.vendor) { 2582 var vendorBody = '<span class="dgwt-wcas-product-vendor"><span class="dgwt-wcas-product-vendor-label">' + dgwt_wcas.labels.vendor_sold_by + ' </span>' + suggestion.vendor + '</span>' 2583 2584 if (typeof suggestion.vendor_url != 'undefined' && suggestion.vendor_url) { 2585 // Since version v1.12.0 suggestions tag was changed from <div> to <a> and vendor links are no longer supported. 2586 html += '<span class="dgwt-wcas-product-vendor-link" data-url="' + suggestion.vendor_url + '">' + vendorBody + '</span>'; 2587 } else { 2588 html += vendorBody; 2589 } 2590 2591 } 2592 2593 // Custom content after description (3rd party) 2594 html += that.apply3rdPartyPlaceholder('content_after', suggestion); 2595
2596 // Display score (only visible in debug mode with ?fibodebug=score) 2597 if (typeof suggestion.score !== 'undefined') { 2598 html += '<div class="dgwt-wcas-score">Score: ' + suggestion.score + '</div>'; 2599 } 2600 2601 // Close title wrapper 2602 html += '</div>'; 2603 2604 2605 var showPrice = options.showPrice === true && typeof suggestion.price != 'undefined', 2606 showMetaBefore = typeof suggestion.meta_before != 'undefined', 2607 showMetaAfter = typeof suggestion.meta_after != 'undefined', 2608 showMeta = showPrice || showMetaBefore || showMetaAfter; 2609 // @todo show sale and featured badges 2610 2611 // Meta 2612 html += showMeta ? '<div class="dgwt-wcas-meta">' : ''; 2613 2614 // Custom content before meta (3rd party) 2615 if (showMetaBefore) { 2616 html += that.apply3rdPartyPlaceholder('meta_before', suggestion); 2617 } 2618 2619 // Price 2620 if (showPrice) { 2621 html += '<span class="dgwt-wcas-sp">' + suggestion.price + '</span>'; 2622 } 2623 2624 // Custom content after meta (3rd party) 2625 if (showMetaAfter) { 2626 html += that.apply3rdPartyPlaceholder('meta_after', suggestion); 2627 } 2628 2629 // Close Meta 2630 html += showMeta ? '</div>' : ''; 2631 2632 html += isImg ? '</div>' : ''; 2633 html += '</a>'; 2634 2635 return html; 2636 }, 2637 apply3rdPartyPlaceholder: function (name, suggestion) { 2638 var content = ''; 2639 if (typeof suggestion[name] != 'undefined' && suggestion[name]) { 2640 content = suggestion[name]; 2641 } 2642 return content; 2643 }, 2644 getSearchStyle: function () { 2645 var that = this, 2646 $searchWrapp = that.getFormWrapper(), 2647 style = 'solaris'; //Default style 2648 2649 if (!$searchWrapp || $searchWrapp.length === 0) { 2650 return style; 2651 } 2652 2653 $($searchWrapp?.attr('class')?.split(/\s+/)).each(function (index) { 2654 if (/dgwt-wcas-style-/i.test(this)) { 2655 style = this.replace(/dgwt-wcas-style-/i, ''); 2656 } 2657 }); 2658 2659 if (style === 'pirx-compact') { 2660 style = 'pirx'; 2661 } 2662 2663 return style; 2664 }, 2665 adjustContainerWidth: function () { 2666 var that = this, 2667 $searchBar = that.getFormWrapper(), 2668 $suggestions = that.getSuggestionsContainer(), 2669 $detailsPanel = that.getDetailsContainer(), 2670 $baseElement = that.getForm(), 2671 baseWidth = $baseElement.outerWidth(); 2672 2673 if (!$searchBar.length) { 2674 return; 2675 } 2676 2677 // Mode 1 - suggestions wrapper width is the same as search bar width 2678 $suggestions.css('width', baseWidth + 'px'); 2679 2680 // Mode 2 - keep the suggestions wrapper and the details panel together under the search bar 2681 if (that.canShowDetailsPanel() && baseWidth >= that.options.dpusbBreakpoint) { 2682 var measurementError = 0; 2683
2684 // Width 50:50 2685 $suggestions.css('width', baseWidth / 2); 2686 $detailsPanel.css('width', baseWidth / 2); 2687 2688 // Fix browsers subtleties such as calculating sizes as float numbers. 2689 measurementError = baseWidth - ($suggestions.outerWidth() + $detailsPanel.outerWidth()); 2690 if (measurementError != 0) { 2691 $detailsPanel.css('width', $detailsPanel.outerWidth() + measurementError); 2692 } 2693 } 2694 }, 2695 positionPreloaderAndMic: function ($formWrapper) { 2696 var that = this; 2697 2698 var $submit = typeof $formWrapper == 'object' ? $formWrapper.find('.dgwt-wcas-search-submit') : $('.dgwt-wcas-search-submit'); 2699 2700 if ($submit.length > 0) { 2701 $submit.each(function () { 2702 var $preloader = $(this).closest('.dgwt-wcas-search-wrapp').find('.dgwt-wcas-preloader'), 2703 isSolarisStyle = $(this).closest('.dgwt-wcas-search-wrapp').hasClass('dgwt-wcas-style-solaris'), 2704 isVoiceSearchSupported = $(this).closest('.dgwt-wcas-search-wrapp').hasClass(that.options.voiceSearchSupportedClass), 2705 $voiceSearch = $(this).closest('.dgwt-wcas-search-wrapp').find('.' + that.options.voiceSearchClass); 2706 2707 if (isVoiceSearchSupported && isSolarisStyle) { 2708 if (dgwt_wcas.is_rtl == 1) { 2709 $voiceSearch.css('transform', 'translateX(' + $(this).outerWidth() + 'px)'); 2710 } else { 2711 $voiceSearch.css('transform', 'translateX(-' + $(this).outerWidth() + 'px)'); 2712 } 2713 } 2714 2715 if (dgwt_wcas.is_rtl == 1) { 2716 $preloader.css('left', $(this).outerWidth() + 'px'); 2717 } else { 2718 $preloader.css('right', $(this).outerWidth() + 'px'); 2719 } 2720 2721 }); 2722 } 2723 2724 }, 2725 /* 2726 * Manages preloader 2727 * 2728 * @param action (show or hide) 2729 * @param container (parent selector) 2730 * @param cssClass 2731 */ 2732 preloader: function (action, place, cssClass) { 2733 var that = this, 2734 html, 2735 $container, 2736 defaultClass = 'dgwt-wcas-preloader-wrapp', 2737 cssClasses = cssClass == null ? defaultClass : defaultClass + ' ' + cssClass; 2738 2739 if (place === 'form') { 2740 2741 // Return early if the preloader is disable via the settings for a search bar 2742 if (dgwt_wcas.show_preloader != 1) { 2743 return; 2744 } 2745 2746 $container = that.getFormWrapper().find('.dgwt-wcas-preloader'); 2747 } else if (place === 'details') { 2748 $container = that.getDetailsContainer(); 2749 } 2750 2751 if ($container.length == 0) { 2752 return; 2753 } 2754 2755 // Handle preloader for a search bar 2756 if (place === 'form') { 2757 if (action === 'hide') { 2758 $container.removeClass(cssClass); 2759 $container.html(''); 2760 } else { 2761 $container.addClass(cssClass); 2762 if (typeof dgwt_wcas.preloader_icon == 'string') { 2763 $container.html(dgwt_wcas.preloader_icon); 2764 } 2765 } 2766 return; 2767 } 2768 2769 // Handle preloader for a details panel 2770 var $preloader = $container.find('.' + defaultClass); 2771 2772 // Action hide 2773 if (action === 'hide') { 2774 if ($preloader.length) { 2775 $preloader.remove(); 2776 } 2777 return 2778 } 2779 2780 // Action show 2781 if (action === 'show') { 2782 var rtlSuffix = that.options.isRtl ? '-rtl' : ''; 2783 html = '<div class="' + cssClasses + '"><img class="dgwt-wcas-placeholder-preloader" src="' + dgwt_wcas.img_url + 'placeholder' + rtlSuffix + '.png" /></div>'; 2784 that.detailsPanelClearScene(); 2785 if ($preloader.length) { 2786 $preloader.remove(); 2787 } 2788 $container.prepend(html); 2789 } 2790 }, 2791 verifySuggestionsFormat: function (suggestions) { 2792 2793 // If suggestions is string array, convert them to supp
2793orted format: 2794 if (suggestions.length && typeof suggestions[0] === 'string') { 2795 return $.map(suggestions, function (value) { 2796 return {value: value, data: null}; 2797 }); 2798 } 2799 2800 return suggestions; 2801 }, 2802 processResponse: function (result, originalQuery, cacheKey) { 2803 var that = this, 2804 options = that.options; 2805 2806 result.suggestions = that.verifySuggestionsFormat(result.suggestions); 2807 2808 // Cache results if cache is not disabled: 2809 if (!options.noCache) { 2810 that.cachedResponse[cacheKey] = result; 2811 if (options.preventBadQueries && !result.suggestions.length) { 2812 that.badQueries.push(originalQuery); 2813 } 2814 } 2815 2816 // Return if originalQuery is not matching current query: 2817 if (originalQuery !== that.getQuery(that.currentValue)) { 2818 return; 2819 } 2820 2821 that.suggestions = result.suggestions; 2822 that.suggest(); 2823 }, 2824 activate: function (index) { 2825 var that = this, 2826 activeItem, 2827 selected = that.classes.selected, 2828 container = that.getSuggestionsContainer(), 2829 children = container.find('.' + that.classes.suggestion); 2830 2831 container.find('.' + selected).removeClass(selected); 2832 2833 that.selectedIndex = index; 2834 2835 if (that.selectedIndex !== -1 && children.length > that.selectedIndex) { 2836 activeItem = children.get(that.selectedIndex); 2837 $(activeItem).addClass(selected); 2838 return activeItem; 2839 } 2840 2841 return null; 2842 }, 2843 selectHint: function () { 2844 var that = this, 2845 i = $.inArray(that.hint, that.suggestions); 2846 2847 that.select(i); 2848 }, 2849 select: function (i) { 2850 var that = this; 2851 2852 if (that.options.disableHits) { 2853 return; 2854 } 2855 2856 // Break early if a "select" event isn't related to suggestions 2857 if (typeof that.suggestions[i] == 'undefined') { 2858 return; 2859 } 2860 2861 // Don't select if there is headline element 2862 if (typeof that.suggestions[i] != 'undefined' 2863 && (that.suggestions[i].type == 'headline' || that.suggestions[i].type == 'headline-v2')) { 2864 return; 2865 } 2866 2867 that.closeOverlayMobile(); 2868 that.hide(); 2869 that.onSelect(i); 2870 }, 2871 moveUp: function () { 2872 var that = this; 2873 2874 if (that.selectedIndex === -1) { 2875 return; 2876 } 2877 2878 that.latestActivateSource = 'key'; 2879 2880 if (that.selectedIndex === 0) { 2881 that.getSuggestionsContainer().children('.' + that.classes.suggestion).first().removeClass(that.classes.selected); 2882 that.selectedIndex = -1; 2883 that.ignoreValueChange = false; 2884 that.el.val(that.currentValue); 2885 return; 2886 } 2887 2888 that.adjustScroll(that.selectedIndex - 1, 'up'); 2889 }, 2890 moveDown: function () { 2891 var that = this; 2892 2893 if (that.selectedIndex === (that.suggestions.length - 1)) { 2894 return; 2895 } 2896 2897 that.latestActivateSource = 'key'; 2898 2899 that.adjustScroll(that.selectedIndex + 1, 'down'); 2900 }, 2901 adjustScroll: function (index, direction) { 2902 var that = this; 2903 2904 2905 if (that.suggestions[index].type === 'headline') { 2906 index = direction === 'down' ? index + 1 : index - 1; 2907 } 2908 2909 if (typeof that.suggestions[index] == 'undefined') { 2910 return; 2911 } 2912 2913 var activeItem = that.activate(index); 2914 2915 that.getDetails(that.suggestions[index]); 2916 2917 if (that.suggestions[index].type === 'more_products') { 2918 2919 return; 2920 } 2921
2922 if (!activeItem || that.canShowDetailsPanel()) { 2923 return; 2924 } 2925 2926 var offsetTop, 2927 upperBound, 2928 lowerBound, 2929 $suggestionContainer = that.getSuggestionsContainer(), 2930 heightDelta = $(activeItem).outerHeight(false); 2931 2932 offsetTop = activeItem.offsetTop; 2933 upperBound = $suggestionContainer.scrollTop(); 2934 lowerBound = upperBound + that.options.maxHeight - heightDelta; 2935 2936 if (offsetTop < upperBound) { 2937 $suggestionContainer.scrollTop(offsetTop); 2938 } else if (offsetTop > lowerBound) { 2939 $suggestionContainer.scrollTop(offsetTop - that.options.maxHeight + heightDelta); 2940 } 2941 2942 if (!that.options.preserveInput) { 2943 // During onBlur event, browser will trigger "change" event, 2944 // because value has changed, to avoid side effect ignore, 2945 // that event, so that correct suggestion can be selected 2946 // when clicking on suggestion with a mouse 2947 that.ignoreValueChange = true; 2948 //that.el.val(that.getValue(that.suggestions[index].value)); 2949 } 2950 }, 2951 onSelect: function (index) { 2952 var that = this, 2953 onSelectCallback = that.options.onSelect, 2954 suggestion = that.suggestions[index], 2955 forceSubmit = false; 2956 2957 if (typeof suggestion.type != 'undefined') { 2958 if ( 2959 suggestion.type === 'more_products' 2960 || (that.actionTriggerSource === 'enter' && that.latestActivateSource != 'key' && suggestion.type != 'product_variation') 2961 || (that.actionTriggerSource === 'enter' && that.latestActivateSource != 'key' && suggestion.type == 'product_variation' && !that.options.goToFirstVariationOnSubmit) 2962 ) { 2963 that.el.closest('form').trigger('submit'); 2964 forceSubmit = true; 2965 } 2966 2967 if (suggestion.type === 'history-search') { 2968 that.currentValue = that.getValue(suggestion.value); 2969 if (that.currentValue !== that.el.val() && !that.options.preserveInput) { 2970 that.el.val(that.currentValue.replace(/(<([^>]+)>)/gi, ' ').replace(/\s\s+/g, ' ')); 2971 } 2972 that.el.closest('form').trigger('submit'); 2973 forceSubmit = true; 2974 } 2975 2976 } 2977 2978 if (suggestion.type === 'product' || suggestion.type === 'product_variation') { 2979 if (that.options.showRecentlySearchedProducts) { 2980 that.saveHistoryProducts(suggestion); 2981 } 2982 } 2983 2984 if (!forceSubmit) { 2985 2986 that.currentValue = that.getValue(suggestion.value); 2987 2988 if (that.currentValue !== that.el.val() && !that.options.preserveInput) { 2989 that.el.val(that.currentValue.replace(/(<([^>]+)>)/gi, ' ').replace(/\s\s+/g, ' ')); 2990 } 2991 2992 if (suggestion.url.length > 0) { 2993 window.location.href = suggestion.url; 2994 } 2995 2996 that.suggestions = []; 2997 that.selection = suggestion; 2998 } 2999 3000 if (typeof onSelectCallback === 'function') { 3001 onSelectCallback.call(that.element, suggestion); 3002 } 3003 }, 3004 openInNewTab: function (index) { 3005 var that = this, 3006 suggestion = that.suggestions[index]; 3007 if (suggestion.url.length > 0) { 3008 window.open(suggestion.url, '_blank').trigger('focus'); 3009 } 3010 }, 3011 getValue: function (value) { 3012 var that = this, 3013 delimiter = that.options.delimiter, 3014 currentValue, 3015 parts; 3016 3017 if (!delimiter) { 3018 return value; 3019 } 3020 3021 currentValue = that.currentValue; 3022 parts = currentValue.split(delimiter); 3023 3024 if (parts.length === 1) { 3025 return value; 3026 } 3027 3028 return currentValue.substr(0, currentValue.length - parts[parts.length - 1].length) + value; 3029 }, 3030 dispose: function () { 3031 var that = this, 3032 $el = that.el, 3033 $formWrapper = that.getFormWrapper(), 3034 $suggestionsWrapper = that.getSuggestionsContainer(), 3035 $mobileHandler = $formWrapper.find('.js-dgwt-wcas-enable-mobile-form'); 3036 3037 // Remove all events 3038 if ($formWrapper.length) { 3039 var $items = $formWrapper.find('*'); 3040 $items.each(function () { 3041 $(this).off('.autocomplete'); 3042 }); 3043 } 3044 3045 $el.off('fibosearch/ping'); 3046 3047 $formWrapper.off('click.autocomplete', '.js-dgwt-wcas-search-icon-handler'); 3048 3049 $el.removeData('autocomplete'); 3050 $(window).off('resize.autocomplete', that.fixPosition); 3051 3052 $formWrapper.removeClass('dgwt-wcas-active'); 3053 3054 that.close(false); 3055 3056 // Remove mobile handler 3057 if ($mobileHandler.length) { 3058 $mobileHandler.remove(); 3059 } 3060 3061 if ($suggestionsWrapper.length) { 3062 $suggestionsWrapper.html(''); 3063 } 3064 }, 3065 isMountedOverlayDarkened: function () { 3066 var that = this, 3067 $wrapp = that.getFormWrapper(), 3068 mounted = false;
3069 3070 if ($wrapp.hasClass(that.classes.darkenOverlayMounted)) { 3071 mounted = true; 3072 } 3073 return mounted; 3074 }, 3075 enableOverlayDarkened: function () { 3076 var that = this, 3077 options = that.options, 3078 $formWrapper; 3079 3080 if (!that.isMountedOverlayDarkened()) { 3081 return; 3082 } 3083 3084 $formWrapper = that.getFormWrapper(); 3085 3086 $formWrapper.addClass('dgwt-wcas-search-darkoverl-on'); 3087 $('body').addClass('dgwt-wcas-darkoverl-on'); 3088 3089 // Create node 3090 if ($('.' + options.darkenedOverlayClass).length == 0) { 3091 var html = '<div class="' + options.darkenedOverlayClass + '"><div></div><div></div><div></div><div></div></div>'; 3092 $('body').append(html); 3093 var $darkenedOverlay = $('.' + that.options.darkenedOverlayClass); 3094 3095 that.positionOverlayDarkened(); 3096 3097 $darkenedOverlay.on('click.autocomplete', function (e) { 3098 that.disableOverlayDarkened(); 3099 }); 3100 3101 } 3102 3103 that.overlayDarkenedState = 'on'; 3104 3105 }, 3106 disableOverlayDarkened: function () { 3107 var that = this, 3108 options = that.options, 3109 $wrapps; 3110 3111 if (!that.isMountedOverlayDarkened()) { 3112 return; 3113 } 3114 3115 $wrapps = $('.dgwt-wcas-search-darkoverl-on'); 3116 3117 if ($wrapps.length) { 3118 $wrapps.removeClass('dgwt-wcas-search-darkoverl-on'); 3119 } 3120 $('body').removeClass('dgwt-wcas-darkoverl-on'); 3121 3122 3123 var $el = $('.' + options.darkenedOverlayClass); 3124 if ($el.length > 0) { 3125 $el.remove(); 3126 that.overlayDarkenedState = 'off'; 3127 } 3128 }, 3129 positionOverlayDarkened: function () { 3130 var that = this, 3131 fixed = false, 3132 $darkenedOverlay = $('.' + that.options.darkenedOverlayClass); 3133 3134 if ($darkenedOverlay.length > 0) { 3135 3136 if (that.ancestorHasPositionFixed(that.getFormWrapper())) { 3137 fixed = true; 3138 $darkenedOverlay.addClass('dgwt-wcas-suggestions-wrapp-fixed'); 3139 } else { 3140 $darkenedOverlay.removeClass('dgwt-wcas-suggestions-wrapp-fixed'); 3141 } 3142 3143 $darkenedOverlay.children('div').each(function (i) { 3144 that.positionOverlayDarkenedDiv($(this), i + 1, fixed); 3145 }); 3146 } 3147 }, 3148 positionOverlayDarkenedDiv: function ($el, orient, fixed) { 3149 var that = this, 3150 elData, 3151 $baseEl = that.getFormWrapper(), 3152 css, 3153 secureOffset = 200; // Secure buffer 3154 3155 3156 // Different position for search icon layout 3157 if ($baseEl.hasClass('js-dgwt-wcas-layout-icon')) { 3158 $baseEl = that.getForm(); 3159 } 3160 3161 elData = that.getElementInfo($baseEl); 3162 3163 /** 3164 * Note 1: If fixed == true, it means position should be calculated related to screen, 3165 * otherwise it will be calculated related to document 3166 * 3167 * Note 2: It concerns cases 1,3 and 4. 1px is subtracted to achieve an exact match of document height. 3168 * I don't know why it's needed. 3169 */ 3170 3171 switch (orient) { 3172 case 1: 3173 css = { 3174 left: (-secureOffset) + 'px', 3175 top: (-secureOffset) + 'px', 3176 width: (elData.left + secureOffset) + 'px', 3177 height: ($(document).outerHeight(false) + secureOffset - 1) + 'px' 3178 }; 3179 break; 3180 case 2: 3181 var topSpan = fixed ? elData.topViewPort : elData.top; 3182 css = { 3183 left: (-secureOffset) + 'px', 3184 top: (-secureOffset) + 'px', 3185 width: ($(window).outerWidth(false) + secureOffset) + 'px', 3186 height: (topSpan + secureOffset) + 'px', 3187 }; 3188 break; 3189 case 3: 3190 css = { 3191 left: (elData.left + elData.width) + 'px', 3192 top: (-secureOffset) + 'px', 3193 width: ($(window).outerWidth(false) - elData.right) + 'px', 3194 height: ($(document).outerHeight(false) + secureOffset - 1) + 'px' 3195 }; 3196 break; 3197 case 4: 3198 var topSpan = fixed ? elData.topViewPort : elData.top; 3199 css = { 3200 left: (-secureOffset) + 'px', 3201 top: (topSpan + elData.height) + 'px', 3202 width: ($(window).outerWidth(false) + secureOffset) + 'px', 3203 height: ($(document).outerHeight(false) - elData.bottom - 1) + 'px' 3204 }; 3205 break; 3206 } 3207 3208 if (css) { 3209 $el.css(css); 3210 } 3211 }, 3212 showCloseButton: function () { 3213 var that = this, 3214 iconBody = typeof dgwt_wcas.close_icon != 'undefined' ? dgwt_wcas.close_icon : '', 3215 $actionsEl = that.getFormWrapper().find('.' + that.options.preloaderClass); 3216 3217 if (that.el.val().length < that.options.minChars) { 3218 return; 3219 } 3220 3221 // Click close icon 3222 if (!$actionsEl.hasClass(that.options.closeTrigger)) { 3223 $actionsEl.on('click.autocomplete', function () { 3224 that.close(true); 3225 }); 3226 } 3227 3228 $actionsEl.addClass(that.options.closeTrigger); 3229 $actionsEl.html(iconBody); 3230 3231 }, 3232 hideCloseButton: function () { 3233 var that = this, 3234 $btn = that.getFormWrapper().find('.' + that.options.closeTrigger); 3235 3236 if ($btn.length) { 3237 $btn.removeClass(that.options.closeTrigger); 3238 $btn.html(''); 3239 } 3240 3241 $btn.off('click.autocomplete'); 3242 }, 3243 canShowPreSuggestions: function () { 3244 var that = this, 3245 canShow = false;
3246 3247 if (that.options.showRecentlySearchedProducts || that.options.showRecentlySearchedPhrases) { 3248 canShow = true; 3249 } 3250 3251 return canShow; 3252 }, 3253 showPreSuggestions: function () { 3254 var that = this, 3255 suggestionsIndex = 0, 3256 i, 3257 html = '', 3258 $suggestionsWrapper = that.getSuggestionsContainer(), 3259 $searchBar = that.getFormWrapper(), 3260 noHistory = true, 3261 historyProducts = [], 3262 historySearches = [], 3263 origShowImageOpt = that.options.showImage; 3264 3265 that.isPreSuggestionsMode = true; 3266 3267 that.suggestions = []; 3268 that.suggestionsContainer.addClass('dgwt-wcas-has-img'); 3269 if (!origShowImageOpt) { 3270 that.suggestionsContainer.addClass('dgwt-wcas-has-img-forced'); 3271 } 3272 3273 that.options.showImage = true; 3274 3275 if (that.options.showRecentlySearchedProducts) { 3276 historyProducts = utils.getLocalStorageItem(that.recentlyViewedProductsKey, []); 3277 } 3278 3279 if (that.options.showRecentlySearchedPhrases) { 3280 historySearches = utils.getLocalStorageItem(that.recentlySearchedPhrasesKey, []); 3281 } 3282 3283 // Break early if there is nothing to show 3284 if (historyProducts.length === 0 && historySearches.length === 0) { 3285 return; 3286 } 3287 3288 // Show headline 3289 that.suggestions.push({type: 'headline-v2', value: '',}); 3290 html += '<span class="dgwt-wcas-suggestion dgwt-wcas-suggestion-headline-v2" data-index="' + suggestionsIndex + '">'; 3291 if (typeof dgwt_wcas.labels['search_hist'] != 'undefined') { 3292 var label = dgwt_wcas.labels['search_hist']; 3293 label += ' <span class="js-dgwt-wcas-sugg-hist-clear dgwt-wcas-sugg-hist-clear">' + dgwt_wcas.labels['search_hist_clear'] + '</span>'; 3294 html += '<span className="dgwt-wcas-st">' + label + '</span>'; 3295 } 3296 html += '</span>'; 3297 suggestionsIndex++; 3298 3299 // History: products 3300 if (historyProducts.length > 0) { 3301 for (i = 0; i < historyProducts.length; i++) { 3302 html += that.createProductSuggestion(historyProducts[i], suggestionsIndex, 'dgwt-wcas-suggestion-history-product'); 3303 that.suggestions.push(historyProducts[i]); 3304 suggestionsIndex++; 3305 } 3306 } 3307 3308 3309 // History: searches 3310 if (historySearches.length > 0) { 3311 for (i = 0; i < historySearches.length; i++) { 3312 var suggestion = { 3313 type: 'history-search', 3314 value: historySearches[i], 3315 url: '#', 3316 thumb_html: dgwt_wcas.magnifier_icon 3317 }; 3318 3319 if ($searchBar.hasClass('dgwt-wcas-style-pirx')) { 3320 suggestion.thumb_html = dgwt_wcas.magnifier_icon_pirx; 3321 } 3322 3323 that.suggestions.push(suggestion); 3324 3325 html += '<a href="' + suggestion.url + '" class="' + that.classes.suggestion + ' dgwt-wcas-suggestion-history-search" data-index="' + suggestionsIndex + '">'; 3326 html += '<span class="dgwt-wcas-si">' + suggestion.thumb_html + '</span>'; 3327 html += '<div class="dgwt-wcas-content-wrapp">'; 3328 html += '<div class="dgwt-wcas-st"><span class="dgwt-wcas-st-title">' + utils.formatHtml(suggestion.value) + '</span></div>' 3329 html += '</div>'; 3330 html += '</a>'; 3331 3332 suggestionsIndex++; 3333 } 3334 } 3335 3336 // Show pre-suggestions 3337 $suggestionsWrapper.html(html); 3338 $suggestionsWrapper.show(); 3339 3340 // Add class on show 3341 $('body').addClass('dgwt-wcas-open'); 3342 $('body').addClass('dgwt-wcas-open-pre-suggestions'); 3343 var searchStyle = that.getSearchStyle(); 3344 $('html').addClass('dgwt-wcas-open-' + that.getSearchStyle()); 3345 if (searchStyle === 'pirx') { 3346 $('html').addClass('dgwt-wcas-open-pirx-compact'); 3347 } 3348 3349 // Reset the latest mousedown position 3350 that.isMouseDownOnSearchElements = false;
3351 3352 that.visible = true; 3353 that.fixPosition(); 3354 that.options.showImage = origShowImageOpt; 3355 3356 3357 document.dispatchEvent(new CustomEvent('fibosearch/open', { 3358 detail: that 3359 })); 3360 3361 document.dispatchEvent(new CustomEvent('fibosearch/show-pre-suggestions', { 3362 detail: that 3363 })); 3364 }, 3365 resetPreSuggestions: function () { 3366 var that = this, 3367 $suggestionsWrapp = that.getSuggestionsContainer(), 3368 activeInstance = utils.getActiveInstance(); 3369 3370 utils.removeLocalStorageItem(that.recentlyViewedProductsKey); 3371 utils.removeLocalStorageItem(that.recentlySearchedPhrasesKey); 3372 3373 that.suggestions = []; 3374 $suggestionsWrapp.html(''); 3375 $('body').removeClass('dgwt-wcas-open-pre-suggestions'); 3376 3377 activeInstance.el.trigger('focus'); 3378 }, 3379 hidePreSuggestions: function () { 3380 var that = this; 3381 3382 if (!that.options.showImage) { 3383 that.suggestionsContainer.removeClass('dgwt-wcas-has-img'); 3384 } 3385 that.suggestionsContainer.removeClass('dgwt-wcas-has-img-forced'); 3386 3387 that.isPreSuggestionsMode = false; 3388 }, 3389 saveHistoryProducts: function (suggestion) { 3390 var that = this, 3391 viewedProducts = utils.getLocalStorageItem(that.recentlyViewedProductsKey, []); 3392 3393 viewedProducts = [suggestion, ...viewedProducts]; 3394 viewedProducts = [...new Map(viewedProducts.map((item) => { 3395 if (typeof item['price'] != 'undefined') { 3396 delete item['price']; 3397 } 3398 3399 if (!that.options.showImage) { 3400 item['thumb_html'] = dgwt_wcas.history_icon; 3401 } 3402 return [item['post_id'], item]; 3403 })).values()]; 3404 utils.setLocalStorageItem(that.recentlyViewedProductsKey, viewedProducts.slice(0, 5)); 3405 }, 3406 saveHistorySearches: function (value) { 3407 var that = this, 3408 phrases = utils.getLocalStorageItem(that.recentlySearchedPhrasesKey, []); 3409 3410 phrases = [value, ...phrases]; 3411 phrases = [...new Set(phrases)]; 3412 utils.setLocalStorageItem(that.recentlySearchedPhrasesKey, phrases.slice(0, 5)); 3413 }, 3414 addActiveClassIfMissing: function () { 3415 var activeEl = document.activeElement; 3416 if ( 3417 typeof activeEl == 'object' 3418 && $(activeEl).length 3419 && $(activeEl).hasClass('dgwt-wcas-search-input') 3420 ) { 3421 3422 var $search = $(activeEl).closest('.dgwt-wcas-search-wrapp'); 3423 3424 if ($search.length && !$search.hasClass('dgwt-wcas-active')) { 3425 $search.addClass('dgwt-wcas-active'); 3426 } 3427 } 3428 }, 3429 ancestorHasPositionFixed: function ($element) { 3430 3431 var $checkElements = $element.add($element.parents()); 3432 var isFixed = false; 3433 3434 $checkElements.each(function () { 3435 3436 if ($(this).css("position") === "fixed") { 3437 isFixed = true; 3438 return false; 3439 } 3440 }); 3441 return isFixed; 3442 }, 3443 gaEvent: function (label, category) { 3444 var that = this; 3445 var gaObj = window.hasOwnProperty('GoogleAnalyticsObject') && window.hasOwnProperty(window['GoogleAnalyticsObject']) ? window[window['GoogleAnalyticsObject']] : false; 3446 if (that.options.sendGAEvents) { 3447 try { 3448 if (typeof gtag !== 'undefined') { 3449 gtag('event', 'autocomplete_search', { 3450 'event_label': label, 3451 'event_category': category 3452 }); 3453 } else if (gaObj !== false) { 3454 var tracker = gaObj.getAll()[0]; 3455 if (tracker) tracker.send({ 3456 hitType: 'event', 3457 eventCategory: category, 3458 eventAction: 'autocomplete_search', 3459 eventLabel: label 3460 }); 3461 } 3462 } catch (error) { 3463 } 3464 } 3465 if (that.options.enableGASiteSearchModule) { 3466 try { 3467 if (typeof gtag !== 'undefined') { 3468 gtag('event', 'page_view', { 3469 'page_path': '/?s=' + encodeURI(label) + '&post_type=product&dgwt_wcas=1', 3470 }); 3471 } else if (gaObj !== false) { 3472 var tracker2 = gaObj.getAll()[0]; 3473 if (tracker2) { 3474 tracker2.set('page', '/?s=' + encodeURI(label) + '&post_type=product&dgwt_wcas=1'); 3475 tracker2.send('pageview'); 3476 } 3477 } 3478 } catch (error) { 3479 } 3480 } 3481 3482 $(document).trigger('dgwtWcasGAEvent', {'term': label, 'category': category}); 3483 }, 3484 initVoiceSearch: function () { 3485 var that = this; 3486 if (!that.options.voiceSearchEnabled) { 3487 return false;
3488 } 3489 var $formWrapper = that.getFormWrapper(); 3490 var $input = $formWrapper.find('.' + that.options.searchInputClass); 3491 var $voiceSearch = $formWrapper.find('.' + that.options.voiceSearchClass); 3492 3493 var speechRecognition = false; 3494 if (typeof SpeechRecognition === "function") { 3495 speechRecognition = SpeechRecognition; 3496 } else if (typeof webkitSpeechRecognition === "function") { 3497 speechRecognition = webkitSpeechRecognition; 3498 } 3499 if (!speechRecognition) { 3500 return false; 3501 } 3502 3503 if (utils.isBrowser('Chrome') && utils.isIOS()) { 3504 // Chrome speech recognition on iPhone and iPad is not working well. 3505 return false; 3506 } 3507 if (utils.isSafari()) { 3508 // We don't support voice search on Safari because it's hard to debug. 3509 return false; 3510 } 3511 3512 that.voiceSearchSetState('inactive', $voiceSearch); 3513 $formWrapper.addClass(that.options.voiceSearchSupportedClass); 3514 3515 that.voiceSearchRecognition = new speechRecognition(); 3516 that.voiceSearchRecognition.lang = that.options.voiceSearchLang; 3517 that.voiceSearchRecognition.continuous = false; 3518 that.voiceSearchRecognition.interimResults = true; 3519 that.voiceSearchRecognition.maxAlternatives = 1; 3520 3521 $voiceSearch.on('click', function () { 3522 if ( 3523 $formWrapper.hasClass('dgwt-wcas-mobile-overlay-trigger-active') && 3524 !$('html').hasClass('dgwt-wcas-overlay-mobile-on') 3525 ) { 3526 $formWrapper.find('.js-dgwt-wcas-enable-mobile-form').trigger('click'); 3527 $formWrapper.find('.' + that.options.searchInputClass).trigger('blur'); 3528 } 3529 if (that.voiceSearchStarted) { 3530 that.voiceSearchAbort(); 3531 return; 3532 } 3533 if (that.voiceSearchIsInitialized()) { 3534 that.voiceSearchAbort(); 3535 } 3536 that.voiceSearchRecognition.start(); 3537 }); 3538 3539 that.voiceSearchRecognition.onstart = function (event) { 3540 that.voiceSearchSetState('active', $voiceSearch); 3541 } 3542 3543 that.voiceSearchRecognition.onresult = function (event) { 3544 const result = event.results[0]; 3545 const text = result[0].transcript; 3546 $input.val(text); 3547 if (result.isFinal) { 3548 $input.trigger('change'); 3549 if (!('ontouchend' in document)) { 3550 $input.trigger('focus'); 3551 } 3552 that.voiceSearchSetState('inactive', $voiceSearch); 3553 } 3554 } 3555 3556 that.voiceSearchRecognition.onspeechend = function () { 3557 that.voiceSearchSetState('inactive', $voiceSearch); 3558 that.voiceSearchRecognition.stop(); 3559 } 3560 3561 that.voiceSearchRecognition.onnomatch = function (event) { 3562 that.voiceSearchSetState('inactive', $voiceSearch); 3563 } 3564 3565 that.voiceSearchRecognition.onerror = function (event) { 3566 switch (event.error) { 3567 case 'aborted': 3568 case 'no-speech': 3569 that.voiceSearchSetState('inactive', $voiceSearch); 3570 break; 3571 case 'network': 3572 break; 3573 case 'not-allowed': 3574 case 'service-not-allowed': 3575 that.voiceSearchSetState('off', $voiceSearch); 3576 break; 3577 } 3578 } 3579 }, 3580 voiceSearchAbort: function () { 3581 var that = this; 3582 if (that.voiceSearchIsInitialized()) { 3583 that.voiceSearchRecognition.abort(); 3584 that.voiceSearchStarted = false; 3585 } 3586 }, 3587 voiceSearchIsInitialized: function () { 3588 var that = this; 3589 return that.voiceSearchRecognition !== null; 3590 }, 3591 voiceSearchSetState: function (state, $voiceSearch) { 3592 var that = this; 3593 switch (state) { 3594 case 'active': 3595 that.voiceSearchStarted = true; 3596 if (typeof dgwt_wcas.voice_search_active_icon == 'string') { 3597 $voiceSearch.html(dgwt_wcas.voice_search_active_icon); 3598 } 3599 // $voiceSearch.removeClass(that.options.voiceSearchDisabledClass).addClass(that.options.voiceSearchActiveClass); 3600 break; 3601 case 'inactive': 3602 that.voiceSearchStarted = false;
vendor: 10,598 bytes, lines 3603-3842
3603 if (typeof dgwt_wcas.voice_search_inactive_icon == 'string') { 3604 $voiceSearch.html(dgwt_wcas.voice_search_inactive_icon); 3605 } 3606 // $voiceSearch.removeClass(that.options.voiceSearchActiveClass + ' ' + that.options.voiceSearchDisabledClass); 3607 break; 3608 case 'off': 3609 that.voiceSearchStarted = false; 3610 // $voiceSearch.removeClass(that.options.voiceSearchActiveClass).addClass(that.options.voiceSearchDisabledClass); 3611 if (typeof dgwt_wcas.voice_search_disabled_icon == 'string') { 3612 $voiceSearch.html(dgwt_wcas.voice_search_disabled_icon); 3613 } 3614 break; 3615 } 3616 }, 3617 }; 3618 3619 // Create chainable jQuery plugin: 3620 $.fn.dgwtWcasAutocomplete = function (options, args) { 3621 var dataKey = 'autocomplete'; 3622 // If function invoked without argument return 3623 // instance of the first matched element: 3624 if (!arguments.length) { 3625 return this.first().data(dataKey); 3626 } 3627 3628 return this.each(function () { 3629 var inputElement = $(this), 3630 instance = inputElement.data(dataKey); 3631 3632 if (typeof options === 'string') { 3633 if (instance && typeof instance[options] === 'function') { 3634 instance[options](args); 3635 } 3636 } else { 3637 // If instance already exists, destroy it: 3638 if (instance && instance.dispose) { 3639 instance.dispose(); 3640 } 3641 3642 instance = new DgwtWcasAutocompleteSearch(this, options); 3643 inputElement.data(dataKey, instance); 3644 } 3645 }); 3646 }; 3647 3648 // Don't overwrite if it already exists 3649 if (!$.fn.autocomplete) { 3650 $.fn.autocomplete = $.fn.dgwtWcasAutocomplete; 3651 } 3652 3653 (function () { 3654 /*----------------------------------------------------------------- 3655 /* IE11 polyfills 3656 /*-----------------------------------------------------------------*/ 3657 if (utils.isIE11()) { 3658 (function (self, undefined) { 3659 function Call(t, l) { 3660 var n = arguments.length > 2 ? arguments[2] : []; 3661 if (!1 === IsCallable(t)) throw new TypeError(Object.prototype.toString.call(t) + "is not a function."); 3662 return t.apply(l, n) 3663 } 3664 3665 function CreateMethodProperty(e, r, t) { 3666 var a = {value: t, writable: !0, enumerable: !1, configurable: !0}; 3667 Object.defineProperty(e, r, a) 3668 } 3669 3670 function Get(n, t) { 3671 return n[t] 3672 } 3673 3674 function IsCallable(n) { 3675 return "function" == typeof n 3676 } 3677 3678 function RequireObjectCoercible(e) { 3679 if (null === e || e === undefined) throw TypeError(Object.prototype.toString.call(e) + " is not coercible to Object."); 3680 return e 3681 } 3682 3683 function SameValueNonNumber(e, n) { 3684 return e === n 3685 } 3686 3687 function ToBoolean(o) { 3688 return Boolean(o) 3689 } 3690 3691 function ToObject(e) { 3692 if (null === e || e === undefined) throw TypeError(); 3693 return Object(e) 3694 } 3695 3696 function GetV(t, e) { 3697 return ToObject(t)[e] 3698 } 3699 3700 function GetMethod(e, n) { 3701 var r = GetV(e, n); 3702 if (null === r || r === undefined) return undefined; 3703 if (!1 === IsCallable(r)) throw new TypeError("Method not callable: " + n); 3704 return r 3705 } 3706 3707 function Type(e) { 3708 switch (typeof e) { 3709 case"undefined": 3710 return "undefined"; 3711 case"boolean": 3712 return "boolean"; 3713 case"number": 3714 return "number"; 3715 case"string": 3716 return "string"; 3717 case"symbol": 3718 return "symbol"; 3719 default: 3720 return null === e ? "null" : "Symbol" in self && (e instanceof self.Symbol || e.constructor === self.Symbol) ? "symbol" : "object" 3721 } 3722 } 3723 3724 function IsRegExp(e) { 3725 if ("object" !== Type(e)) return !1; 3726 var n = "Symbol" in self && "match" in self.Symbol ? Get(e, self.Symbol.match) : undefined; 3727 if (n !== undefined) return ToBoolean(n); 3728 try { 3729 var t = e.lastIndex; 3730 return e.lastIndex = 0, RegExp.prototype.exec.call(e), !0 3731 } catch (l) { 3732 } finally { 3733 e.lastIndex = t 3734 } 3735 return !1 3736 } 3737 3738 function OrdinaryToPrimitive(r, t) { 3739 if ("string" === t) var e = ["toString", "valueOf"]; else e = ["valueOf", "toString"]; 3740 for (var i = 0; i < e.length; ++i) { 3741 var n = e[i], a = Get(r, n); 3742 if (IsCallable(a)) { 3743 var o = Call(a, r); 3744 if ("object" !== Type(o)) return o 3745 } 3746 } 3747 throw new TypeError("Cannot convert to primitive.") 3748 } 3749 3750 function SameValueZero(n, e) { 3751 return Type(n) === Type(e) && ("number" === Type(n) ? !(!isNaN(n) || !isNaN(e)) || (1 / n === Infinity && 1 / e == -Infinity || (1 / n == -Infinity && 1 / e === Infinity || n === e)) : SameValueNonNumber(n, e)) 3752 } 3753 3754 function ToInteger(n) { 3755 if ("symbol" === Type(n)) throw new TypeError("Cannot convert a Symbol value to a number"); 3756 var t = Number(n); 3757 return isNaN(t) ? 0 : 1 / t === Infinity || 1 / t == -Infinity || t === Infinity || t === -Infinity ? t : (t < 0 ? -1 : 1) * Math.floor(Math.abs(t)) 3758 } 3759 3760 function ToLength(n) { 3761 var t = ToInteger(n); 3762 return t <= 0 ? 0 : Math.min(t, Math.pow(2, 53) - 1) 3763 } 3764 3765 function ToPrimitive(e) { 3766 var t = arguments.length > 1 ? arguments[1] : undefined; 3767 if ("object" === Type(e)) { 3768 if (arguments.length < 2) var i = "default"; else t === String ? i = "string" : t === Number && (i = "number"); 3769 var r = "function" == typeof self.Symbol && "symbol" == typeof self.Symbol.toPrimitive ? GetMethod(e, self.Symbol.toPrimitive) : undefined; 3770 if (r !== undefined) { 3771 var n = Call(r, e, [i]); 3772 if ("object" !== Type(n)) return n; 3773 throw new TypeError("Cannot convert exotic object to primitive.") 3774 } 3775 return "default" === i && (i = "number"), OrdinaryToPrimitive(e, i) 3776 } 3777 return e 3778 } 3779 3780 function ToString(t) { 3781 switch (Type(t)) { 3782 case"symbol": 3783 throw new TypeError("Cannot convert a Symbol value to a string"); 3784 case"object": 3785 return ToString(ToPrimitive(t, String)); 3786 default: 3787 return String(t) 3788 } 3789 } 3790 3791 CreateMethodProperty(Array.prototype, "includes", function e(r) { 3792 "use strict"; 3793 var t = ToObject(this), o = ToLength(Get(t, "length")); 3794 if (0 === o) return !1; 3795 var n = ToInteger(arguments[1]); 3796 if (n >= 0) var a = n; else (a = o + n) < 0 && (a = 0); 3797 for (; a < o;) { 3798 var i = Get(t, ToString(a)); 3799 if (SameValueZero(r, i)) return !0; 3800 a += 1 3801 } 3802 return !1 3803 }); 3804 CreateMethodProperty(String.prototype, "includes", function e(t) { 3805 "use strict"; 3806 var r = arguments.length > 1 ? arguments[1] : undefined, n = RequireObjectCoercible(this), 3807 i = ToString(n); 3808 if (IsRegExp(t)) throw new TypeError("First argument to String.prototype.includes must not be a regular expression"); 3809 var o = ToString(t), g = ToInteger(r), a = i.length, p = Math.min(Math.max(g, 0), a); 3810 return -1 !== String.prototype.indexOf.call(i, o, p) 3811 }); 3812 })('object' === typeof window && window || 'object' === typeof self && self || 'object' === typeof global && global || {}); 3813 } 3814 3815 // RUN 3816 $(document).ready(function () { 3817 "use strict"; 3818 3819 /*----------------------------------------------------------------- 3820 /* Mobile detection 3821 /*-----------------------------------------------------------------*/ 3822 if (utils.isIOS()) { 3823 $('html').addClass('dgwt-wcas-is-ios'); 3824 } 3825 3826 /*----------------------------------------------------------------- 3827 /* Set some global variables 3828 /*-----------------------------------------------------------------*/ 3829 window.dgwt_wcas.resizeOnlyOnce = null; 3830 window.dgwt_wcas.scrollOnlyOnce = null; 3831 3832 /*----------------------------------------------------------------- 3833 /* Fire autocomplete 3834 /*-----------------------------------------------------------------*/ 3835 3836 window.dgwt_wcas.config = { 3837 minChars: dgwt_wcas.min_chars, 3838 width: dgwt_wcas.sug_width, 3839 autoSelectFirst: false, 3840 triggerSelectOnValidInput: false, 3841 serviceUrl: dgwt_wcas.ajax_search_endpoint, 3842 paramName: 's',
3843 showDetailsPanel: dgwt_wcas.show_details_panel == 1 ? true : false, 3844 showImage: dgwt_wcas.show_images == 1 ? true : false, 3845 showPrice: dgwt_wcas.show_price == 1 ? true : false, 3846 showDescription: dgwt_wcas.show_desc == 1 ? true : false, 3847 showSKU: dgwt_wcas.show_sku == 1 ? true : false, 3848 showSaleBadge: dgwt_wcas.show_sale_badge == 1 ? true : false, 3849 showFeaturedBadge: dgwt_wcas.show_featured_badge == 1 ? true : false, 3850 dynamicPrices: typeof dgwt_wcas.dynamic_prices != 'undefined' && dgwt_wcas.dynamic_prices ? true : false, 3851 saleBadgeText: dgwt_wcas.labels.sale_badge, 3852 featuredBadgeText: dgwt_wcas.labels.featured_badge, 3853 isRtl: dgwt_wcas.is_rtl == 1 ? true : false, 3854 showHeadings: dgwt_wcas.show_headings == 1 ? true : false, 3855 isPremium: dgwt_wcas.is_premium == 1 ? true : false, 3856 taxonomyBrands: dgwt_wcas.taxonomy_brands, 3857 layoutBreakpoint: dgwt_wcas.layout_breakpoint, 3858 mobileOverlayBreakpoint: dgwt_wcas.mobile_overlay_breakpoint, 3859 mobileOverlayWrapper: dgwt_wcas.mobile_overlay_wrapper, 3860 mobileOverlayDelay: dgwt_wcas.mobile_overlay_delay, 3861 debounceWaitMs: dgwt_wcas.debounce_wait_ms, 3862 sendGAEvents: dgwt_wcas.send_ga_events, 3863 enableGASiteSearchModule: dgwt_wcas.enable_ga_site_search_module, 3864 appendTo: typeof dgwt_wcas.suggestions_wrapper != 'undefined' ? dgwt_wcas.suggestions_wrapper : 'body', 3865 showProductVendor: typeof dgwt_wcas.show_product_vendor != 'undefined' && dgwt_wcas.show_product_vendor ? true : false, 3866 disableHits: typeof dgwt_wcas.disable_hits != 'undefined' && dgwt_wcas.disable_hits ? true : false, 3867 disableSubmit: typeof dgwt_wcas.disable_submit != 'undefined' && dgwt_wcas.disable_submit ? true : false, 3868 voiceSearchEnabled: typeof dgwt_wcas.voice_search_enabled != 'undefined' && dgwt_wcas.voice_search_enabled ? true : false, 3869 voiceSearchLang: typeof dgwt_wcas.voice_search_lang != 'undefined' ? dgwt_wcas.voice_search_lang : '', 3870 showRecentlySearchedProducts: typeof dgwt_wcas.show_recently_searched_products != 'undefined' ? dgwt_wcas.show_recently_searched_products : false, 3871 showRecentlySearchedPhrases: typeof dgwt_wcas.show_recently_searched_phrases != 'undefined' ? dgwt_wcas.show_recently_searched_phrases : false, 3872 goToFirstVariationOnSubmit: typeof dgwt_wcas.go_to_first_variation_on_submit != 'undefined' ? dgwt_wcas.go_to_first_variation_on_submit : false, 3873 }; 3874 3875 $('.dgwt-wcas-search-input').dgwtWcasAutocomplete(window.dgwt_wcas.config); 3876 3877 /** 3878 * If a user clicked on the search bar o an icon before it finished initializing, 3879 * trigger a focus or click on that after initialization. 3880 */ 3881 var $focusedElement = $(document.activeElement); 3882 if ($focusedElement.length) { 3883 if ($focusedElement.hasClass('dgwt-wcas-search-input')) { 3884 $focusedElement.trigger('focus'); 3885 } else if ($focusedElement.hasClass('js-dgwt-wcas-search-icon-handler')) { 3886 $focusedElement.trigger('click'); 3887 } 3888 } 3889 }); 3890 3891 3892 /** 3893 * UI Fixer. Fixes several known UX issues related to search bars 3894 */ 3895 var UI_FIXER = { 3896 brokenSearchUi: typeof dgwt_wcas.fixer.broken_search_ui != 'undefined' && dgwt_wcas.fixer.broken_search_ui ? true : false, 3897 brokenSearchUiAjax: typeof dgwt_wcas.fixer.broken_search_ui_ajax != 'undefined' && dgwt_wcas.fixer.broken_search_ui_ajax ? true : false, 3898 brokenSearchUiHard: typeof dgwt_wcas.fixer.broken_search_ui_hard != 'undefined' && dgwt_wcas.fixer.broken_search_ui_hard ? true : false, 3899 brokenSearchElementorPopups: typeof dgwt_wcas.fixer.broken_search_elementor_popups != 'undefined' && dgwt_wcas.fixer.broken_search_elementor_popups ? true : false, 3900 brokenSearchJetMobileMenu: typeof dgwt_wcas.fixer.broken_search_jet_mobile_menu != 'undefined' && dgwt_wcas.fixer.broken_search_jet_mobile_menu ? true : false, 3901 brokenSearchBrowserBackArrow: typeof dgwt_wcas.fixer.broken_search_browsers_back_arrow != 'undefined' && dgwt_wcas.fixer.broken_search_browsers_back_arrow ? true : false, 3902 forceRefreshCheckout: typeof dgwt_wcas.fixer.force_refresh_checkout != 'undefined' && dgwt_wcas.fixer.force_refresh_checkout ? true : false, 3903 searchBars: [], 3904 init: function () { 3905 var that = this; 3906 3907 /** 3908 * Fix broken search bars UI - first approach, after loading the page 3909 * Some page builders can copy instances of search bar without events eg. mobile usage. 3910 */ 3911 if (that.brokenSearchUi) { 3912 $(document).ready(function () { 3913 that.fixBrokenSearchUi(); 3914 }); 3915 } 3916 3917 /** 3918 * 3919 */ 3920 if (that.brokenSearchUiAjax) { 3921 that.fixBrokenSearchUiAjax(); 3922 } 3923 3924 /** 3925 * Repair search bars continuously 3926 * May overload the browser. Disabled by default. 3927 */ 3928 if (that.brokenSearchUiHard) { 3929 that.fixBrokenSearchUiHard(); 3930 } 3931 3932 /** 3933 * Fix Elementor popups 3934 * Reinit the search bars after loading Elementor popup 3935 */ 3936 if (that.brokenSearchElementorPopups) { 3937 $(document).ready(function () { 3938 that.fixBrokenSearchOnElementorPopupsV1(); 3939 that.fixBrokenSearchOnElementorPopupsV2(); 3940 }); 3941 } 3942 3943 /** 3944 * Fix search bars displayed in Jet Smart Menu 3945 * if there are duplicated inputs 3946 */ 3947 if (that.brokenSearchJetMobileMenu) { 3948 $(window).on('load', function () { 3949 that.fixSearchInJetMobileMenu(); 3950 }); 3951 } 3952 3953 /** 3954 * Fix broken search bars after click browser's back arrow. 3955 * Not worked for some browsers especially Safari and FF 3956 * Add dgwt-wcas-active class if wasn't added for some reason 3957 */ 3958 if (that.brokenSearchBrowserBackArrow) { 3959 that.fixbrokenSearchBrowserBackArrow(); 3960 } 3961 3962 /** 3963 * Refreshing the content on the checkout page when a product is added to the cart from the search Details Panel 3964 */ 3965 if (that.forceRefreshCheckout) { 3966 that.fixforceRefreshCheckout(); 3967 } 3968 }, 3969 fixBrokenSearchUi: function () { 3970 var that = this; 3971 3972 $(document).ready(function () { 3973 setTimeout(function () { 3974 that.pullAndReconditionSearchBars(); 3975 }, 50); 3976 }); 3977 3978 $(window).on('load', function () { 3979 setTimeout(function () { 3980 that.pullAndReconditionSearchBars(); 3981 }, 500); 3982 }); 3983 }, 3984 fixBrokenSearchUiAjax: function () { 3985 var that = this; 3986 $(document).ajaxSuccess(function (event, request, settings) { 3987 3988 // Exclude FiboSearch and WooCommerce AJAX requests 3989 if (typeof settings.url == 'string' && new RegExp('search\.php|wc-ajax').test(settings.url)) { 3990 return; 3991 } 3992 3993 if (typeof request.responseText == 'string' && request.responseText.includes('dgwt-wcas-search-input')) { 3994 setTimeout(function () { 3995 that.pullAndReconditionSearchBars(); 3996 }, 500); 3997 } 3998 }); 3999 }, 4000 fixBrokenSearchUiHard: function () { 4001 var that = this; 4002 $(document).ready(function () { 4003 4004 if (that.searchBars.length === 0) { 4005 that.pullAndReconditionSearchBars(); 4006 } 4007 4008 setInterval(function () { 4009 that.pullAndReconditionSearchBars(); 4010 }, 1000); 4011 }); 4012 }, 4013 fixBrokenSearchOnElementorPopupsV1: function () { 4014 var that = this; 4015 $(document).on('elementor/popup/show', () => { 4016 setTimeout(function () { 4017 that.pullAndReconditionSearchBars(); 4018 }, 500); 4019 }); 4020 }, 4021 fixBrokenSearchOnElementorPopupsV2: function () { 4022 var that = this; 4023 $(document).ready(function () { 4024 if ( 4025 typeof window.elementorFrontend != 'undefined' 4026 && typeof window.elementorFrontend.documentsManager != 'undefined' 4027 && typeof window.elementorFrontend.documentsManager.documents != 'undefined' 4028 ) { 4029 4030 $.each(elementorFrontend.documentsManager.documents, function (id, document) { 4031 4032 if (typeof document.getModal != 'undefined' && document.getModal) { 4033 4034 document.getModal().on('show', function () { 4035 setTimeout(function () { 4036 that.pullAndReconditionSearchBars(); 4037 }, 500); 4038 4039 }); 4040 } 4041 }); 4042 } 4043 }); 4044 }, 4045 fixSearchInJetMobileMenu: function () { 4046 var that = this; 4047 4048 if ($('.jet-mobile-menu__toggle').length === 0) { 4049 return; 4050 } 4051 4052 $(document).ajaxSend(function (event) { 4053 4054 if ( 4055 typeof event.currentTarget != 'undefined' 4056 && typeof event.currentTarget.activeElement == 'object' 4057 && $(event.currentTarget.activeElement).hasClass('jet-mobile-menu__toggle') 4058 ) { 4059 4060 setTimeout(function () { 4061 var $search = $(".jet-mobile-menu__container .dgwt-wcas-search-input"); 4062 4063 if ($search.length > 0) { 4064 that.pullAndReconditionSearchBars(); 4065 } 4066 4067 }, 500); 4068 4069 } 4070 }); 4071 }, 4072 fixforceRefreshCheckout: function () { 4073 $(document.body).on('added_to_cart', function () { 4074 if ( 4075 $(document.body).hasClass('woocommerce-checkout') && 4076 $('.dgwt-wcas-search-input').length > 0 4077 ) { 4078 $(document.body).trigger('update_checkout'); 4079 } 4080 }); 4081 }, 4082 fixbrokenSearchBrowserBackArrow: function () { 4083 $(window).on('load', function () { 4084 var i = 0; 4085 var interval = setInterval(function () { 4086 4087 var activeEl = document.activeElement; 4088 if ( 4089 typeof activeEl == 'object' 4090 && $(activeEl).length 4091 && $(activeEl).hasClass('dgwt-wcas-search-input') 4092 ) { 4093
4094 var $search = $(activeEl).closest('.dgwt-wcas-search-wrapp'); 4095 4096 if ($search.length && !$search.hasClass('dgwt-wcas-active')) { 4097 $search.addClass('dgwt-wcas-active'); 4098 clearInterval(interval); 4099 } 4100 } 4101 4102 // Stop after 5 seconds 4103 if (i > 10) { 4104 clearInterval(interval); 4105 } 4106 4107 i++; 4108 4109 }, 500); 4110 }); 4111 }, 4112 pullAndReconditionSearchBars: function () { 4113 var that = this, 4114 $inputs = $('.dgwt-wcas-search-input'), 4115 firstPull = that.searchBars.length == 0; 4116 4117 if ($inputs.length > 0) { 4118 $inputs.each(function () { 4119 var $searchBar = $(this), 4120 isNew = true, 4121 i; 4122 4123 // Check if this search bar is new one or not 4124 if (that.searchBars.length > 0) { 4125 for (i = 0; i < that.searchBars.length; i++) { 4126 if ($searchBar[0] === that.searchBars[i][0]) { 4127 isNew = false; 4128 break; 4129 } 4130 } 4131 } 4132 4133 if (isNew) { 4134 var changedId = false; 4135 if (!that.hasUniqueId($searchBar)) { 4136 that.makeUniqueID($searchBar); 4137 changedId = true; 4138 } 4139 4140 if (!firstPull || !that.isInitialized($searchBar) || changedId) { 4141 that.reinitSearchBar($searchBar) 4142 } 4143 4144 that.searchBars.push($searchBar); 4145 } 4146 4147 if (!that.hasEvents($searchBar)) { 4148 that.reinitSearchBar($searchBar) 4149 } 4150 4151 }); 4152 } 4153 }, 4154 hasEvents: function ($searchBarInput) { 4155 var hasEvents = false; 4156 $searchBarInput.trigger('fibosearch/ping'); 4157 if ($searchBarInput.hasClass('fibosearch-pong')) { 4158 hasEvents = true; 4159 } 4160 $('.fibosearch-pong').removeClass('fibosearch-pong'); 4161 return hasEvents; 4162 }, 4163 isInitialized: function ($searchBarInput) { 4164 return typeof $searchBarInput.data('autocomplete') == 'object'; 4165 }, 4166 hasUniqueId: function ($searchBarInput) { 4167 var that = this, 4168 unique = true; 4169 if (that.searchBars.length > 0) { 4170 for (var i = 0; i < that.searchBars.length; i++) { 4171 if ($searchBarInput.attr('id') === that.searchBars[i].attr('id')) { 4172 unique = false; 4173 } 4174 } 4175 } 4176 return unique; 4177 }, 4178 reinitSearchBar: function ($searchBarInput) { 4179 if (typeof $searchBarInput.data('autocomplete') == 'object') { 4180 $searchBarInput.data('autocomplete').dispose(); 4181 } 4182 $searchBarInput.dgwtWcasAutocomplete(window.dgwt_wcas.config); 4183 }, 4184 makeUniqueID: function ($searchBarInput) { 4185 var newID = Math.random().toString(36).substring(2, 6); 4186 newID = 'dgwt-wcas-search-input-' + newID; 4187 4188 $searchBarInput.attr('id', newID); 4189 $searchBarInput.closest('form').find('label').attr('for', newID); 4190 }, 4191 } 4192 4193 if (typeof dgwt_wcas.fixer.core == 'undefined') { 4194 dgwt_wcas.fixer.core = UI_FIXER;
4195 dgwt_wcas.fixer.core.init(); 4196 } 4197 4198 }()); 4199 4200}));
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.