/*jshint loopfunc: true*/
/*global google */
/*global Throbber */
/*global InfoBox */
/*global MarkerWithLabel */
/*global handleLocationError */
/*global trustedAssetsURL*/
var map, markerList, locations = [];
var infowindow;
var placeSearch, autocomplete;
var currentLatlng;
var requiredRegularSearch;
var componentForm = {
street_number: 'short_name',
route: 'long_name',
locality: 'long_name',
administrative_area_level_1: 'short_name',
country: 'long_name',
postal_code: 'short_name'
};
var locatorForm = document.getElementById('storelocator');
var brandDropdown = document.getElementById('brandselect');
var geoDetectButton = document.getElementById('currentLocationBtn');
var addressInput = document.getElementById('autocomplete');
var selectedOption = {
'brand' : 'all-brands'
};
var endpoints = {
'all' : '/webservices/store/storelist',
'brandAll' : '/webservices/store/manufacturer/storelist/'
};
var webserviceUrl = endpoints.all;
var resultsVisible = false;
var throbber = Throbber({
color: 'black',
padding: 30,
size: 32,
fade: 200,
}).appendTo(document.getElementById('address-form-group'));
function initialize() {
var defaultLat = 40.745812;
var defaultLng = -100.913895;
if (sessionStorageAvailable()) {
window.onbeforeunload = function () {
sessionStorage.setItem('Trusted.StoreLocator.Results', '');
sessionStorage.setItem('Trusted.StoreLocator.CurrentMarker', '');
};
}
brandDropdown.addEventListener('change', selectEndpoint);
geoDetectButton.addEventListener('click', StoreLocator.DetectCurrentLocation);
map = new google.maps.Map(document.getElementById('map'), {
center: { lat: defaultLat, lng: defaultLng },
zoom: 4,
scrollwheel: false,
});
google.maps.event.addDomListener(window, 'resize', function() {
StoreLocator.RefreshMap(true);
});
// Create the autocomplete object, restricting the search
// to geographical location types.
autocomplete = new google.maps.places.Autocomplete(
/** @type {HTMLInputElement} */(document.getElementById('autocomplete')),
{ types: ['geocode'] });
// When the user selects an address from the dropdown,
// populate the address fields in the form.
google.maps.event.addListener(autocomplete, 'place_changed', function() {
fillInAddress();
StoreLocator.LocationSearch(webserviceUrl);
});
$(locatorForm).bind('submit', function(e) {
e.preventDefault();
return false;
});
checkForParams();
}
function selectEndpoint() {
var selection = brandDropdown.value;
if (!selection.length || selection === 'all-brands') {
selectedOption.brand = 'all-brands';
webserviceUrl = endpoints.all;
} else {
webserviceUrl = endpoints.brandAll + selection;
}
if (resultsVisible) {
StoreLocator.LocationSearch(webserviceUrl);
}
}
// [START region_fillform]
function fillInAddress() {
// Get the place details from the autocomplete object.
var place = autocomplete.getPlace();
if (typeof place.geometry === 'undefined') {
StoreLocator.GetByRegularSearch(place.name);
} else {
currentLatlng = { 'lat': place.geometry.location.lat, 'lng': place.geometry.location.lng };
for (var component in componentForm) {
if (component !== undefined) {
document.getElementById(component).value = '';
document.getElementById(component).disabled = false;
}
}
// Get each component of the address from the place details
// and fill the corresponding field on the form.
for (var i = 0; i < place.address_components.length; i++) {
var addressType = place.address_components[i].types[0];
if (componentForm[addressType]) {
var val = place.address_components[i][componentForm[addressType]];
document.getElementById(addressType).value = val;
}
}
}
}
// [END region_fillform]
// [START region_geolocation]
// Bias the autocomplete object to the user's geographical location,
// as supplied by the browser's 'navigator.geolocation' object.
function geolocate() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var geolocation = new google.maps.LatLng(
position.coords.latitude, position.coords.longitude);
var circle = new google.maps.Circle({
center: geolocation,
radius: position.coords.accuracy
});
autocomplete.setBounds(circle.getBounds());
});
}
}
// [END region_geolocation]
function sessionStorageAvailable() {
try {
return 'sessionStorage' in window && window.sessionStorage !== null;
} catch(e) {
return false;
}
}
function checkForParams() {
var passThruBrand = $.query.get('brand').toString();
var passThruAddress = $.query.get('address').toString();
if (passThruBrand.length) {
$(brandDropdown).find('option').removeAttr('selected');
$(brandDropdown).find('option[value='+passThruBrand+']').attr('selected',true);
$(brandDropdown).trigger('change');
}
if (passThruAddress.length) {
$(addressInput).val(passThruAddress);
}
if (passThruBrand.length || passThruAddress.length) {
StoreLocator.GetByRegularSearch(passThruAddress);
}
}
var StoreLocator = {
LocationSearch: function (webserviceUrl, showLoaderBool) {
var textCriteria = '';
textCriteria = $('#autocomplete').val();
var addresstext = '';
if (!showLoaderBool) {
throbber.start();
}
if($('#street_number').val() !== '' || $('#route').val() !== '') {
addresstext = $('#street_number').val() + ',' + $('#route').val();
}
$.ajax({
type: 'GET',
url: webserviceUrl,
dataType: 'json',
success: function (response) {
var cleanResponse = [];
for (var result = 0; result < response.length; result++) {
var calculatedMeter = StoreLocator.GetDistance(currentLatlng, {
'lat': response[result].latitude,
'lng': response[result].longitude
});
var validPlaceCond = (
response[result].latitude !== null ||
response[result].longitude !== null
);
if (validPlaceCond) {
response[result].metersAway = calculatedMeter;
cleanResponse.push(response[result]);
}
}
var distSortData = cleanResponse.sort(function(a, b) {
return a.metersAway - b.metersAway;
});
if (sessionStorageAvailable()) {
sessionStorage.setItem('Trusted.StoreLocator.Results', JSON.stringify(distSortData));
}
var completeHtml = [];
for (var con = 0; con < cleanResponse.length; con++) {
completeHtml.push(StoreLocator.GenerateCard(cleanResponse[con], con));
}
var sortedHtmlString = '';
for (var res = 0; res < completeHtml.length; res++) {
sortedHtmlString += completeHtml[res].templateCard.replace(/@@/g,'
' + (res + 1) + '
');
}
if (cleanResponse.length > 0) {
$('#dvResult').html(sortedHtmlString);
StoreLocator.DrawMarker(distSortData);
$('.resultCard').click(function(e) {
$('.resultCard').removeClass('selected');
$(this).addClass('selected');
StoreLocator.OpenMarker($(this).attr('id') + '_' + 'details');
});
$('.resultCard').first().click();
}
else {
$('#dvResult').html(StoreLocator.NoResultTemplate());
}
StoreLocator.ShowList();
},
error: function (req, response) {
console.log('Error:' + response);
}
});
$('.google-map').height($('#dvResult').height());
$('#dvResult').height($('.google-map').height());
},
RefreshMap: function(refreshBool) {
if (sessionStorageAvailable() && refreshBool && resultsVisible) {
var lastMarkerOpen = JSON.parse(sessionStorage.getItem('Trusted.StoreLocator.CurrentMarker'));
map.setCenter(lastMarkerOpen.latLng);
}
google.maps.event.trigger(Map, 'resize');
},
SanitizeId: function(str) {
return String(str).replace(/&/g, '_').replace(//g, '_').replace(/"/g, '_');
},
GenerateCard: function (item, idx) {
//0 markerlabel
//1 miles
//2 assets/logo/Richard-Mille-logo.png
//3 Richard Mille Boutique
//4 9700 Collins Ave, Bal Harbour, FL 33154
var cardNum = idx + 1;
var calculatedmile = (item.metersAway / 1609.34).toFixed(2);
var addressLine = item.address1 !== null && item.address2 !== null ? (item.address1 + '
' + item.address2) : (item.address1 || item.address2);
var taddress = addressLine + '
' + item.city + ', ' + item.state + ' ' + item.zipCode;
var itemID = StoreLocator.SanitizeId(item.brandUniqueName+'_'+item.locationUniqueName);
var templateObj = {
'templateCard' : '' + '
' +
//Index when sorted
'@@' +
'
' + calculatedmile + ' mile(s)
' +
'
' +
'
' +
'
' + item.retailerName + '
' +
'
' + taddress + '' +
'
Store Details' +
'
' +
'
'
};
return templateObj;
},
CurrentMarker: function(id, latLng) {
if (sessionStorageAvailable() && id && latLng) {
var markerObj = {
'id': id,
'latLng': latLng
};
var currentMarkerString = JSON.stringify(markerObj);
sessionStorage.setItem('Trusted.StoreLocator.CurrentMarker', currentMarkerString);
}
},
OpenMarker :function(id){
for (var mc = 0; mc < markerList.length; mc++) {
if (markerList[mc].Id === id) {
var markerLatLng = new google.maps.LatLng(markerList[mc].position.lat(), markerList[mc].position.lng());
google.maps.event.trigger(markerList[mc], 'click');
StoreLocator.CurrentMarker(id, markerLatLng);
map.setZoom(11);
}
}
},
NoResultTemplate: function () {
return 'No results found. Please refine you search criteria.
';
},
ShowList: function(){
resultsVisible = true;
$('#dvResult').show();
$('.google-map').css('margin-left', $('#dvResult').width() + 'px');
$('#map').width(window.innerWidth - $('#dvResult').width());
throbber.stop();
},
HideList: function () {
$('#dvResult').hide();
$('.google-map').css('margin-left','');
},
DrawMarker: function (data) {
markerList = [];
locations = data;
infowindow = new InfoBox({
alignBottom: true,
disableAutoPan: false,
maxWidth: 450,
pixelOffset: new google.maps.Size(-220, -205),
zIndex: null,
boxStyle: {
// top arrow in the info window
opacity: 0.9,
width: '450px'
},
closeBoxMargin: '12px -36px 2px 2px',
closeBoxURL: 'https://www.google.com/intl/en_us/mapfiles/close.gif', //close button icon
infoBoxClearance: new google.maps.Size(10, 10)
});
var bounds = new google.maps.LatLngBounds();
var marker;
var image = {
url: trustedAssetsURL + 'assets/images/marker.png',
// This marker is 20 pixels wide by 32 pixels high.
size: new google.maps.Size(40, 42),
// The origin for this image is (0, 0).
origin: new google.maps.Point(0, 0),
// The anchor for this image is the base of the flagpole at (0, 32).
anchor: new google.maps.Point(0, 32)
};
for (var i = 0; i < data.length; i++) {
var retailer = data[i];
var retailerId = StoreLocator.SanitizeId(retailer.brandUniqueName+'_'+retailer.locationUniqueName+'_details');
var labelCharLength = (i+1).toString().length;
var labelAnchorPos = labelCharLength > 1 ? new google.maps.Point(-14, 28) : new google.maps.Point(-18, 28) ;
marker = new MarkerWithLabel({
position: { lat: retailer.latitude, lng: retailer.longitude },
map: map,
icon: image,
Id: retailerId,
labelContent: i+1,
labelAnchor: labelAnchorPos,
labelClass: 'labels', // the CSS class for the label
labelStyle: { opacity: 0.75 }
});
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function () {
if (typeof marker === 'object' && typeof marker.Id === 'string') {
var markerResultId = marker.Id.replace('_details', '');
$('.resultCard.selected').removeClass('selected');
$('#'+markerResultId).addClass('selected');
//TODO add ScrollTo behavior to this result
}
var cards = $('.card');
var isLatLngFn = typeof currentLatlng.lat === 'function' && typeof currentLatlng.lng === 'function';
var currentLat = isLatLngFn ? currentLatlng.lat() : currentLatlng.lat;
var currentLng = isLatLngFn ? currentLatlng.lng() : currentLatlng.lng;
var localItem = locations[i];
$('#' + localItem.Id).addClass('selected');
var localaddress = $('#street_number').val() + $('#route').val() + ', ' + $('#locality').val() + ', ' + $('#administrative_area_level_1').val() + $('#postal_code').val();
var drivinglink = 'https://maps.google.com/?saddr=' + currentLat + ',' + currentLng + '&daddr=' + localItem.latitude + ',' + localItem.longitude;
var addressLine = localItem.address1 !== null && localItem.address2 !== null ? (localItem.address1 + '
' + localItem.address2) : (localItem.address1 || localItem.address2);
var logoArea = localItem.brandLogo !== null ? '' : '';
var drivingDirections = 'Driving Directions';
var storePermalink = 'View Store Details';
infowindow.setContent('' +
logoArea + '
' + '
' + localItem.retailerName+ '
' +
' ' + addressLine + '
' + localItem.city + ', ' + localItem.state + ' ' + localItem.zipCode + '
' +
'
Store Details
' + storePermalink + '
' + drivingDirections + '');
infowindow.open(map, marker);
$('.gm-style-iw').next('div').remove();
//map.setCenter({ 'lat': localItem.latitude, 'lng': localItem.longitude });
map.setCenter(new google.maps.LatLng(localItem.latitude, localItem.longitude));
};
})(marker, i));
map.setOptions({ maxZoom: 18 });
bounds.extend(marker.position);
markerList.push(marker); map.setCenter();
}
},
DetectCurrentLocation: function () {
if (navigator.geolocation) {
throbber.start();
navigator.geolocation.getCurrentPosition(function (position) {
var pos = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
map.setCenter(pos);
currentLatlng = pos;
var geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
var placeholderUpdate = '';
geocoder.geocode({ 'latLng': latlng }, function (results, status) {
if (status === google.maps.GeocoderStatus.OK) {
if (results.length > 0) {
for (var component in componentForm) {
if (component) {
document.getElementById(component).value = '';
document.getElementById(component).disabled = false;
}
}
for (var i = 0; i < results[0].address_components.length; i++) {
var addressType = results[0].address_components[i].types[0];
if (componentForm[addressType]) {
var val = results[0].address_components[i][componentForm[addressType]];
document.getElementById(addressType).value = val;
placeholderUpdate += ' ' + val;
}
}
StoreLocator.LocationSearch(webserviceUrl, 'false');
requiredRegularSearch = false;
}
$(addressInput).attr('placeholder', placeholderUpdate.trim());
}
});
}, function () {
handleLocationError(true, infowindow, map.getCenter());
});
} else {
// Browser doesn't support Geolocation
handleLocationError(false, infowindow, map.getCenter());
}
},
Rad: function (x) {
return x * Math.PI / 180;
},
GetDistance : function(p1, p2) {
var isPlace = typeof p1.lat === 'function' && typeof p1.lng === 'function';
var lat1 = isPlace ? p1.lat() : p1.lat;
var lng1 = isPlace ? p1.lng() : p1.lng;
var R = 6378137; // Earths mean radius in meter
var dLat = StoreLocator.Rad(p2.lat - lat1);
var dLong = StoreLocator.Rad(p2.lng - lng1);
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(StoreLocator.Rad(lat1)) * Math.cos(StoreLocator.Rad(p2.lat)) *
Math.sin(dLong / 2) * Math.sin(dLong / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c;
return d; // returns the distance in meter
},
GetByRegularSearch: function (address) {
var geocoder = new google.maps.Geocoder();
geocoder.geocode({ 'address': address }, function (results, status) {
if (status === google.maps.GeocoderStatus.OK) {
if (results.length > 0) {
var pos = {
lat: results[0].geometry.location.lat(),
lng: results[0].geometry.location.lng()
};
map.setCenter(pos);
currentLatlng = pos;
for (var component in componentForm) {
if (component) {
document.getElementById(component).value = '';
document.getElementById(component).disabled = false;
}
}
for (var i = 0; i < results[0].address_components.length; i++) {
var addressType = results[0].address_components[i].types[0];
if (componentForm[addressType]) {
var val = results[0].address_components[i][componentForm[addressType]];
document.getElementById(addressType).value = val;
}
}
StoreLocator.LocationSearch(webserviceUrl);
}
} else {
console.log('Geocode was not successful for the following reason: ' + status);
}
});
}
};
$(document).ready(function(){
initialize();
$(addressInput).on({
'keyup': function(evt) {
if (evt.which === 13) {
StoreLocator.LocationSearch(webserviceUrl);
}
else {
requiredRegularSearch = true;
}
if ($('#autocomplete').val() === '') {
$('.fa-times-circle').hide();
} else {
$('.fa-times-circle').show();
}
},
'paste': function(evt) {
if (evt.which === 13) {
StoreLocator.LocationSearch(webserviceUrl);
}
else {
requiredRegularSearch = true;
}
if ($('#autocomplete').val() === '') {
$('.fa-times-circle').hide();
} else {
$('.fa-times-circle').show();
}
}
});
$('.fa-times-circle').click(function () {
$('.fa-times-circle').hide();
$('#autocomplete').val('');
});
$('.map-list').show();
$('.retailer-list').hide();
});