· 9 years ago · Sep 29, 2016, 11:32 PM
1/** Set up object array to be used later by map, markers, and list
2 */
3var locations = [{
4 name: "Red Bull Arena",
5 address: "600 Cape May St, Harrison, NJ 07029",
6 lat: 40.737046,
7 long: -74.150361,
8 marker: '',
9 yelpWeb: "https://api.yelp.com/v2/business/red-bull-arena-harrison"
10}, {
11 name: "MetLife Stadium",
12 address: "1 MetLife Stadium Dr, East Rutherford, NJ 07073",
13 lat: 40.813091,
14 long: -74.074209,
15 marker: '',
16 yelpWeb: "https://api.yelp.com/v2/business/metlife-stadium-east-rutherford"
17}, {
18 name: "World Trade Center",
19 address: "1 World Trade Center, New York, NY 10007",
20 lat: 40.713175,
21 long: -74.013104,
22 marker: '',
23 yelpWeb: "https://api.yelp.com/v2/business/one-world-trade-center-new-york-4"
24}, {
25 name: "Zeppelin Hall Biergarten",
26 address: "88 Liberty View Dr, Jersey City, NJ 07302",
27 lat: 40.715120,
28 long: -74.046754,
29 marker: '',
30 yelpWeb: "https://api.yelp.com/v2/business/zeppelin-hall-biergarten-and-restaurant-jersey-city-2"
31}, {
32 name: "Prudential Center",
33 address: "25 Lafayette St, Newark, NJ 07102",
34 lat: 40.733617,
35 long: -74.171150,
36 marker: '',
37 yelpWeb: "https://api.yelp.com/v2/business/prudential-center-newark"
38}, {
39 name: "Madison Square Garden",
40 address: "7th Ave & 32nd St, New York, NY 10001",
41 lat: 40.750691,
42 long: -73.993476,
43 marker: '',
44 yelpWeb: "https://api.yelp.com/v2/business/madison-square-garden-new-york"
45}];
46
47
48
49
50/** Considering how 'this' changes in every scope, 'self' will preserve
51 * 'this' value throughout viewModel. Since we want our array of objects to be
52 * able to detect changes as well as respond to changes we use knockout's
53 * observableArray and pass our array of objects (locations) through it.
54 * It will now be referred to self.places.
55 */
56var viewModel = function() {
57 var self = this;
58 self.places = ko.observableArray(locations);
59
60 /** Set currentLocation to first object in object array.
61 * When particular object is clicked from list, change currentLocation
62 * value to the clicked location. Also trigger a click on the marker.
63 */
64 this.currentLocation = ko.observable(self.places()[0]);
65 this.setLocation = function(clickedLocation) {
66 self.currentLocation(clickedLocation);
67 google.maps.event.trigger(clickedLocation.marker, 'click');
68 };
69
70 /** Setting up search so it filters through object array or locations
71 * while allowing lowercase typing to bring back relevant results.
72 */
73 self.query = ko.observable('');
74
75 /** Display list of locations in a list view
76 */
77 self.search = ko.computed(function() {
78 for (var i = 0; i < locations.length; i++) {
79 locations[i].marker.setVisible(true);
80 }
81 /** If what's typed in input lowercase or not matches a location in object array
82 * display the results, however many there are. If there are objects that don't contain
83 * what's typed in the input then hide those objects.
84 */
85 return ko.utils.arrayFilter(locations, function(place) {
86 if (place.name.toLowerCase().indexOf(self.query().toLowerCase()) >= 0) {
87 return true;
88 }
89 infowindow.close();
90
91 place.marker.setVisible(false);
92 return false;
93 });
94 });
95
96};
97
98function nonce_generate() {
99 return (Math.floor(Math.random() * 1e12).toString());
100}
101var yelpAPI = function(i) {
102 console.log(i);
103 var yelp_url = locations[i].yelpWeb;
104
105 var parameters = {
106 oauth_consumer_key: 'AOsWUWqrkWd3Lx9RHt4ihA',
107 oauth_token: 'rqRj4BFQ1xVBEut_57pPedSonmLjkyde',
108 oauth_nonce: nonce_generate(),
109 oauth_timestamp: Math.floor(Date.now() / 1000),
110 oauth_signature_method: 'HMAC-SHA1',
111 oauth_version: '1.0',
112 callback: 'cb', // This is crucial to include for jsonp implementation in AJAX or else the oauth-signature will be wrong.
113 ll: '40.753011, -74.128069',
114 radius: 40000,
115 limit: 5
116 };
117
118 var encodedSignature = oauthSignature.generate('GET', yelp_url, parameters, 'bVxTwnXgkOCAg5Kfhrw7eWEthu8', 'cK98_xpt5iXoBJVyeysJzw5Ypxk');
119 parameters.oauth_signature = encodedSignature;
120
121 /** Configure Yelp API settings as well as provide some error handling
122 */
123 var settings = {
124 url: yelp_url,
125 data: parameters,
126 cache: true, // This is crucial to include as well to prevent jQuery from adding on a cache-buster parameter "_=23489489749837", invalidating our oauth-signature
127 dataType: 'jsonp',
128 success: function(results) {
129 /** Do stuff with results
130 */
131 locations[i].url = results.url;
132 locations[i].rating_img_small_url = results.rating_img_url_small;
133 locations[i].snippet_text = results.snippet_text;
134 locations[i].image_url = results.image_url;
135 },
136 error: function() {
137 /** Do stuff on fail
138 */
139 alert("You have encountered an error");
140 }
141 };
142
143 /** Send AJAX query via jQuery library.
144 */
145 $.ajax(settings);
146};
147/*for (var i = 0; i < locations.length; i++) {
148 yelpAPI(i);
149}*/
150var map, bounds, infowindow;
151/** Main map function that zooms in and centers it at specific location due to the given
152 * coordinates. Also displays the map in the respective div.
153 */
154function initMap() {
155 map = new google.maps.Map(document.getElementById('map'), {
156 zoom: 12,
157 center: new google.maps.LatLng(40.753011, -74.128069)
158 });
159 bounds = new google.maps.LatLngBounds();
160 infowindow = new google.maps.InfoWindow();
161
162
163
164 /** Marker gets created on map with a falling animation and positioned in respective coordinates from locations array up top.
165 */
166 function createMarker(location) {
167 latlng = new google.maps.LatLng(location.lat, location.long);
168 var marker = new google.maps.Marker({
169 map: map,
170 animation: google.maps.Animation.DROP,
171 position: latlng
172 });
173
174 bounds.extend(marker.position);
175
176 /** When marker gets clicked on, it toggles bouncing animation and info window pops up
177 */
178 google.maps.event.addListener(marker, 'click', function() {
179 html = '<h3>' + location.name + '</h3>';
180 html += '<br><img src=' + location.image_url + '><br>' + location.address;
181 html += '<br><img src=' + location.rating_img_small_url + '>';
182 html += '<p>' + location.snippet_text + '<a href="' + location.url + '">more...</a></p>';
183 yelpAPI(location);
184 infowindow.setContent(html);
185 infowindow.open(map, this);
186 toggleBounce(marker);
187 });
188
189 return marker;
190
191
192 }
193
194
195 /** Set's bounce animation to marker with a timer on it so it doesn't
196 * keep bouncing forever
197 */
198 function toggleBounce(marker) {
199 if (marker.getAnimation() !== null) {
200 marker.setAnimation(null);
201 } else {
202 marker.setAnimation(google.maps.Animation.BOUNCE);
203 setTimeout(function() { marker.setAnimation(null); }, 650);
204 }
205 }
206
207 /** Loop that iterates through each object in the locations array. Marker property stores coordinates
208 * for exact location for each object. Because createMarker function is called it will display each
209 * and every marker in locations on the map.
210 */
211 for (var i = 0; i < locations.length; i++) {
212 locations[i].marker = createMarker(locations[i]);
213 }
214 map.fitBounds(bounds);
215
216 /** Activate knockout bindings
217 */
218 ko.applyBindings(new viewModel());
219
220
221
222
223
224}
225
226/** Open the drawer when the menu ison is clicked.
227 */
228var menu = document.querySelector('#burgMenu');
229var main = document.querySelector('main');
230var drawer = document.querySelector('#drawer');
231
232menu.addEventListener('click', function(e) {
233 drawer.classList.toggle('open');
234 e.stopPropagation();
235});
236main.addEventListener('click', function() {
237 drawer.classList.remove('open');
238});