1var LocationsTemplate = { 2 3 // Will get set during the initialization call made by LocationsService 4 locationsService: null, 5 6 // Do not set to false without implementing. 7 useMultipleMaps: true, 8 9 // You do not need to change this unless you modify the template 10 locationBlock: "#locations-block", 11 12 // Change to the state selector 13 stateSelector: ".search-state-selector", 14 15 // Change to the city selector 16 citySelector: ".search-city-selector", 17 18 // This gets called when the template initializes 19 initialize: function(service) { 20 locationsService = service; 21 }, 22 23 renderTemplate: function(element, data) { 24 var source = $(element).html(); 25 var tmpl = Handlebars.compile(source); 26 return tmpl(data); 27 }, 28 29 // This is how each location block will display. 30 locationHTML: function( entry ) { 31 var hideOrderOnline = false; 32 33 if( (entry['hours'].indexOf('store-opening') > -1) || entry['hours'] == '' || entry['status'] == 7) { 34 hideOrderOnline = true; 35 } 36 37 var locationPage = "/locator/" + entry['companyname'].replace(/\s/g, "-") + "_LN" + entry['id'] + ".html"; 38 var webAddressTitle; 39 40 if(entry['webaddress'] != ""){ 41 webAddressTitle = entry['webaddress'].replace(/.*?:\/\//g, ""); 42 locationPage = entry['webaddress']; 43 } 44 45 data = { 46 company_name: entry['companyname'], 47 owner_name: entry['ownername'], 48 owner_title: entry['ownertitle'], 49 owner_image: entry['ownerimage'], 50 address1: entry['address1'], 51 hours: entry['hours'], 52 phone: entry['phonenumber'], 53 location_id: entry['id'], 54 location_number: entry['number'], 55 kilometers: Math.round((locationsService.calculateGeoDistance(locationsService.latitude, entry['latitude'], locationsService.longitude, entry['longitude'])) * 10) / 10, 56 latitude: entry['latitude'], 57 longitude: entry['longitude'], 58 city: entry['city'], 59 state: entry['state'], 60 web_address: entry['webaddress'], 61 location_url: locationPage, 62 web_address_title: webAddressTitle, 63 image: entry['thumbnail'] 64 } 65 return this.renderTemplate('#entry-template', data); 66 67 }, 68 // This is how your information window will display when you click on a marker. 69 infoWindowHTML: function( entry ) { 70 data = { 71 address1: entry['address1'], 72 address2: entry['city'] + ", " + entry['state'] + " " + entry['zip'], 73 latitude: entry['latitude'], 74 longitude: entry['longitude'], 75 store_id: entry['id'], 76 city: entry['city'], 77 state: entry['state'], 78 zip: entry['zip'] 79 } 80 return this.renderTemplate('#map-info-template', data); 81 }, 82 83 84 stateOptionHTML: function( key, entry ) { 85 return "<option value='" + key + "'>" + entry + "</option>"; 86 }, 87 cityOptionHTML: function( key, entry ) { 88 return "<option value='" + entry + "'>" + entry + "</option>"; 89 }, 90 // You generally won't have to edit below this line. sdfsdfsdfsd 91 generateMap: function( id ) { 92 entry = locationsService.findEntryById(id); 93 var latLon = new google.maps.LatLng(entry['latitude'], entry['longitude']); 94 var mapOptions = { 95 zoom: 16, 96 center: latLon, 97 mapTypeId: google.maps.MapTypeId.ROADMAP 98 }; 99 100 var map = new google.maps.Map(document.getElementById("location-" + entry['id'] + "-map"), mapOptions); 101 return map; 102 }, 103 104 generateMarker: function ( map, id ) { 105 entry = locationsService.findEntryById(id); 106 marker_data = { 107 title: "NuMale Medical Center: " + entry['number'], 108 map: map, 109 position: new google.maps.LatLng(entry['latitude'], entry['longitude']), 110 } 111 var marker = new google.maps.Marker(marker_data); 112 return marker; 113 }, 114 115 generateInfoWindow: function (map, marker) { 116 var info = new google.maps.InfoWindow({ 117 content: "<div class='location-info-window'>" + this.infoWindowHTML( entry ) + "</div>" 118 }); 119 120 google.maps.event.addListener(marker, 'click ', function() { 121 info.open(map, marker); 122 }); 123 124 return info; 125 }, 126 127 DOMHandlers: function() { 128 $(document).on('click ', '.location-map', function() { 129 id = $(this).data('id'); 130 if ($("#location-" + id + " > .location-map-container").css("display") == "none") { 131 $("#location-" + id + " > .location-map-container").css("display", "block"); 132 var map = LocationsTemplate.generateMap(id); 133 var marker = LocationsTemplate.generateMarker(map, id); 134 var info = LocationsTemplate.generateInfoWindow(map, marker); 135 info.open(map, marker); 136 google.maps.event.addListener(info, 'domready', function() { 137 map.panBy(0, -50); 138 }); 139 } 140 else 141 {
142 $("#location-" + id + " > .location-map-container").css("display", "none"); 143 } 144 }); 145 $(this.stateSelector).change(function() { 146 $(LocationsTemplate.stateSelector + " option[value='TEMP']").remove(); 147 var html = ""; 148 updateCitySelectorHTML = function( service ) { 149 return function( key, entry ) { 150 html = html + LocationsTemplate.cityOptionHTML( key, entry ); 151 }; 152 }; 153 $.each(LocationsService.cities[$(this).val()][0], updateCitySelectorHTML(this)); 154 $(LocationsTemplate.citySelector).html(html); 155 }); 156 157 $("#location-search-zip").submit(function( event ) { 158 var zipcode = $("#LocationZip").val(); 159 LocationsService.request('locations', zipcode); 160 if ($("#LocationState").val() != "TEMP") { 161 $("#LocationState").html("<option value='TEMP'>Select your province...</option>" + $("#LocationState").html() ); 162 $("#LocationCity").html("<option>--</option>"); 163 } 164 $('html, body').animate({ 165 scrollTop: $("#locations-block").offset().top - 100 166 }, 2000); 167 event.preventDefault(); 168 }); 169 $("#location-search-state-city").submit(function( event ) { 170 var state = $("#LocationState").val(); 171 var city = $("#LocationCity").val(); 172 if (state != "TEMP") { 173 LocationsService.request('locations','',state,city); 174 $("#LocationZip").val(''); 175 } 176 $('html, body').animate({ 177 scrollTop: $("#locations-block").offset().top - 100 178 }, 2000); 179 event.preventDefault(); 180 }); 181 } 182} 183 184var LocationsService = { 185 service: this, 186 table: [], 187 states: [], 188 cities: [], 189 latitude: 0, 190 longitude: 0, 191 zipcode: '', 192 mobile: false, 193 194 initialize: function( mobile ) { 195 this.mobile = mobile; 196 LocationsTemplate.initialize( this ); 197 if (mobile) { 198 this.getGeo(); 199 } 200 201 var getURLParameter = function(name) { 202 return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search)||[,""])[1].replace(/\+/g, '%20'))||null; 203 }; 204 205 var zipcode = getURLParameter("zipcode"); 206 this.request('initialize', zipcode); 207 LocationsTemplate.DOMHandlers(); 208 }, 209 210 request: function( action, zipcode, state, city ) { 211 $.ajax({ 212 type: 'GET', 213 url: "ajax.Location.php", 214 dataType: 'json', 215 data: { action: action, zipcode: zipcode, state: state, city: city }, 216 context: this, 217 success: function( response ) { 218 if (action == 'initialize') 219 { 220 if (!this.mobile) { 221 this.setGeo(response[0]); 222 } else { 223 this.getGeo(); 224 } 225 this.table = response[1]; 226 this.states = response[2]; 227 this.cities = response[3]; 228 // this.updateDOM(); 229 this.updateSearchDOM(); 230 } 231 else if (action == 'geolocation') 232 { 233 this.setGeo(response[0]); 234 this.table = response[1]; 235 this.updateLocationsDOM(); 236 } 237 else if (action == 'locations') 238 { 239 if (zipcode != "") { 240 this.setGeo(response[0]); 241 this.table = response[1]; 242 } else { 243 this.table = response[0]; 244 } 245 246 this.updateLocationsDOM(); 247 } 248 else if (action == "statecity") 249 { 250 this.states = response[0]; 251 this.cities = response[1]; 252 this.updateSearchDOM(); 253 } 254 } 255 }); 256 }, 257 258 updateDOM: function() { 259 this.updateLocationsDOM(); 260 this.updateSearchDOM(); 261 //LocationsTemplate.DOMHandlers(); 262 }, 263 264 updateSearchDOM: function() { 265 var html = "<option value='TEMP'>Select your province...</option>"; 266 updateStateSelectorHTML = function( service ) { 267 return function( key, entry ) { 268 html = html + LocationsTemplate.stateOptionHTML( key, entry ); 269 }; 270 }; 271 $.each(this.states, updateStateSelectorHTML(this)); 272 $(LocationsTemplate.stateSelector).html(html); 273 274 var html = "<option>--</option>"; 275 /*updateCitySelectorHTML = function( service ) { 276 return function( key, entry ) { 277 html = html + LocationsTemplate.cityOptionHTML( key, entry ); 278 }; 279 }; 280 $.each(LocationsService.cities[$(LocationsTemplate.stateSelector).val()][0], updateCitySelectorHTML(this));*/ 281 $(LocationsTemplate.citySelector).html(html); 282 283 $("#LocationZip").val(this.zipcode); 284 285 //LocationsTemplate.DOMHandlers(); 286 }, 287 288 updateLocationsDOM: function() { 289 this.table.sort( this.sortByGeo(this) ); 290 291 var html = "";
292 updateLocationsHTML = function( service ) { 293 return function( key, entry ) { 294 html = html + "<div class='location-container' data-id='" + entry['id'] + "' id='location-" + entry['id'] + "'>" 295 + LocationsTemplate.locationHTML( entry ) 296 + "</div>"; 297 }; 298 }; 299 if (this.table.length == 0) { 300 $(LocationsTemplate.locationBlock).html('<h3>No locations found using the search terms provided.</h3>'); 301 } else { 302 $.each(this.table, updateLocationsHTML(this)); 303 $(LocationsTemplate.locationBlock).html(html); 304 } 305 306 //LocationsTemplate.DOMHandlers(); 307 }, 308 309 findEntryById: function(id) { 310 for(var i = 0; i < this.table.length; i++) 311 { 312 if (this.table[i]['id'] == id) 313 return this.table[i]; 314 } 315 316 return null; 317 }, 318 319 calculateGeoDistance: function (lat1, lat2, lon1, lon2) { 320 var R = 6371; // km 321 var dLat = (lat2-lat1) * Math.PI / 180; 322 var dLon = (lon2-lon1) * Math.PI / 180; 323 var lat1 = lat1 * Math.PI / 180; 324 var lat2 = lat2 * Math.PI / 180; 325 326 var a = Math.sin(dLat/2) * Math.sin(dLat/2) + 327 Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2); 328 var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 329 var d = R * c; 330 331 return d; 332 }, 333 334 sortByGeo: function(service) { 335 return function(a, b) { 336 return service.calculateGeoDistance(service.latitude, a['latitude'], service.longitude, a['longitude'])-service.calculateGeoDistance(service.latitude, b['latitude'], service.longitude, b['longitude']); 337 } 338 }, 339 340 341 getGeo: function() { 342 if (Modernizr.geolocation) { 343 navigator.geolocation.getCurrentPosition(this.setGeoMobile); 344 } else { 345 // no native support; maybe try a fallback? 346 this.request('geolocation'); 347 } 348 }, 349 350 setGeo: function(response) { 351 this.latitude = response['latitude']; 352 this.longitude = response['longitude']; 353 this.zipcode = response['zipCode']; 354 }, 355 356 setGeoMobile: function(position) { 357 LocationsService.latitude = position.coords.latitude; 358 LocationsService.longitude = position.coords.longitude; 359 LocationsService.zipcode = ''; 360 LocationsService.updateDOM(); 361 } 362}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.