Sometimes we need to save geographical coordinates (latitude and longitude) where our employees do some transactions in Dynamics. This summer I strongly wanted to replace this geo-position system suggested by the community by other system:
Why I don´t like the old system? First it´s a Dotnet and could be not supported in all systems. Second, we need GPS capabilities in our device to run this. You might say “We always need GPS to get geolocation, don´t we?”, and the answer is a big no. All the webs catch our location no matter we have or not GPS in our device.
The IP approaches.
There are many services that can find my position using my IP address. You don´t need a GPS in your device.
We will test an IP geolocation service (http://ip-api.com/json), when a AL page is opening this way:
trigger OnOpenPage()
var
ClientWeb: HttpClient;
GeoResponse: HttpResponseMessage;
GeoContent: Text;
begin
GeoResponse.Content.ReadAs(GeoContent);
Message(GeoContent);
end;
And thanks for taking part, but this location is far from my home (Logrono, Spain):
You have probably already guessed the reason: the httpclient is executed in the server side, so this isn´t my home, is server home.
The best of both worlds.
Our browsers have a component that almost universally is supported in all devices, the component geolocation inside navigator component. In JavaScript could be invoked this way: navigator.geolocation.getCurrentPosition(showPosition);
I said above is the best of both worlds because it works this way: if your device has GPS (cell, tablet) returns GPS location. Otherwise it returns a very accurate position based in your client IP.
You can try here from several devices: https://www.w3schools.com/html/tryit.asp?filename=tryhtml5_geolocation and you will notice that works.
How I can use navigator geolocation from AL?
I gave up developing the system, but later I found the add-in and JavaScript integration, and all became easy. I told about it in this previous post: https://community.dynamics.com/nav/b/conceptsindailynavisionwork/archive/2018/11/23/javascript-and-al-the-regular-expressions-example
I will follow similar steps:
First, I create a new AL project.
Second a new script included in the project folder (file “GeoLocalizacion.js”):
function ObtenerPosicionJson(){
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(EnviarPosicionNAV)
} else {
alert("Geolocation is not supported by this browser.");
}
}
function EnviarPosicionNAV(position) {
const MiLocalizacion = {"Latitude": position.coords.latitude,
"Longitude": position.coords.longitude};
Microsoft.Dynamics.NAV.InvokeExtensibilityMethod('PosicionCargadaJSon', [MiLocalizacion]);
};
Declare a new add-in control in AL, to connect the Script to AL (file “GeoLocation.al”):
controladdin ControlGeografico
{
Scripts = 'GeoLocalizacion.js';
procedure ObtenerPosicionJson();
event PosicionCargadaJSon(Posicion: JsonObject);
}
Create a new Page with this controls (file “Page50106.al”):
field("Posicion geografica"; TextoPosicion)
{
ApplicationArea = All;
}
usercontrol(ControlName; ControlGeografico)
{
ApplicationArea = All;
trigger PosicionCargadaJSon(Posicion: JsonObject)
begin
Posicion.WriteTo(TextoPosicion);
end;
And a page action to call the script trough the add-in control declared:
actinon(CoordenadasJson)
{
Caption = 'Obtener coordenadas Json';
ApplicationArea = All;
trigger OnAction()
begin
CurrPage.ControlName.ObtenerPosicionJson();
end;
}
If we run the AL project, when we push “Obtener coordenadas JSON” action, we get our real geolocation in the text box:
Mechanism recap.
- From new AL page: When we push action “CoordenadasJSON”, we call JavaScript function “ObtenerPosicionJson”.
- At the end of this code JavaScript returns control to AL Page again with “Microsoft.Dynamics.NAV.InvokeExtensibilityMethod” statement.
- Back to the AL page, trigger “PosicionCargadaJSon” is executed and leaves the result in text box “TextoPosicion”.
The bridges between AL and JavaScript are:
- Control add-in declaration in a file.
- The add-in control declaration in the page.
*This post is locked for comments