Search code examples
javascriptjquerygoogle-mapstags

Getting text between option tags to use with Google Maps route calculator


Here is the section of Javascript I am working on. It displays the correct address for each part of the route segment, but I would like to be able to also have it display the text in between the option tags in the html so that I can identify which address belongs to which person. I figured Jquery would be the best way to do that, but I could not figure out how to get it to display the text between the option tags that corresponded to the starting address of the particular leg of the route. Is there a way to do this using Jquery?

  var totalTime = 0
  for (var i = 0; i < route.legs.length; i++) {
  var routeSegment = i + 1;

  travelTime.push(route.legs[i].duration.value);
  travelDistance.push(route.legs[i].distance.value);
  summaryPanel.innerHTML += 'Route Segment: ' + routeSegment + '<br>';
  var name = $("#waypoints option[value='route.legs[i]']").text()

  summaryPanel.innerHTML += name + '<br>';
  summaryPanel.innerHTML += route.legs[i].start_address + ' to ';
  summaryPanel.innerHTML += route.legs[i].end_address + '<br><br>';
  summaryPanel.innerHTML += route.legs[i].distance.text + '<br>';
  summaryPanel.innerHTML += route.legs[i].duration.text + '<br>';
  summaryPanel.innerHTML += '_________________________________________________' + '<br><br>'; 
  } 

HTML:

    <div id="map-canvas"></div>
    <div id="sidebar">
        <div id="text"><b>Start:</b>

            <select id="start">
                <option value="100 Main Street, Hartford, CT">Office Location</option>
            </select>
            <br> <b>Waypoints:</b> 
            <br> <i>(Ctrl-Click for up to 8 selections)</i> 
            <br>
            <select multiple id="waypoints">
                <option value="32 Storrs Road, Storrs, CT">John Smith</option>
                <option value="32 Elm Street, Enfield, CT">Jane Doe</option>
                <option value="2100 Hillside Road, Storrs, CT">Jonathan</option>
            </select>
            <br> <b>End:</b>

            <select id="end">
                <option value="100 Main Street, Hartford, CT">Office Location</option>
            </select>
            <br>
            <input type="submit" onclick="calcRoute();">
            <br>
            <br>
            <div id="directions_panel"></div>
            <div id="total_time"></div>
        </div>
    </div>

jsfiddle


Solution

  • There is a function in geoxml3 to parse out the text content of an HTML element:

    //nodeValue: Extract the text value of a DOM node, with leading and trailing whitespace trimmed
    // from geoxml3: https://code.google.com/p/geoxml3/source/browse/branches/polys/geoxml3.js
    function nodeValue(node, defVal) {
      var retStr="";
      if (!node) {
        return (typeof defVal === 'undefined' || defVal === null) ? '' : defVal;
      }
       if(node.nodeType==3||node.nodeType==4||node.nodeType==2){
          retStr+=node.nodeValue;
       }else if(node.nodeType==1||node.nodeType==9||node.nodeType==11){
          for(var i=0;i<node.childNodes.length;++i){
             retStr+=arguments.callee(node.childNodes[i]);
          }
       }
       return retStr;
    };
    

    If I change your code to create an array of "names" associated with each waypoint using that function to populate the array with the text content of each selected option element:

    function calcRoute() {
        var start = document.getElementById('start').value;
        var end = document.getElementById('end').value;
        var waypts = [];
        var names = [];
        var checkboxArray = document.getElementById('waypoints');
        for (var i = 0; i < checkboxArray.length; i++) {
            if (checkboxArray.options[i].selected == true) {
                waypts.push({
                    location: checkboxArray[i].value,
                    stopover: true
                });
                names.push(nodeValue(checkboxArray[i]));
            }
        }
        names.push("Office");
    

    Then they can be put in the sidebar like this:

    for (var i = 0; i < route.legs.length; i++) {
       var routeSegment = i + 1;
    
       travelTime.push(route.legs[i].duration.value);
       travelDistance.push(route.legs[i].distance.value);
       var name = $("#waypoints option[value='route.legs[i]']").text();
       summaryPanel.innerHTML += 'Route Segment: ' + routeSegment + '<br>';
       summaryPanel.innerHTML += 'to: ' + names[i] + '<br>';
       summaryPanel.innerHTML += name + '<br>';
       summaryPanel.innerHTML += route.legs[i].start_address + ' to ';
       summaryPanel.innerHTML += route.legs[i].end_address + '<br><br>';
       summaryPanel.innerHTML += route.legs[i].distance.text + '<br>';
       summaryPanel.innerHTML += route.legs[i].duration.text + '<br>';
       summaryPanel.innerHTML += '_________________________________________________' + '<br><br>';
    }
    

    working fiddle

    working code snippet:

    var directionsDisplay;
    var directionsService = new google.maps.DirectionsService();
    var map;
    var names = [];
    
    function initialize() {
      directionsDisplay = new google.maps.DirectionsRenderer();
      var connecticut = new google.maps.LatLng(41.6000, -72.7000);
      var mapOptions = {
        zoom: 10,
        center: connecticut
      }
      map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
      directionsDisplay.setMap(map);
    }
    
    function calcRoute() {
      var start = document.getElementById('start').value;
      var end = document.getElementById('end').value;
      var waypts = [];
      var names = [];
      var checkboxArray = document.getElementById('waypoints');
      for (var i = 0; i < checkboxArray.length; i++) {
        if (checkboxArray.options[i].selected == true) {
          waypts.push({
            location: checkboxArray[i].value,
            stopover: true
          });
          names.push(nodeValue(checkboxArray[i]));
        }
      }
      names.push("Office");
      var request = {
        origin: start,
        destination: end,
        waypoints: waypts,
        optimizeWaypoints: true,
        travelMode: google.maps.TravelMode.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 = '';
          var total = document.getElementById('total_time');
          total.innerHTML = '';
          var travelTime = [];
          var travelDistance = [];
          Array.prototype.sum = function() {
            for (var i = 0, L = this.length, sum = 0; i < L; sum += this[i++]);
            return sum;
          }
    
    
          // For each route, display summary information.
          var totalTime = 0
          for (var i = 0; i < route.legs.length; i++) {
            var routeSegment = i + 1;
    
            travelTime.push(route.legs[i].duration.value);
            travelDistance.push(route.legs[i].distance.value);
            var name = $("#waypoints option[value='route.legs[i]']").text();
            summaryPanel.innerHTML += 'Route Segment: ' + routeSegment + '<br>';
            if (route.waypoint_order && (i < route.waypoint_order.length)) {
              summaryPanel.innerHTML += 'to: ' + names[route.waypoint_order[i]] + '<br>';
            } else {
              summaryPanel.innerHTML += 'to: ' + names[i] + '<br>';
            }
            if (route.waypoints_order && i < route.waypoints_order
            summaryPanel.innerHTML += name + '<br>';
            summaryPanel.innerHTML += route.legs[i].start_address + ' to ';
            summaryPanel.innerHTML += route.legs[i].end_address + '<br><br>';
            summaryPanel.innerHTML += route.legs[i].distance.text + '<br>';
            summaryPanel.innerHTML += route.legs[i].duration.text + '<br>';
            summaryPanel.innerHTML += '_________________________________________________' + '<br><br>';
          }
    
    
    
    
          secondsTotal = travelTime.sum();
    
          function fromSeconds(sec) {
            var d = new Date(0, 0, 0);
            d.setSeconds(+sec);
            if (secondsTotal < 7200) {
              return (d.getHours() ? d.getHours() + ' hour and ' : '') + d.getMinutes() + ' minutes';
            } else {
              return (d.getHours() ? d.getHours() + ' hours and ' : '') + d.getMinutes() + ' minutes';
            }
          }
    
          milesTotal = Math.round(travelDistance.sum() * 0.000621371);
    
          // change to mpg of car 
          var mpg = 22;
          // change to cost of gas
          var costOfGas = 2.79;
          var fuelCost = ((milesTotal / mpg) * costOfGas).toFixed(2);
          var fuelReimbursement = (milesTotal * .2).toFixed(2);
          var fuelRemainder = (fuelReimbursement - fuelCost).toFixed(2);
    
    
    
          total.innerHTML += fromSeconds(secondsTotal) + ' total' + '<br>';
          total.innerHTML += milesTotal + ' miles total' + '<br><br>';
          total.innerHTML += 'Fuel cost: ' + '$' + fuelCost + '<br>';
          total.innerHTML += 'State reimbursement: ' + '$' + fuelReimbursement + '<br>';
          total.innerHTML += 'Amount leftover: ' + '$' + fuelRemainder;
    
    
        }
      });
    }
    
    google.maps.event.addDomListener(window, 'load', initialize);
    
    //nodeValue: Extract the text value of a DOM node, with leading and trailing whitespace trimmed
    // from geoxml3: https://code.google.com/p/geoxml3/source/browse/branches/polys/geoxml3.js
    function nodeValue(node, defVal) {
      var retStr = "";
      if (!node) {
        return (typeof defVal === 'undefined' || defVal === null) ? '' : defVal;
      }
      if (node.nodeType == 3 || node.nodeType == 4 || node.nodeType == 2) {
        retStr += node.nodeValue;
      } else if (node.nodeType == 1 || node.nodeType == 9 || node.nodeType == 11) {
        for (var i = 0; i < node.childNodes.length; ++i) {
          retStr += arguments.callee(node.childNodes[i]);
        }
      }
      return retStr;
    };
    html,
    body {
      height: 100%;
      margin: 0px;
      padding: 0px;
    }
    #map-canvas {
      float: left;
      width: 70%;
      height: 100%;
      position: fixed;
    }
    #sidebar {
      height: 100%;
      width: 30%;
      float: right;
      border-width: 2px;
      overflow: auto;
      font-family: "Arial", san-serif;
    }
    #waypoints {
      width: 400px;
      height: 150px;
      padding: 5px;
    }
    #directions_panel,
    #total_time {
      font-family: "Arial", san-serif;
      background-color: #FFFFFF
    }
    #total_time {
      font-weight: bold;
    }
    #text {
      margin: 12px;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script src="http://maps.google.com/maps/api/js"></script>
    <div id="map-canvas"></div>
    <div id="sidebar">
      <div id="text"><b>Start:</b>
    
        <select id="start">
          <option value="100 Main Street, Hartford, CT">Office Location</option>
        </select>
        <br> <b>Waypoints:</b> 
        <br> <i>(Ctrl-Click for up to 8 selections)</i> 
        <br>
        <select multiple id="waypoints">
          <option value="32 Storrs Road, Storrs, CT">John Smith</option>
          <option value="32 Elm Street, Enfield, CT">Jane Doe</option>
          <option value="2100 Hillside Road, Storrs, CT">Jonathan</option>
        </select>
        <br> <b>End:</b>
    
        <select id="end">
          <option value="100 Main Street, Hartford, CT">Office Location</option>
        </select>
        <br>
        <input type="submit" onclick="calcRoute();">
        <br>
        <br>
        <div id="directions_panel"></div>
        <div id="total_time"></div>
      </div>
    </div>