Generate directions URL from two postcode fields

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

Viewing 6 reply threads
  • 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

Viewing 6 reply threads
  • You must be logged in to reply to this topic.