Create a filemaker app that integrates google map api for drawing regions and testing coordinates.



A filemaker app that integrates google map api for drawing regions and testing coordinates. We will create this from scratch and hope you follow along.

------------WHAT THE APP DOES---------------------

Draw as many regions/areas as you want on the map using Google Maps polygons control and remember to name them. You can also edit the names of your areas in the "region" layout. These polygons will be used to check which coordinate belongs to which area on the map.






Enter your coordinates into the longitude and latitude fields in the region layout. Remember to use the "New Record" button.

You can also check and edit your coordinates from the dataLocation layout. You can as well import your coordinate into those fields, as you wish...



When your polygons and coordinate data are ready. Click the Start button IN THE REGION LAYOUT (Note: there are two start buttons. Use the one in "region" layout to send your data to the webviewer...







Then finally move to the "map" layout. This is where your map is. Click the start button here to compute areas. Areas will be computed for each coordinate and the result will be stored in the dataLocation layout table in JSON format, because a coordinate has many to many relationship with your areas or polygon... It will be easier if there is a one to one relationship though.



Note: Your coordinates data will be used to create markers for visual feedback so you can easily locate them and where they belong on the map.

You can also change the api key from the map layout...

You can also export your data to an external json file by running the appropriate scripts...from the script workspace.


----------FOLLOW THE INSTRUCTION TO CREATE THE APP--------------


PREREQUISITE:


TOOLS:


1. CREATE YOUR DATABASE AND TABLES:

In your local database, create two tables and name them anything you wish. In my own case, I named them: location and region.


In the location table, we will store majorly the coordinates information such as latitude and longitude data that we need to check. We would also leave a field for the areas they belong, however, we will not enter anything in this field directly because the result of this field will be calculated by our app. We can also enforce this from the field settings.


In the region table, we will have the names of each region we create using the Google Map's polygon control. More so, we will also create a field to store the coordinates of the vertices of our polygons commonly referred to as the polygon's paths.


You may be tempted to store the polygons directly rather than their paths. Well, it should be possible because an attempt to store the polygons in an array was successful, however, I find it to be a lot more efficient to just pass many polygon's data back and forth from Javascript to Filemaker through JSON, hence just one parameter that refer to the JSON, so I decided to JSON-encode the polygon's paths data, which is impossible with an MVCArray, i.e. the polygon object native type.


We will also have some global fields that we will use to pass our JSON data to the webviewer that harbors our map for region calculations. And maybe another one to hold our API key.


Finally on this part, since the area names will be the final output that will be written in the location's table, and since this same area names are the names also entered into the region's table from the polygons created directly in the map's layout, then we can create a relationship between our two tables using their region/area fields.


2. CREATE YOUR LAYOUTS:

Create three layouts. Name them anything you want as usual. However, I named mine: map, location and region. More so, it does not necessarily have to be like that. You can decide how you want to create yours.


The map layout will contain the map where polygons will be drawn. I decided to make it a full screen map so you have the full canvas for drawing polygons. Makes sense right?


The location layout will consist of the location table. There, you can enter or import the coordinates you wish to test.


The region layout will contain the polygon's data such as names and paths information. You may also have your global fields there and possibly resulting JSON data fields


3. CREATE YOUR SCRIPTS:

Now that your database and layouts are ready the next thing to do is create your scripts that passes your data back and forth and also do the calculations.


The first thing you want to do is create the javascript that will create the polygons, name them and pass the information to your filemaker app.


To do that, you need to create an HTML, CSS and Javascript program. The easiest way is to enter your program directly into the FileMaker WebViewer control.


However, I find it easy to test my JavaScript code out of FileMaker first before transferring it into FileMaker WebViewer. Following this approach, create a separate file and name it anything you want, I'll name mine "google.html".


Inside google.html, write or copy the following html code as a template:


<!DOCTYPE html>

<html>

  <head>    

  </head>

  <body>

  </body>

</html>


The first thing to do is add google map's dependency via the style tag as usual, after which, you will need to define the size of your map through CSS:


<!DOCTYPE html>

<html>

  <head>

    <style>

       /* Set the size of the div element that contains the map */

      #map {

        height: 400px;  /* The height is 400 pixels */

        width: 100%;  /* The width is the width of the web page */

       }

    </style>

    <script defer src='https://maps.googleapis.com/maps/api/js?key=AIzaSyCbO_rYdIovGZDxIvqaonxXGKf0Q6ErRuc&callback=initMap&libraries=drawing,geometry'>

    </script>

  </head>

  <body>

  </body>

</html>



Please note that I used "/* */" multi-line comment delimiter as opposed to "//" for single line comment, as this works better for Filemaker in general. Remember that we intend to transfer this code to FileMaker. 

Also note that we have added our API key, and both the drawing and geometry libraries to our google map script dependencies:


<script defer src='https://maps.googleapis.com/maps/api/js?key=AIzaSyCbO_rYdIovGZDxIvqaonxXGKf0Q6ErRuc&callback=initMap&libraries=drawing,geometry'>


The added callback (initMap) is the first function that will be called by default. It is added by default. Having done that, we shall add out elements. We need two elements:


1. A map element 


2.  A navigation component where we shall first hardcode the input box of our app to get latitude and longitude coordinates from the user. These coordinates will be used to check for which region a particular geographical point belongs. Remember we'll draw these polygons later on.


3. A submit button. This will be used to invoke the calculation function.



<!DOCTYPE html>

<html>

  <head>

    <style>

       /* Set the size of the div element that contains the map */

      #map {

        height: 400px;  /* The height is 400 pixels */

        width: 100%;  /* The width is the width of the web page */

       }

    </style>

    <script defer src='https://maps.googleapis.com/maps/api/js?key=AIzaSyCbO_rYdIovGZDxIvqaonxXGKf0Q6ErRuc&callback=initMap&libraries=drawing,geometry'>

    </script>

  </head>

  <body>

    <h3>My Google Maps Demo</h3>

    <nav>  

      <input id='lat' type='number' placeholder='Enter Latitude'>

      <input id='lon' type='number' placeholder='Enter Longitude'>

      <button id='submit'>Get Area</button>  

    </nav>



    <!--The div element for the map -->

    <div id='map' style="border: 1px solid red"></div>

</body>
<html>

Remember the initMap callback function?! It is time to define it. You use this function to initialize or configure your map as shown below. There are lots of ways to configure your map however, but for this app, we will only need to keep it simple as shown:


<!DOCTYPE html>

<html>

  <head>

    <style>

       /* Set the size of the div element that contains the map */

      #map {

        height: 400px;  /* The height is 400 pixels */

        width: 100%;  /* The width is the width of the web page */

       }

    </style>

    <script defer src='https://maps.googleapis.com/maps/api/js?key=AIzaSyCbO_rYdIovGZDxIvqaonxXGKf0Q6ErRuc&callback=initMap&libraries=drawing,geometry'>

    </script>

  </head>

  <body>

    <h3>My Google Maps Demo</h3>

    <nav>  

      <input id='lat' type='number' placeholder='Enter Latitude'>

      <input id='lon' type='number' placeholder='Enter Longitude'>

      <button id='submit'>Get Area</button>  

    </nav>

    <!--The div element for the map -->

    <div id='map' style="border: 1px solid red"></div>

    <script>

      var polyarray = [];

     

function initMap() {

  const map = new google.maps.Map(document.getElementById('map'), {

    center: { lat: -34.397, lng: 150.644 },

    zoom: 8,

  });

</script>

</body>

</html>


Notice the polyarray variable, i used it to hold the polygons drawn in main memory. You can load your map now (You may decide to load it through a local server if you wish) from the browser. 


Since we will use the drawing library to define the our regions, it is time to invoke and configure it using the inbuilt drawing manager as shown:


<!DOCTYPE html>

<html>

  <head>

    <style>

       /* Set the size of the div element that contains the map */

      #map {

        height: 400px;  /* The height is 400 pixels */

        width: 100%;  /* The width is the width of the web page */

       }

    </style>

    <script defer src='https://maps.googleapis.com/maps/api/js?key=AIzaSyCbO_rYdIovGZDxIvqaonxXGKf0Q6ErRuc&callback=initMap&libraries=drawing,geometry'>

    </script>

  </head>

  <body>

    <h3>My Google Maps Demo</h3>

    <nav>  

      <input id='lat' type='number' placeholder='Enter Latitude'>

      <input id='lon' type='number' placeholder='Enter Longitude'>

      <button id='submit'>Get Area</button>  

    </nav>

    <!--The div element for the map -->

    <div id='map' style="border: 1px solid red"></div>

    <script>

      var polyarray = [];

     

function initMap() {

  const map = new google.maps.Map(document.getElementById('map'), {

    center: { lat: -34.397, lng: 150.644 },

    zoom: 8,

  });


  const drawingManager = new google.maps.drawing.DrawingManager({

    drawingMode: google.maps.drawing.OverlayType.POLYGON,

    drawingControl: true,

    drawingControlOptions: {

      position: google.maps.ControlPosition.TOP_CENTER,

      drawingModes: [

        google.maps.drawing.OverlayType.MARKER,

        google.maps.drawing.OverlayType.CIRCLE,

        google.maps.drawing.OverlayType.POLYGON,

        google.maps.drawing.OverlayType.POLYLINE,

        google.maps.drawing.OverlayType.RECTANGLE

      ],

    },

    markerOptions: {

      icon:        'https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png',

    },    

  });

  drawingManager.setMap(map);

}

  

</script>

    

  </body>

</html>



For more information on the configuration options, visit the google maps API docs. Now you can draw on your map via four modes:


1. You can insert markers

2. You can draw lines

3.  You can draw circles and

4.  You can draw polygons. In this app, we only need the polygon and marker modes, so you can remove the other two.


We want to invoke a save function each time a polygon is drawn so we can use its data in our calculation. Also, you may need to know what coordinate a point has for testing purpose as we would when testing our app. I have included to functions. One to shout out the drawn marker coordinates and the other to prompt the user for the name of the polygon or region:



<!DOCTYPE html>

<html>

  <head>

    <style>

       /* Set the size of the div element that contains the map */

      #map {

        height: 400px;  /* The height is 400 pixels */

        width: 100%;  /* The width is the width of the web page */

       }

    </style>

    <script defer src='https://maps.googleapis.com/maps/api/js?key=AIzaSyCbO_rYdIovGZDxIvqaonxXGKf0Q6ErRuc&callback=initMap&libraries=drawing,geometry'>

    </script>

  </head>

  <body>

    <h3>My Google Maps Demo</h3>

    <nav>  

      <input id='lat' type='number' placeholder='Enter Latitude'>

      <input id='lon' type='number' placeholder='Enter Longitude'>

      <button id='submit'>Get Area</button>  

    </nav>

    <!--The div element for the map -->

    <div id='map' style="border: 1px solid red"></div>

    <script>

      var polyarray = [];

     

function initMap() {

  const map = new google.maps.Map(document.getElementById('map'), {

    center: { lat: -34.397, lng: 150.644 },

    zoom: 8,

  });

  const drawingManager = new google.maps.drawing.DrawingManager({

    drawingMode: google.maps.drawing.OverlayType.POLYGON,

    drawingControl: true,

    drawingControlOptions: {

      position: google.maps.ControlPosition.TOP_CENTER,

      drawingModes: [

        google.maps.drawing.OverlayType.MARKER,

      /*  google.maps.drawing.OverlayType.CIRCLE,*/

        google.maps.drawing.OverlayType.POLYGON

        /*google.maps.drawing.OverlayType.POLYLINE,*/

        /*google.maps.drawing.OverlayType.RECTANGLE,*/

      ],

    },

    markerOptions: {

      icon:

        'https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png',

    },    

  });


google.maps.event.addListener(drawingManager, 'markercomplete', function(marker) {  

  alert(marker.getPosition().lat() + ' ' + marker.getPosition().lng());

});


google.maps.event.addListener(drawingManager, 'polygoncomplete', function(polygon) {  

  var areaName = prompt('Enter Name of Area');

      

  let polyWithName = {polyObj:polygon, polyName:areaName};

  polyarray.push(polyWithName);          

});

  drawingManager.setMap(map);

}

  

</script>

    

  </body>

</html>



Lastly, we want to invoke our calculation function when the submit button is clicked. The callback function checks each polygon against the coordinate through the inbuilt poly.containsLocation( ) method.




<!DOCTYPE html>

<html>

  <head>

    <style>

       /* Set the size of the div element that contains the map */

      #map {

        height: 400px;  /* The height is 400 pixels */

        width: 100%;  /* The width is the width of the web page */

       }

    </style>

    <script defer src='https://maps.googleapis.com/maps/api/js?key=AIzaSyCbO_rYdIovGZDxIvqaonxXGKf0Q6ErRuc&callback=initMap&libraries=drawing,geometry'>

    </script>

  </head>

  <body>

    <h3>My Google Maps Demo</h3>


<nav>  

      <input id='lat' type='number' placeholder='Enter Latitude'>

      <input id='lon' type='number' placeholder='Enter Longitude'>

      <button id='submit'>Get Area</button>  

    </nav>

    <!--The div element for the map -->

    <div id='map' style="border: 1px solid red"></div>

    <script>

      var polyarray = [];

     

function initMap() {

  const map = new google.maps.Map(document.getElementById('map'), {

    center: { lat: -34.397, lng: 150.644 },

    zoom: 8,

  });

  const drawingManager = new google.maps.drawing.DrawingManager({

    drawingMode: google.maps.drawing.OverlayType.POLYGON,

    drawingControl: true,

    drawingControlOptions: {

      position: google.maps.ControlPosition.TOP_CENTER,

      drawingModes: [

        google.maps.drawing.OverlayType.MARKER,

      /*  google.maps.drawing.OverlayType.CIRCLE,*/

        google.maps.drawing.OverlayType.POLYGON

        /*google.maps.drawing.OverlayType.POLYLINE,*/

        /*google.maps.drawing.OverlayType.RECTANGLE,*/

      ],

    },

    markerOptions: {

      icon:

        'https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png',

    },    

  });


google.maps.event.addListener(drawingManager, 'markercomplete', function(marker) {  

  alert(marker.getPosition().lat() + ' ' + marker.getPosition().lng());

});


google.maps.event.addListener(drawingManager, 'polygoncomplete', function(polygon) {  

  var areaName = prompt('Enter Name of Area');


      

  let polyWithName = {polyObj:polygon, polyName:areaName};

  polyarray.push(polyWithName);          

});


  document.getElementById('submit').addEventListener('click', function() {

       

    var lat = document.getElementById('lat').value;

    var lon = document.getElementById('lon').value;

    

      if(lat <= 90 && lat >= -90 && lon <= 180 && lon >= -180) {                  

        var testPos = new google.maps.LatLng(lat, lon);


        var marker = new google.maps.Marker({

          position: testPos,

          map:map,

          draggable: true,

          animation: google.maps.Animation.DROP,    

        });


        var abc = [];

        polyarray.forEach(p => {

          var polygon = p.polyObj

          if (google.maps.geometry.poly.containsLocation(testPos, polygon)) {

            abc.push(p.polyName);

          }

        });

        setTimeout(

          function(){ 

            if (abc.length < 1) {

              alert('No Area');

            } else {

              alert(abc);

          }

        }, 3000);

      } else {

          alert('Error data');

      }

  });

  drawingManager.setMap(map);

}




</script>

    

  </body>

</html>



What we did was get the coordinates from our input boxes and then used them to create a latlng object which is needed to create a marker (Creating a marker is not necessary here, we only used it for visually identifying our points). We then queried out google map API to inform us if the coordinates is contained in any of the polygon (A point can be contained in many polygon and vice versa, making it a many-to-many relationship). We finally waited sometime for the query to complete using the setTimeout( ) function since the polygons to check may be many. You can adjust your time to accommodate for the number of polygons you may be querying against. In my own case, I used 3 seconds because I have few polygons. Using setTimeout to wait synchronuously is not a good approach, we will therefore change this approach to a better one shortly.



Also note that we have constrained the ranges of our coordinates using an if () statement. We want to ensure that latitude is within the range of -90 to 90 and longitude within -180 to 180.


You can now test your program, it should be working fine. If you have any error, make sure you have followed the procedure properly. 


The only downside is that you will lose all your work if you close and reopen your project, since all our data were stored in the volatile RAM. To correct this, we need to have a database, which in this case is obviously our FileMaker. Some changes will be made to our app in order to store our polygon data and resulting calculation data on Filemaker.


Copy and paste or type the following into your webviewer address box:



"data:text/html,<!DOCTYPE html>

<html>

  <head>

    <style>

       /* Set the size of the div element that contains the map */

      #map {

        height: 400px;  /* The height is 400 pixels */

        width: 100%;  /* The width is the width of the web page */

       }

    </style>

    <script defer src='https://maps.googleapis.com/maps/api/js?key=" & stef::apikey & "&callback=initMap&libraries=drawing,geometry'>

    </script>

  </head>

  <body>    

    <nav>      

      <button id='submit'>START</button>  

    </nav>

    <!--The div element for the map -->

    <div id='map'></div>

    <script>

      var polyarray = [];

var r = 0;     

function initMap() {

  const map = new google.maps.Map(document.getElementById('map'), {

    center: { lat: -34.397, lng: 150.644 },

    zoom: 8,

  });



  const drawingManager = new google.maps.drawing.DrawingManager({

    drawingMode: google.maps.drawing.OverlayType.POLYGON,

    drawingControl: true,

    drawingControlOptions: {

      position: google.maps.ControlPosition.TOP_CENTER,

      drawingModes: [

        google.maps.drawing.OverlayType.MARKER,      

        google.maps.drawing.OverlayType.POLYGON        

      ],

    },

    markerOptions: {

      icon:

        'https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png',

    },    

  });


google.maps.event.addListener(drawingManager, 'markercomplete', function(marker) {  

  alert(marker.getPosition().lat() + ' ' + marker.getPosition().lng());

});


google.maps.event.addListener(drawingManager, 'polygoncomplete', function(polygon) {

areaName = prompt('Enter Name of Area');  

var p = polygon.getPath().getArray(); 

var pl = [];

p.forEach(function(pb) {

 pc = pb.lat();

 pd = pb.lng();

 pe = {lat:pc, lng:pd};

 pl.push(pe);

});


  let polyWithName = {polyPath:pl, polyName:areaName};         

let pa = JSON.stringify(polyWithName);

theURL = 'fmp://$/" & Get ( FileName ) & "?script=updatedb&param=' + pa;

window.location = theURL ;

});


  drawingManager.setMap(map);


 var pod = " & region::regionJson & " ;

var l = 0;

var color = ['#ff4000', '#ffff00', '#4000ff', '#ffbf00', '#bfff00', '#00ffff', '#FFA07A', '#9ACD32'];


if (pod != null && pod !== undefined && pod.length > 0) {


pod.forEach(function(po) {


const pgon = new google.maps.Polygon({

    paths: po.polyObj.polyPath,

fillColor: color[l],

map: map

});

if (l >= color.length - 1) {l = 0;} else {

l++;

}


 });

}


}


document.getElementById('submit').addEventListener('click', function(e) {

       var polyData = " & region::regionJson & " ;

       var coordData = " & region::coordJson & " ;

if (polyData.length == 0) {alert('Wrong Data!'); return;}

if (coordData.length == 0) {alert('Wrong Data!'); return;}


var totalResult = [];


coordData.forEach(function(c) {

let lat = c.lat;

let lon = c.lon;


var coordResult = [];


 if(lat <= 90 && lat >= -90 && lon <= 180 && lon >= -180) {                  

        var latlon = new google.maps.LatLng(lat, lon);


        var marker = new google.maps.Marker({

          position: latlon,

          map: map,

          draggable: false,

          animation: google.maps.Animation.DROP,    

        });


var i = 0;

polyData.forEach(function(po) {


const pgon = new google.maps.Polygon({

    paths: po.polyObj.polyPath,

map: map

});


if (google.maps.geometry.poly.containsLocation(latlon, pgon)) {

var polyResult = {area: po.area};

coordResult.push(polyResult);

if (i === polyData.length-1) {i = 0; cont(coordResult, totalResult, coordData);} else { i++;} 

          } else {

var polyResult = {area: 'No Area'};

coordResult.push(polyResult);

if (i === polyData.length-1) {i = 0; cont(coordResult, totalResult, coordData);} else { i++;} 

    }

  });

}

});

});


function cont(coordResult, totalResult, coordData) {

var cr = [];

for(var i = 0; i <= coordResult.length - 1; i++) {

if (coordResult[i].area !== 'No Area') {

cr.push(coordResult[i]);

  }

 }

if(cr.length !== 0) {


var polyResult = {area: cr};

totalResult.push(polyResult);

if (r === coordData.length-1) {

r = 0; 

cont2(totalResult); 

} else { r++;} 

 } else {

var polyResult = {area: 'No Area'};

totalResult.push(polyResult);

if (r === coordData.length-1) {r = 0; cont2(totalResult);} else { r++;} 

 }

}


function cont2(totalResult) {

var pz = JSON.stringify(totalResult);

theURL = 'fmp://$/" & Get ( FileName ) & "?script=updateresult&param=' + pz;

window.location = theURL ;

}


</script>

    

  </body>

</html>"



All the things to note have been punched out by boldening. The First thing to note here is the "data:text/html," which is needed to inform FileMaker that you wish to load an html. The next is the "layout::apikey". I added a global apikey field to my layout table and referred to it using "layout::apikey" which is one way to refer to the data in a field. The idea is to store the your Google Map API key in this one (global) field so it can be changed by the user or used by many independent user.


We have also removed our input elements so we can store our coordinates directly in Filemaker. Like that, we have opportunities, for instance to save our coordinates for future use, etc. You can also store many coordinates in a table and use them in your calculations all at once. Great isn't it?! We left the start button to invoke our calculation JavaScript.


Also, since there is a general prejudice towards sending JSON from JavaScript frontends to servers and databases and vice versa, we will be using this approach as opposed to sending an array of data which has known issues. However, because we cannot JSONize (I mean serialize) polygon data directly, we used "polygon.getPath().getArray()" to get the needed path of each polygon, and then the coordinates of the vertices of the polygon using lat( ) and lng( ), and then send those to FileMaker instead, such that whenever we need the associated polygon, we reconstructed it using the path and latlng object.


We used

 

theURL = 'fmp://$/" & Get ( FileName ) & "?script=updatedb&param=' + pa;

window.location = theURL ;


to pass the the serialized data to FileMaker. For more information on that, check FileMaker specs.


Also take note of:

var pod = " & region::regionJson & ";

Note that Filemaker frowns generally at having a double quote within your html as you may want to include it. Direct double quotes are reserved for delimiting Filemaker statements and you use the & to concatenate. And because we referred to a field (regionJson) in our local Filemaker database region table (we could also have saved it in a Filemaker or Javascript variable), we had to concatenate it in order to make Filemaker syntax blend with our Javascript. The value in this field would be our serialized polygon data (since we need to render our polygon from this data so they can persist, it is better to convert them to json and reference them, which in turn is automatically converted to javascript object at runtime. Nice uh?! As you can see, I did not bother parsing the json). More so, we rendered these polygons using different colors. 

Finally on this, we did tried to avoid using ES6 syntaxes like the arrow function and async/await functionality even though we could have made our async app more efficient with them, simply because ES6 was generally not implemented in Filemaker 18 Pro, the version I used. Rather, I used a foreach and then controlled all asynchronization with a counting variable, "l" in this polygon render case.
Finally on my Javascript, is the implementation of the start callback which does the final calculation. Using the click event, I retrieved the serialized polygons data and the serialized coordinates data with the polyData and coordData variables respectively, stop the program if empty and then check each coordinate if contained in one or more of the polygon (created from the polygon data referenced by, a little change to the previous start callback.

Note that we used variables to control asynchronization while avoiding ES6 and then send the result as a json referenced by totalResult variable.

The Last Operation...

The last thing to do is to catch the JSON and store them in the necessary field using Filemaker script. But before we talk about this script, we need to discuss the 2 scripts that converted our polygon data and coordinates data inputs to json and stored them in region::regionJson and region::coordJson respectively.

Create two new Filemaker script in the script workspace. You can name them anything but mine are polyToJson and coordToJson. Type or copy and paste the following code polyToJson:


Type or copy and paste the following code coordToJson:


Create the third script and name it anything you want. Mine is updateDatabase. Type or copy and paste the following code updateDatabase:



I used a separate start button to trigger both coordToJson and regionToJson. Note that once coordToJson completes, regionToJson is triggered as shown in coordToJson script. I kept this button in the region's layout because all types of data can be entered via the region's layout. This implies that anytime a new record of coordinates are entered or whenever a polygon is drawn, this start button must first be clicked to convert all data to json and then the start button in the main layout page must be clicked to trigger the calculation.



You will also need to refresh your app whenever you change your API key field if necessary. You can then run your app. Weldone! 


Subscribe for more Filemaker tips. You may also follow me on Twitter, Youtube, Facebook and Instagram

To contact us, click on the "Contact Us" page above or add a comment below. We will get back to you sooner than you think. Thanks.



Ibukun Olofin is a senior software/systems developer
@Cardis since 2009, whose heart melts whenever he 
sees a sincere smile or laughter.

Hire Me!
+2348101691795
giftedcardis@outlook.com
bit.ly/cardisdevs








Cardis is proudly powered by:




...The World Needs You...

Comments

Popular posts from this blog

Solve Complex Maths Like ODE with Laplace, Maclaurin's Series Expansion, Fourier Series Expansion and the Heat Equation (PDE) with Matlab. [Cardis!]

Simplest Method To Create A Group Chat Web App 2020