Last active
August 29, 2015 14:22
-
-
Save niekvandepas/a69ee05e38f4e867b31a to your computer and use it in GitHub Desktop.
McDonalds storefinder
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function() { | |
alert('testing') | |
window.mcdStoreLocator = {}; | |
// Simple JavaScript Templating | |
// John Resig - http://ejohn.org/ - MIT Licensed | |
(function(){ | |
var cache = {}; | |
mcdStoreLocator.createMicroTemplate = function createMicroTemplate(label, element) { | |
if (cache[label]) return cache[label]; | |
var str = element.textContent; | |
var returnFunc = new Function("obj", | |
"var p=[],print=function(){p.push.apply(p,arguments);};" + | |
// Introduce the data as local variables using with(){} | |
"with(obj){p.push('" + | |
// Convert the template into pure JavaScript | |
str | |
.replace(/[\r\t\n]/g, " ") | |
.split("<%").join("\t") | |
.replace(/((^|%>)[^\t]*)'/g, "$1\r") | |
.replace(/\t=(.*?)%>/g, "',$1,'") | |
.split("\t").join("');") | |
.split("%>").join("p.push('") | |
.split("\r").join("\\'") | |
+ "');}return p.join('');"); | |
cache[label] = returnFunc; | |
return cache[label]; | |
}; | |
})(); | |
mcdStoreLocator.StoreLocator = function() { | |
this.templates = {}; | |
this.locationData = []; | |
this.currentFilters = []; | |
this.activeMarkers = []; | |
this.youAreHereMarker = null; | |
this.isSmallWidth = false; | |
this.isLoading = false; | |
this.supportGeolocation = false; | |
this.mapMarkerIcons = { | |
youAreHere: { | |
url: mcdStoreLocatorSettings.assetPath + "/img/[email protected]", | |
scaledSize: new google.maps.Size(82 / 2, 92 / 2), | |
origin: new google.maps.Point(0,0), | |
anchor: new google.maps.Point(39 / 2, 82 / 2) | |
}, | |
location: { | |
url: mcdStoreLocatorSettings.assetPath + "/img/[email protected]", | |
scaledSize: new google.maps.Size(60 / 2, 86 / 2), | |
origin: new google.maps.Point(0,0), | |
anchor: new google.maps.Point(30 / 2, 82 / 2) | |
}, | |
} | |
this.divResults = document.querySelector(".storelocator__results"); | |
this.divResultsList = document.querySelector(".storelocator__results-list"); | |
this.divViews = document.querySelector(".storelocator__views"); | |
this.divSingleViewContainer = document.querySelector(".storelocator__single-view-container"); | |
this.divNoResults = $(".storelocator__no-results"); | |
this.divAcceptLocation = $(".storelocator__accept-location"); | |
this.filterButtons = $(".storelocator__filter"); | |
this.iconResetFilters = $(".storelocator__filter[data-filter=none]").find(".storelocator__filtericon"); | |
this.divFiltersListContainer = $(".storelocator__filters-list-container"); | |
this.ulFiltersList = $(".storelocator__filters-list"); | |
this.btnFilterArrowUp = $(".storelocator__filters-arrow--up"); | |
this.btnFilterArrowDown = $(".storelocator__filters-arrow--down"); | |
this.searchField = $(".storelocator__input-location"); | |
this.btnCurrentPosition = $(".storelocator__btn-current-position"); | |
this.searchForm = $(".storelocator__search-form"); | |
this.btnBack = document.querySelector(".storelocator__content-title--back-button"); | |
this.init(); | |
} | |
mcdStoreLocator.StoreLocator.prototype.init = function() { | |
this.onResize(); | |
this.initMap(); | |
this.initTemplates(); | |
this.initEvents(); | |
this.initStartValues(); | |
if (this.searchField.val() == "") { | |
this.autoLocateAndGetCloseRestaurants(); | |
}else{ | |
this.searchForm.trigger("submit"); | |
} | |
} | |
mcdStoreLocator.StoreLocator.prototype.initMap = function() { | |
this.map = new google.maps.Map(document.querySelector(".storelocator__map"), { | |
zoom: 7, | |
center: new google.maps.LatLng(52.03366734651407, 5.429455423242189), | |
mapTypeId: google.maps.MapTypeId.ROADMAP, | |
draggable: !this.isSmallWidth, | |
streetViewControl: false, | |
disableDefaultUI: true, | |
zoomControl: true, | |
zoomControlOptions: { | |
position: google.maps.ControlPosition.TOP_RIGHT, | |
style: google.maps.ZoomControlStyle.SMALL | |
}, | |
panControl: !this.isSmallWidth, | |
panControlOptions: { | |
position: google.maps.ControlPosition.TOP_RIGHT | |
} | |
}); | |
this.geocoder = new google.maps.Geocoder(); | |
} | |
mcdStoreLocator.StoreLocator.prototype.initTemplates = function() { | |
var _this = this; | |
$("script[store-locator-micro-template]").each(function(i, el) { | |
var templateName = $(el).attr("store-locator-micro-template"); | |
_this.templates[templateName] = mcdStoreLocator.createMicroTemplate(templateName, el); | |
}); | |
} | |
mcdStoreLocator.StoreLocator.prototype.initEvents = function() { | |
var _this = this; | |
this.btnBack.addEventListener("click", function() { | |
_this.toggleSingleView(false, null, true); | |
}); | |
this.searchForm.bind("submit", function(event) { | |
event.preventDefault(); | |
_this.searchForLocation(_this.searchField.val(), function(data) { | |
var location = data[0].geometry.location; | |
_this.getLocations(location.lat(), location.lng(), 10); | |
}); | |
}); | |
this.searchField.bind("click", function(event) { | |
_this.searchField.select(); | |
}); | |
this.btnFilterArrowUp.bind("click", function(event) { | |
_this.divFiltersListContainer.animate({ | |
scrollTop: 0 | |
}); | |
_this.btnFilterArrowUp.hide(); | |
_this.btnFilterArrowDown.show(); | |
}); | |
this.btnFilterArrowDown.bind("click", function(event) { | |
_this.divFiltersListContainer.animate({ | |
scrollTop: _this.ulFiltersList.height() - _this.divFiltersListContainer.height() | |
}); | |
_this.btnFilterArrowUp.show(); | |
_this.btnFilterArrowDown.hide(); | |
}); | |
this.btnCurrentPosition.bind("click", function(event) { | |
if (_this.supportGeolocation) _this.autoLocateAndGetCloseRestaurants(); | |
}); | |
this.filterButtons.each(function(i, el) { | |
var tar = $(el); | |
var iconTarget = tar.find(".storelocator__filtericon"); | |
var filter = tar.attr("data-filter"); | |
// Reset filter-button | |
if (filter == "none") { | |
tar.bind("click", function() { | |
_this.resetFilters(); | |
}); | |
}else{ | |
// All filters | |
tar.bind("click", function() { | |
iconTarget.toggleClass("active"); | |
if (iconTarget.is(".active")) { | |
_this.toggleFilter(filter, true); | |
}else{ | |
_this.toggleFilter(filter, false); | |
} | |
_this.applyFilters(_this.currentFilters); | |
}) | |
} | |
}); | |
$(window).bind("resize", function() { | |
_this.onResize(); | |
}); | |
} | |
mcdStoreLocator.StoreLocator.prototype.initStartValues = function() { | |
if (mcdStoreLocatorSettings.filters) { | |
var filters = mcdStoreLocatorSettings.filters.split(","); | |
for (var i = 0; i < filters.length; i++) { | |
$(".storelocator__filter[data-filter="+filters[i]+"]").click(); | |
} | |
} | |
} | |
mcdStoreLocator.StoreLocator.prototype.onResize = function() { | |
var _this = this; | |
if (window.innerWidth < 768) { | |
this.isSmallWidth = true; | |
}else{ | |
this.isSmallWidth = false; | |
} | |
} | |
mcdStoreLocator.StoreLocator.prototype.toggleLoading = function(flag) { | |
var _this = this; | |
this.isLoading = flag; | |
if (flag) { | |
$(_this.divResults).toggleClass("loading", true); | |
_this.searchField.attr("disabled", true); | |
}else{ | |
$(_this.divResults).toggleClass("loading", false); | |
_this.searchField.attr("disabled", false); | |
} | |
} | |
mcdStoreLocator.StoreLocator.prototype.autoLocateAndGetCloseRestaurants = function() { | |
var _this = this; | |
_this.resetResults(); | |
_this.searchField.val("Even wachten a.u.b."); | |
//_this.toggleLoading(true); | |
if (navigator.geolocation) { | |
_this.divAcceptLocation.show(); | |
_this.supportGeolocation = true; | |
navigator.geolocation.getCurrentPosition(function(position) { | |
_this.divAcceptLocation.hide(); | |
var latlng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude); | |
_this.setCenterAndZoom(latlng, 12); | |
_this.searchForLocation(latlng, function(data) { | |
var location = data[0].geometry.location; | |
if (!_this.youAreHereMarker) { | |
_this.youAreHereMarker = new google.maps.Marker({ | |
position: new google.maps.LatLng(location.lat(), location.lng()), | |
animation: google.maps.Animation.DROP, | |
icon: _this.mapMarkerIcons.youAreHere, | |
map: _this.map | |
}); | |
} | |
_this.getLocations(location.lat(), location.lng(), 10); | |
}); | |
}, function(error) { | |
_this.divAcceptLocation.hide(); | |
_this.supportGeolocation = false; | |
console.log(error); | |
_this.searchField.val(""); | |
_this.toggleLoading(false); | |
_this.btnCurrentPosition.addClass("not-available"); | |
}); | |
}else{ | |
_this.supportGeolocation = false; | |
_this.searchField.val(""); | |
_this.toggleLoading(false); | |
_this.btnCurrentPosition.addClass("not-available"); | |
} | |
} | |
mcdStoreLocator.StoreLocator.prototype.callAPI = function(action, data, callback) { | |
data.action = action; | |
data.storelocator_v2 = true; | |
$.ajax({ | |
url: window.location.href, | |
type: "post", | |
dataType: "json", | |
data: data, | |
success: alert('testing at line 282'), | |
error: function() { | |
throw("Error in api"); | |
} | |
}); | |
} | |
mcdStoreLocator.StoreLocator.prototype.resetResults = function() { | |
var _this = this; | |
_this.locationData = []; | |
_this.divResultsList.innerHTML = ""; | |
this.divNoResults.hide(); | |
this.clearMarkers(); | |
this.toggleSingleView(false); | |
} | |
mcdStoreLocator.StoreLocator.prototype.clearMarkers = function() { | |
for (var i = 0; i < this.activeMarkers.length; i++) { | |
var marker = this.activeMarkers[i]; | |
marker.setMap(null); | |
marker = null; | |
} | |
this.activeMarkers = []; | |
} | |
mcdStoreLocator.StoreLocator.prototype.getLocations = function(lat, lon, distance) { | |
var _this = this; | |
_this.resetResults(); | |
_this.toggleLoading(true); | |
_this.callAPI("getLocations", { | |
lat: lat, | |
lon: lon, | |
distance: distance | |
}, function(data) { | |
_this.locationData = data; | |
_this.processLocationData(); | |
_this.toggleLoading(false); | |
_this.setCenterAndZoom(new google.maps.LatLng(lat, lon), 12); | |
_this.applyFilters(_this.currentFilters); | |
}); | |
} | |
mcdStoreLocator.StoreLocator.prototype.processLocationData = function() { | |
var _this = this; | |
for (var i = 0; i < _this.locationData.length; i++) { | |
var location = _this.locationData[i]; | |
location.openStatus = _this.calculateOpenStatus(location.openTimes); | |
if (location.openTimesMcDrive) location.mcDriveOpenStatus = _this.calculateOpenStatus(location.openTimesMcDrive); | |
// add open status to features for filtering | |
if (location.openStatus.isOpen || (location.mcDriveOpenStatus && location.mcDriveOpenStatus.isOpen)) location.features.push("open"); | |
} | |
} | |
mcdStoreLocator.StoreLocator.prototype.toggleSingleView = function(flag, location, scrollFlag) { | |
var _this = this; | |
if (flag) { | |
$(_this.divViews).css({ | |
transform: "translate(-100%, 0)", | |
webkitTransform: "translate(-100%, 0)" | |
}); | |
location.currentLocation = _this.searchField.val(); | |
var newSingleLocationViewElement = _this.templates.singleLocationView(location); | |
_this.divSingleViewContainer.innerHTML = newSingleLocationViewElement; | |
if (_this.isSmallWidth) { | |
_this.rememberScrollPosition = document.body.scrollTop; | |
$(_this.divViews).css({ | |
height: _this.divSingleViewContainer.offsetHeight + 50 | |
}); | |
$("html, body").animate({ | |
scrollTop: $(".storelocator__map").offset().top | |
}, { | |
duration: 500 | |
}) | |
} | |
}else{ | |
$(_this.divViews).css({ | |
transform: "translate(0, 0)", | |
webkitTransform: "translate(0, 0)" | |
}); | |
if (_this.isSmallWidth) { | |
$(_this.divViews).css({ | |
height: _this.divResultsList.offsetHeight ? _this.divResultsList.offsetHeight + 35 : 400 | |
}); | |
if (scrollFlag) { | |
$("html, body").animate({ | |
scrollTop: _this.rememberScrollPosition | |
}, { | |
duration: 1000 | |
}); | |
} | |
} | |
} | |
} | |
mcdStoreLocator.StoreLocator.prototype.populateLocationList = function(data) { | |
var _this = this; | |
_this.divResultsList.innerHTML = ""; | |
for (var i = 0; i < data.length; i++) { | |
var location = data[i]; | |
_this.addListItem(location); | |
} | |
if (data.length < 1) { | |
this.divNoResults.show(); | |
}else{ | |
this.divNoResults.hide(); | |
} | |
if (_this.isSmallWidth) { | |
$(_this.divViews).css({ | |
height: _this.divResultsList.offsetHeight ? _this.divResultsList.offsetHeight + 35 : 400 | |
}); | |
} | |
} | |
mcdStoreLocator.StoreLocator.prototype.resetFilters = function() { | |
this.filterButtons.find(".storelocator__filtericon").toggleClass("active", false); | |
this.currentFilters = []; | |
this.applyFilters(this.currentFilters); | |
} | |
mcdStoreLocator.StoreLocator.prototype.toggleFilter = function(filter, flag) { | |
var filterIndex = this.currentFilters.indexOf(filter); | |
if (flag) { | |
if (filterIndex == -1) this.currentFilters.push(filter); | |
}else{ | |
if (filterIndex !== -1) this.currentFilters.splice(filterIndex, 1); | |
} | |
if (this.currentFilters.length > 0) { | |
this.iconResetFilters.toggleClass("active", true); | |
}else{ | |
this.iconResetFilters.toggleClass("active", false); | |
} | |
} | |
mcdStoreLocator.StoreLocator.prototype.applyFilters = function(filters) { | |
if (this.isLoading) return false; | |
var filtered = this.getFilteredLocationsFromCurrentLocationData(filters); | |
this.toggleSingleView(false); | |
this.clearMarkers(); | |
this.populateLocationList(filtered); | |
} | |
mcdStoreLocator.StoreLocator.prototype.getFilteredLocationsFromCurrentLocationData = function(filters) { | |
_this = this; | |
var filteredData = []; | |
function applyFiltersForLocation(location, filters) { | |
for (var i = 0; i < filters.length; i++) { | |
var feature = filters[i]; | |
if (location.features.indexOf(feature) == -1) return false; | |
} | |
return true; | |
} | |
for (var i = 0; i < _this.locationData.length; i++) { | |
var location = _this.locationData[i]; | |
if (applyFiltersForLocation(location, filters)) filteredData.push(location); | |
} | |
return filteredData; | |
} | |
mcdStoreLocator.StoreLocator.prototype.calculateOpenStatus = function(openTimes, forceCurrentString) { | |
var now = new Date(); | |
var currentWeekday = (now.getDay() == 0 ? 6 : now.getDay() - 1); // transformed so 0 is monday | |
var previousWeekday = currentWeekday == 0 ? 6 : currentWeekday - 1; // previous weekday, if monday then sunday | |
var currentTimeString = forceCurrentString || (now.getHours().toString().length < 2 ? "0" + now.getHours() : now.getHours()) + ":" + (now.getMinutes().toString().length < 2 ? "0" + now.getMinutes() : now.getMinutes()); | |
var yesterdayOpeningHours = openTimes[previousWeekday]; | |
var todayOpeningHours = openTimes[currentWeekday]; | |
// Check if is still open from last day | |
if (todayOpeningHours.open > yesterdayOpeningHours.close && yesterdayOpeningHours.close > currentTimeString) { | |
return { | |
activeDay: previousWeekday, | |
isOpen: true | |
} | |
} | |
// Check if open today | |
var todayCloseHour = todayOpeningHours.close; | |
if (todayCloseHour < todayOpeningHours.open) { | |
var closeArray = todayCloseHour.split(":"); | |
todayCloseHour = (24 + closeArray[0]) + ":" + (closeArray[1].toString().length < 2 ? "0" + closeArray[1] : closeArray[1]); | |
} | |
if (todayOpeningHours.open <= currentTimeString && todayCloseHour >= currentTimeString) { | |
return { | |
activeDay: currentWeekday, | |
isOpen: true | |
} | |
} | |
return { | |
activeDay: currentWeekday, | |
isOpen: false | |
} | |
} | |
mcdStoreLocator.StoreLocator.prototype.searchForLocation = function(locationInput, callback) { | |
var _this = this; | |
function gotLocation(data, status) { | |
if (status == google.maps.GeocoderStatus.OK) { | |
_this.setCenterAndZoom(new google.maps.LatLng(data[0].geometry.location.lat(), data[0].geometry.location.lng()), 12); | |
_this.searchField.val(data[0].formatted_address); | |
callback(data); | |
} | |
} | |
if (typeof locationInput == "string") { | |
this.geocoder.geocode({ | |
address: locationInput, | |
country: "NL", | |
region: "NL" | |
}, gotLocation); | |
}else{ | |
this.geocoder.geocode({ | |
latLng: locationInput, | |
country: "NL", | |
region: "NL" | |
}, gotLocation); | |
} | |
} | |
mcdStoreLocator.StoreLocator.prototype.setCenterAndZoom = function(center, zoom) { | |
this.map.setCenter(center); | |
if (zoom != undefined) this.map.setZoom(zoom); | |
var ww = window.innerWidth; | |
if (ww > 768){ | |
this.map.panBy(-180, 0); | |
} | |
} | |
mcdStoreLocator.StoreLocator.prototype.addListItem = function(location) { | |
var _this = this; | |
var locationElement = $(this.templates.locationListItem(location).trim()); | |
var locationMarker = new google.maps.Marker({ | |
position: new google.maps.LatLng(location.lat, location.lon), | |
map: _this.map, | |
icon: _this.mapMarkerIcons.location | |
//animation: google.maps.Animation.DROP | |
}); | |
google.maps.event.addListener(locationMarker, "click", function() { | |
_this.toggleSingleView(true, location); | |
_this.setCenterAndZoom(new google.maps.LatLng(location.lat, location.lon), 15); | |
}); | |
_this.activeMarkers.push(locationMarker); | |
locationElement.bind("click", function(event) { | |
_this.toggleSingleView(true, location); | |
_this.setCenterAndZoom(new google.maps.LatLng(location.lat, location.lon), 15); | |
}); | |
_this.divResultsList.appendChild(locationElement[0]); | |
} | |
window.addEventListener("load", function() { | |
mcdStoreLocator.main = new mcdStoreLocator.StoreLocator(); | |
}); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment