PageSourceSearch

https://diverite.com/wp-content/plugins/dive-rite-dealer-locator-4/assets/locator.js

js diverite.com collected 2026-10-02 07:00:30 UTC 6,472 bytes, 186 lines download raw bytes

1
2let map, markers = [], userLocation = null;
3
4function initMap() {
5    const center = { lat: 39.8283, lng: -98.5795 };
6    map = new google.maps.Map(document.getElementById("map"), {
7        zoom: 4,
8        center,
9    });
10
11    initSearchBar();
12    populateDropdowns();
13    renderMarkers(DiveRiteData.stores);
14}
15
16function initSearchBar() {
17    const input = document.createElement("input");
18    input.id = "location-search";
19    input.placeholder = "Enter a location";
20    input.className = "search-box";
21    document.querySelector(".filter-bar").prepend(input);
22
23    const radius = document.createElement("select");
24    radius.id = "search-radius";
25    [5, 10, 25, 50, 100].forEach(miles => {
26        const opt = document.createElement("option");
27        opt.value = miles;
28        opt.textContent = `${miles} mi`;
29        radius.appendChild(opt);
30    });
31    document.querySelector(".filter-bar").prepend(radius);
32
33    const autocomplete = new google.maps.places.Autocomplete(input);
34    autocomplete.addListener("place_changed", () => {
35        const place = autocomplete.getPlace();
36        if (place.geometry) {
37            userLocation = place.geometry.location;
38            updateMap();
39        }
40    });
41}
42
43function populateDropdowns() {
44    const countrySel = document.getElementById("filter-country");
45    const stateSel = document.getElementById("filter-state");
46    const citySel = document.getElementById("filter-city");
47
48    const countries = [...new Set(DiveRiteData.stores.map(s => s.country))].sort((a, b) => {
49        if (a === "United States") return -1;
50        if (b === "United States") return 1;
51        return a.localeCompare(b);
52    });
53
54    countries.forEach(c => {
55        const opt = document.createElement("option");
56        opt.value = c;
57        opt.textContent = c;
58        countrySel.appendChild(opt);
59    });
60
61    countrySel.addEventListener("change", () => {
62        const country = countrySel.value;
63        const states = [...new Set(DiveRiteData.stores.filter(s => s.country === country).map(s => s.state))].sort();
64        stateSel.innerHTML = "<option value=''>All States</option>";
65        states.forEach(st => {
66            const opt = document.createElement("option");
67            opt.value = st;
68            opt.textContent = st;
69            stateSel.appendChild(opt);
70        });
71        citySel.innerHTML = "<option value=''>All Cities</option>";
72        updateMap();
73    });
74
75    stateSel.addEventListener("change", () => {
76        const country = countrySel.value;
77        const state = stateSel.value;
78        const cities = [...new Set(DiveRiteData.stores.filter(s => s.country === country && s.state === state).map(s => s.city))].sort();
79        citySel.innerHTML = "<option value=''>All Cities</option>";
80        cities.forEach(ct => {
81            const opt = document.createElement("option");
82            opt.value = ct;
83            opt.textContent = ct;
84            citySel.appendChild(opt);
85        });
86        updateMap();
87    });
88
89    citySel.addEventListener("change", updateMap);
90}
91
92function updateMap() {
93    const country = document.getElementById("filter-country").value;
94    const state = document.getElementById("filter-state").value;
95    const city = document.getElementById("filter-city").value;
96    const radius = parseFloat(document.getElementById("search-radius").value || 100);
97
98    const filtered = DiveRiteData.stores.filter(s => {
99        const matchCountry = !country || s.country === country;
100        const matchState = !state || s.state === state;
101        const matchCity = !city || s.city === city;
102        const matchRadius = !userLocation || haversineDistance(userLocation.lat(), userLocation.lng(), s.lat, s.lng) <= radius;
103        return matchCountry && matchState && matchCity && matchRadius;
104    });
105
106    renderMarkers(filtered);
107}
108
109function renderMarkers(stores) {
110    markers.forEach(m => m.setMap(null));
111    markers = [];
112
113    const bounds = new google.maps.LatLngBounds();
114    const list = document.getElementById("store-list");
115    list.innerHTML = "";
116
117    stores.forEach(store => {
118
119           
120        const pos = { lat: parseFloat(store.lat), lng: parseFloat(store.lng) };
121         console.log("Marker Position:", pos);
122        const marker = new google.maps.Marker({
123            position: pos,
124            map,
125            title: store.title ? store.title.trim() : "Dealer",
126        });
127        markers.push(marker);
128        bounds.extend(pos);
129
130        const infoWindow = new google.maps.InfoWindow({
131            content: `
132                <div style="min-width:200px">
133                    <strong>${store.title || 'Dealer'}</strong><br>
134                    ${store.street}, ${store.city}, ${store.state} ${store.postal_code}<br>
135                    <a href="tel:${store.phone}">${store.phone}</a><br>
136                    <a href="https://maps.google.com/?q=${store.lat},${store.lng}" target="_blank">Directions</a>
137                </div>
138            `
139        });
140        marker.addListener("click", () => {
141            infoWindow.open(map, marker);
142        });
143
144        const item = document.createElement("div");
145        item.className = "store-item";
146        item.innerHTML = `
147            <strong>${store.title || 'Dealer'}</strong><br>
148            ${store.street}, ${store.city}, ${store.state} ${store.postal_code}<br>
149            <a href="tel:${store.phone}">${store.phone}</a><br>
150            <a href="https://maps.google.com/?q=${store.lat},${store.lng}" target="_blank">Directions</a>
151        `;
152        list.appendChild(item);
153    });
154
155    if (stores.length > 0) {
156        map.fitBounds(bounds);
157    }
158}
159
160function haversineDistance(lat1, lon1, lat2, lon2) {
161    function toRad(x) { return x * Math.PI / 180; }
162    const R = 3958.8; // Miles
163    const dLat = toRad(lat2 - lat1);
164    const dLon = toRad(lon2 - lon1);
165    const a = Math.sin(dLat / 2) ** 2 +
166              Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) *
167              Math.sin(dLon / 2) ** 2;
168    return R * (2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)));
169}
170
171
172window.addEventListener("load", () => {
173    initMap();
174    if (navigator.geolocation) {
175        navigator.geolocation.getCurrentPosition(
176            (pos) => {
177                userLocation = new google.maps.LatLng(pos.coords.latitude, pos.coords.longitude);
178                updateMap();
179            },
180            (err) => {
181                console.warn("Geolocation failed or blocked:", err.message);
182            }
183        );
184    }
185});
186

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.