1

I have managed to create a simple map with a marked route between 2 destinations. Additionally, I need to pull the distance value and then do some basic math with it (multiply it by 2). It all works, but not on page load. More precise, map is displayed on page load as well as distance, but distance value doesn't get pulled and it doesn't get multiplied by 2. I have managed to make it work on mouse move, but it's not the perfect replacement.

Here is the code:

<head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <meta charset="utf-8">
    <title>Directions</title>
    <link href="/maps/documentation/javascript/examples/default.css" rel="stylesheet">
    <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&region=US"></script>
    <script src="http://code.jquery.com/jquery-1.7.1.js" type="text/javascript"></script>
    <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/jquery-ui.min.js"></script>
    <script src="http://www.pengoworks.com/workshop/jquery/calculation/jquery.calculation.min.js" type="text/javascript"></script>
    <script>
        $(document).ready(function() {

            var rendererOptions = {
                draggable: false
            };
            var directionsDisplay = new google.maps.DirectionsRenderer(rendererOptions);;
            var directionsService = new google.maps.DirectionsService();
            var map;

            function initialize() {

                var mapOptions = {
                    zoom: 7,
                    mapTypeId: google.maps.MapTypeId.ROADMAP,
                };
                map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
                directionsDisplay.setMap(map);
                directionsDisplay.setPanel(document.getElementById('directionsPanel'));

                google.maps.event.addListener(directionsDisplay, 'directions_changed', function() {
                    computeTotalDistance(directionsDisplay.directions);
                });

                calcRoute();
            }

            function calcRoute() {

                var request = {
                    origin: 'Houston',
                    destination: 'Dallas',
                    travelMode: google.maps.DirectionsTravelMode.DRIVING
                };
                directionsService.route(request, function(response, status) {
                    if (status == google.maps.DirectionsStatus.OK) {
                        directionsDisplay.setDirections(response);
                    }
                });
            }

            function computeTotalDistance(result) {
                var total = 0;
                var myroute = result.routes[0];
                for (var i = 0; i < myroute.legs.length; i++) {
                    total += myroute.legs[i].distance.value;
                }
                total = total / 1000.
                document.getElementById('total').innerHTML = total + ' km';
            }

            google.maps.event.addDomListener(window, 'load', initialize);


            function stripint() {
                var val = $('[jsdisplay=distance]').text(); // get text content of <span jstcache="7">

                // Replace using regex instead of strings, to catch more than the first match
                val = val.replace(/\./g, "");
                val = val.replace(/,/g, ".");
                val = val.replace(/_/g, ",");

                $('#dist').val(val);
            }

            function recalc() {

                $("[id^='total_price_ht']").calc(
                // the equation to use for the calculation
                "di * 10", {
                    bind: "keyup",
                    di: $("[id^='dist']")
                }, function(s) {
                    // return the number as a dollar amount
                    return "$" + s.toFixed(2);
                });
            }

            $('#content').mousemove(function() {
                stripint();
                recalc();
            });

            stripint();
            recalc();
        });
    </script>
</head>

<body>
    <div id="content">
        <p>Distance: <span id="total"></span>

        </p>
        <input type="text" value="0" name="dist" id="dist" />
        <div id="total_price_ht_0" class="price">$0.00</div>
        <div id="map-canvas" style="width:100%; height:500px"></div>
        <div id="directionsPanel" style="width:100%; height:auto"></div>
    </div>
</body>

3 Answers 3

2
+50

first of all you don't need to use $(document).ready() because you already bind the initialize function to the window onLoad event google.maps.event.addDomListener(window, 'load', initialize);

what you want is wait until the directions and distance are calculated, you don't really need to read it from the directionsPanel, you can read whatever you need directly from the API response.

use the callback in calcRoute like this:

directionsService.route(request, function(response, status) {
  if (status == google.maps.DirectionsStatus.OK) {
    directionsDisplay.setDirections(response);
    dist = response.routes[0].legs[0].distance.text;
    stripint(dist);
    recalc();
  }
});

you also need to add the dist argument to you strprint:

function stripint(val) {

  // Replace using regex instead of strings, to catch more than the first match
  val = val.replace(/\./g, "");
  val = val.replace(/,/g, ".");
  val = val.replace(/_/g, ",");

  $('#dist').val(val);
}

so your new code doesn't use document.ready and calculates the price immediately when the API responds.

the new <script> tag:

var rendererOptions = {
    draggable: false
};
var directionsDisplay = new google.maps.DirectionsRenderer(rendererOptions);
var directionsService = new google.maps.DirectionsService();
var map;

function initialize() {

    var mapOptions = {
        zoom: 7,
        mapTypeId: google.maps.MapTypeId.ROADMAP,
    };
    map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
    directionsDisplay.setMap(map);
    directionsDisplay.setPanel(document.getElementById('directionsPanel'));

    google.maps.event.addListener(directionsDisplay, 'directions_changed', function () {
        computeTotalDistance(directionsDisplay.directions);
    });

    calcRoute();
}

function calcRoute() {

    var request = {
        origin: 'Houston',
        destination: 'Dallas',
        travelMode: google.maps.DirectionsTravelMode.DRIVING
    };
    directionsService.route(request, function (response, status) {
        if (status == google.maps.DirectionsStatus.OK) {
            directionsDisplay.setDirections(response);
            dist = response.routes[0].legs[0].distance.text;
            stripint(dist);
            recalc();
        }
    });
}

function computeTotalDistance(result) {
    var total = 0;
    var myroute = result.routes[0];
    for (var i = 0; i < myroute.legs.length; i++) {
        total += myroute.legs[i].distance.value;
    }
    total = total / 1000.
    document.getElementById('total').innerHTML = total + ' km';
}

google.maps.event.addDomListener(window, 'load', initialize);


function stripint(val) {

    // Replace using regex instead of strings, to catch more than the first match
    val = val.replace(/\./g, "");
    val = val.replace(/,/g, ".");
    val = val.replace(/_/g, ",");

    $('#dist').val(val);
}

function recalc() {

    $("[id^='total_price_ht']").calc(
        // the equation to use for the calculation
        "di * 10", {
            bind: "keyup",
            di: $("[id^='dist']")
        }, function (s) {
            // return the number as a dollar amount
            return "$" + s.toFixed(2);
        });
}
Sign up to request clarification or add additional context in comments.

1 Comment

What I want to add: Both directionsService.route (an ajax request in disguise) and directionsDisplay.setDirections seem to be asynchronous. For this reason, if you wouldn't retrieve the 'total distance' from the ajax request where stripint(dist); is now, and instead try to get the distance from $('[jsdisplay=distance]'), you'll find that at that point the distance is not yet in that field.
0

here is no need to have two tags; you can put everything inside one. Some of your functions use jQuery selectors, try to put all of them inside the $(document).ready(), this will guarantee that all the selected elements are available by the time they are called:

$(document).ready(function(){

  //Insert your functions with selectors here

});

Here is the rearranged code with everything inside document.ready: http://jsbin.com/iqejiy/1/edit

Hope it helps.

6 Comments

This would probably work, but I'm missing where to put it. I have set up a fiddle (jsfiddle.net/rbnUU), although for some reason it won't display the map. Where does it go, before the closing body tag? (<script>$(document).ready(function(){stripint();recalc();})();</script></body>)
@take2 Anything inside a $(document).ready(function(){}); can be placed anywhere after a call to the jquery library. It would be better to place both the call to the jQuery library and your code just before the </body> tag. The .ready() method makes sure the page has been loaded.
I have updated the fiddle: jsfiddle.net/rbnUU/3. I tested it on the browser and there are no error; now you must check if your functions work like you want. I would place all the <script> tags just before </body>; makes it load faster. If it worked for you, please accept the answer :)
Thank you rpabon, however for me still nothing has changed in the browser. What happens is: 1. The map gets loaded, directions are displayed and <span id="total"></span> gets populated. 2. However, for <input type="text" id="dist" name="dist" value="0"> and <div class="price" id="total_price_ht_0">$</div> to get populated mouse still has to be moved.
It seems that the problem is that inside the google maps container the jQuery events are not available, perhaps by the fact that the map has its own mouse events; I have no experience working with google maps, so I cannot offer you help there, sorry.
|
-1

i think you are missing document.ready() here.

4 Comments

How exactly should I implement it in this case? I have tried to change the last script to <script>$( document ).ready( recalc );</script>, but it doesn't change anything.
$(document).ready(function(){ //Insert the functions here });
-1 @aakashkrgoel: By inspecting the code, you could have seen this wouldn't have worked. Not -every- problem can be fixed by simply wrapping document.ready() around it, and this is one of them.
@Sumurai8: I agree..but i wrote this wrt the comment take2 left on this post, as the code statement in the comment was itself wrong.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.