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/marker-you@2x.png", | |
| 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/marker-location@2x.png", | |
| 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