I have code like this:
<input type="text" id="start" name="o">
<input type="text" id="end" name="d">
<input type="text" id="total" name="total" hidden="hidden">
<button onclick="calcRoute();" value="/index.php?route=information/mymove" >text</button>
<script>
function calcRoute() {
var start = document.getElementById('start').value;
var end = document.getElementById('end').value;
var request = {
origin: start,
destination: end,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
computeTotalDistance(response);
}
});
}
function computeTotalDistance(result) {
var total = 0;
var myroute = result.routes[0];
for (i = 0; i < myroute.legs.length; i++) {
total += myroute.legs[i].distance.value;
}
total = total / 1000.
document.getElementById("total").value = total + " km";
}
</script>
If I use this code for the button:
<input type="button" value="go" onclick="calcRoute();"> this executes the javascript function, but does not pass the data to another page.
I have also this part in the controller file:
if (isset($this->request->post['o'])) {
$data['o'] = $this->request->post['o'];
}
if (isset($this->request->post['d'])) {
$data['d'] = $this->request->post['d'];
}
if (isset($this->request->post['total'])) {
$data['total'] = $this->request->post['total'];
}
A few important things: you need to make this button a proper submit button, you need to make sure it returns callback as opposed to calling the function directly and you need to make sure the callback returns false. This is how to prevent default behaviour which would be sending the form without running the script.
<form action="index.php?route=information/mymove" method="post">
<input type="text" id="start" name="o">
<input type="text" id="end" name="d">
<input type="text" id="total" name="total" hidden="hidden">
<button type="submit" onclick="return calcRoute();">text</button>
</form>
<script>
function calcRoute() {
var start = document.getElementById('start').value;
var end = document.getElementById('end').value;
var request = {
origin: start,
destination: end,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
computeTotalDistance(response);
}
});
return false;
}
function computeTotalDistance(result) {
var total = 0;
var myroute = result.routes[0];
for (i = 0; i < myroute.legs.length; i++) {
total += myroute.legs[i].distance.value;
}
total = total / 1000.
document.getElementById("total").value = total + " km";
}
</script>
I think you should be able to modify the computeTotalDistance function so that once all the calculations are complete it will add the total value to the desired hidden input and then submit the form.
function computeTotalDistance(result) {
var total = 0;
var myroute = result.routes[0];
for (i = 0; i < myroute.legs.length; i++) {
total += myroute.legs[i].distance.value;
}
total = total / 1000;
document.getElementById("total").value = total + " km";
if( total && document.getElementById("total").value!='' ) document.getElementById("total").parentNode.submit();
}
Alternatively another option would be to use this same callback function to send and ajax request to the same endpoint url.
function computeTotalDistance(result) {
var total = 0;
var myroute = result.routes[0];
for (i = 0; i < myroute.legs.length; i++) {
total += myroute.legs[i].distance.value;
}
total = total / 1000;
document.getElementById("total").value = total + " km";
/* send the total by ajax to endpoint url */
ajax.call( this, url, 'total='+total, (r)=>{
alert(r);
} );
}
function ajax( url, params, callback ){
with( new XMLHttpRequest() ){
onreadystatechange=function(e){
if( this.status==200 && this.readyState==4 ){
callback.call( this.response )
}
}
open( 'POST', url, true );
setRequestHeader('Content-Type','application/x-www-form-urlencoded');
send( params );
}
}
It was not originally stated that you wished to view the total in another page, merely that you wished to send the value to another page. As that is a requirement then ajax, in this case, is not the best option at all - as there is a form it should be submitted as my initially modified function tries to do.
update:
Full example, tested and working which emulates what your code is trying to do.
<?php
if( $_SERVER['REQUEST_METHOD']=='POST' ){
/*
consider this as "another page" - the form has submitted to here
and you can see the POST data...
*/
exit(printf('<pre>%s</pre>',print_r($_POST,true)));
}
?>
<!doctype html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title>Google Maps: Route Calculations</title>
<style>
#map{
width:800px;
height:600px;
float:none;
margin:auto;
}
</style>
<script>
function initMap(){
let _lat = 56.55;
let _lng = -2.72;
let _form = document.querySelector( 'form[name="route-plotter"]' );
let latlng=new google.maps.LatLng( _lat, _lng );
let options = {
zoom: 10,
center: latlng,
mapTypeId: google.maps.MapTypeId.TERRAIN
};
let map = new google.maps.Map( document.getElementById('map'), options );
const calcroute=function(){
let request = {
origin: document.getElementById('start').value,
destination: document.getElementById('end').value,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
let directionsService = new google.maps.DirectionsService();
let directionsDisplay = new google.maps.DirectionsRenderer();
directionsService.route(request, function(response, status) {
if ( status == google.maps.DirectionsStatus.OK ) {
directionsDisplay.setDirections( response );
calculatedistance( response );
}
});
};
const calculatedistance=function(result){
let total=0;
let route=result.routes[0];
route.legs.forEach( leg=>{
total+=leg.distance.value;
});
document.getElementById('total').value=total;
_form.submit();
};
_form.querySelector('button').addEventListener('click',calcroute,false)
}
</script>
<script async defer src='//maps.googleapis.com/maps/api/js?key=APIKEY&callback=initMap'></script>
</head>
<body>
<div id='map'></div>
<form name='route-plotter' method="post">
<input type="text" id="start" name="start" value="dundee" />
<input type="text" id="end" name="end" value="aberdeen" />
<input type="text" id="total" name="total" hidden="hidden">
<button type="button">Go get the distance</button>
</form>
</body>
</html>
Related
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
I made a selectBox which had its range of values from a Google Sheet Column. I also want to take an Integer input value from the user and then write this value in a specific cell according to option taken from selectBox. The html link does not show the integer response box. Is it possible to do the above plan in a while loop? Would appreciate any ideas and correction of code
function doGet() {
var ap = SpreadsheetApp.openByUrl("Gsheet URL here");
var ui = SpreadsheetApp.getUi();
var user = ui.prompt("Put down a number");
var result = result.getSelectedButton();
var sheet = ap.getSheetByName("lv");
var values = sheet.getRange("A2:A10").getValues();
var options = values.map(function(row)
{
#To show show the selected option??
var item = options.getSelecteditem();
if (item === A3)
{
var cell = SpreadsheetApp.getActiveSheet().getActiveCell();
var a1 = cell.getA3Notation();
var val = cell.getValue();
SpreadsheetApp.getUi().alert("Ur value is "+a1+" value is "+val);
}
{
return '<option value="' + row[0] + '">' + row[0] + '</option>';
});
var html = '<form onSubmit="handleSubmit(this)"> Type of Cuisine' + options.join('') + '</select></form>';
return HtmlService.createHtmlOutput(html);
}
Using an Html Dialog to Control User Inputs
Not sure what you wanted so here's a complete example I whipped up for you.
Code.gs:
function processInput(obj) {
Logger.log(JSON.stringify(obj));
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName('Sheet0');
const [min,max,locs] = sh.getRange('B1:B3').getValues().flat();
Logger.log('min: %s max: %s locs: %s',min,max,locs)
const lA = locs.split(',');
if(obj.int > max) {
obj.msg = "Too High Try Again";
return obj;
} else if (obj.int < min) {
obj.msg = "To Low Try Again";
return obj;
} else if (!~lA.indexOf(obj.loc)) {
obj.msg = "Invalid Location";
return obj;
} else {
sh.getRange(obj.loc).setValue(obj.int);
obj.msg = "Complete";
return obj;
}
}
Following function Launches the dialog:
function launchInputDialog() {
SpreadsheetApp.getUi().showModelessDialog(HtmlService.createHtmlOutputFromFile('ah1'),"Enter Input");
}
html:
<!DOCTYPE html>
<html>
<head>
</head>
<style>input {margin: 2px 5px 2px 0;}</style>
<body>
<form>
<input type="text" id="in1" placeholder="Enter an integer" />
<br /><input type="text" id="in2" placeholder="Enter a location" />
<br /><input type="button" value="Process" onClick="processinput();" />
</form>
<div id="msg"></div>
<script>
function processinput() {
document.getElementById("msg").innerHTML = '';
let v1 = parseInt(document.getElementById('in1').value);
let v2 = document.getElementById('in2').value;
let obj = {int:v1,loc:v2,msg:''};
google.script.run
.withSuccessHandler(robj => {
console.log(JSON.stringify(robj))
if(robj.msg == "Complete") {
document.getElementById("msg").innerHTML = `Value: ${robj.int} Location: ${robj.loc} Try Again`;
document.getElementById("in1").value = '';
document.getElementById("in2").value = '';
} else {
document.getElementById("msg").innerHTML = robj.msg;
}
})
.processInput(obj);
}
</script>
</body>
</html>
Short Demo:
This version uses a <select> tag to allow the user to determine where the data will be loaded
GS:
function doPost(e) {
Logger.log(e.postData.contents);
Logger.log(e.postData.type);
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Sheet1");
let data = JSON.parse(e.postData.contents);
sh.getRange(data.loc).setValue(data.id)
}
function sendData(obj) {
const url = ScriptApp.getService().getUrl();
const params = { "contentType": "application/json", "payload": JSON.stringify(obj), "muteHttpExceptions": true, "method": "post", "headers": { "Authorization": "Bearer " + ScriptApp.getOAuthToken() } };
UrlFetchApp.fetch(url, params);
}
function displayError(msg) {
SpreadsheetApp.getUi().alert(msg);
}
function launchMyDialog() {
SpreadsheetApp.getUi().showModelessDialog(HtmlService.createHtmlOutputFromFile('ah1'), 'My Dialog');
}
function getSelectOptions() {
var ss = SpreadsheetApp.getActive();
var sh = ss.getSheetByName('Options');
var rg = sh.getDataRange();
var vA = rg.getValues();
var options = [];
for (var i = 0; i < vA.length; i++) {
options.push(vA[i][0]);
}
return vA;
}
HTML:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<form>
<input type="text" id="txt1" name="id" placeholder="Enter Numbers only"/>
<select id="sel1" name="loc"></select>
<input type="button" value="submit" onClick="processForm(this.parentNode);" />
</form>
<script>
function processForm(obj) {
console.log(obj.id.value);
if(obj.id.value.match(/[A-Za-z]/)) {
google.script.run.displayError("Invalid Characters Found in id field");
} else {
google.script.run.sendData(obj);
}
}
window.onload = function() {
google.script.run
.withSuccessHandler(updateSelect)
.getSelectOptions();
}
function updateSelect(vA) {
var select = document.getElementById("sel1");
select.options.length = 0;
for(var i=0;i<vA.length;i++) {
select.options[i] = new Option(vA[i],vA[i]);
}
}
</script>
</body>
</html>
Demo:
I have to select a marker in a map based on the button click. I have multiple marker with each marker associated to button below. I want to change "myloc" on that button click and by default it must select 13, 100.
Html
<div class="row">
<input type="button" id="btn-first" class="btn-a" value = "First">
<input type="button" id="btn-second" class="btn-a" value = "Second">
</div>
JS
let myloc = new L.LatLng(13, 100);
var map = L.map('map').setView(myloc, 12);
$(function () {
$('.btn-a').on('click', function(e){
e.preventDefault();
var clsName = $(this).val();
var lat, long;
if (clsName == 'First') {
lat = 13;
long = 100;
} else if(clasName = 'Second') {
lat = 14;
long = 101;
}
})
});
I dont see you setting the myLoc object anywhere. You are just assigning value for lat, lng. Check the snippet below to see if it answers your question.
Here, you initiliaze myLoc and on button click get new values for lat, lng and set it at the end again for myLoc
//just a temp function to show the example. Dont add this in your code
var L = {
LatLng: function(lat, lng) {
console.log("Current Values for Lat, Lng: " + lat + " , "+ lng);
}
}
let myloc = new L.LatLng(13, 100);
//var map = L.map('map').setView(myloc, 12);
$(function () {
$('.btn-a').on('click', function(e){
// e.preventDefault();
var clsName = $(this).val();
var lat, long;
if (clsName == 'First') {
lat = 13;
long = 100;
} else if(clasName = 'Second') {
lat = 14;
long = 101;
}
//set the myloc here
myloc = new L.LatLng(lat, long);
//then map again
//L.map('map').setView(myloc, 12)
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row">
<input type="button" id="btn-first" class="btn-a" value = "First">
<input type="button" id="btn-second" class="btn-a" value = "Second">
</div>
Below is an approach you can use, similar to what you we're doing. The example uses event delegation to monitor button clicks and then sets the lat and long variables accordingly. Those variables are then used to update the value of the global myLoc. I used an object literal in place of your new L.LatLng object for simplicity.
let myLoc = {
lat: 13,
long: 100
};
//new L.LatLng(13, 100);
document.querySelector('.row').addEventListener('click', function(e) {
if (e.target.type === 'button') {
let lat = 0;
let long = 0;
if (e.target.id === 'btn-first') {
lat = 13;
long = 100;
} else if (e.target.id === 'btn-second') {
lat = 14;
long = 101;
}
myLoc = {
lat,
long
};
console.log(`myLoc.lat: ${myLoc.lat}; myLoc.long ${myLoc.long}`);
//new L.LatLng(lat, long);
}
});
<div class="row">
<input type="button" id="btn-first" class="btn-a" value="First">
<input type="button" id="btn-second" class="btn-a" value="Second">
</div>
$(document).ready(function () {
$('.btn-a').each(function () {
$(this).click(function () {
var $this = $(this).val();
if ($this == 'First') {
$(this).val('One');
} else if ($this == 'Second') {
$(this).val('Two');
}
})
});
});
Here is the code I have so far. Someone posted it for people to use. It calculates distance well but when I try to calculate my delivery cost, it wont give me an error but it also won't output the value. The "$?" stays the same. I don't have a lot of experience coding and I've tried a number of things. I'm at a loss here. Please help!
<font face="cookie"><script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"> </script>
<!-- Browser key 1 -->
<script src="http://maps.google.com/maps? file=api&v=2&key=AIzaSyA9kMASRkOAbPFdzd4u5o_F0JyXKieOSQk" type="text/javascript"></script>
<script type="text/javascript">
//Initialize location vars
var location1;
var location2;
$(document).ready(function() {
console.log('test');
initialize();
//Grab the address values from the form on submit, and then run the maps code
$('#map-form').submit(function(event) {
//Also, stop the form from actually submitting
event.preventDefault();
address1 = $('#address1').val();
address2 = $('#address2').val();
//Run it, baby!
showLocation();
});
});
var geocoder, location1, location2;
function initialize() {
//Create new object of the google maps api
geocoder = new GClientGeocoder();
}
function showLocation() {
geocoder.getLocations(address1, function (response) {
if (!response || response.Status.code != 200)
{
alert("Sorry, we were unable to geocode address 1");
}
else
{
location1 = {lat: response.Placemark[0].Point.coordinates[1], lon: response.Placemark[0].Point.coordinates[0], address: response.Placemark[0].address};
geocoder.getLocations(address2, function (response) {
if (!response || response.Status.code != 200)
{
alert("Sorry, we were unable to geocode address 2");
}
else
{
location2 = {lat: response.Placemark[0].Point.coordinates[1], lon: response.Placemark[0].Point.coordinates[0], address: response.Placemark[0].address};
calculateDistance();
}
});
}
});
}
function calculateDistance()
{
try
{
var glatlng1 = new GLatLng(location1.lat, location1.lon);
var glatlng2 = new GLatLng(location2.lat, location2.lon);
var miledistance = glatlng1.distanceFrom(glatlng2, 3959).toFixed(1);
var kmdistance = (miledistance * 1.609344).toFixed(1);
//Write the value wherever you want!
$('#mile_distance').html(miledistance);
}
catch (error)
{
alert(error);
}
}
price = $('#price').val();
delivery = $('#delivery').val();
var miles = mile_distance - 25;
if (miles<0)
{
miles = 0;
}
var C = (miles * .575);
$('#price').val(C.toFixed(2));
var delivery_cost = 10;
var D = (delivery_cost + price);
$('#delivery').val(D.toFixed(2));
</script>
<form id="map-form">
<input type="text" placeholder="Address 1" id="address1" />
<input type="text" placeholder="Address 2" id="address2" />
<input type="submit" value="Submit" />
</form>
<p>The distance is: <span id="mile_distance">?</span> miles</p>
<p>Your delivery cost is: $<span id="delivery">?</span> </p>
</font>
The following code is not a part of any function and, therefore, will be executed immediately after it's loaded, even before your GUI fully appears on the screen.
price = $('#price').val();
delivery = $('#delivery').val();
var miles = mile_distance - 25;
if (miles < 0) {
miles = 0;
}
var C = (miles * .575);
$('#price').val(C.toFixed(2));
var delivery_cost = 10;
var D = (delivery_cost + price);
$('#delivery').val(D.toFixed(2));
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.