PageSourceSearch

https://www.hopenn.com/wp-content/mu-plugins/wp-company-manager/assets/js/wpcm.js?ver=1790757958

js hopenn.com collected 2026-10-04 05:01:34 UTC 19,838 bytes, 583 lines download raw bytes

1var WPCM = (function (WPCM, $) {
2    // Window Completely Loaded
3    $(window).on("load", function () {
4        // Initialize models, collections, and views
5        WPCM.Locations = new WPCM.Collections.Locations();
6
7        if ($("#closest_location").length) {
8            WPCM.User = new WPCM.Models.User();
9            WPCM.ClosestLocation = new WPCM.Views.ClosestLocation({
10                el: "#closest_location",
11                model: WPCM.User,
12            });
13        }
14
15        if ($("#wpcm_zip").length) {
16            WPCM.LocationSearch = new WPCM.Views.SearchByZip({
17                el: $("#wpcm_zip"),
18                collection: WPCM.Locations,
19            });
20        }
21
22        if ($("#map").length) {
23            // Initialize Map
24            WPCM.Map = new WPCM.Views.Map({
25                el: $("#map"),
26                collection: WPCM.Locations,
27            });
28
29            if ($("#locations_list").length) {
30                WPCM.List = new WPCM.Views.List({
31                    el: $("#locations_list"),
32                    collection: WPCM.Locations,
33                });
34            }
35
36            if (typeof WPCM_LOCATION_ID !== "undefined") {
37                // Single location map
38                WPCM.Locations.fetch({
39                    data: {
40                        location_id: WPCM_LOCATION_ID,
41                    },
42                });
43            } else {
44                const urlParams = new URLSearchParams(window.location.search);
45                const wpcmZipcode = urlParams.get('zipcode');
46                const wpcmDivision = urlParams.get('division');
47
48                WPCM.Locations.fetch({
49                    data: {
50                        zipcode: wpcmZipcode,
51                        division: wpcmDivision,
52                    },
53                    reset: true,
54                    success: function (collection, response, options) {
55                        WPCM.Locations.originalModels = collection.toJSON();
56                        WPCM.Locations.originalCollection =
57                            new Backbone.Collection(
58                                WPCM.Locations.originalModels
59                            );
60
61                        $(document).trigger("cm:initial-locations-fetch");
62                    },
63                });
64            }
65
66            // Fake Marker
67            WPCM.ActiveLocation = new WPCM.Models.ActiveLocation();
68            WPCM.FakeMarker = new WPCM.Views.FakeMarker({
69                el: $(".js-fake-map-infowindow"),
70                model: WPCM.ActiveLocation,
71            });
72        }
73
74        // NOTE: Custom filter trigger
75        $(document).on("cm:filter-by-id", (e, location_id) => {
76            WPCM.Locations.fetch({
77                data: {
78                    location_id: location_id,
79                },
80            });
81        });
82
83        $(document).on("cm:filter-by-division", (e, division_id) => {
84            WPCM.Locations.fetch({
85                data: {
86                    division: division_id,
87                },
88            });
89        });
90    });
91
92    /**
93     * FEDS - No Need to Edit This Section
94     */
95    WPCM.Models = WPCM.Models || {};
96    WPCM.Collections = WPCM.Collections || {};
97    WPCM.Views = WPCM.Views || {};
98    WPCM = _.extend(WPCM, Backbone.Events);
99
100    WPCM.Models.Location = Backbone.Model.extend({
101        urlRoot: "/wp-json/wpcm-locations/vl/view",
102
103        default: {
104            title: "",
105            address: "",
106            phone: "",
107            directions: "",
108            url: "",
109            hours: "",
110        },
111    });
112
113    WPCM.Models.User = Backbone.Model.extend({
114        default: {
115            geo: {
116                latitude: 0,
117                longitude: 0,
118            },
119            location: "",
120        },
121
122        initialize: function () {
123            this.on("change:geo", this._setClosestLocation, this);
124            $(document).on(
125                "click",
126                "#get_geolocation",
127                $.proxy(this.getLocation, this)
128            );
129            this.maybeSetLocation();
130        },
131
132        maybeSetLocation: function () {
133            // Checks PFX and cookie for geo info to set closest location
134            if (_.isEmpty(this.get("geo"))) {
135                if (
136                    typeof PersonalizeFX !== "undefined" &&
137                    typeof PersonalizeFX.uLoc.lat !== "undefined"
138                ) {
139                    this.set("geo", {
140                        latitude: PersonalizeFX.uLoc.lat,
141                        longitude: PersonalizeFX.uLoc.lng,
142                    });
143                } else {
144                    if (typeof Cookies.get("wpcm-geo") !== "undefined") {
145                        const pos = Cookies.getJSON("wpcm-geo");
146                        this._setLocation({
147                            coords: {
148                                latitude: pos.latitude,
149                                longitude: pos.longitude,
150                            },
151                        });
152                    }
153                }
154            }
155            if (!_.isEmpty(this.get("geo"))) {
156                this._setClosestLocation();
157            }
158        },
159
160        getLocation: function (e) {
161            e.preventDefault();
162            this.askForLocation();
163        },
164
165        askForLocation: function () {
166            if (navigator.geolocation) {
167                navigator.geolocation.getCurrentPosition(
168                    _.bind(this._setLocation, this),
169                    _.bind(this._locationError)
170                );
171            } else {
172                console.log("Geolocation is not supported in this browser.");
173                WPCM.trigger("User/Location/Error");
174            }
175        },
176
177        _setLocation: function (pos) {
178            if (typeof Cookies.get("wpcm-geo") == "undefined") {
179                Cookies.set(
180                    "wpcm-geo",
181                    {
182                        latitude: pos.coords.latitude,
183                        longitude: pos.coords.longitude,
184                    },
185                    { expires: 30 }
186                );
187            }
188            this.set("geo", {
189                latitude: pos.coords.latitude,
190                longitude: pos.coords.longitude,
191            });
192        },
193
194        _locationError: function (err) {
195            console.log(err);
196            console.warn("ERROR(" + err.code + "): " + err.message);
197            WPCM.trigger("User/Location/Error");
198        },
199
200        _setClosestLocation: function () {
201            const self = this;
202            // Fetch closest location, set cookie
203            if (typeof Cookies.get("wpcm-closest") == "undefined") {
204                $.get("/wp-json/wpcm-locations/v1/closest", {
205                    latitude: this.get("geo").latitude,
206                    longitude: this.get("geo").longitude,
207                }).done(function (response) {
208                    self.set("location", response);
209                    Cookies.set("wpcm-closest", response, { expires: 30 });
210                });
211            } else {
212                this.set("location", Cookies.getJSON("wpcm-closest"));
213            }
214        },
215    });
216
217    /**
218     * Active Location
219     */
220    WPCM.Models.ActiveLocation = Backbone.Model.extend({
221        defaults: {
222            location: null,
223        },
224    });
225
226    WPCM.Collections.Locations = Backbone.Collection.extend({
227        url: "/wp-json/wpcm-locations/v1/view",
228        model: WPCM.Models.Location,
229
230        initialize: function () {
231            this.originalModels = [];
232            this.originalCollection = [];
233        },
234
235        filter: function (filterVal) {
236            const filtered = this.originalCollection.filter(function (
237                location
238            ) {
239                return _.contains(location.get("filteredAttribute"), filterVal);
240            });
241            this.reset(filtered);
242        },
243
244        clearFilter: function () {
245            this.reset(this.originalModels);
246        },
247    });
248
249    /**
250     * Renders the Marker Info Window Html
251     */
252    WPCM.Views.Marker = Backbone.View.extend({
253        template: null,
254
255        initialize: function () {
256            this.template = _.template($("#markerTemplate").html());
257        },
258
259        render: function () {
260            this.$el.html(this.template(this.model.toJSON()));
261            return this;
262        },
263    });
264
265    /**
266     * Renders out the Google Map
267     */
268    WPCM.Views.Map = Backbone.View.extend({
269        map: null,
270        infoWindow: null,
271        filterView: null,
272        markers: [],
273
274        defaults: {
275            // MAP STYLING: replace [] with the JS array from Snazzy Maps
276            styles: [],
277            mapTypeId: google.maps.MapTypeId.ROADMAP,
278            restriction: {
279                latLngBounds: {
280                    north: 85,
281                    south: -85,
282                    west: -180,
283                    east: 180,
284                },
285                strictBounds: true,
286            }
287        },
288
289        initialize: function (options) {
290            this.setElement(options.el);
291            this.map = new google.maps.Map(
292                document.getElementById("map"),
293                this.defaults
294            );
295            this.infoWindow = new google.maps.InfoWindow({ content: "" });
296            // Add Listeners to the Locations Collection
297            this.listenTo(this.collection, "reset", this.render);
298            this.listenTo(this.collection, "sync", this.render);
299        },
300
301        addMarker: function (location, options = {}) {
302            const attrs = location.toJSON(),
303                self = this;
304            if (attrs.lat == "" || attrs.lng == "") {
305                //empty lat/lng from say a no-address location from the client, breaks the bounds
306                console.log(attrs);
307                return;
308            }
309            if (
310                attrs.exclude_from_map &&
311                !(options && options.singular_location)
312            ) {
313                const singular =
314                    typeof WPCM_LOCATION_ID !== "undefined" &&
315                    String(attrs.id) === String(WPCM_LOCATION_ID);
316                if (!singular) {
317                    return;
318                }
319            }
320
321            let pinType = "black";
322            if (attrs.color_scheme) {
323                pinType = attrs.color_scheme;
324            }
325
326            const position = new google.maps.LatLng(attrs.lat, attrs.lng),
327                marker = new google.maps.Marker({
328                    animation: google.maps.Animation.DROP,
329                    position: position,
330                    title: attrs.post.post_title,
331                    icon: {
332                        url: `${WPCM.plugin_url}assets/img/map-pin-${pinType}.png`,
333                    },
334                });
335            marker.setMap(this.map);
336            this.markers.push(marker);
337            this.bounds.extend(marker.position);
338            google.maps.event.addListener(marker, "click", function () {
339                self.infoWindow.setContent(
340                    new WPCM.Views.Marker({ model: location }).render().el
341                );
342                self.infoWindow.open(self.map, this);
343
344                // Update Active Location
345                WPCM.ActiveLocation.set("location", location);
346            });
347        },
348
349        render: function (collection) {
350            this.removeMarkers();
351            this.bounds = new google.maps.LatLngBounds();
352            if (!collection.isEmpty()) {
353                const singularPage =
354                    typeof WPCM_LOCATION_ID !== "undefined" &&
355                    collection.length === 1;
356                collection.each(
357                    function (loc) {
358                        this.addMarker(loc, {
359                            singular_location: singularPage,
360                        });
361                    },
362                    this
363                );
364                this.map.setCenter(this.bounds.getCenter());
365                if (typeof WPCM_LOCATION_ID !== "undefined") {
366                    // Single-location pages: keep a regional view.
367                    // fitBounds on one marker zooms to street level.
368                    const setSingleLocationZoom = () => {
369                        this.map.setZoom(9);
370                    };
371                    setSingleLocationZoom();
372                    google.maps.event.addListenerOnce(
373                        this.map,
374                        "idle",
375                        setSingleLocationZoom
376                    );
377                } else {
378                    this.map.fitBounds(this.bounds);
379                }
380
381                if (!_.isEmpty(WPCM.action.display)) {
382                    const marker = _.findWhere(this.markers, {
383                        title: WPCM.action.display,
384                    });
385                    if (typeof marker !== "undefined") {
386                        google.maps.event.trigger(marker, "click");
387                        this.map.setCenter(marker.getPosition());
388                    }
389                }
390
391                // If there's only one marker, automatically open infobox
392                if (1 === collection.length) {
393                    google.maps.event.trigger(this.markers[0], "click");
394                }
395
396                if ('1' == WPCM.group_clusters) {
397                    const clusterSVG = window.btoa(`<svg fill="#000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 240">
398                        <circle cx="120" cy="120" opacity=".6" r="70"></circle>
399                        <circle cx="120" cy="120" opacity=".3" r="90"></circle>
400                        <circle cx="120" cy="120" opacity=".2" r="110"></circle>
401                    </svg>`);
402
403                    // NOTE: Special case from this edit -> https://madeline.webfxph.com/website-thread/3606/?access_token=3b9f7856462f44bb8ad332ef4aad7276
404                    const clusteredMarkers = this.markers.filter(marker => {
405                        return marker.title.toLowerCase().includes('bronx');
406                    });
407
408                    const markerCluster = new markerClusterer.MarkerClusterer({
409                        map: this.map,
410                        markers: clusteredMarkers,
411                        renderer: {
412                            render: ({ markers, _position: position }) => {
413                                const markersCount = markers.length;
414                                return new google.maps.Marker({
415                                    position,
416                                    icon: {
417                                        url: `data:image/svg+xml;base64,${clusterSVG}`,
418                                        scaledSize: new google.maps.Size(60, 60),
419                                    },
420                                    label: {
421                                        text: String(markersCount),
422                                        color: "#fff",
423                                    },
424                                    zIndex: 1000 + markersCount,
425                                });
426                            },
427                        },
428                    });
429                }
430            }
431            return this;
432        },
433
434        addModelToMap: function () {
435            const attrs = this.model.toJSON();
436            const singularLocation =
437                typeof WPCM_LOCATION_ID !== "undefined" &&
438                String(attrs.id) === String(WPCM_LOCATION_ID);
439            this.addMarker(this.model, {
440                singular_location: singularLocation,
441            });
442            this.map.setCenter(new google.maps.LatLng(attrs.lat, attrs.lng));
443        },
444
445        removeMarkers: function () {
446            const self = this;
447            for (let i = 0; i < this.markers.length; i++) {
448                self.markers[i].setMap(null);
449            }
450            this.markers = [];
451        },
452    });
453
454    /**
455     * Renders out the List of locations
456     */
457    WPCM.Views.List = Backbone.View.extend({
458        template: null,
459
460        initialize: function (options) {
461            this.setElement(options.el);
462            this.listenTo(this.collection, "sync", this.render);
463            this.listenTo(this.collection, "reset", this.render);
464        },
465
466        render: function (collection) {
467            this.$el.empty();
468            if (!this.collection.isEmpty()) {
469                this.collection.each(this.addOne, this);
470            } else {
471                this.$el.append(
472                    '<p class="col-sm-12 no-results">Sorry, we don\'t have any locations within your current search distance.</p>'
473                );
474            }
475            return this;
476        },
477
478        addOne: function (model) {
479            const item = new WPCM.Views.ListItem({ model: model });
480            this.$el.append(item.render().el);
481            return this;
482        },
483    });
484
485    /**
486     * Renders each individual location in list
487     */
488    WPCM.Views.ListItem = Backbone.View.extend({
489        initialize: function (options) {
490            this.template = _.template($("#listItemTemplate").html());
491        },
492
493        render: function () {
494            this.setElement(this.template(this.model.toJSON()));
495            return this;
496        },
497    });
498
499    /**
500     * Renders out closest location widget
501     */
502    WPCM.Views.ClosestLocation = Backbone.View.extend({
503        template: null,
504
505        initialize: function (options) {
506            this.setElement(options.el);
507            this.template = _.template($("#closestLocationTemplate").html());
508            this.model.on("change:location", this.render, this);
509            if (!_.isEmpty(this.model.get("location"))) {
510                this.render();
511            }
512        },
513
514        render: function (location) {
515            if (!_.isEmpty(this.model.get("location"))) {
516                this.$el.html(this.template(this.model.get("location")));
517            }
518            return this;
519        },
520    });
521
522    /**
523     * Renders out closest location from zipcode
524     */
525    WPCM.Views.SearchByZip = Backbone.View.extend({
526        initialize: function (options) {
527            this.setElement(options.el);
528            if (!_.isEmpty(WPCM.action.zipcode)) {
529                this.$el.find(".wpcm-zip__form").trigger("submit");
530            }
531        },
532
533        events: {
534            "submit .wpcm-zip__form": "onSubmit",
535        },
536
537        onSubmit: function (event) {
538            event.preventDefault();
539            const zipcode = this.$el.find(".wpcm-zip__zipcode").val();
540            const distance = this.$el.find(".wpcm-zip__distance").val();
541            const imahuman = this.$el.find("#imahuman").val();
542            const division = this.$el.find(".wpcm-zip__division").val();
543
544            const data = {
545                zipcode: zipcode,
546                distance: distance,
547                imahuman: imahuman,
548                division: division,
549            };
550
551            this.collection.fetch({
552                reset: true,
553                data,
554            });
555
556           this.syncFiltersToQueryString(data);
557        },
558
559        syncFiltersToQueryString({
560            zipcode,
561            division
562        }) {
563            const url = new URL(window.location.href);
564            url.searchParams.set('zipcode', zipcode);
565            url.searchParams.set('division', division);
566            history.pushState(null, '', url);
567        }
568    });
569
570    WPCM.Views.FakeMarker = Backbone.View.extend({
571        initialize: function () {
572            this.template = _.template($("#markerTemplate").html());
573            this.listenTo(this.model, "change", this.render);
574        },
575
576        render: function () {
577            this.$el.html(this.template(this.model.get("location").toJSON()));
578            return this;
579        },
580    });
581
582    return WPCM;
583})(WPCM || {}, jQuery);

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.