/* eslint-disable object-shorthand */ /* eslint-disable prefer-arrow-callback */ /* eslint-disable vars-on-top */ /* eslint-disable strict */ /* eslint-disable no-var */ /* eslint-disable complexity */ (function(algolia, instantsearch) { var collectionPage = Boolean(algolia.is_collection_results_page) && Boolean(algolia.config.instant_search_enabled_on_collection); if ( (!algolia.full_results && !collectionPage) || !algolia.config.instant_search_enabled ) { return; } var _ = algolia._; var $ = algolia.jQuery; /** * Array which will contain all filters to be applied while initiating the * search API call. */ var searchFilters = []; // Filters for collection page var collectionFacetFilter = null; var collectionRulesContextValue = null; if (collectionPage) { var matches = window.location.pathname.match(/\/collections\/([^/]+)/i); var handle = Boolean(matches) && matches.length === 2 ? matches[1] : null; if (algolia.config.collection_id_indexing) { collectionFacetFilter = algolia.current_collection_id ? 'collection_ids:"' + algolia.current_collection_id + '"' : null; } else { collectionFacetFilter = 'collections:"' + handle + '"'; } // Add the collection filter to the list of search filters searchFilters.push(collectionFacetFilter); collectionRulesContextValue = algolia.config.collection_id_query_rules ? algolia.current_collection_id : handle; } // Filters for stock policy var stockPolicyFilter = null; if (algolia.config.stock_policy) { if (algolia.config.stock_policy === 'allow') { /** * For 'allow', we don't need to add any filter as we want to continue * displaying all out of stock items. */ } else if (algolia.config.stock_policy === 'deny') { // For 'deny' we will filter out all items based on inventory quantity stockPolicyFilter = 'inventory_quantity > 0'; } else if (algolia.config.stock_policy === 'continue') { /** * For 'continue' we will filter on `inventory_available` attribute whose * value is dependent on: * `inventory_quantity > 0 OR inventory_policy == 'continue'` */ stockPolicyFilter = 'inventory_available:true'; } // Add the stock policy filter to the list of search filters if (stockPolicyFilter) { searchFilters.push(stockPolicyFilter); } } var results_selector = collectionPage ? algolia.config.collection_css_selector : algolia.config.results_selector; var activeSortOrders = collectionPage && algolia.collectionSortOrders ? algolia.collectionSortOrders : algolia.sortOrders; results_selector += ', .algolia-shopify-instantsearch'; var $hiding = $( '' ); $hiding.appendTo($('head')); var instant = { colors: algolia.config.colors, distinct: Boolean(algolia.config.show_products), facets: { hidden: collectionPage && algolia.collectionHiddenFacets ? algolia.collectionHiddenFacets : algolia.hiddenFacets, shown: collectionPage && algolia.collectionShownFacets ? algolia.collectionShownFacets : algolia.shownFacets, list: collectionPage && algolia.collectionFacets ? algolia.collectionFacets : algolia.facets, widgets: collectionPage && algolia.collectionFacetsWidgets ? algolia.collectionFacetsWidgets : algolia.facetsWidgets, }, hitsPerPage: collectionPage && algolia.config.collections_full_results_hits_per_page ? algolia.config.collections_full_results_hits_per_page : algolia.config.products_full_results_hits_per_page, poweredBy: false, search: instantsearch({ appId: algolia.config.app_id, apiKey: algolia.config.search_api_key, indexName: '' + algolia.config.index_prefix + 'products', searchParameters: { clickAnalytics: true, facetingAfterDistinct: Boolean(algolia.config.show_products), }, urlSync: {}, searchFunction: function(searchFunctionHelper) { // Set query parameters here because they're not kept when someone // presses the Back button if set in the `init` function of a custom widget var helper = instant.search.helper; var page = helper.getPage(); helper.setQueryParameter( 'highlightPreTag', '' ); helper.setQueryParameter('highlightPostTag', ''); if (instant.distinct) { helper.setQueryParameter('distinct', true); } // Assign any required filters if (searchFilters.length) { helper.setQueryParameter('filters', searchFilters.join(' AND ')); } // Collection page features if (collectionPage) { // Collection page merchandising: // If we are on a collection page, `collectionRulesContextValue` is defined if (collectionRulesContextValue) { helper.setQueryParameter('ruleContexts', [ collectionRulesContextValue.toString(), ]); } else { helper.setQueryParameter('ruleContexts', []); } } helper.setPage(page); searchFunctionHelper.search(); }, }), selector: results_selector + ', .algolia-shopify-instantsearch', sortOrders: activeSortOrders, storeName: algolia.storeName, templates: { currentItem: algolia.getTemplate( 'instant_search_current_refined_values_item' ), empty: algolia.getTemplate('instant_search_no_result'), page: algolia.compileTemplate('instant_search'), product: algolia.getTemplate('instant_search_product'), stats: algolia.getTemplate('instant_search_stats'), style: algolia.compileTemplate('instant_search.css'), }, }; algolia.instantsearch = instant; if (instant.poweredBy) { // eslint-disable-next-line no-console console.log('Algolia: Instant-Search'); } function readjust() { var width = instant.$results.outerWidth(); var suffix = 'lg'; if (width < 400) suffix = 'xs'; else if (width < 800) suffix = 'sm'; else if (width < 1200) suffix = 'md'; instant.$results .removeClass('ais-results-size-xs') .removeClass('ais-results-size-sm') .removeClass('ais-results-size-md') .removeClass('ais-results-size-lg') .addClass('ais-results-size-' + suffix); } // Bind helpers _.forEach( Object.assign({}, algolia.helpers, algolia.translation_helpers), function(helper, name) { instant.search.templatesConfig.helpers[name] = helper; } ); instant.search.templatesConfig.compileOptions = algolia.hoganOptions; algolia.appendStyle( algolia.render(instant.templates.style, { distinct: instant.distinct, colors: instant.colors, }) ); $(document).ready(function() { if ( collectionPage && $(algolia.config.collection_css_selector).length === 0 ) { throw new Error( 'Instant search CSS selector for collection page is incorrect\nFore more info see : https://www.algolia.com/doc/integration/shopify/building-search-ui/instant-search/#css-selector' ); } else if ($(algolia.config.results_selector).length === 0) { throw new Error( 'Instant search CSS selector is incorrect\nFore more info see : https://www.algolia.com/doc/integration/shopify/building-search-ui/instant-search/#css-selector' ); } instant.$results = $(instant.selector); instant.$results.html( algolia.render(instant.templates.page, { facets: instant.facets.list, storeName: instant.storeName, translations: algolia.translations, multipleSortOrders: activeSortOrders.length > 1, }) ); readjust(); $(window).resize(function() { readjust(); }); // Mobile facets display instant.search.addWidget({ init: function() { var $button = $('.ais-facets-button'); $button.on('click', function() { var $facets = $('.ais-facets'); if ($facets.hasClass('ais-facets__shown')) { $button.text('Show filters'); $facets.removeClass('ais-facets__shown'); } else { $button.text('Hide filters'); $facets.addClass('ais-facets__shown'); } }); }, }); // Search input instant.search.addWidget( instantsearch.widgets.searchBox({ container: '.ais-search-box-container', placeholder: algolia.translations.searchForProduct, poweredBy: false, }) ); // Logo & clear instant.search.addWidget({ init: function(opts) { if (!instant.poweredBy) { $('.ais-algolia-icon').hide(); } $('.ais-clear-input-icon').on('click', function() { opts.helper.setQuery('').search(); $('.ais-search-box--input') .val('') .focus(); }); }, render: function(opts) { if (!opts.state.query) { if (instant.poweredBy) { $('.ais-algolia-icon').show(); } $('.ais-clear-input-icon').hide(); } else { $('.ais-clear-input-icon').show(); $('.ais-algolia-icon').hide(); } }, }); // Stats instant.search.addWidget( instantsearch.widgets.stats({ container: '.ais-stats-container', templates: { body: instant.templates.stats, }, transformData: { body: function(data) { return Object.assign({}, data, { processingTimeS: data.processingTimeMS / 1000, start: data.page * data.hitsPerPage + 1, end: Math.min((data.page + 1) * data.hitsPerPage, data.nbHits), translations: algolia.translations, }); }, }, }) ); // Sort orders if (activeSortOrders.length > 1) { instant.search.addWidget( instantsearch.widgets.sortBySelector({ container: '.ais-sort-orders-container', indices: instant.sortOrders, }) ); } // Change display instant.search.addWidget({ init: function() { $('.ais-search-header').on( 'click', '.ais-change-display-block', function() { $( '.ais-change-display-block:not(.ais-change-display-selected)' ).addClass('ais-change-display-selected'); $( '.ais-change-display-list.ais-change-display-selected' ).removeClass('ais-change-display-selected'); $('.ais-results-as-list') .removeClass('ais-results-as-list') .addClass('ais-results-as-block'); } ); $('.ais-search-header').on( 'click', '.ais-change-display-list', function() { $( '.ais-change-display-list:not(.ais-change-display-selected)' ).addClass('ais-change-display-selected'); $( '.ais-change-display-block.ais-change-display-selected' ).removeClass('ais-change-display-selected'); $('.ais-results-as-block') .removeClass('ais-results-as-block') .addClass('ais-results-as-list'); } ); }, }); // Hidden facets var list = _.map(instant.facets.hidden, function(facet) { return facet.name; }); instant.search.addWidget({ getConfiguration: function() { return { facets: list, disjunctiveFacets: list, }; }, init: function() {}, }); // Current refined values var attributes = _.map(instant.facets.shown, function(facet) { return { name: facet.name, label: facet.title, }; }); instant.search.addWidget( instantsearch.widgets.currentRefinedValues({ container: '.ais-current-refined-values-container', cssClasses: { root: 'ais-facet', header: 'ais-facet--header', body: 'ais-facet--body', }, templates: { header: algolia.translations.selectedFilter, item: instant.templates.currentItem, clearAll: algolia.translations.clearAll, }, onlyListedAttributes: true, attributes: attributes, }) ); // Facets _.forEach(instant.facets.widgets, function(widget) { instant.search.addWidget( instantsearch.widgets[widget.name](widget.params) ); }); // Hits instant.search.addWidget( instantsearch.widgets.hits({ container: '.ais-hits-container', hitsPerPage: instant.hitsPerPage, templates: { empty: instant.templates.empty, item: instant.templates.product, }, transformData: { item: function(product) { return Object.assign({}, product, { _distinct: instant.distinct, can_order: product.inventory_management !== 'shopify' || product.inventory_policy === 'continue' || product.inventory_quantity > 0, translations: algolia.translations, queryID: instant.search.helper.lastResults._rawResults[0].queryID, productPosition: product.__hitIndex + 1, }); }, empty: function(params) { return Object.assign({}, params, { translations: algolia.translations, }); }, }, }) ); // Redirect to product on click instant.search.addWidget({ init: function() { $('.ais-hits-container').on('click', '.ais-hit', function(e) { var $this = $(this); var dataHandle = $this.attr('data-handle'); var variant_id = $this.attr('data-variant-id'); var distinct = $this.attr('data-distinct'); var link = '/products/' + dataHandle; if (distinct !== 'true') { link += '?variant=' + variant_id; } if (algolia.config.analytics_enabled) { algolia.clickTracker(e); } window.location.href = link; }); $('.ais-hits-container').on('click', '.ais-hit a', function(e) { e.stopPropagation(); if (algolia.config.analytics_enabled) { algolia.clickTracker(e); } }); }, }); // Add to cart instant.search.addWidget({ init: function() { $('.ais-hits-container').on('click', '.ais-hit--cart-button', function( e ) { e.stopPropagation(); var $this = $(this); var formId = $this.attr('data-form-id'); if (formId) { document.getElementById(formId).submit(); } }); }, }); // No result actions instant.search.addWidget({ init: function(opts) { $('.ais-hits-container').on( 'click', '.ais-hit-empty--clear-filters', function() { var helper = opts.helper; helper.clearTags(); _.forEach(instant.facets.list, function(facet) { helper.clearRefinements(facet.name); }); helper.search(); } ); $('.ais-hits-container').on( 'click', '.ais-hit-empty--clear-input', function() { opts.helper.setQuery('').search(); $('.ais-search-box--input') .val('') .focus(); } ); }, }); // Pagination instant.search.addWidget( instantsearch.widgets.pagination({ container: '.ais-pagination-container', padding: 2, maxPages: 20, }) ); // Main instant.search.start(); $hiding.remove(); }); })(window.algoliaShopify, window.instantsearch);