Using Google Maps API in Kintone?

I’m wondering if there is a way to connect Kintone Javascript to Google Maps API so we can use their functions. I’ve been trying it so far with no luck.

Hello James,

It is definitely possible to use Google Maps API in Kintone JavaScript customization. However, there is no detailed article written about it.

Though it should be possible by enabling Google Maps to call document.write after onload event and loading the Google API library (https://maps-api-ssl.google.com/maps/api/js?v=3&sensor=false).

Kintone Developer Program has two map-related tutorials:

There is a Japanese article about using Google Maps API in Kintone JavaScript customization:

Here is the relevant code with comments translated into English:

/*
 * Map display sample program
 * Copyright (c) 2013 Cybozu
 * Licensed under the MIT License
 */

(() => {

  'use strict';
  // Google Maps API Key
  const api_key = 'Your Google API key';

  // Add the element to the header
  const load = (src) => {
    const head = document.getElementsByTagName('head')[0];
    const script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = src;
    head.appendChild(script);
  };

  // Execute the Google Maps API
  const loadGMap = () => {
    // Define document.write
    const nativeWrite = document.write;
    document.write = (html) => {
      const m = html.match(/script.+src="([^"]+)"/);
      if (m) {
        load(m[1]);
      } else {
        nativeWrite(html);
      }
    };
    // Load the Google Map API library
    load('https://maps.googleapis.com/maps/api/js?v=3&key=' + api_key);
  };

  // Display a map using the value of the address field in the record display event
  kintone.events.on('app.record.detail.show', (event) => {

    // Based on the address information, display the map below the address field
    const drawMap = () => {
      if (kintone.app.record.getFieldElement('address').length === 0) {
        return;
      }
      // Verify that a "map_address" named element does not already exist
      if (document.getElementsByName('map_address').length !== 0) {
        return;
      }

      // Create a div element to display the map
      const mapAddressEl = document.createElement('div');
      mapAddressEl.setAttribute('id', 'map_address');
      mapAddressEl.setAttribute('name', 'map_address');

      // Add the element, set by mapAddressEl, to the space field placed in the "address_field" field
      const space = kintone.app.record.getSpaceElement('Map');
      space.appendChild(mapAddressEl);

      // Define a Google Geocoder
      const gc = new google.maps.Geocoder();

      // Get the value from the "address_field" field
      const rec = kintone.app.record.get();
      const addressValue = rec.record.address_field.value;

      // Execute the Geocoding API
      gc.geocode({
        address: addressValue,
        language: 'en',
        country: 'US'
      }, (results, status) => {
        if (status === google.maps.GeocoderStatus.OK) {

          // Specify the size of map elements
          mapAddressEl.setAttribute('style', 'width: 300px; height: 250px');

          const point = results[0].geometry.location;
          const address = results[0].formatted_address;

          // Set the map display settings (center position, zoom size, etc.)
          const opts = {
            zoom: 15,
            center: point,
            mapTypeId: google.maps.MapTypeId.ROADMAP,
            scaleControl: true
          };
          const map = new google.maps.Map(document.getElementById('map_address'), opts);

          // Set the marker
          new google.maps.Marker({
            position: point,
            map: map,
            title: address
          });
        }
      });
    };

    // Wait for Google Map to load
    const waitLoaded = (_timeout, interval) => {
      setTimeout(() => {
        const timeout = _timeout - interval;
        if ((typeof google !== 'undefined')
              && (typeof google.maps !== 'undefined')
              && (typeof google.maps.version !== 'undefined')) {
          drawMap(); // Show map based on address
        } else if (_timeout > 0) {
          waitLoaded(timeout, interval);
        }
      }, interval);
    };

    if (document.getElementsByName('map_latlng').length === 0) {
      loadGMap();
      waitLoaded(10 * 1000, 100);
    }
  });

})();

:warning: Above code will require the following in the Kintone App:

  • Text field with address_field as the field code
  • Space field with Map as the field code
1 Like

I have looked at those documents and what I want is not to display a map, but instead use the Distance Matrix API from Google so I can calculate the distance between two locations so we can use that to track gas mileage.

 

I’m wondering if their’s a way that I can just connect to my API key and then access different API’s that way such as:

 

var geocoder =new google.maps.Geocoder();  
  
var service =new google.maps.DistanceMatrixService();

I’m still working out a full solution, but I found many more helpful examples on the Cybozu developer website. I just had to use Chrome to translate the page to English from Japanese automatically, but they have a lot of good examples, such as this one:

Geolocation API(位置情報)を使ったモバイル用のカスタマイズをしよう – cybozu developer network

I’ll post a full solution once I finish.

I’ve figured out how to connect to Google Maps API and both the Distance Matrix Service and the Geocoder.

With help from Kintone’s Japanese Developer tutorial: 住所から地図を表示する - cybozu developer network

I was able to get it started and figure out the rest.

Like in the above article, I downloaded the customer database template that is already provided in Kintone.

Then, instead of adding a space field, I added a second label field across from the one already present and gave it a field name of address2 and changed the label header to End Address as well.

Here’s my full code for those that need help as well:

(() => {

  'use strict';
  // Google Maps API Key
  const api_key = 'Your Google API key';

  // Add the element to the header
  const load = (src) => {
    const head = document.getElementsByTagName('head')[0];
    const script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = src;
    head.appendChild(script);
  };

  // Execute the Google Maps API
  const loadGMap = () => {
    // Define document.write
    const nativeWrite = document.write;
    document.write = (html) => {
      const m = html.match(/script.+src="([^"]+)"/);
      if (m) {
        load(m[1]);
      } else {
        nativeWrite(html);
      }
    };
    // Load the Google Map API library
    load('https://maps.googleapis.com/maps/api/js?v=3&key=' + api_key);
  };

  // Display a map using the value of the address field in the record display event
  kintone.events.on('app.record.detail.show', (event) => {

    // Based on the address information, display the map below the address field
    const drawMap = () => {
      if (kintone.app.record.getFieldElement('address').length === 0) {
        return;
      }
      // Verify that a "map_address" named element does not already exist
      if (document.getElementsByName('map_address').length !== 0) {
        return;
      }

      // Create a div element to display the map
      const mapAddressEl = document.createElement('div');
      mapAddressEl.setAttribute('id', 'map_address');
      mapAddressEl.setAttribute('name', 'map_address');

      // Add the element, set by mapAddressEl, to the space field placed in the "address_field" field
      const space = kintone.app.record.getSpaceElement('Map');
      space.appendChild(mapAddressEl);

      // Define a Google Geocoder
      const gc = new google.maps.Geocoder();

      // Get the value from the "address_field" field
      const rec = kintone.app.record.get();
      const addressValue = rec.record.address_field.value;

      // Execute the Geocoding API
      gc.geocode({
        address: addressValue,
        language: 'en',
        country: 'US'
      }, (results, status) => {
        if (status === google.maps.GeocoderStatus.OK) {

          // Specify the size of map elements
          mapAddressEl.setAttribute('style', 'width: 300px; height: 250px');

          const point = results[0].geometry.location;
          const address = results[0].formatted_address;

          // Set the map display settings (center position, zoom size, etc.)
          const opts = {
            zoom: 15,
            center: point,
            mapTypeId: google.maps.MapTypeId.ROADMAP,
            scaleControl: true
          };
          const map = new google.maps.Map(document.getElementById('map_address'), opts);

          // Set the marker
          new google.maps.Marker({
            position: point,
            map: map,
            title: address
          });
        }
      });
    };

    // Wait for Google Maps to load
    const waitLoaded = (_timeout, interval) => {
      setTimeout(() => {
        const timeout = _timeout - interval;
        if ((typeof google !== 'undefined')
              && (typeof google.maps !== 'undefined')
              && (typeof google.maps.version !== 'undefined')) {
          drawMap(); // Show map based on address
        } else if (_timeout > 0) {
          waitLoaded(timeout, interval);
        }
      }, interval);
    };

    if (document.getElementsByName('map_latlng').length === 0) {
      loadGMap();
      waitLoaded(10 * 1000, 100);
    }
  });

})();
1 Like