Created
February 19, 2016 17:47
-
-
Save painteddigital/9801cbcf75d7322c3bc4 to your computer and use it in GitHub Desktop.
This file contains 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
/* | |
TODOS: | |
- Add listener for user changing DOM DTP | |
- Add local variable to store in | |
- QA DTP logic | |
- Test sort options for sending to search | |
- Add Optimizely logging when JSON loads fail | |
*/ | |
var link = document.createElement("link"); | |
link.href = "https://dl.dropboxusercontent.com/u/4902148/Sites/opentable/assets/styles/explore-tab.css"; | |
link.type = "text/css"; | |
link.rel = "stylesheet"; | |
document.getElementsByTagName("head")[0].appendChild(link); | |
// Add Lodash | |
// (function() { | |
// var url = ["cdnjs.cloudflare.com/ajax/libs/lodash.js/4.3.0/lodash.min.js"]; | |
// for(var i=0; i < url.length; i++){ | |
// var v = document.createElement('script'); v.type = 'text/javascript'; v.async = true; | |
// v.src = ('https:' == document.location.protocol ? 'https://' : 'http://') + url[i]; | |
// var s = document.head; s.parentNode.appendChild(v); | |
// } | |
// })(); | |
// GLOBALS | |
window.OT.Navigation = []; | |
window.OT.Navigation.metro = "8"; | |
window.OT.Navigation.region = "77"; | |
window.OT.Navigation.currentLocation = null; | |
var searchRootURL = ""; | |
var dinersChoiceRootURL = ""; | |
var landmarkRootURL = ""; | |
var debug = true; | |
var personalizer = false; | |
var maxItemsToShow = 8; | |
$(window).ready(function(){ | |
var dropdown = '<div id="explore-menu" class="menu-target menu">'+ | |
'<div class="menu-container ot-menu-content-wrapper">'+ | |
'<div class="explore-group">'+ | |
'<div class="explore-group-header">'+ | |
'<span class="icon-utensils"></span>'+ | |
'<h4>Search by cuisine</h4>'+ | |
'<span>In <span class="explore-location"></span></span>'+ | |
'</div>'+ | |
'<ul id="cuisines" class="explore-menu-list"></ul>'+ | |
'</div>'+ | |
'<div class="explore-group">'+ | |
'<div class="explore-group-header">'+ | |
'<span class="icon-trophy"></span>'+ | |
'<h4>Top restaurants</h4>'+ | |
'<span>In <span class="explore-location"></span></span>'+ | |
'</div>'+ | |
'<ul id="top" class="explore-menu-list"></ul>'+ | |
'</div>'+ | |
'<div class="explore-group">'+ | |
'<div class="explore-group-header">'+ | |
'<span class="icon-landmark-large"></span>'+ | |
'<h4>Restaurants near landmarks</h4>'+ | |
'<span>Near <span class="explore-location"></span></span>'+ | |
'</div>'+ | |
'<ul id="landmarks" class="explore-menu-list"></ul>'+ | |
'</div>'+ | |
'</div>'+ | |
'</div>'; | |
$("#explore-menu-link").after(dropdown); | |
OT.Common.Menus.bindMenu("#explore-menu-link"); | |
$("#explore-menu-label").on("click", "a#explore-menu-link", function(){ | |
window.trackOptimizelyEvent("header_exploremenulink_click"); | |
}); | |
// doesn't work right now | |
if(debug){ | |
window.addEventListener("click", function(e) { | |
var href = e.target.getAttribute("href"); | |
if(!href) | |
href = e.target.parentElement.getAttribute("href"); | |
if(href) { | |
location.href = href + "&exploreTab=1"; | |
e.preventDefault(); | |
} | |
}); | |
} | |
$.ajax({ | |
dataType: "json", | |
url: "https://dl.dropboxusercontent.com/u/4902148/Sites/opentable/assets/js/explore-data-map.json", | |
context: document.body | |
}).done(function(data) { | |
// debugLog("loaded external js"); | |
// debugLog(data); | |
// INIT GLOBALS | |
initCurrentLocation(data['locations']); | |
searchRootURL = data['links'][0].search; | |
dinersChoiceRootURL = data['links'][0].dinerschoice; | |
landmarkRootURL = data['links'][0].landmarks; | |
// successfully retrieved location, init UI | |
if(getCurrentLocation()){ | |
updateCurrentLocationLabels(); | |
if(personalizer){ | |
getCuisines(data['cuisines']); | |
} else { | |
appendCuisines(data['cuisines']); | |
} | |
appendDinersChoice(data['dinersChoicePages']); | |
getPOI(data['landmarks']); | |
} | |
}) | |
}); | |
/* | |
CONTROLLER FUNCTIONS | |
*/ | |
function getCuisines(failsafeData){ | |
var cuisineCount = 18; | |
$.ajax({ | |
dataType: "json", | |
url: "https://dl.dropboxusercontent.com/u/4902148/sites/opentable/assets/js/nyc-cuisines.json", | |
context: document.body, | |
}).done(function(data) { | |
var topCuisines = []; | |
var region = getRegion(); | |
if(region == ""){ | |
// Sort by `user` in ascending order and by `age` in descending order. | |
// removes the regional distinction | |
var reducedData = _.reduceRight(data, function(flattened, other) { | |
return flattened.concat(other); | |
}, []); | |
// order by restaurant count | |
var orderedCuisines = _.sortBy(reducedData, function(obj){ return -obj.count; }); | |
// grab the first [n] in the list | |
topCuisines = orderedCuisines.slice(0, cuisineCount); | |
// _.each(topCuisines, function(cuisine) { | |
// debugLog(cuisine.name, cuisine.count); | |
// }); | |
} else { | |
topCuisines = data[region].slice(0, cuisineCount); | |
// _.each(topCuisines, function(cuisine) { | |
// debugLog(cuisine.cuisine_name, cuisine.cuisine_count); | |
// }); | |
} | |
convertCuisineFormatting(topCuisines); | |
}).fail(function(jqXHR, textStatus, errorThrown){ | |
debugLog("error getting cuisine JSON, loading static cuisines"); | |
appendCuisines(failsafeData); | |
}); | |
} | |
function getPOI(failsafeData){ | |
var POICount = 18; | |
$.ajax({ | |
dataType: "json", | |
url: "https://dl.dropboxusercontent.com/u/4902148/sites/opentable/assets/js/nyc-poi.json", | |
context: document.body, | |
}).done(function(data) { | |
window.OT.Navigation.poiData = data; | |
var region = getRegion(); | |
var landmarks = []; | |
if(region == ""){ | |
landmarks = data; | |
} else { | |
// Sort first by popularity, grabbing only the first 15 that match the region, then sort those Alphabetically | |
landmarks = _.filter(data, function(obj){ | |
return obj.Macro == getRegion(); | |
}); | |
} | |
landmarks = _.sortBy(landmarks, function(obj){ return -obj.Popularity; }).slice(0, POICount); | |
landmarks = _.sortBy(landmarks, function(obj){ return obj.Name; }); | |
convertPOIFormatting(landmarks); | |
}).fail(function(jqXHR, textStatus, errorThrown){ | |
debugLog("error getting POI JSON, loading static POI"); | |
appendLandmarks(failsafeData); | |
}); | |
} | |
function convertCuisineFormatting(receivedData){ | |
var reformattedList = [] | |
var region = getRegion(); | |
var currentLocation = getCurrentLocation(); | |
_.each(receivedData, function(cuisine) { | |
var reformattedCuisine = { | |
"title":cuisine.name, | |
"restaurantCount":cuisine.count, | |
"regionId":region, | |
"urlParams":"personalizer=true&cuisineids="+cuisine.id, | |
"cuisineId":cuisine.id | |
} | |
reformattedList.push(reformattedCuisine); | |
}); | |
currentLocation.cuisines = reformattedList; | |
appendCuisines(); | |
} | |
function convertPOIFormatting(receivedData){ | |
var reformattedList = [] | |
var currentLocation = getCurrentLocation(); | |
_.each(receivedData, function(point) { | |
var reformattedPoint = { | |
"title":point.Name, | |
"id":point.ID, | |
"regionId":point.Macro, | |
"metroId":point.Metro, | |
"popularity":point.Popularity | |
} | |
reformattedList.push(reformattedPoint); | |
}); | |
currentLocation.landmarks = reformattedList; | |
appendLandmarks(); | |
} | |
// GETTERS | |
function getDTP(){ | |
// More OT-Friendly way: OT.Common.Cookies.get("OT_dtp_values") | |
// Example data = {covers: "2", datetime: "2016-02-11 19:00"} | |
var dtp = ""; | |
var dtpCookieValues = OT.Common.Cookies.get("OT_dtp_values"); | |
if(dtpCookieValues != "undefined"){ | |
dtp = "&"+encodeURIComponent(document.cookie.split("OT_dtp_values=")[1].split(";")[0]); | |
} | |
var dtpDOMString = ""; | |
// if DOM elements are present, override cookie since it can get out dated | |
if($("select[name=Select_1]").val() != "" && $("input#submit_datepicker").val() != "" && $("select[name=Select_0]").val() != ""){ | |
dtp += "&covers="+$("select[name=Select_1]").val(); | |
dtp += "&dateTime="+$("input#submit_datepicker").val(); | |
dtp += encodeURIComponent(" "+$("select[name=Select_0]").val()); | |
} | |
return dtp; | |
} | |
function getRegion(){ | |
return window.OT.Navigation.region; | |
} | |
function getMetro(){ | |
return window.OT.Navigation.metro; | |
} | |
function getCurrentLocation(){ | |
return window.OT.Navigation.currentLocation; | |
} | |
// SETTERS | |
function setRegion(newRegion){ | |
window.OT.Navigation.region = newRegion; | |
} | |
function setMetro(newMetro){ | |
window.OT.Navigation.metro = newMetro; | |
} | |
function setCurrentLocation(newLocationObject){ | |
window.OT.Navigation.currentLocation = newLocationObject; | |
} | |
function initCurrentLocation(allLocationData){ | |
// Save location data locally | |
window.OT.Navigation.locationData = allLocationData; | |
// Attempt to get location from Cookie | |
var split = document.cookie.split("lvCKE=lvmreg=")[1] | |
var ids = split.split("%2C"); | |
setMetro(ids[0]); | |
setRegion(ids[1].split("&")[0]); | |
//debugLog(getMetro(),getRegion()); | |
// First attempt to match to cookie instead of UI for stability | |
// if cookie returns "0" region, set to nothing to match url param expectations | |
if(getRegion() == "0"){ setRegion(""); } | |
// get JSON for current metro/region | |
setCurrentLocation(_.find(allLocationData, function(obj){ | |
return obj.searchParams[0].metroId == getMetro() && obj.searchParams[0].regionId == getRegion(); | |
})); | |
// Check that cookie data matches location header string | |
// If that fails, then fallback to setting location based on | |
if($(".location-picker-region").text().indexOf(getCurrentLocation().title) > -1){ | |
debugLog("cookie location matches UI"); | |
} else { | |
debugLog("cookie location doesn't match UI"); | |
var locationMatch = _.find(allLocationData, function(obj){ | |
return obj.title == $(".location-picker-region").text(); | |
}); | |
if(typeof locationMatch != "undefined"){ | |
setCurrentLocation(locationMatch); | |
} else { | |
debugLog("cant find a region from UI, using NYC metro data"); | |
setCurrentLocation(_.find(allLocationData, function(obj){ | |
return obj.title == "New York / Tri-State Area"; | |
})); | |
} | |
} | |
} | |
/* | |
VIEW FUNCTIONS | |
*/ | |
function updateCurrentLocationLabels(){ | |
$("#location").text(getCurrentLocation().title); | |
$(".explore-location").text(getCurrentLocation().title); | |
} | |
function appendCuisines(cuisines){ | |
var currentLocation = getCurrentLocation(); | |
if(typeof currentLocation.cuisines != "undefined"){ | |
debugLog("loading retrieved cuisine JSON"); | |
_.each(currentLocation.cuisines, function(cuisineObject, key){ | |
appendCuisineDOMElem(cuisineObject); | |
}); | |
} else { | |
_.each(currentLocation.cuisineIds, function(cuisineId, key){ | |
debugLog("proceeding with error-safe cuisines"); | |
var cuisineObject = _.find(cuisines, function(obj){ | |
return obj['id'] == cuisineId; | |
}); | |
appendCuisineDOMElem(cuisineObject) | |
}); | |
} | |
} | |
function appendCuisineDOMElem(cuisineObject){ | |
var dtpParams = getDTP(); | |
var currentLocation = getCurrentLocation(); | |
$("#cuisines").append("<li><a href=\""+searchRootURL+"&metroId="+currentLocation.searchParams[0].metroId+"®ionIds="+currentLocation.searchParams[0].regionId+dtpParams+"&"+cuisineObject.urlParams+"\">"+cuisineObject.title+"</a></li>"); | |
$("#cuisines").on("click", "a", function(){ | |
window.trackOptimizelyEvent("header_cuisine_click"); | |
}); | |
hideLongColumns($("#cuisines")); | |
} | |
function appendDinersChoice(dinersChoicePages){ | |
var currentLocation = getCurrentLocation(); | |
_.each(currentLocation.dinersChoiceIds, function(dinersChoiceId, key){ | |
var dinersChoiceObject = _.find(dinersChoicePages, function(obj){ | |
return obj['id'] == dinersChoiceId; | |
}); | |
var urlParams = (currentLocation.dinersChoiceParams.indexOf("?") > -1) ? "&"+dinersChoiceObject.urlParams : "?"+dinersChoiceObject.urlParams | |
$("#top").append("<li><a href=\""+dinersChoiceRootURL+currentLocation.dinersChoiceParams+urlParams+"\">"+dinersChoiceObject.title+"</a></li>"); | |
}); | |
$("#top").on("click", "a", function(){ | |
window.trackOptimizelyEvent("header_dinerschoice_click"); | |
}); | |
hideLongColumns($("#top")); | |
} | |
function appendLandmarks(failsafeLandmarks){ | |
var currentLocation = getCurrentLocation(); | |
// if we didn't pass in failsafe data, then we got real JSON. | |
// this check expacts that JSON to be found under currentlocation.landmarks | |
if(typeof currentLocation.landmarks != "undefined"){ | |
debugLog("loading retrieved POI JSON", currentLocation.landmarks); | |
_.each(currentLocation.landmarks, function(landmarkObject, key){ | |
$("#landmarks").append("<li><a href=\""+landmarkRootURL+landmarkObject.id+"\">"+landmarkObject.title+"</a></li>"); | |
}); | |
} else { | |
debugLog("loading failsafe POIs"); | |
_.each(currentLocation.landmarkIds, function(landmarkId, key){ | |
var landmarkObject = _.find(failsafeLandmarks, function(obj){ | |
return obj['id'] == landmarkId; | |
}); | |
$("#landmarks").append("<li><a href=\""+landmarkRootURL+landmarkObject.urlParams+"\">"+landmarkObject.title+"</a></li>"); | |
}); | |
} | |
$("#landmarks").on("click", "a", function(){ | |
window.trackOptimizelyEvent("header_landmark_click"); | |
}); | |
hideLongColumns($("#landmarks")); | |
} | |
function hideLongColumns($listElement){ | |
var singleItemHeight = $listElement.children("li").height(); | |
if($listElement.height() > singleItemHeight*maxItemsToShow && $listElement.children().length > maxItemsToShow){ | |
$listElement.addClass("short"); | |
$listElement.parent().append("<a href=\"#\" class=\"view-more secondary with-arrow text-arrow-down-small\">Show More</a>"); | |
$listElement.parent().on("click", ".view-more", showLongColumn); | |
} | |
} | |
function showLongColumn(e){ | |
$(this).siblings(".explore-menu-list").toggleClass("short long", 400, "easeOutQuint"); | |
// debugLog($(e.currentTarget).parent()); | |
var text = $(this).text(); | |
$(this).toggleClass("text-arrow-down-small text-arrow-up-small").text(text == "Show More" ? "Show Fewer" : "Show More"); | |
window.trackOptimizelyEvent("header_showmore_click"); | |
e.stopPropagation(); | |
return false; | |
} | |
/* | |
UTILITIES | |
*/ | |
function debugLog(a,b,c){ | |
if(debug){ | |
if(typeof c != "undefined"){ | |
console.log(a, b, c); | |
} else if(typeof b != "undefined"){ | |
console.log(a, b); | |
} else { | |
console.log(a) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment