PageSourceSearch

https://www.daltile.com/-/media/Base-Themes/SearchTheme/Scripts/component-search-facet-dropdown.js

js daltile.com collected 2026-09-24 19:03:11 UTC 13,061 bytes, 295 lines download raw bytes

1/**
2 * Facet dropdown component functionality
3 * @module dropdown
4 * @param  {jQuery} $ Instance of jQuery
5 * @param  {Document} document dom document object
6 * @return {Object} list of methods for working with component dropdown
7*/
8XA.component.search.facet.dropdown = (function ($, document) {
9
10    "use strict";
11    /**
12    * This object stores all public api methods
13    * @type {Object.<Methods>}
14    * @memberOf module:dropdown
15    */
16    var api = {},
17        urlHelperModel,
18        queryModel
19    /**
20    * @name module:dropdown.FacetDropdownModel
21    * @constructor
22    * @augments Backbone.Model
23    */
24    var FacetDropdownModel = XA.component.search.baseModel.extend(
25        /** @lends module:dropdown.FacetDropdownModel.prototype **/
26        {
27            /**
28            * Default model options
29            * @default
30            */
31            defaults: {
32                template: "<% _.forEach(results, function(result){" +
33                    "%><option data-facetName=\"<%= result.Name !== '' ? encodeURIComponent(result.Name) : '_empty_' %>\" <%= result.Selected !== undefined ? 'selected' : '' %> ><%= result.Name !== '' ? result.Name : emptyText %> (<%= result.Count %>)</option><%" +
34                    "}); %>",
35                dataProperties: {},
36                blockNextRequest: false,
37                resultData: {},
38                optionSelected: false,
39                sig: []
40            },
41            /**
42             * Listens to changes on facets and hash
43            * @listens module:XA.component.search.vent~event:facet-data-loaded
44            * @listens module:XA.component.search.vent~event:facet-data-filtered
45            * @listens module:XA.component.search.vent~event:facet-data-partial-filtered
46            * @listens module:XA.component.search.vent~event:hashChanged
47            */
48            initialize: function () {
49                //Event to get data at the begining or when there are no hash parameters in the url - one request for all controls
50                XA.component.search.vent.on("facet-data-loaded", this.processData.bind(this));
51
52                //Event to get filtered data
53                XA.component.search.vent.on("facet-data-filtered", this.processData.bind(this));
54
55                //If the url contains a hash, and facet name control is clicked, then we have to listen for partial filtering
56                XA.component.search.vent.on("facet-data-partial-filtered", this.processData.bind(this));
57
58                //Event after change of hash
59                XA.component.search.vent.on("hashChanged", this.updateComponent.bind(this));
60            },
61            /**
62             * Toggle value of blockNextRequest variable
63             * @memberof module:dropdown.FacetDropdownModel
64             * @alias module:dropdown.FacetDropdownModel#toggleBlockRequests
65             */
66            toggleBlockRequests: function () {
67                var state = this.get("blockNextRequest");
68                this.set(this.get("blockNextRequest"), !state);
69            },
70            /**
71             * Processes data that comes as parameter update
72             * model and sorts facets
73             * @param {Object} data Data from server with facet values
74             * @memberof module:dropdown.FacetDropdownModel
75             * @alias module:dropdown.FacetDropdownModel#processData
76             */
77            processData: function (data) {
78                var inst = this,
79                    hashObj = queryModel.parseHashParameters(window.location.hash),
80                    sig = inst.get("sig"),
81                    dataProperties = this.get("dataProperties"),
82                    searchResultsSignature = dataProperties.searchResultsSignature.split(','),
83                    sortOrder = dataProperties.sortOrder,
84                    facet = dataProperties.f,
85                    facetItem,
86                    facedData,
87                    i, j;
88
89                for (j = 0; j < searchResultsSignature.length; j++) {
90                    if (data.Facets.length > 0 && (data.Signature === searchResultsSignature[j]) || data.Signature === "" || data.Signature === null) {
91                        facedData = _.find(data.Facets, function (f) {
92                            return f.Key.toLowerCase() === facet.toLowerCase();
93                        });
94
95                        if (facedData === undefined) {
96                            return;
97                        }
98
99                        for (i = 0; i < sig.length; i++) {
100                            if (!jQuery.isEmptyObject(_.pick(hashObj, sig[i]))) {
101                                if (hashObj[sig[i]] !== "") {
102                                    facetItem = _.where(facedData.Values, { Name: hashObj[sig[i]] });
103                                    if (facetItem.length === 0) {
104                                        facetItem = _.where(facedData.Values, { Name: "" });
105                                    }
106                                    if (facetItem.length > 0) {
107                                        facetItem[0].Selected = true;
108                                        inst.optionSelected = true;
109                                    }
110                                }
111                            }
112                        }
113
114                        this.sortFacetArray(sortOrder, facedData.Values);
115                        inst.set({ resultData: facedData.Values });
116                    }
117                }
118            },
119            /**
120             * Sets option selected value to model based on hash
121             * @param {Object} hash Hash stored as an object
122             * @memberof module:dropdown.FacetDropdownModel
123             * @alias module:dropdown.FacetDropdownModel#updateComponent
124             */
125            updateComponent: function (hash) {
126                var sig = this.get("sig"), i, facetPart;
127
128                for (i = 0; i < sig.length; i++) {
129                    facetPart = sig[i].toLowerCase();
130                    if (hash.hasOwnProperty(facetPart) && hash[facetPart] !== "") {
131                        this.set({ optionSelected: true });
132                    } else {
133                        this.set({ optionSelected: false });
134                    }
135                }
136            }
137        });
138    /**
139    * @name module:dropdown.FacetDropdownView
140    * @constructor
141    * @augments Backbone.View
142    */
143    var FacetDropdownView = XA.component.search.baseView.extend(
144        /** @lends module:dropdown.FacetDropdownView.prototype **/
145
146        {
147            /**
148            * Initially sets data to model and watches events on which
149            * view should be updated
150            * @listens module:dropdown.FacetDropdownModel~event:change
151            * @memberof module:dropdown.FacetDropdownView
152            * @alias module:dropdown.FacetDropdownView#initialize
153            */
154            initialize: function () {
155                var dataProperties = this.$el.data();
156                this.properties = dataProperties.properties;
157
158                if (this.model) {
159                    this.model.set({ dataProperties: this.properties });
160                    this.model.set("sig", this.translateSignatures(this.properties.searchResultsSignature, this.properties.f));
161                }
162
163                this.model.on("change", this.render, this);
164            },
165            /**
166             * list of events for Backbone View
167            * @memberof module:dropdown.FacetDropdownView
168            * @alias module:dropdown.FacetDropdownView#events
169             */
170            events: {
171                "change .facet-dropdown-select": "updateFacet",
172                "click .bottom-remove-filter, .clear-filter": "clearFilter"
173            },
174            /**
175             * Calculates value of optionSelected value in model and calls
176             * ["updateSignaturesHash"]{@link module dropdown.FacetDropdownView#updateSignaturesHash}
177             * inside of ["updateHash"]{@link module:searchQuery.updateHash}
178            * @memberof module:dropdown.FacetDropdownView
179            * @alias module:dropdown.FacetDropdownView#updateFacet
180             */
181            updateFacet: function (param) {
182                var $selectedOption = this.$el.find(".facet-dropdown-select").find("option:selected"),
183                    facetName = decodeURIComponent($selectedOption.data("facetname")),
184                    sig = this.model.get("sig");
185
186                if (facetName === "") {
187                    this.model.set({ optionSelected: false });
188                } else {
189                    this.model.set({ optionSelected: true });
190                }
191                queryModel.updateHash(this.updateSignaturesHash(sig, facetName, {}));
192            },
193            /**
194            * Renders view
195            * @memberof module:dropdown.FacetDropdownView
196            * @alias module:dropdown.FacetDropdownView#render
197            */
198            render: function () {
199                var inst = this,
200                    resultData = inst.model.get("resultData"),
201                    dropdown = this.$el.find(".facet-dropdown-select"),
202                    emptyValueText = inst.model.get('dataProperties').emptyValueText,
203                    facetClose = this.$el.find(".facet-heading > span"),
204                    notSelectedOption = dropdown.find("option:first"),
205                    notSelectedOptionEntry = $("<option />"),
206                    template = _.template(inst.model.get("template")),
207                    templateResult = template({ results: resultData, emptyText: emptyValueText });
208
209                this.manageVisibilityByData(this.$el, resultData)
210                notSelectedOptionEntry.text(notSelectedOption.text());
211                notSelectedOptionEntry.data("facetname", "");
212
213                if (this.model.get("optionSelected")) {
214                    facetClose.addClass("has-active-facet");
215                } else if (notSelectedOption.data("facetname") === "") {
216                    facetClose.removeClass("has-active-facet");
217                }
218
219                dropdown.empty().append(notSelectedOptionEntry).append(templateResult);
220            },
221            /**
222            * Clears selected filters and updates hash by calling
223            * ["updateHash"]{@link module:searchQuery.updateHash}
224            * @memberof module:dropdown.FacetDropdownView
225            * @alias module:dropdown.FacetDropdownView#clearFilter
226             */
227            clearFilter: function () {
228                var dropdown = this.$el.find(".facet-dropdown-select"),
229                    facetClose = this.$el.find(".facet-heading > span"),
230                    sig = this.model.get("sig");
231
232                queryModel.updateHash(this.updateSignaturesHash(sig, "", {}));
233                this.model.set({ optionSelected: false });
234                facetClose.removeClass("has-active-facet");
235                dropdown.val(dropdown.find("option:first").val());
236            }
237        });
238    /**
239    * For each search dropdown component on a page creates instance of
240    * ["FacetDropdownModel"]{@link module:dropdown.FacetDropdownModel} and
241    * ["FacetDropdownView"]{@link module:dropdown.FacetDropdownView}
242    * @memberOf module:dropdown
243    * @alias module:dropdown.init
244    */
245
246    api.init = function () {
247        if ($("body").hasClass("on-page-editor")) {
248            return;
249        }
250
251        queryModel = XA.component.search.query;
252        urlHelperModel = XA.component.search.url;
253
254        var facetDropdownList = $(".facet-dropdown:not(.initialized)");
255
256        _.each(facetDropdownList, function (elem) {
257            var $el = $(elem),
258                view = new FacetDropdownView({ el: $el, model: new FacetDropdownModel() });
259
260            $el.addClass("initialized");
261        });
262    };
263    /**
264    *
265    * @memberOf module:dropdown
266    * @alias module:dropdown.getFacetDataRequestInfo
267    * @returns {Array<FacetDataRequestInfo>} facet data needed for request
268    */
269    api.getFacetDataRequestInfo = function () {
270        var facetDropdownList = $(".facet-dropdown"),
271            result = [];
272
273        _.each(facetDropdownList, function (elem) {
274            var properties = $(elem).data().properties,
275                signatures = properties.searchResultsSignature.split(','),
276                i;
277
278            for (i = 0; i < signatures.length; i++) {
279                result.push({
280                    signature: signatures[i] === null ? "" : signatures[i],
281                    facetName: properties.f,
282                    endpoint: properties.endpoint,
283                    filterWithoutMe: true
284                });
285            }
286        });
287
288        return result;
289    };
290
291    return api;
292
293}(jQuery, document));
294
295XA.register("facetDropdown", XA.component.search.facet.dropdown);

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.