Skip to content

Xojo and JavaScript – A Perfect Combination

In the newest version of the MBS Xojo Plugin 10.0 we offer functions for the use of JavaScript in your Xojo solutions. If you have a problem that you want to solve, you don’t have to reinvent the wheel again and again. Perhaps someone has already found a solution to this problem and shared the solution on the Internet. So start a search engine and try your luck. Special thanks to André Rinas whose site supplies very useful JavaScript snippets. This example is based on one of his JavaScript codes. Because you can use JavaScript code in your Xojo projects, you not need to convert an existing JavaScript function to Xojo syntax to use it directly in your projects.

In this example, I’ll show you a JavaScript that calculates the difference between two geo coordinates given by longitude and latitude. We will design a GUI with 4 Textfields. Two fields contains the longitude and latitude of the first coordinate, two other fields store the longitude and latitude of the second coordinate. Furthermore we need a label that shows the result of the calculation and a button to start it. Then we look at the JavaScript code.

For the calculation we need the longitude and latitude in the unit radiance. Because that we need a function that converts between angle and radiance since we have the coordinates in the unit angle. The formula for the calculation is y = x * Pi / 180. 

A JavaScript function for that looks like this:

function DegToRad( deg ) {         
        return deg * Math.PI / 180; 
}

The keyword “function” starts a function definition, followed by the function name. The parameters are written with brackets, just like in Xojo, but without data type. The calculation for the function body is surrounded by curly brackets. Math.Pi is a built-in constant that defines Pi, so we use it here to do the math. 

Then we can write the function for the distance calculation:

function distance( lat1, lon1, lat2, lon2 ) {                
       var R = 6371; // The earth's radius in km

       lat1 = DegToRad(lat1);
       lat2 = DegToRad(lat2);
       lon1 = DegToRad(lon1);
       lon2 = DegToRad(lon2);
  
       var x = (lon2 - lon1) * Math.cos((lat1+lat2) / 2);
       var y = (lat2 - lat1);
       var d = Math.sqrt(x*x + y*y) * R;
       return d;
 
}
 

We have a function with four input parameters. That are the latitudes and longitudes of the coordinates. For each of these values we call the converting function and save the returned value in the variable again. Because these variables are defined as parameters of the function, we don’t need to declare them again. Moreover JavaScript has dynamic data types and internally uses doubles for all numbers. Because of this we don’t need to define them. All other variables (R, x, y and d) are explicitly declared with the keyword “var”. When using variables, we must pay attention to the fact that JavaScript is a case-sensitive language. A and a would be two different variables!

This JavaScript function is perfect for our use. Now we want to look at the possibilities to embedded it to our program.  At first we want to evaluate the JavaScript. Because that we create a new instance of the JavaScriptEngineMBS class and evaluate the JavaScript with the “Evaluate function”. In the parameter of the function we set our JavaScript as a string. Additionally, we append the call of the function in JavaScript syntax. 

	Dim js As New JavaScriptEngineMBS
	Dim r as Variant = js.Evaluate("function DegToRad( deg )  { return deg * Math.PI / 180 ; } function 	distance( lat1, lon1, lat2, lon2 ) { var R = 6371 ; lat1 = DegToRad(lat1); lat2 = DegToRad(lat2); lon1 = DegToRad(lon1); lon2 = DegToRad(lon2); var x = (lon2 - lon1) * Math.cos((lat1 + lat2) / 2); var y = (lat2 - lat1); var d = Math.sqrt(x * x + y * y) * R ; return d ; } distance( 50.73743, 7.0982068, 50.61, 7.2025);")

Then we have the result of the variable. The result is of type variant with an embedded double value. If we want the result as a string, we call the “EvaluateToString” function in place of the “Evaluate” function with the same parameters and the plugin performs toString operation in JavaScript if needed. 

It would be very annoying if we have to change the string of the JavaScript for each query by hand. Furthermore we want to calculate the difference between the coordinates that are set in the text fields and not between fix coordinates. One possibility to do this is to set global properties in JavaScript environment with the MBS Plugin functions.

Before we call one of the evaluation functions we set the variables like that: 

js.GlobalProperty("lat1") = LatitudeA.Text
js.GlobalProperty("lat2") = LatitudeB.Text
js.GlobalProperty("lon1") = LongitudeA.Text
js.GlobalProperty("lon2") = LongitudeB.Text

Then we replace the constant values in the function call, with our variables : 

distance( lat1, lon1, lat2, lon2 )

If we want to avoid setting this huge part of script in every evaluation function, we can add the DagToRad function and the distance function to the environment of the JavaScript. Then we only need to call the distance function with the right parameters. That is easier for debugging, too. Here the final example code:

Dim lat1 As String = LatitudeA.Text
Dim lat2 As String = LatitudeB.Text
Dim lon1 As String = LongitudeA.Text
Dim lon2 As String = LongitudeB.Text
Dim r As Variant 
 
Dim js As New JavaScriptEngineMBS
js.AddFunction "DegToRad", "function( deg ) { return deg * Math.PI / 180 ;}"  js.AddFunction "distance", "function( lat1, lon1, lat2, lon2 ) { lat1 = DegToRad(lat1); lat2 = DegToRad(lat2); lon1 = DegToRad(lon1); lon2 = DegToRad(lon2); var R = 6371; var x = (lon2-lon1) * Math.cos((lat1+lat2)/2); var y = (lat2-lat1); var d = Math.sqrt(x*x + y*y) * R; return d; }"
 r = js.CallFunction("distance", lat1, lon1, lat2, lon2)
 Result.Text = str(r, “####.##") 

Once the JavaScriptEngineMBS object is initialized, you can store it in a window property and reuse it several times to do more calculations. A great use for this JavaScript is to do calculations in your applications to match the hash/signature algorithm used by a web service to authenticate. If you get a JavaScript snippet, you can just run it, if required dependencies are provided. And you may find it useful to perform JavaScript server side for your Xojo web apps.

I hope that you like our new JavaScript functions. I wish you lots of fun with them. If you have any questions, please do not hesitate to contact us. 

Stefanie Juchmes studies Computer Science at the University of Bonn. She came in touch with Xojo due to the work of her brother-in-law and got a junior developer position in early 2019 at Monkeybread Software. You may have also read her articles in Xojo Developer Magazine