Search code examples
jquerygoogle-maps-api-3prepend

Prepend to Gmaps directions element


I'm using the Google Maps JavaScript API and I would like to prepend the phrase "Starting From" to the ".adp-placemark" class that is included in the directions output by Google:

$('.adp-placemark').prepend('Starting From:');

The prepend is not working. However, if I view the page and use the Console tool in Inspector and then run the above code it will prepend as it should.

Where do I place this code? I've also tried placing it in a separate function and inside document ready.

function initMap() {
  var directionsDisplay = new google.maps.DirectionsRenderer;
  var directionsService = new google.maps.DirectionsService;
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 7,
    center: {lat: 41.85, lng: -87.65}
  });
  directionsDisplay.setMap(map);
  directionsDisplay.setPanel(document.getElementById('right-panel'));

  var control = document.getElementById('floating-panel');
  control.style.display = 'block';
  map.controls[google.maps.ControlPosition.TOP_CENTER].push(control);

  var onChangeHandler = function() {
    calculateAndDisplayRoute(directionsService, directionsDisplay);
  };
  document.getElementById('start').addEventListener('change', onChangeHandler);
  document.getElementById('end').addEventListener('change', onChangeHandler);
}

function calculateAndDisplayRoute(directionsService, directionsDisplay) {
  var start = document.getElementById('start').value;
  var end = document.getElementById('end').value;
  directionsService.route({
    origin: start,
    destination: end,
    travelMode: 'DRIVING'
  }, function(response, status) {
    if (status === 'OK') {
      directionsDisplay.setDirections(response);
      $('.adp-placemark').prepend('Starting From:');
    } else {
      window.alert('Directions request failed due to ' + status);
    }
  });
}
html, body {
  height: 100%;
  margin: 0;
  padding: 0;
}
#map {
  height: 100%;
}
#floating-panel {
  position: absolute;
  top: 10px;
  left: 25%;
  z-index: 5;
  background-color: #fff;
  padding: 5px;
  border: 1px solid #999;
  text-align: center;
  font-family: 'Roboto','sans-serif';
  line-height: 30px;
  padding-left: 10px;
}
#right-panel {
  font-family: 'Roboto','sans-serif';
  line-height: 30px;
  padding-left: 10px;
}

#right-panel select, #right-panel input {
  font-size: 15px;
}

#right-panel select {
  width: 100%;
}

#right-panel i {
  font-size: 12px;
}
#right-panel {
  height: 100%;
  float: right;
  width: 390px;
  overflow: auto;
}
#map {
  margin-right: 400px;
}
#floating-panel {
  background: #fff;
  padding: 5px;
  font-size: 14px;
  font-family: Arial;
  border: 1px solid #ccc;
  box-shadow: 0 2px 2px rgba(33, 33, 33, 0.4);
  display: none;
}
@media print {
  #map {
    height: 500px;
    margin: 0;
  }
  #right-panel {
    float: none;
    width: auto;
  }
}
<div id="floating-panel">
  <strong>Start:</strong>
  <select id="start">
    <option value="chicago, il">Chicago</option>
    <option value="st louis, mo">St Louis</option>
    <option value="joplin, mo">Joplin, MO</option>
    <option value="oklahoma city, ok">Oklahoma City</option>
    <option value="amarillo, tx">Amarillo</option>
    <option value="gallup, nm">Gallup, NM</option>
    <option value="flagstaff, az">Flagstaff, AZ</option>
    <option value="winona, az">Winona</option>
    <option value="kingman, az">Kingman</option>
    <option value="barstow, ca">Barstow</option>
    <option value="san bernardino, ca">San Bernardino</option>
    <option value="los angeles, ca">Los Angeles</option>
  </select>
  <br>
  <strong>End:</strong>
  <select id="end">
    <option value="chicago, il">Chicago</option>
    <option value="st louis, mo">St Louis</option>
    <option value="joplin, mo">Joplin, MO</option>
    <option value="oklahoma city, ok">Oklahoma City</option>
    <option value="amarillo, tx">Amarillo</option>
    <option value="gallup, nm">Gallup, NM</option>
    <option value="flagstaff, az">Flagstaff, AZ</option>
    <option value="winona, az">Winona</option>
    <option value="kingman, az">Kingman</option>
    <option value="barstow, ca">Barstow</option>
    <option value="san bernardino, ca">San Bernardino</option>
    <option value="los angeles, ca">Los Angeles</option>
  </select>
</div>
<div id="right-panel"></div>
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script async defer
src="https://maps.googleapis.com/maps/api/js?sensor=false&callback=initMap">
</script>


Solution

  • EDIT: As mentioned in the comments the first solution was incomplete as the 'Starting from:' was added to both tables (which I missed the first time)

    In order to solve it using only CSS you could add nth-child(n) selectors to find the .adp-placemark you with to include the prepended text, like so:

        /* Pseudo-element to add 'Starting from:' to the first element that appears */
        .adp > div:nth-child(2) .adp-placemark::before {
          content: 'Starting from:';
          white-space: nowrap;
        }
    
        /* Pseudo-element to add 'Going to:' to the second element that appears */
        .adp > div:nth-child(3) .adp-placemark::before {
            content: 'Going to:';
            white-space: nowrap;
        }
    

    On the other hand since the right-panel code is been generated by the Google Maps Api I wouldn't attempt to programatically change the generated HTML, because eventually the API may provide a different structure, which would make the solution to fail (been the solution in js or css).


    One way to go about solving this issue would be to include a css pseudo-class to the .adp-placemark, removing the need to get the timing of the table rendering right, like so:

    .adp-placemark::before {
        content: 'Starting from:';
        white-space: nowrap;
    }
    

    I've also updated your snippet:

    function initMap() {
      var directionsDisplay = new google.maps.DirectionsRenderer;
      var directionsService = new google.maps.DirectionsService;
      var map = new google.maps.Map(document.getElementById('map'), {
        zoom: 7,
        center: {lat: 41.85, lng: -87.65}
      });
      directionsDisplay.setMap(map);
      directionsDisplay.setPanel(document.getElementById('right-panel'));
    
      var control = document.getElementById('floating-panel');
      control.style.display = 'block';
      map.controls[google.maps.ControlPosition.TOP_CENTER].push(control);
    
      var onChangeHandler = function() {
        calculateAndDisplayRoute(directionsService, directionsDisplay);
      };
      document.getElementById('start').addEventListener('change', onChangeHandler);
      document.getElementById('end').addEventListener('change', onChangeHandler);
    }
    
    function calculateAndDisplayRoute(directionsService, directionsDisplay) {
      var start = document.getElementById('start').value;
      var end = document.getElementById('end').value;
      directionsService.route({
        origin: start,
        destination: end,
        travelMode: 'DRIVING'
      }, function(response, status) {
        if (status === 'OK') {
          directionsDisplay.setDirections(response);
          $('.adp-placemark').prepend('Starting From:');
        } else {
          window.alert('Directions request failed due to ' + status);
        }
      });
    }
    html, body {
      height: 100%;
      margin: 0;
      padding: 0;
    }
    #map {
      height: 100%;
    }
    #floating-panel {
      position: absolute;
      top: 10px;
      left: 25%;
      z-index: 5;
      background-color: #fff;
      padding: 5px;
      border: 1px solid #999;
      text-align: center;
      font-family: 'Roboto','sans-serif';
      line-height: 30px;
      padding-left: 10px;
    }
    #right-panel {
      font-family: 'Roboto','sans-serif';
      line-height: 30px;
      padding-left: 10px;
    }
    
    #right-panel select, #right-panel input {
      font-size: 15px;
    }
    
    #right-panel select {
      width: 100%;
    }
    
    #right-panel i {
      font-size: 12px;
    }
    #right-panel {
      height: 100%;
      float: right;
      width: 390px;
      overflow: auto;
    }
    #map {
      margin-right: 400px;
    }
    #floating-panel {
      background: #fff;
      padding: 5px;
      font-size: 14px;
      font-family: Arial;
      border: 1px solid #ccc;
      box-shadow: 0 2px 2px rgba(33, 33, 33, 0.4);
      display: none;
    }
    
    /* Pseudo-element to add 'Starting from:' to the first element that appears */
    .adp > div:nth-child(2) .adp-placemark::before {
      content: 'Starting from:';
      white-space: nowrap;
    }
    
    /* Pseudo-element to add 'Going to:' to the second element that appears */
    .adp > div:nth-child(3) .adp-placemark::before {
        content: 'Going to:';
        white-space: nowrap;
    }
    
    
    @media print {
      #map {
        height: 500px;
        margin: 0;
      }
      #right-panel {
        float: none;
        width: auto;
      }
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id="floating-panel">
      <strong>Start:</strong>
      <select id="start">
        <option value="chicago, il">Chicago</option>
        <option value="st louis, mo">St Louis</option>
        <option value="joplin, mo">Joplin, MO</option>
        <option value="oklahoma city, ok">Oklahoma City</option>
        <option value="amarillo, tx">Amarillo</option>
        <option value="gallup, nm">Gallup, NM</option>
        <option value="flagstaff, az">Flagstaff, AZ</option>
        <option value="winona, az">Winona</option>
        <option value="kingman, az">Kingman</option>
        <option value="barstow, ca">Barstow</option>
        <option value="san bernardino, ca">San Bernardino</option>
        <option value="los angeles, ca">Los Angeles</option>
      </select>
      <br>
      <strong>End:</strong>
      <select id="end">
        <option value="chicago, il">Chicago</option>
        <option value="st louis, mo">St Louis</option>
        <option value="joplin, mo">Joplin, MO</option>
        <option value="oklahoma city, ok">Oklahoma City</option>
        <option value="amarillo, tx">Amarillo</option>
        <option value="gallup, nm">Gallup, NM</option>
        <option value="flagstaff, az">Flagstaff, AZ</option>
        <option value="winona, az">Winona</option>
        <option value="kingman, az">Kingman</option>
        <option value="barstow, ca">Barstow</option>
        <option value="san bernardino, ca">San Bernardino</option>
        <option value="los angeles, ca">Los Angeles</option>
      </select>
    </div>
    <div id="right-panel"></div>
    <div id="map"></div>
    <!-- Replace the value of the key parameter with your own API key. -->
    <script async defer
    src="https://maps.googleapis.com/maps/api/js?sensor=false&callback=initMap">
    </script>

    Hope it helps, Cheers.