Skip to content

Instantly share code, notes, and snippets.

@jonathanread
Created April 30, 2018 20:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jonathanread/a8eb508e9b0da22162660d55fdf69486 to your computer and use it in GitHub Desktop.
Save jonathanread/a8eb508e9b0da22162660d55fdf69486 to your computer and use it in GitHub Desktop.
Sitefinity Example of pin good map using odata service
<style>
#content h1.storeName {
font-size: 24px;
margin: 0 0 5px 0;
padding: 0;
line-height: 1em
}
#content h1.storeName:hover {
cursor: pointer;
}
.location img {
float: left
}
.gm-style-iw .location address {
float: right
}
#stores-list {
height: 320px;
margin-top: 15px;
overflow-y: scroll;
clear: both;
float: none
}
@media (min-width: 768px) {
#stores-list {
height: 515px;
}
}
#stores-list address {
line-height: 1em;
}
#stores-list .location {
border-bottom: solid 1px #ccc;
margin: 10px 0;
padding: 5px 0;
}
#searchBtn {
background: #00b4c9;
color: #fff;
border: 0;
font-family: "Open Sans";
border-radius: 2px;
box-shadow: 0 2px 4px #ccc;
transition: all .3s ease-out;
padding: 10px 25px;
font-size: 16px;
text-transform: none;
font-weight: 400;
float: right
}
#clearBtn {
background: #ff2020;
color: #fff;
border: 0;
font-family: "Open Sans";
border-radius: 2px;
box-shadow: 0 2px 4px #ccc;
transition: all .3s ease-out;
padding: 10px 25px;
font-size: 16px;
text-transform: none;
font-weight: 400;
}
.infoWindowLink {
color: blue;
margin: 10px 0;
display: block
}
#userInputs {
margin: 0 0 10px 0;
}
#store-locator-wrapper button:hover {
cursor: pointer
}
</style>
<script type="text/javascript">
var map;
var markers = [];
var apiUrl = '/api/default/stores/';
var filteredStores = [];
var storesLatLng;
var us_center = { lat: 39.5, lng: -98.35 };
function initMap() {
$.ajax(apiUrl).done(function (data) {
allStores = data.value;
map = new google.maps.Map(
document.getElementById('map_canvas_all_stores'),
{
zoom: 4,
center: us_center,
gestureHandling: 'greedy'
});
parseStores(allStores);
});
}
function clearSearch(e) {
e.preventDefault();
$('#userStoreSearch').val('');
$('#distanceFromUser').val('8045');
parseStores(allStores, true);
return false;
}
function parseStores(stores, clearList = false) {
if (stores) {
storesLatLng = stores.map(function (store) {
if (store.Address) {
return { lat: store.Address.Latitude, lng: store.Address.Longitude };
}
});
var listElement = document.getElementById('stores-list');
clearStoreList(clearList, listElement);
addMarkersToMap(stores, listElement);
centerMap();
}
}
function clearStoreList(clear, listElement) {
if (clear) {
listElement.innerHTML = '';
clearMarkers();
}
}
function addMarkersToMap(stores, listElement) {
for (var i = 0; i < stores.length; i++) {
var store = stores[i];
addMarker(store);
addToLocationList(store, i, listElement);
}
}
function addMarker(store) {
var position;
if (store.Address) {
position = { lat: store.Address.Latitude, lng: store.Address.Longitude };
}
if (position) {
var marker = new google.maps.Marker({
position: position,
map: map,
title: store.Title
});
markers.push(marker);
var infoWindowContent = createInfoWindowContent(store, marker);
}
}
function clearMarkers() {
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(null);
}
markers = [];
}
function centerMap() {
var latlngbounds = new google.maps.LatLngBounds();
for (var i = 0; i < storesLatLng.length; i++) {
latlngbounds.extend(storesLatLng[i]);
}
map.setCenter(latlngbounds.getCenter());
map.fitBounds(latlngbounds);
}
function addToLocationList(store, index, list) {
if (list) {
list.innerHTML += "<div class='location'><address><h1 class='storeName' onclick='showInfoWindow(" + index + ")'>" + store.Title + "</h1>"
+ (store.Address ? store.Address.Street + "<br/>" +
store.Address.City + ", " + store.Address.StateCode + " " + store.Address.Zip : '') +
"</address><div>" + (store.distance ? "<strong>Distance: </strong>" + store.distance : '') + "</div></div>";
}
}
var infoWindow = null;
function createInfoWindowContent(store, marker) {
var content = (store.ImageUrl ? "<div class='location'>" + "<img height='75px' style='margin-right:10px' src='" + store.ImageUrl + "' />" : '') +
"<address style='padding-right:10px'><h1 class='storeName'>" + store.Title + "</h1>" +
(store.Address ? store.Address.Street + "<br />" +
store.Address.City + ", " + store.Address.StateCode + " " + store.Address.Zip : '') +
"</address><div>" + (store.distance ? "<strong>Distance: </strong>" + store.distance : '') +
"</div><a class='infoWindowLink' href='" + store.Url + "'>Details</a></div>";
marker.addListener('click', function () {
if (infoWindow)
infoWindow.close();
infoWindow = new google.maps.InfoWindow({ content: content });
infoWindow.open(map, marker);
});
}
function showInfoWindow(id) {
google.maps.event.trigger(markers[id], 'click');
$('html, body').animate({ scrollTop: $('#map_canvas_all_stores').offset().top });
}
function findStores(e) {
e.preventDefault();
var distance = $('#distanceFromUser').val();
if (distance) {
var userLocation = $('#userStoreSearch').val();
if (userLocation) {
filteredStores = [];
var storesLatLng = allStores.map(function (store) {
return { lat: store.Address.Latitude, lng: store.Address.Longitude };
});
if (storesLatLng.length > 25) {
var index = Math.ceil(storesLatLng.length / 25);
for (var i = 0; i <= index; i++) {
var stores = storesLatLng.slice(i * 25, 25);
getDistances(stores, userLocation);
}
}
}
}
return false;
}
function getDistances(destinations, userLocation) {
var service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix({
origins: [userLocation],
destinations: destinations,
travelMode: 'DRIVING',
unitSystem: google.maps.UnitSystem.IMPERIAL
}, distanceMatrixResponse);
}
function distanceMatrixResponse(response, status) {
if (status === 'OK') {
var origins = response.originAddresses;
var destinations = response.destinationAddresses;
var userSearchDistance = parseInt($('#distanceFromUser').val());
for (var i = 0; i < origins.length; i++) {
var results = response.rows[i].elements;
for (var j = 0; j < results.length; j++) {
var element = results[j];
if (element.status === 'OK') {
if (element.distance.value <= userSearchDistance) {
var store = allStores[j];
if (store) {
store.distance = element.distance.text;
filteredStores.push(store);
}
}
}
}
}
if (filteredStores.length > 0) {
parseStores(filteredStores, true);
} else {
parseStores([{ Title: 'No stores found.' }], true);
}
} else { console.log(response); }
}
</script>
<div id="store-locator-wrapper">
<div id="userInputs">
<select id="distanceFromUser" onchange="findStores(event)">
<option value="8045" selected>5 Miles</option>
<option value="40234">25 Miles</option>
<option value="80467">50 Miles</option>
</select>
&nbsp; From: &nbsp;
<input id="userStoreSearch" type="text" placeholder="Zip or City, State" />
</div>
<button id="clearBtn" onclick="clearSearch(event)">Clear</button>
<button id="searchBtn" type="button" onclick="findStores(event)">Find Stores</button>
<div id="stores-list">
</div>
</div>
<script async defer src='https://maps.googleapis.com/maps/api/js?key=<%= apikey %>&callback=initMap'></script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment