PageSourceSearch

https://www.xanax.com/-/media/Base-Themes/SearchTheme/Scripts/component-search-location-filter.js

js xanax.com collected 2026-09-24 22:54:54 UTC 13,806 bytes, 339 lines download raw bytes

1XA.component.search.locationfilter = (function ($, document) {
2
3    "use strict";
4
5    var api = {},
6        locationFilters = [],
7        views = [],
8        queryModel,
9        urlHelperModel,
10        scriptsLoaded = false,
11        mapsConnector = XA.connector.mapsConnector,
12        LocationFilterModel,
13        LocationFilterView,
14        initialize;
15
16    initialize = function() {
17        var i, view;
18        for (i = 0; i < locationFilters.length; i++) {
19            //crate Backbone.js views - one view per component on the page
20            view = new LocationFilterView({el: locationFilters[i], model: new LocationFilterModel()});
21        }
22    };
23
24    LocationFilterModel = Backbone.Model.extend({
25        defaults: {
26            dataProperties: {},
27            sig: []
28        },
29        initAutocompleteEngine : function() {
30            var _this = this,
31                searchEngine;
32
33            //initialize predictive only when number of predictions is non-zero
34            if(_this.get("dataProperties").p > 0){
35                    searchEngine = new Bloodhound({
36                        datumTokenizer: Bloodhound.tokenizers.obj.whitespace("name"),
37                        queryTokenizer: Bloodhound.tokenizers.whitespace,
38                        limit :  _this.get("dataProperties").p,
39                        remote : {
40                            url : "-",
41                            replace : function(){
42                                return Date.now().toString();
43                            },
44                            transport : function(options, onSuccess, onError){
45                                var queryParams =  _this.get("queryParams");
46                                if(!queryParams.text){
47                                    onSuccess([]);
48                                    return;
49                                }
50                                mapsConnector.locationAutocomplete(queryParams,
51                                    function (results) { //success
52                                        var simplifiedResults = results.map(function(result) {
53                                            if (result.hasOwnProperty("text")) {
54                                                return result.text;
55                                            }
56                                            return result;
57                                        });
58
59                                        onSuccess(simplifiedResults);
60                                    },
61                                    function(){ //fail
62                                        onError("Could not autocomplete");
63                                    });
64                            }
65                        }
66                });
67                searchEngine.initialize();
68                this.set({"searchEngine" : searchEngine});
69            }
70        }
71    });
72
73    LocationFilterView = XA.component.search.baseView.extend({
74        initialize: function () {
75            var inst = this,
76                dataProperties = this.$el.data(),
77                $textBox = this.$el.find(".location-search-box-input"),
78                signatures = dataProperties.properties.searchResultsSignature.split(',');
79
80            if (dataProperties.properties.searchResultsSignature === null) {
81                dataProperties.properties.searchResultsSignature = "";
82            }
83
84            this.model.set({ dataProperties: dataProperties.properties });
85            this.model.set({ sig: signatures});
86            this.model.set({ queryParams: { maxResults: dataProperties.p, text: "" } });
87            this.model.initAutocompleteEngine();
88
89            var autocompleteEngine = this.model.get("searchEngine");
90
91            if(autocompleteEngine){
92                $textBox.typeahead({
93                    hint : true,
94                    minLength : 2
95                },
96                {
97                    source : autocompleteEngine.ttAdapter(),
98                    templates : {
99                        suggestion : function(data) {
100                            return '<div class="suggestion-item">' + data + '</div>';
101                        }
102                    }
103                }).on("typeahead:selected",function(args, selected){
104                    inst.translateUserLocation(selected);
105                    $textBox.typeahead("val", selected);
106                });
107            }
108
109            this.addressLookup();
110
111            XA.component.search.vent.on("hashChanged", function(hash) {
112                var address = hash[signatures.length > 0 && signatures[0] !== "" ? signatures[0] + "_a" : "a"];
113                if (typeof address !== "undefined" && address !== null && address !== "") {
114                    $textBox.val(address);
115                }
116            });
117        },
118        events: {
119            "click .location-search-box-button": "addressLookup",
120            "keypress .location-search-box-input": "searchTextChanges",
121            "keyup .location-search-box-input" : "autocomplete"
122        },
123        addressLookup: function(e){
124            var properties = this.model.get("dataProperties"),                
125                lookupQuery = {
126                    text : this.getAddress(),
127                    maxResults : 1
128                },
129                hashObj;
130
131            if (lookupQuery.text === "") {
132                hashObj = this.createHashObject("", "");
133                this.updateHash(hashObj, properties);
134                return;
135            }
136
137            switch (properties.mode) {
138                case "Location": {
139                    //use browser to detect location
140                    this.detectLocation();
141                    break;
142                }
143                case "UserProvided": {
144                    //take address entered by user and try to convert it to latitude and longitude
145                    this.translateUserLocation(lookupQuery);
146                    break;
147                }
148                case "Mixed": {
149                    //use user address otherwise try to detect location by browser
150                    if (typeof(lookupQuery.text) === "undefined" || lookupQuery.text === "") {
151                        this.detectLocation();
152                    } else {
153                        this.translateUserLocation(lookupQuery);
154                    }
155                    break;
156                }
157            }
158        },
159        getAddress: function() {
160            var $textBox = this.$el.find(".location-search-box-input.tt-input"),
161                text = $textBox.length !== 0 ? $textBox.val() : this.$el.find(".location-search-box-input").val(),
162                hash = queryModel.parseHashParameters(window.location.hash),
163                signatures = this.model.get("sig"),
164                address;
165
166            if (text === "" || typeof text === "undefined") {
167                address = hash[signatures.length > 0 && signatures[0] !== "" ? signatures[0] + "_a" : "a"];
168                if (address !== "") {
169                    text = address;
170                }
171                if (typeof text === "undefined") {
172                    text = "";
173                }
174            }
175
176            return text;
177        },
178        autocomplete : function(args){
179            var $textBox,
180                queryParams,
181                properties = this.model.get("dataProperties");
182
183            args.stopPropagation();
184            if (args.keyCode === 13) {
185                return;
186            }
187
188            $textBox = this.$el.find(".location-search-box-input.tt-input");
189
190            queryParams = {
191                text : $textBox.length !== 0 ? $textBox.val() : this.$el.find(".location-search-box-input").val(),
192                maxResults : properties.p
193            };
194            this.model.set({queryParams : queryParams});
195        },
196        searchTextChanges: function(e) {
197            e.stopPropagation();
198            if (e.keyCode === 13) {
199                this.addressLookup(e);
200                return false;
201            }
202            return true;
203        },
204        translateUserLocation: function(lookupQuery) {
205            var that = this,
206                properties = this.model.get("dataProperties"),
207                text = typeof lookupQuery.text !== "undefined" ? lookupQuery.text : lookupQuery,
208                $textBox = this.$el.find(".location-search-box-input.tt-input"),
209                hashObj = {};
210
211            if (text === "") {
212                return;
213            }
214            mapsConnector.addressLookup({ text: text }, function(data) {
215                hashObj = that.createHashObject(data[0] + "|" + data[1], properties.f + ",Ascending");
216                that.updateHash(hashObj, properties);
217            }, function () {
218                console.error("Error while getting '" + text + "' location");
219            });
220            $textBox.blur();
221            if ($textBox.val() === "") {
222                $textBox.val(text);
223            }
224        },
225        detectLocation: function() {
226            var properties = this.model.get("dataProperties"),
227                $textBox = this.$el.find(".location-search-box-input"),
228                sig = this.model.get("sig"),
229                hash = queryModel.parseHashParameters(window.location.hash),
230                param,
231                hashObj = {},
232                that = this;
233
234             XA.component.locationService.detectLocation(
235                function (location) {
236                    hashObj = that.createHashObject(location[0] + "|" + location[1], properties.f + ",Ascending");
237                    that.updateHash.call(that, hashObj, properties);
238                    if ($textBox.length > 0) {
239                        $textBox.attr("placeholder", properties.myLocationText);
240                    }
241                },
242                function (errorMessage) {
243                    //do not update the hash in any way when then location isn't available
244                    console.log(errorMessage);
245                }
246          );
247        },
248        updateHash: function (params, properties) {
249            var sig = this.model.get("sig"),
250                signature,
251                searchModels = typeof XA.component.search !== "undefined" ? XA.component.search.results.searchResultModels : [],
252                $textBox = this.$el.find(".location-search-box-input.tt-input"),
253                text = $textBox.length !== 0 ? $textBox.val() : this.$el.find(".location-search-box-input").val(),
254                i, j;
255
256            //clear load more offset in each of search results with the same signature when location is changes
257            //at the moment this is needed to clear offset but should be handle in search service in the future
258            for (i = 0; i < searchModels.length; i++) {
259                for (j = 0; j < sig.length; j++) {
260                    signature = sig[j];
261                    if (searchModels[i].get("dataProperties").sig === signature) {
262                        searchModels[i].set("loadMoreOffset", 0);
263                    }
264                }
265            }
266
267            if (text !== null && text !== "") {
268                for (i = 0; i < sig.length; i++) {
269                    signature = sig[i];
270                    params[signature !== "" ? signature + "_a" : "a"] = text;
271                }
272            }
273
274            queryModel.updateHash(params, properties.targetUrl);
275            for (i = 0; i < sig.length; i++) {
276                XA.component.search.vent.trigger("my-location-coordinates-changed", {
277                    sig: sig[i],
278                    coordinates: params[sig[i] !== "" ? sig[i] + "_g" : "g"].split("|")
279                });
280            }
281        },
282        createHashObject: function(g, o) {
283            var sig = this.model.get("sig"),
284                signature, 
285                hashObj = {},
286                i;
287
288            for (i = 0; i < sig.length; i++) {
289                signature = sig[i];
290                hashObj[signature !== "" ? signature + "_g" : "g"] = g;
291                hashObj[signature !== "" ? signature + "_o" : "o"] = o;
292            }
293
294            return hashObj;
295        }
296    });
297
298    api.init = function() {
299        if ($("body").hasClass("on-page-editor")) {
300            return;
301        }
302
303        queryModel = XA.component.search.query;
304        urlHelperModel = XA.component.search.url;
305
306        var components = $(".location-filter:not(.initialized)");
307       
308        _.each(components, function(elem) {
309            var $el = $(elem),
310                properties = $el.data("properties");
311
312            //collect all found components - we will use them later to create views
313            locationFilters.push($el);
314
315            //load google or bing scripts in order to properly use address lookup functionality but just
316            //when we are not in Location mode (in this mode we are taking location form the browser)
317            if (!scriptsLoaded && properties.mode !== "Location") {
318                mapsConnector.loadScript(properties.key, XA.component.search.locationfilter.scriptsLoaded);
319            } else {
320                initialize();
321            }
322
323            $el.addClass("initialized");
324        });
325    };
326
327    api.scriptsLoaded = function() {
328        if (!scriptsLoaded) {
329            console.log("Maps api loaded");
330            scriptsLoaded = true;
331            initialize();
332        }
333    };
334
335    return api;
336
337}(jQuery, document));
338
339XA.register("locationfilter", XA.component.search.locationfilter);

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.