ng-repeat not working until after submit button is hit twice - javascript

I am messing with the google maps API and using angular, and I am having an issue binding the data from the API to a variable and displaying it correctly with an ng-repeat. The ng-repeat is supposed to list the name property of the place objects, but it does not do that unless I enter the same zipcode twice. Here is the html:
<!DOCTYPE html>
<html ng-app = "openApp">
<head>
<meta charset="utf-8">
<title>Open Sesame</title>
<script src = "http://maps.googleapis.com/maps/api/js? key=AIzaSyArO1n-5w8xxPblR_aDxV6Ul1VLik3_pRY&libraries=places"></script>
<script src = "vendors/angular/angular.min.js"></script>
<script src = "assets/scripts/composite.all.min.js"></script>
<link rel = "stylesheet" href = "assets/styles/style.css" />
</head>
<body ng-controller = "MainController as main">
<h1>Is it open?</h1>
<!-- <button ng-click = ""></button> -->
<div id = "googleMap"></div>
<form>
<input type = "text" ng-model = "main.zipcode"/>
<input type = "submit" ng-click = "main.enterZip()" />
</form>
<div id = "displayInfo">
<ul>
<li ng-repeat = "item in main.openPlaces">
test {{item.name}}
</li>
</ul>
</div>
</body>
</html>
and here is the client side javascript:
angular.module('openApp', [])
.controller('MainController', ['$http', function($http){
var vm = this;
vm.latitude;
vm.longitude;
vm.openPlaces = [];
initialize();
vm.enterZip = function(){
$http.get('/zipcodeApi/'+ vm.zipcode)
.then(function(response){
vm.latitude = response.data.lat;
vm.longitude = response.data.lng;
initialize();
})
}
function initialize(){
var mapLocation = new google.maps.LatLng(vm.latitude, vm.longitude);
var openNow = [];
var mapProp = {
center: mapLocation,
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("googleMap"), mapProp);
var placesRequest = {
location: mapLocation,
radius: '2000',
types: ['restaurant'],
keyword: 'restaurant',
};
var service = new google.maps.places.PlacesService(map);
service.nearbySearch(placesRequest, function(results, status) {
if(status == google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
var listedHours = results[i].opening_hours;
if(typeof listedHours != 'undefined' && listedHours.open_now === true){
openNow.push(results[i]);
var place = results[i];
var marker = new google.maps.Marker({
map: map,
position: place.geometry.location
});
}
}
}
vm.openPlaces = openNow;
})//closes nearbySearch()
}
}]);

MainController would work because you named your controller MainController in the JS file. And that's the same reason MainController as main won't work.

Related

Display LocalStorage on HTML page

I am having issues displaying data from localStorage into my HTML page, when I open the console the data is been saved, the issue is with innerhtml.
Below is both my html and JS code.
When i run the console, I can see that my data is saved on localStorage, the issue is inputing that data into the page
Here is my html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Fizzle</title>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/css/bootstrap.min.css"
integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65"
crossorigin="anonymous"
/>
<link rel="stylesheet" href="css/style.css" />
<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
</head>
<body class="">
<div class="row">
<div class="col">
<ul class="workouts">
<section class="weather">
<div id="today-container">
<div class="current-weather">
<h3 class="brand">the weather</h3>
</div>
<div>
<h1 class="temp">16°</h1>
<div class="city-time">
<h1 class="name">London</h1>
<small>
<span class="date">Monday Sep 19</span>
</small>
</div>
</div>
</section>
<form class="form hidden">
<div class="form__row">
<label class="form__label">Type</label>
<select class="form__input form__input--type">
<option value="running">Running</option>
<option value="cycling">Cycling</option>
</select>
</div>
<div class="form__row">
<label class="form__label">Distance</label>
<input id="distance-input"
class="form__input form__input--distance"
placeholder="km"
/>
</div>
<div class="form__row">
<label class="form__label">Duration</label>
<input id="duration-input"
class="form__input form__input--duration"
placeholder="min"
/>
</div>
<div class="form__row">
<label class="form__label">Elevation</label>
<input id ="elevation-input"
class="form__input form__input--cadence"
placeholder="meters"
/>
</div>
<button class="form__btn">OK</button>
</form>
</ul>
</div>
<div class="col">
<div id="map"></div>
</div>
<p> <h4 class="ElementThatHoldsTheHistoryData"></h4></p>
</div>
<div id="floating-panel"></div>
<div id="sidebar"></div>
<script
src="https://maps.googleapis.com/maps/api/js?key=API Key here"
defer>
</script>
<!-- <script async defer src="https://maps.googleapis.com/maps/api/js?key=APIkey here=initMap&libraries=geometry"></script> -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<script src="js/app.js"></script>
</body>
</html>
Here is my JS code:
enter code her/Get all necessary elements from the DOM
const temp = document.querySelector(".temp");
const dateOutput = document.querySelector(".date");
const timeOutput = document.querySelector(".time");
const distance = document.querySelector("#distance-input");
const duration = document.querySelector("#duration-input");
const elevation = document.querySelector(".form__input--elevation");
const todayContainer = document.querySelector("#today-container");
// set my variables
var currentWeather = document.querySelector(".current-weather");
var APIkey = "&appid=99d1a7e58f500ed377f1399b47f88c6a";
var distanceInput = document.getElementById("distance-input");
var durationInput = document.getElementById("duration-input");
var elevationInput = document.getElementById("elevation-input");
var map;
var markers = [];
var directionsService;
var directionsRenderer;
var workoutElements = document.getElementsByClassName("workout");
var btn = document.querySelector(".form__btn");
//Default city when the page loads/------------------------------------------------------------
let cityInput = "London";
/// Get date /----------------------------------------------------------------------------------------------------------------
const date = moment().format("h:mm a - dddd MMM YY");
dateOutput.innerText = date;
// console.log(date);
// Google map
// map code with 2 markers and directions-----working code------------------------
function initMap() {
map = new google.maps.Map(document.getElementById("map"), {
center: { lat: 51.509865, lng: -0.118092 }, //center mapp to Hyde park London
zoom: 12.5,
});
directionsService = new google.maps.DirectionsService();
directionsRenderer = new google.maps.DirectionsRenderer();
directionsRenderer.setMap(map);
directionsRenderer.setOptions({
polylineOptions: {
strokeColor: "red",
},
suppressMarkers: true,
});
// Add a click event listener to the map
google.maps.event.addListener(map, "click", function (event) {
addMarker(event.latLng);
});
}
function addMarker(location) {
// Add the marker at the clicked location
var marker = new google.maps.Marker({
position: location,
map: map,
});
markers.push(marker);
if (markers.length >= 2) {
calculateAndDisplayRoute();
}
}
function deleteMarkers() {
// Clear markers from the map
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(null);
}
markers = [];
}
//function to add distance and duration:
function calculateAndDisplayRoute() {
var request = {
origin: markers[0].getPosition(),
destination: markers[1].getPosition(),
travelMode: "BICYCLING",
provideRouteAlternatives: true,
unitSystem: google.maps.UnitSystem.METRIC,
};
directionsService.route(request, function (response, status) {
if (status === "OK") {
directionsRenderer.setDirections(response);
var distance = response.routes[0].legs[0].distance.text;
var duration = response.routes[0].legs[0].duration.text;
var elevation = response.routes[0].legs[0].elevation;
// set input values
document.getElementById("distance-input").value = distance;
document.getElementById("duration-input").value = duration;
document.getElementById("elevation-input").value = elevation;
} else {
window.alert("Directions request failed due to " + status);
}
});
}
function getLocation() {
navigator.geolocation.getCurrentPosition((data) => {
const lat = data.coords.latitude;
const lon = data.coords.longitude;
initMap(lat, lon);
currentConditions(lat, lon);
});
}
//Weather
//fetch data from current weather api, and display desired data on the page
function currentConditions(lat, lon) {
let currentWeatherAPI = `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}${APIkey}&units=metric`;
const tempDisplay = document.querySelector(".temp");
const cityname = document.querySelector(".name");
fetch(currentWeatherAPI)
.then(function (response) {
return response.json();
})
.then(function (wdata) {
// city's name, and use moment to get the date
// var city = getLocation();
// weather condition icon
var weatherIcon = wdata.weather[0].icon;
//add
tempDisplay.innerText = Math.round(wdata.main.temp) + "°";
cityname.innerText = wdata.name;
});
}
getLocation();
// local storage
btn.addEventListener("click", function (event) {
event.preventDefault();
// Clear form
distance.value = "";
duration.value = "";
// Clear markers from the map
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(null);
}
markers = [];
var rides = JSON.parse(localStorage.getItem("rides")) || []; // Add new ride to existing rides data in LS
var newRide = { distance: distance.value, duration: duration.value };
rides.push(newRide);
localStorage.setItem("rides", JSON.stringify(rides));
// for loop to iterate through the collection of elements and set the innerHTML property of each element to the stored data.
var element = document.querySelector("ElementThatHoldsTheHistoryData");
for (let i = 0; i < rides.length; i++) {
var h4 = document.createElement("p");
h4.textContent = `The Distance was ${rides[i].distance} and the Duration was ${rides[i].duration}`;
element.appendChild(h4);
}});
Arrange your p tag like this
const h4 = `<p>The Distance was ${rides[i].distance} and the Duration was ${rides[i].duration}</p>`
Instead of document.querySelector I would prefer to use getElementById or className
document.getElementById('question-header').append(h4)
Finally, append your HTML to the Id

Googlemaps places Autocomplete by className - JS loop Problem

I need to add Autocomplete to input fields by ClassName. I got it to work but Google does not sent the Address with Postalcode back.
So I am trying to use addListener to insert the formatted_address on the input field.
In this example the input[i] on the autocomplete.addListener is not working:
function initMap() {
var input = $('.my_adresse');
for (i = 0; i < input.length; i++) {
var autocomplete = new google.maps.places.Autocomplete(input[i], {
types: ['address'],
componentRestrictions: {
'country': ["de", "ch", "aut"]
}
});
autocomplete.addListener('place_changed', function() {
var place = autocomplete.getPlace();
$(input[i]).val(place.formatted_address);
});
}
}
On this example only the last Element of the loop is working:
var input = $('.my_adresse');
for (i = 0; i < input.length; i++) {
var autocomplete = new google.maps.places.Autocomplete(input[i], {
types: ['address'],
componentRestrictions: {
'country': ["de", "ch", "aut"]
}
});
var input_to_change= input[i];
autocomplete.addListener('place_changed', function() {
var place = autocomplete.getPlace();
$(input_to_change).val(place.formatted_address);
});
}
}
Why am I getting just the last element of the loop?
What is the best solution to get the Complete Address with postal code using Google Maps places Autocomplete?
One way to address the issue is with function closure, create a createAutocomplete function to hold closure on the input and the autocomplete object:
function createAutocomplete(input, index) {
var autocomplete = new google.maps.places.Autocomplete(input, {
types: ['address'],
componentRestrictions: {
'country': ["de", "ch", "aut"]
}
});
var input_to_change = input;
autocomplete.addListener('place_changed', function() {
var place = autocomplete.getPlace();
console.log(place);
$(input).val(place.formatted_address);
});
}
and call that in your loop:
for (i = 0; i < input.length; i++) {
createAutocomplete(input[i], i);
}
proof of concept fiddle
code snippet:
// This example requires the Places library. Include the libraries=places
// parameter when you first load the API. For example:
// <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places">
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: -33.8688,
lng: 151.2195
},
zoom: 13
});
var bounds = new google.maps.LatLngBounds();
var input = $('.my_adresse');
for (i = 0; i < input.length; i++) {
createAutocomplete(input[i], i);
}
function createAutocomplete(input, index) {
var autocomplete = new google.maps.places.Autocomplete(input, {
types: ['address'],
componentRestrictions: {
'country': ["de", "ch", "aut"]
}
});
var input_to_change = input;
autocomplete.addListener('place_changed', function() {
var place = autocomplete.getPlace();
console.log(place);
if (place != null) {
$(input).val(place.formatted_address);
if (place.geometry.location) {
var marker = new google.maps.Marker({
position: place.geometry.location,
map: map,
title: "" + index
});
bounds.extend(marker.getPosition());
map.fitBounds(bounds);
}
}
});
}
}
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 70%;
}
/* Optional: Makes the sample page fill the window. */
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="pac-card" id="pac-card">
<div>
<div id="title">
Autocomplete search
</div>
</div>
<div id="pac-container">
<input id="pac-input" class="my_adresse" type="text" placeholder="Enter a location">
</div>
<div>
<input class="my_adresse" type="text" placeholder="Enter a location">
</div>
<div>
<input class="my_adresse" type="text" placeholder="Enter a location">
</div>
<div>
<input class="my_adresse" type="text" placeholder="Enter a location">
</div>
</div>
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=places&callback=initMap" async defer></script>

Global variable assigned value in one function is not accessible in another

I am using geolocation to collect coordinates and make an API call to get the weather in Fahrenheit. I'm assigning the global variable tempNum this value within one of my functions that adds the temperature to the page using function getWeatherByCoordinates(latitude, longitude).
Later, I am trying to access this variable and pass the value as an argument into another function typeConversion for which I am attempting to convert the temperature value to Celsius. It is returning NaN and when debugging, I can't figure out why.
Here is my HTML and JS. I feel like since I declared my variable at the global level and set "return varName" in the function that I assigned the value to it, that the value should be accessible throughout my JS; but I may have done something wrong or misunderstood variable scope. Please assist.
var place = document.getElementById("meat");
var header = document.getElementById("header");
var weather = document.getElementById("Weather");
var latitude;
var longitude;
var coordinates = document.getElementById("coordinates");
function success(position) {
latitude = position.coords.latitude;
longitude = position.coords.longitude;
getWeatherByCoordinates(latitude, longitude);
};
//else {
// //Write Code to alternatively show a Zip-Code Search Box;
//};
navigator.geolocation.getCurrentPosition(success);
var city = document.getElementById("city");
var weatherDescription = document.getElementById("weather-description");
var roundTempF;
var roundTempC;
var tempNum;
var tempStringFFull
function getWeatherByCoordinates(latitude, longitude) {
var fullURL = "http://api.openweathermap.org/data/2.5/weather?lat=" + latitude + "&lon=" + longitude + "&APPID=75ed54453a6e806917cfa439b3fb1dd9&units=imperial";
$.getJSON(fullURL, function (data) {
var tempString = data.main.temp;
var tempNum = parseInt(tempString);
roundTempF = Math.floor(tempNum);
stringF = roundTempF.toString();
tempStringFFull = stringF + "\xB0" + " F";
weather.innerText = tempStringFFull;
city.innerText = data.name;
weatherDescription.innerText = data.weather[0].description;
if (data.dt > data.sys.sunrise && data.dt < data.sys.sunset) {
$("#whole-page").removeClass("whole");
$("#whole-page").removeClass("night");
$("#whole-page").addClass("day");
}
else {
$("#whole-page").removeClass("whole");
$("#whole-page").removeClass("night");
$("#whole-page").addClass("night");
};
event.preventDefault();
});
return tempNum;
};
function typeConversion(tempNum) {
if (changeTempType.innerText === "Celsius") {
var tempStringC;
var celsiusDecimal = (tempNum - 32) * (5 / 9);
roundTempC = Math.floor(celsiusDecimal);
tempStringC = roundTempC.toString();
tempStringC += "\xB0" + " C";
weather.innerText = tempStringC;
changeTempType.innerText = "Farenheit";
return;
}
else if (changeTempType.innerText === "Farenheit") {
weather.innerText = tempStringFFull;
changeTempType.innerText = "Celsius";
return;
}
else {
weather.innerText = "We are unable to retrieve the weather at this time. Please try again later";
changeTempType.innerText = "Celsius";
return;
};
};
var changeTempType = document.getElementById("change-temp-type");
changeTempType.addEventListener("click", typeConversion, false);
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<link href="https://gitcdn.github.io/bootstrap-toggle/2.2.2/css/bootstrap-toggle.min.css" rel="stylesheet"/>
<link rel="stylesheet" type="text/css" href="css/style.css" />
<script defer src="https://use.fontawesome.com/releases/v5.0.6/js/all.js"></script>
<title>Weather</title>
</head>
<body id="whole-page" class="whole">
<div class="wrapper">
<h2 id="header">Check the Current Temperaturate by Zip Code</h2>
<label>Farenheit</label>
<input type="radio" name="temp-type" value="C" id="Celsius-radio"/><label>Celsius</label>-->
<button id="change-temp-type">Celsius</button>
<form>
<p>Enter the Zip Code to see the Weather there!</p>
<input id = "Zip-Code" type="text"/>
<input id = "submit-zip" type="button" value="Get Weather!"/>
</form>
<div>
<h3 id="city"></h3>
<h3 id= "Weather" class="temp-text"></h3>
<h4 id="weather-description"></h4>
</div>
</div>
<script src= "https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.js"> </script>
<script src="javascript/main.js"></script>
</body>
</html>
You have a couple of issues:
You re-declare var tempNum = in your function, meaning it will be a new variable only accessible inside the function scope (leaving the global one unchanged)
Your code inside of $.getJSON is using an asynchronous callback - that means it will run sometime later than the code below it. When you return tempNum, that code has not run yet.
Your return statement isn't really doing anything... just reassigning the global variable will be sufficient.
UPDATE - issue I missed at first:
You are naming your function parameter in typeConversion "tempNum". Again, that will result in a new variable, only accessible within the scope of that function. If you want to affect the global, then this function does not need any parameters at all, and tempNum will then refer to the global variable as intended.
I've tried to clear up all issues below.
var place = document.getElementById("meat");
var header = document.getElementById("header");
var weather = document.getElementById("Weather");
var latitude;
var longitude;
var coordinates = document.getElementById("coordinates");
function success(position) {
latitude = position.coords.latitude;
longitude = position.coords.longitude;
getWeatherByCoordinates(latitude, longitude);
};
//else {
// //Write Code to alternatively show a Zip-Code Search Box;
//};
navigator.geolocation.getCurrentPosition(success);
var city = document.getElementById("city");
var weatherDescription = document.getElementById("weather-description");
var roundTempF;
var roundTempC;
var tempNum;
var tempStringFFull
function getWeatherByCoordinates(latitude, longitude) {
var fullURL = "http://api.openweathermap.org/data/2.5/weather?lat=" + latitude + "&lon=" + longitude + "&APPID=75ed54453a6e806917cfa439b3fb1dd9&units=imperial";
$.getJSON(fullURL, function (data) {
var tempString = data.main.temp;
// removed "var tempNum"...
tempNum = parseInt(tempString);
roundTempF = Math.floor(tempNum);
stringF = roundTempF.toString();
tempStringFFull = stringF + "\xB0" + " F";
weather.innerText = tempStringFFull;
city.innerText = data.name;
weatherDescription.innerText = data.weather[0].description;
if (data.dt > data.sys.sunrise && data.dt < data.sys.sunset) {
$("#whole-page").removeClass("whole");
$("#whole-page").removeClass("night");
$("#whole-page").addClass("day");
}
else {
$("#whole-page").removeClass("whole");
$("#whole-page").removeClass("night");
$("#whole-page").addClass("night");
};
event.preventDefault();
});
//return tempNum;
};
// removed the argument "tempNum", just use the global
function typeConversion() {
if (changeTempType.innerText === "Celsius") {
var tempStringC;
var celsiusDecimal = (tempNum - 32) * (5 / 9);
roundTempC = Math.floor(celsiusDecimal);
tempStringC = roundTempC.toString();
tempStringC += "\xB0" + " C";
weather.innerText = tempStringC;
changeTempType.innerText = "Farenheit";
return;
}
else if (changeTempType.innerText === "Farenheit") {
weather.innerText = tempStringFFull;
changeTempType.innerText = "Celsius";
return;
}
else {
weather.innerText = "We are unable to retrieve the weather at this time. Please try again later";
changeTempType.innerText = "Celsius";
return;
};
};
var changeTempType = document.getElementById("change-temp-type");
changeTempType.addEventListener("click", typeConversion, false);
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<link href="https://gitcdn.github.io/bootstrap-toggle/2.2.2/css/bootstrap-toggle.min.css" rel="stylesheet"/>
<link rel="stylesheet" type="text/css" href="css/style.css" />
<script defer src="https://use.fontawesome.com/releases/v5.0.6/js/all.js"></script>
<title>Weather</title>
</head>
<body id="whole-page" class="whole">
<div class="wrapper">
<h2 id="header">Check the Current Temperaturate by Zip Code</h2>
<label>Farenheit</label>
<input type="radio" name="temp-type" value="C" id="Celsius-radio"/><label>Celsius</label>-->
<button id="change-temp-type">Celsius</button>
<form>
<p>Enter the Zip Code to see the Weather there!</p>
<input id = "Zip-Code" type="text"/>
<input id = "submit-zip" type="button" value="Get Weather!"/>
</form>
<div>
<h3 id="city"></h3>
<h3 id= "Weather" class="temp-text"></h3>
<h4 id="weather-description"></h4>
</div>
</div>
<script src= "https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.js"> </script>
<script src="javascript/main.js"></script>
</body>
</html>
Last note - this will work fine if the function where you need to access tempNum runs later, like in response to a user action. It may still be undefined for a few ms after your page loads, so if you try to use it right at page load time, it may still be undefined. You may want to initialize it to some default value in this case.
Hope this helps.

how to draw polygons one above another polygon

I'm new to google maps api ,i'm trying to draw polygons using google maps api , I want to show the project of the polygon and that project polygon above (inside) allow to draw the building polygon.
I'm trying to clear all my polygon objects before I import new geoJSON data and create new objects.I can't seem to get the setMap(null) function to work correctly. Hopefully someone can kindly let me know where I am failing.
demo
<script type="text/javascript" src="http://maps.google.com/maps/api/js?libraries=geometry,places&sensor=true"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<input type="hidden" id="center_point" value="12.939884,77.62540710000007" />
<input type="hidden" id="projectPolygon" value="" />
<input type="hidden" id="autocompleteLat" value="12.939884" />
<input type="hidden" id="autocompleteLng" value="77.62540710000007" />
<input type="hidden" id="poly_map_codes" value="" />
<input type="hidden" id="zoom_level" value="18" />
<textarea id="xml_valuesMain" style="display:none;">[{"source":"project","latlng":[{"lat":"12.940573081014005","lng":"77.62384235858917"},{"lat":"12.940656731834343","lng":"77.62625098228455"},{"lat":"12.939532671591135","lng":"77.6263153553009"},{"lat":"12.939564040782932","lng":"77.62391209602356"}]}]</textarea>
<textarea id="xml_values" style="display:none;">[{"source":"project","latlng":[{"lat":"12.940573081014005","lng":"77.62384235858917"},{"lat":"12.940656731834343","lng":"77.62625098228455"},{"lat":"12.939532671591135","lng":"77.6263153553009"},{"lat":"12.939564040782932","lng":"77.62391209602356"}]}]</textarea>
<div id="init_map" style="height: 600px;"></div>
<script>
$(function(){
initMap();
});
function initMap()
{
var polygons = [];
var coordinates = [];
var markers=[];
var latt=$('#autocompleteLat').val();
var lngg=$('#autocompleteLng').val();
var amsterdam = new google.maps.LatLng(latt,lngg);
var zoom_level=parseInt($('#zoom_level').val());
var map = new google.maps.Map(document.getElementById('init_map'),{ center: amsterdam, zoom: zoom_level, mapTypeId:google.maps.MapTypeId.SATELLITE });
drawSecondPolygon();
function drawSecondPolygon()
{
google.maps.event.trigger(map, 'refresh');
var data =$('#xml_values').val();
var jsonData = JSON.parse(data);
var polygons = [];
console.log("polygon length="+polygons.length);
for( var i = 0; i < polygons.length; i++ )
{
polygons[i].setMap(null)
}
polygons.length = 0;
for (var i = 0; i < jsonData.length; i++)
{
var latArr = jsonData[i].latlng;
var source_d = jsonData[i].source;
arr = [];
for(j=0; j<latArr.length;j++)
{
var lat=latArr[j].lat;
var lng=latArr[j].lng;
arr.push(new google.maps.LatLng(parseFloat(lat),parseFloat(lng)));
}
if(source_d=="project") { var FillColor='#DA70D6'; var StrokeColr='#BA55D3'; var editval=false; }
else if(source_d=="tower") { var FillColor='#FF8800'; var StrokeColr='#FF8800'; var editval=true; }
else if(source_d=="amenity") { var FillColor='#990000'; var StrokeColr='#990000'; var editval=false; }
else { var FillColor='#66FF00'; var StrokeColr='#66FF00'; var editval=false; }
polygons.push(new google.maps.Polygon({
paths: arr,
Source:source_d,
strokeColor: StrokeColr,
strokeOpacity: 0.8,
strokeWeight: 2,
editable:editval,
clickable:true,
fillColor: FillColor,
fillOpacity: 0.35
}));
console.log("polygons.length="+polygons.length);
polygons[polygons.length-1].setMap(null);
polygons[polygons.length-1].setMap(map);
if(editval==false)
{
console.log("Something working fine");
google.maps.event.addListener(polygons[polygons.length-1], 'click', function (clickEvent)
{
polygons[polygons.length-1].setMap(null);
var newLatLng=$('#poly_map_codes').val();
var clickEventLat=clickEvent.latLng.lat();
var clickEventLng=clickEvent.latLng.lng();
if(newLatLng!='') { newLatLng+=","+clickEventLat+" "+clickEventLng; }
else { newLatLng+=clickEventLat+" "+clickEventLng; }
$('#poly_map_codes').val(newLatLng);
//console.log(newLatLng);
//drawSecondPolygon();
if(newLatLng)
{
var getLatLng=newLatLng;
var getLatLngArr=getLatLng.split(",");
var main_LatLngArr=[];
for(i=0; i<getLatLngArr.length; i++)
{
var my_object={};
var getLatLngExp=getLatLngArr[i].split(" ");
my_object.lat=getLatLngExp[0];
my_object.lng=getLatLngExp[1];
main_LatLngArr.push(my_object);
}
var LatLngObj={};
LatLngObj.source="tower";
LatLngObj.latlng=main_LatLngArr;
var oldPolyArr=$('#xml_valuesMain').val();
var oldPolyArr=JSON.parse(oldPolyArr);
oldPolyArr.push(LatLngObj);
$('#xml_values').val(JSON.stringify(oldPolyArr));
polygons[polygons.length-1].setMap(null);
drawSecondPolygon();
console.log("oldPolyArr="+JSON.stringify(oldPolyArr));
}
});
}
}
}
}
</script>
At a first look you redeclare the var polygons = []; in your drawSecondPolygon function this override the content of the same variable declared in initMap ..
thi comment this line .. so you can use always the parent polygons array
function drawSecondPolygon()
{
google.maps.event.trigger(map, 'refresh');
var data =$('#xml_values').val();
var jsonData = JSON.parse(data);
//var polygons = [];

Google maps api v3 waypoints not showing on the map

I'm working on a google maps v3 project and i've come to a point where i need some help. I have a google map where the user can enter a start and end points, which works fine but when i want to enter waypoints for some reason they wont work( up to 8 waypoints ). Could someone look at the code and help me?
This is how far i have come with the project:
<!DOCTYPE html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title></title>
<link href="map_style.css" rel="stylesheet">
<script src="jquery-1.8.3.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
<script src="maps.js"></script>
<script type="text/javascript">
<!--
function toggle_visibility(id) {
var e = document.getElementById(id);
if(e.style.display == 'block')
e.style.display = 'none';
else
e.style.display = 'block';
}
//-->
</script>
</head>
<body onload="initialize()">
<div id="total"></div>
<div id="map-canvas"></div>
<div id="control_panel">
<div id="user_input">
<label for="start">Start :</label>
<input type="text" id="start" name="start" /><br />
<i>Add multiple Stops along the route (Optional)</i><br />
<ul id="stops">
<li>
<label for="stop1">Stop 1:</label>
<input type="text" id="stop1" name="stop1" />
</li>
</ul>
<input type="button" id="addScnt" value="Add Stop" /><br />
<label for="end">End :</label>
<input type="text" id="end" name="end" /><br />
<br />
<input type="submit" value="Create Route" onclick="calcRoute();" />
<input type="button" id="button" value="Show/Hide Directions" onclick="toggle_visibility('directions_panel');" />
</div>
</div>
<div id="directions_panel"></div>
</body>
</html>
And this is my js file:
$(document).ready(function () {
var scntUl = $('#stops');
var ii = $('#stops').size() + 1;
var MaxInputs = 8;
$('#addScnt').live('click', function () {
if (ii <= MaxInputs) {
$('<li><label for="stop' + ii +'">Stop ' + ii + ': </label><input type="text" id="stop' + ii +'" name="stop' + ii + '" /><input type="button" id="remScnt" value="X" /></li>').appendTo(scntUl);
ii++;
}
return false;
});
$('#remScnt').live('click', function () {
if (ii > 2) {
$(this).parents('li').remove();
ii--;
}
return false;
});
});
var directionDisplay;
var directionsService = new google.maps.DirectionsService();
var map;
function initialize() {
directionsDisplay = new google.maps.DirectionsRenderer();
var map = new google.maps.LatLng(37.09, -95.71);
var mapOptions = {
zoom: 4,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: map
}
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
directionsDisplay.setMap(map);
directionsDisplay.setPanel(document.getElementById("directions_panel"));
}
function calcRoute() {
var start = document.getElementById('start').value;
var end = document.getElementById('end').value;
var waypts = [];
for (var ii = 0; ii < thisStop; ii++) {
var thisStop = document.getElementById("stop" + (ii+1)).value;
if (thisStop.length > 0) {
if (thisStop.length > 0) {
waypts[ii] = {location: thisStop};
}
}
}
var request = {
origin: start,
destination: end,
waypoints: waypts,
optimizeWaypoints: false,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
var route = response.routes[0];
var summaryPanel = document.getElementById('directions_panel');
summaryPanel.innerHTML = '';
}
computeTotalDistance(response);
});
}
function computeTotalDistance(result) {
var totalDist = 0;
var totalTime = 0;
var myroute = result.routes[0];
for (i = 0; i < myroute.legs.length; i++) {
totalDist += myroute.legs[i].distance.value;
totalTime += myroute.legs[i].duration.value;
}
var miles = 0.000621371192;
document.getElementById("total").innerHTML = ("Total distance is: "+ (Math.round( totalDist * miles * 10 ) / 10 ) + " miles " + " and " + " Approximate time is: " + (totalTime / 60 / 60).toFixed(1) + " hours.");
}
If someone needs more info please let me know. Thank you
That's a lot of code to look at. Can you put up a test page, or even a fiddle?
In the meantime, I do see a problem here:
var scntUl = $('#stops');
var ii = $('#stops').size() + 1;
$('#stops') gives you a jQuery object for the <ul id="stops"> element itself, not its children. The length of this object will be 1 no matter how many <li> elements you add inside it. Perhaps you want $('#stops>li') instead? That will give you a jQuery object containing all of the <li> elements.
(BTW you can use the .length property instead of the .size() method - the method is there only for compatibility with old code.)
Also, why are you adding 1 to that length? I didn't look at the code much beyond that, but if you want the number of <li> elements you would just take .length as it is.
I also noticed that the <input> elements all have id="remScnt". You shouldn't use an id more than once; use a class or generate unique ids (or both).
One other thing - .live() is deprecated; use .on instead.
Updated after you posted the map link...
Take a look at this code:
for (var ii = 0; ii < thisStop; ii++) {
var thisStop = document.getElementById("stop" + (ii+1)).value;
if (thisStop.length > 0) {
if (thisStop.length > 0) {
waypts[ii] = {location: thisStop};
}
}
}
There are at least three or four problems here. But rather than try to fix this code as it is, why not take advantage of jQuery to make it easier?
First, go back to the code in your #addScnt click handler where it appends each new <li> into the DOM, and add a classname to the <input> tag, e.g.
<input class="waypoint" ...and the existing attributes here... />
And then where you have that loop above, change it to:
var waypts = [];
$('.waypoint').each( function( i, input ) {
var value = $(input).val();
if( value.length ) waypts.push({ location: value });
});
Note that this code no longer depends on the inputs having the IDs stop1, stop2, etc. Unless you need those IDs elsewhere, you can remove them.
Also I noticed you still have this code:
var scntUl = $('#stops>li');
var ii = $('#stops').length;
What do you think the value of ii will be here? Also, later you have this:
$('<li>...</li>').appendTo(scntUl);
That can't be right. Shouldn't this be appending to #stops itself? You're nesting <li> elements now, which is not what you intended.
Finally, use the Developer Tools in Chrome or another browser to troubleshoot these problems. SO is a great resource, of course, and questions here are always welcome. But it's even better when you can troubleshoot the problems you run into right now with the Developer Tools in Chrome or other browsers. It's worth spending some time exploring all the options available there. Start here for a tutorial on the Chrome DevTools.

Categories

Resources