Generate directions URL from two postcode fields

Forums Dynamic Forms for SharePoint Generate directions URL from two postcode fields

This topic contains 6 replies, has 2 voices, and was last updated by  Alexander Bautz 2 months ago.

  • Author
    Posts
  • #25684

    Maciek Grischke
    Participant

    I have a mileage form with three fields:

    Start Postcode
    End Postcode
    Miles (number)

    I’m trying to generate a google maps URL with two postcodes in this format:

    https://www.google.com/maps/dir/Postcode1/Postcode2

    but I can’t use field values in “HTML Section” (at least in my version: 4.4.3.45 (the latest version is playing up).

    What are the alternatives?

    I want the user to enter both postcodes, click on the link, take the miles from google maps page and enter it in the form manually. Unless there’s a way to automate this? ๐Ÿ˜€

  • #25690

    Alexander Bautz
    Keymaster

    To do this you must have a valid Google maps API key (https://developers.google.com/maps/documentation/directions/get-api-key) and ensure you have mapped your current page URL to it to make it work. Then add this to your tab (in a HTML section):

    <input style="width:150px;margin:5px;" type="button" onclick="showMilageForm()" value="Open map" />

    and add this to your Custom JS:

    function showMilageForm(){
        var p1 = getFieldValue("StartPostcode");
        var p2 = getFieldValue("EndPostcode");
        if(p1 === "" || p2 === ""){
            return;
        }
        var iframe = "<div style='width:600px;height:450px;'><iframe width='600' height='450' frameborder='0' style='border:0' src='https://www.google.com/maps/embed/v1/directions?origin="+p1+"&destination="+p2+"&key=YOUR_API_KEY_HERE' allowfullscreen></iframe></div>";
        console.log(iframe);
        spjs.dffs.alert({
            "title": "Calculate distance",
            "msg": iframe,
            "ok":function(){
                spjs.dffs.closeDlg();
            }
        });
    }

    Replace YOUR_API_KEY_HERE with your unique API key for the directions API.

    Please note that I’m not really familiar with the API settings and cannot guide you on how to enable and ensure your API key is valid for this use, but I guess you figure it out.

    Alexander

  • #25694

    Maciek Grischke
    Participant

    That’s amazing, thanks.

    It’s all good.

    Do you think there’s a way to paste the miles into a field after entering both postcodes? ๐Ÿ˜€

  • #25699

    Alexander Bautz
    Keymaster

    You would have to open the url in a new page and not in a dialog, but you can try it like this:

    function showMilageForm(){
        var p1 = getFieldValue("StartPostcode");
        var p2 = getFieldValue("EndPostcode");
        if(p1 === "" || p2 === ""){
            return;
        }
        var url = "https://www.google.com/maps/dir/"+p1+"/"+p2;
        var a = document.createElement("a");
        a.setAttribute("href",url);
        a.setAttribute("target","_blank");
        document.getElementsByTagName("body")[0].appendChild(a);
        a.click();
    }

    Alexander

  • #25701

    Maciek Grischke
    Participant

    Hi Alexander,

    I updated my reply a few times and I got it working now with my new API.

    Do you think thereโ€™s a way to paste the miles into a field after entering both postcodes? ๐Ÿ˜€

    I’m just investigating JS tutorials online. I’m sure there’s a way.

  • #25705

    Maciek Grischke
    Participant

    Ok I got it working using this code:

    function calcMileage() {
        var startPostcode = getFieldValue("StartPostcode");
        var endPostcode = getFieldValue("EndPostcode");
        var roundTrip = getFieldValue("RoundTrip");
        var origin1 = startPostcode;
    // var origin2 = 'Greenwich, England';
        var destinationA = endPostcode;
    // var destinationB = new google.maps.LatLng(50.087692, 14.421150);
    
        var service = new google.maps.DistanceMatrixService();
        service.getDistanceMatrix(
          {
        origins: [origin1],
        destinations: [destinationA],
        travelMode: 'DRIVING',
    //    transitOptions: TransitOptions,
    //    drivingOptions: DrivingOptions,
        unitSystem: google.maps.UnitSystem.IMPERIAL,
        avoidHighways: false,
        avoidTolls: false,
      }, callback);
      }
    
    function callback(response, status) {
            var roundTrip = getFieldValue("RoundTrip");
      if (status == 'OK') {
        var origins = response.originAddresses;
        var destinations = response.destinationAddresses;
    
        for (var i = 0; i < origins.length; i++) {
          var results = response.rows[i].elements;
          for (var j = 0; j < results.length; j++) {
            var element = results[j];
            var distance = element.distance.text;
            var duration = element.duration.text;
            var from = origins[i];
            var to = destinations[j];
            //console.log('distance');
            //console.log(distance);
            var miles = distance.split(" ");
            var miles2 = miles[0];
            //console.log(miles2);
            //alert(miles2);
    //setFieldValue("Miles",miles2);
            if (roundTrip === true) {
            var miles3 = parseFloat(miles) * 2;
            setFieldValue("Miles",miles3);
    //        alert(miles3);
            } else {
                setFieldValue("Miles",miles2);
                }
          }
        }
      }
    }
    

    but the above requires

    [script async defer src=https://maps.googleapis.com/maps/api/js?key=API_KEY">https://maps.googleapis.com/maps/api/js?key=API_KEY
    [/script]
    

    to be loaded first. I used square brackets for script tags so they don’t get deleted.

    I included this bit in the NewForm “Script Editor” web part.

    Alexander, is this the correct way? It works great, but I want to avoid API to be called every too many times.

  • #25720

    Alexander Bautz
    Keymaster

    Hi,
    I’m glad you were able to figure it out. I’m not familiar with the maps api and cannot really tell if it is OK or not, but as long as it works your only concern (as you already stated) is whether or not the api calls will be so frequent that you need to pay for the traffic. You can see the usage log in the api dashboard if you log in to the Google dashboard.

    Alexander

You must be logged in to reply to this topic.