PageSourceSearch

https://starr.com/-/media/Base-Themes/SearchTheme/Scripts/component-search-facet-range-slider.js

js starr.com collected 2026-09-29 13:10:59 UTC 12,967 bytes, 278 lines download raw bytes

1/**
2 * Range Slider component functionality
3 * @module searchFacetRangeSlider
4 * @param  {jQuery} $ Instance of jQuery
5 * @param  {Document} document dom document object
6 * @return {Object} list of methods for working with range slider
7*/
8XA.component.search.facet.rangeslider = (function ($, document) {
9    /**
10    * This object stores all public api methods
11    * @type {Object.<Methods>}
12    * @memberOf module:searchFacetRangeSlider
13    */
14    var api = {},
15        urlHelperModel,
16        queryModel;
17
18    /**
19    * @name module:searchFacetRangeSlider.SearchFacetRangeSliderModel
20    * @constructor
21    * @augments Backbone.Model
22    */
23    var SearchFacetRangeSliderModel = Backbone.Model.extend(
24        /** @lends module:searchFacetRangeSlider.SearchFacetRangeSliderModel.prototype **/
25        {
26            /**
27           * Default model options
28           * @default
29           */
30            defaults: {
31                dataProperties: {},
32                sig: [],
33                timeStamp: ''
34            }
35        });
36    /**
37    * @name module:searchFacetRangeSlider.SearchFacetRangeSliderView
38    * @constructor
39    * @augments Backbone.View
40    */
41    var SearchFacetRangeSliderView = XA.component.search.baseView.extend(
42        /** @lends module:searchFacetRangeSlider.SearchFacetRangeSliderView.prototype **/
43        {
44            /**
45            * Initially sets data to model and watches events on which
46            * view should be updated
47            * @listens module:searchFacetRangeSlider.SearchFacetRangeSliderView~event:change
48            * @listens module:XA.component.search.vent~event:hashChanged
49            * @memberof module:searchFacetRangeSlider.SearchFacetRangeSliderView
50            */
51            initialize: function () {
52                var dataProperties = this.$el.data();
53                this.properties = dataProperties.properties;
54
55                if (this.model) {
56                    this.model.set({ dataProperties: this.properties });
57                    this.model.set("sig", this.translateSignatures(this.properties.searchResultsSignature, this.properties.f));
58                }
59                this.model.on("change", this.updateSelectedValue, this);
60
61                XA.component.search.vent.on("hashChanged", this.updateModel.bind(this));
62
63                this.render();
64            },
65            /**
66            * list of events for Backbone View
67            * @memberof module:searchFacetRangeSlider.SearchFacetRangeSliderView
68            * @alias module:searchFacetRangeSlider.SearchFacetRangeSliderView#events
69            */
70            events: {
71                'click .bottom-remove-filter, .clear-filter': 'removeFacet',
72                'mouseup .ui-slider-handle': 'updateModel'
73            },
74            /**
75             * Renders view. Use jQueryUI slider with set up from searchFacetRangeSlider
76             * properties
77             * @memberof module:searchFacetRangeSlider.SearchFacetRangeSliderView
78             * @alias module:searchFacetRangeSlider.SearchFacetRangeSliderView#render
79             */
80            render: function () {
81                var self = this,
82                    sig = this.model.get('sig'),
83                    queryModel = XA.component.search.query,
84                    hashObj = queryModel.parseHashParameters(window.location.hash),
85                    minRangeValue = parseFloat(this.model.get('dataProperties').minRangeValue),
86                    maxRangeValue = parseFloat(this.model.get('dataProperties').maxRangeValue),
87                    changeStep = parseFloat(this.model.get('dataProperties').changeStep),
88                    $sliderValue = $('<div />').addClass('slider-value'),
89                    facetClose = this.$el.find('.facet-heading > span'),
90                    $slider = this.$el.find('.slider'),
91                    selectedMinValue,
92                    selectedMaxValue,
93                    i;
94
95                for (i = 0; i < sig.length; i++) {
96                    if (!jQuery.isEmptyObject(_.pick(hashObj, sig[i]))) {
97                        var values = _.values(_.pick(hashObj, sig[i]))[0];
98                        if (values) {
99                            selectedMinValue = parseFloat(values.split("|")[0]);
100                            selectedMaxValue = parseFloat(values.split("|")[1]);
101                            //Adds active class to group close button
102                            facetClose.addClass('has-active-facet');
103                        }
104                    } else {
105                        selectedMinValue = parseFloat(this.model.get('dataProperties').selectedMinValue);
106                        selectedMaxValue = parseFloat(this.model.get('dataProperties').selectedMaxValue);
107                        facetClose.removeClass('has-active-facet');
108                    }
109                }
110
111                if (isNaN(minRangeValue)) {
112                    minRangeValue = 0;
113                }
114                if (isNaN(maxRangeValue)) {
115                    maxRangeValue = 0;
116                }
117                if (isNaN(changeStep) || changeStep === 0) {
118                    changeStep = 1;
119                }
120                if (isNaN(selectedMinValue)) {
121                    selectedMinValue = minRangeValue;
122                }
123                if (isNaN(selectedMaxValue)) {
124                    selectedMaxValue = maxRangeValue;
125                }
126
127                $slider.slider({
128                    range: true,
129                    min: minRangeValue,
130                    max: maxRangeValue,
131                    step: changeStep,
132                    values: [selectedMinValue, selectedMaxValue],
133                    create: function (event, ui) {
134                        $(".slider-value").remove();
135                        $slider.after($sliderValue);
136                        if (selectedMinValue !== 0 || selectedMaxValue !== 0) {
137                            self.updateText(selectedMinValue, selectedMaxValue);
138                        }
139                    },
140                    slide: _.debounce(function (event, ui) {
141                        self.updateModel(self.updateSignaturesHash(sig, ui.values[0] + "|" + ui.values[1], {}));
142                    }, 500)
143                });
144
145            },
146            /**
147             * Sets default values for Range Slider and updates hash according to them
148             * @memberof module:searchFacetRangeSlider.SearchFacetRangeSliderView
149             * @alias module:searchFacetRangeSlider.SearchFacetRangeSliderView#removeFacet
150             */
151            removeFacet: function () {
152                var facet = this.$el,
153                    sig = this.model.get('sig'),
154                    $slider = this.$el.find('.slider'),
155                    $facetClose = facet.find('.facet-heading > span'),
156                    properties = this.model.get('dataProperties'),
157                    hash = queryModel.parseHashParameters(window.location.hash);
158
159                $facetClose.removeClass('has-active-facet');
160
161                properties.selectedMinValue = properties.minRangeValue;
162                properties.selectedMaxValue = properties.maxRangeValue;
163
164                //Updates slider text to default min and max range values
165                this.updateText(properties.minRangeValue, properties.maxRangeValue);
166
167                //Sets slider valued to default min and max range values
168                $slider.slider("values", [properties.minRangeValue, properties.maxRangeValue]);
169
170                this.model.set({ dataProperties: properties });
171
172                if (hash.hasOwnProperty(this.model.get('sig'))) {
173                    queryModel.updateHash(this.updateSignaturesHash(sig, "", hash));
174                }
175            },
176            /**
177             * Updates model based on hash parameters
178             * @param {Object} hash Object that contains hash parameters
179             * @memberof module:searchFacetRangeSlider.SearchFacetRangeSliderView
180             * @alias module:searchFacetRangeSlider.SearchFacetRangeSliderView#updateModel
181             */
182            updateModel: function (hash) {
183                var sig = this.model.get('sig'),
184                    facetPart,
185                    dataProperties,
186                    values,
187                    selectedMinValue,
188                    selectedMaxValue,
189                    i;
190
191                if (!hash) {
192                    hash = queryModel.parseHashParameters(window.location.hash);
193                }
194
195                for (i = 0; i < sig.length; i++) {
196                    facetPart = sig[i].toLocaleString();
197                    if (hash.hasOwnProperty(facetPart)) {
198                        values = _.values(_.pick(hash, facetPart))[0];
199                        if (values !== '') {
200                            selectedMinValue = parseFloat(values.split("|")[0]);
201                            selectedMaxValue = parseFloat(values.split("|")[1]);
202
203                            if (typeof selectedMaxValue === "undefined" ||
204                                typeof selectedMinValue === "undefined") {
205                                continue;
206                            }
207
208                            dataProperties = this.model.get('dataProperties');
209                            dataProperties.selectedMinValue = !isNaN(selectedMinValue) ? selectedMinValue : dataProperties.minRangeValue;
210                            dataProperties.selectedMaxValue = !isNaN(selectedMaxValue) ? selectedMaxValue : dataProperties.maxRangeValue;
211                            this.model.set('dataProperties', dataProperties);
212                            this.model.set("timeStamp", (new Date()).getTime());
213                        } else {
214                            this.removeFacet();
215                        }
216                    }
217                }
218            },
219            /**
220             * Updates selected text values
221             * @memberof module:searchFacetRangeSlider.SearchFacetRangeSliderView
222             * @alias module:searchFacetRangeSlider.SearchFacetRangeSliderView#updateSelectedValue
223             */
224            updateSelectedValue: function () {
225                var dataProperties = this.model.get('dataProperties'),
226                    facetMinValue = dataProperties.selectedMinValue,
227                    facetMaxValue = dataProperties.selectedMaxValue,
228                    $slider = this.$el.find('.slider'),
229                    sig = this.model.get('sig');
230
231                $slider.slider("values", [facetMinValue, facetMaxValue]);
232                this.updateText(facetMinValue, facetMaxValue);
233                this.$el.find('.facet-heading > span').addClass('has-active-facet');
234
235                queryModel.updateHash(this.updateSignaturesHash(sig, facetMinValue + "|" + facetMaxValue, {}));
236            },
237            /**
238             * Updates slider text values text
239             * @param {String} facetMinValue Minimal value of facet
240             * @param {String} facetMaxValue Maximal value of facet
241             * @memberof module:searchFacetRangeSlider.SearchFacetRangeSliderView
242             * @alias module:searchFacetRangeSlider.SearchFacetRangeSliderView#updateSelectedValue
243             */
244            updateText: function (facetMinValue, facetMaxValue) {
245                var $sliderValueField = this.$el.find('.slider-value'),
246                    sliderText = this.model.get('dataProperties').formatingString;
247
248                sliderText = sliderText.replace('{from}', facetMinValue).replace('{to}', facetMaxValue);
249                $sliderValueField.html(sliderText);
250            }
251        });
252    /**
253    * For each search facet range slider component on a page creates instance of 
254    * ["SearchFacetRangeSliderModel"]{@link module:searchFacetRangeSlider.SearchFacetRangeSliderModel} and 
255    * ["SearchFacetRangeSliderView"]{@link module:searchFacetRangeSlider.SearchFacetRangeSliderView} 
256    * @memberOf module:searchFacetRangeSlider
257    * @alias module:searchFacetRangeSlider.init
258    */
259    api.init = function () {
260        queryModel = XA.component.search.query;
261        urlHelperModel = XA.component.search.url;
262
263        var searchFacetRangeSlider = $(".facet-range-selector:not(.initialized)");
264
265        _.each(searchFacetRangeSlider, function (elem) {
266            var $el = $(elem),
267                searchFacetRangeSliderModel = new SearchFacetRangeSliderModel(),
268                searchFacetRangeSliderView = new SearchFacetRangeSliderView({ el: $el, model: searchFacetRangeSliderModel });
269               
270            $el.addClass("initialized");
271        });
272    };
273
274    return api;
275
276}(jQuery, document));
277
278XA.register('searchFacetRangeSlider', XA.component.search.facet.rangeslider);

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.