PageSourceSearch

https://www.springerpub.com/static/version1789146322/frontend/Mage…/js/template/autocomplete/products.js

js springerpub.com collected 2026-09-24 08:48:35 UTC 5,278 bytes, 132 lines download raw bytes

1define([], function () {
2    return {
3
4        ////////////////////
5        //  Template API  //
6        ////////////////////
7
8        getNoResultHtml: function ({html}) {
9            return html`<p>${algoliaConfig.translations.noResults}</p>`;
10        },
11
12        getHeaderHtml: function () {
13            return "";
14        },
15
16        getItemHtml: function ({item, components, html}) {
17            return html`<a class="algoliasearch-autocomplete-hit"
18                           href="${item.__autocomplete_queryID != null ? item.urlForInsights : item.url}"
19                           data-objectId="${item.objectID}"
20                           data-position="${item.position}"
21                           data-index="${item.__autocomplete_indexName}"
22                           data-queryId="${item.__autocomplete_queryID}">
23                <div class="thumb"><img src="${item.thumbnail_url || ''}" alt="${item.name || ''}"/></div>
24                <div class="info">
25                    ${this.safeHighlight(components, item, "name")}
26                    <div class="algoliasearch-autocomplete-category">
27                        ${this.getColorHtml(item, components, html)}
28                        ${this.getCategoriesHtml(item, components, html)}
29                    </div>
30
31                    ${this.getPricingHtml(item, html)}
32                </div>
33            </a>`;
34        },
35
36        getFooterHtml: function ({html, ...resultDetails}) {
37            return html`<div id="autocomplete-products-footer">
38                ${this.getFooterSearchLinks(html, resultDetails)}
39            </div>`;
40        },
41
42        ////////////////////
43        // Helper methods //
44        ////////////////////
45
46        getColorHtml: function(item, components, html) {
47            const highlight = this.safeHighlight(components, item, "color");
48
49            return highlight
50                ? html`<span class="color">color: ${highlight}</span>`
51                : "";
52        },
53
54        getCategoriesHtml: function(item, components, html) {
55            const highlight = this.safeHighlight(components, item, "categories_without_path", false);
56
57            return highlight
58                ? html`<span>in ${highlight}</span>`
59                : "";
60        },
61
62        getOriginalPriceHtml: (item, html, priceGroup) => {
63            if (item['price']?.[algoliaConfig.currencyCode]?.[priceGroup + '_original_formated'] == null) return "";
64
65            return html`<span class="before_special"> ${item['price'][algoliaConfig.currencyCode][priceGroup + '_original_formated']} </span>`;
66        },
67
68        getTierPriceHtml: (item, html, priceGroup) => {
69            if (item['price']?.[algoliaConfig.currencyCode]?.[priceGroup + '_tier_formated'] == null) return "";
70
71            return html`<span class="tier_price"> As low as <span class="tier_value">${item['price'][algoliaConfig.currencyCode][priceGroup + '_tier_formated']}</span></span>`;
72        },
73
74        getPricingHtml: function(item, html) {
75            if (item['price'] == null) return "";
76
77            const priceGroup =  algoliaConfig.priceGroup || 'default';
78
79            return html `<div className="algoliasearch-autocomplete-price">
80                <span className="after_special ${item['price']?.[algoliaConfig.currencyCode]?.[priceGroup + '_original_formated'] != null ? 'promotion' : ''}">
81                    ${item['price']?.[algoliaConfig.currencyCode]?.[priceGroup + '_formated']}
82                </span>
83                ${this.getOriginalPriceHtml(item, html, priceGroup)}
84
85                ${this.getTierPriceHtml(item, html, priceGroup)}
86            </div>`;
87        },
88
89        getFooterSearchCategoryLinks: (html, resultDetails) => {
90            if (resultDetails.allCategories == null || resultDetails.allCategories.length === 0) return "";
91
92            return html ` ${algoliaConfig.translations.orIn}
93                ${resultDetails.allCategories.map((list, index) =>
94                    index === 0 ? html` <span><a href="${list.url}">${list.name}</a></span>` : html`, <span><a href="${list.url}">${list.name}</a></span>`
95                )}
96            `;
97        },
98
99        getFooterSearchLinks: function(html, resultDetails)  {
100            if (resultDetails.nbHits === 0) return "";
101
102            return html`${algoliaConfig.translations.seeIn} <span><a href="${resultDetails.allDepartmentsUrl}">${algoliaConfig.translations.allDepartments}</a></span> (${resultDetails.nbHits})
103                ${this.getFooterSearchCategoryLinks(html, resultDetails)}
104            `;
105        },
106
107        // TODO: Refactor to external lib
108        safeHighlight: function(components, hit, attribute, strict = true) {
109            const highlightResult = hit._highlightResult[attribute];
110
111            if (!highlightResult) return '';
112
113            if (strict
114                &&
115                (
116                    (Array.isArray(highlightResult)) && !highlightResult.find(hit => hit.matchLevel !== 'none')
117                    ||
118                    highlightResult.value === ''
119                )
120            ) {
121                return '';
122            }
123
124            try {
125                return components.Highlight({ hit, attribute });
126            } catch (e) {
127                return '';
128            }
129        }
130
131    };
132});

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.