Map Screen with Input Form

Robin Hearne
Tera Expert

I've created a new Map Screen to display Work Order Tasks and I need to prompt the user to enter some values before the screen loads in order to pre-filter the results.   One of the inputs is a 'radius' to limit the results to tasks that are within a certain distance from the user's current location.   I'm hoping to get some help from the community to let me know how to achieve this.

 

Essentially what I'm try to achieve is the same as the OOTB 'Available Parts' Map Screen but with WOTs instead of Assets.  However, that screen uses legacy UI Parameters as inputs so I don't want to copy that configuration.  I believe that I will need to use an Input form screen but I need help with how to create the input for the 'Radius' and then use that to filter the Data item.

 

Thanks in advance.

 

Robin

1 ACCEPTED SOLUTION

Robin Hearne
Tera Expert

I was able to figure this out as it didn't turn out to be too tricky,  I'll post some highlights here in case it's of help to anyone else.  If you need more detail then just let me know via a reply.

 

Here are the steps involved:

  1. Using Mobile App Builder, I navigated to my Map screen configuration page and created a new 'Input form screen'
  2. On the Input form screen configuration page I create a new Input named "Radius" of type Number
  3. Going back to the Input from screen configuration page I then created a new Variable named "Location" and type GPS Coordinates
  4. I then navigated to the Data item configuration page and created two Parameter records, one named "radius" and the other named "location".
  5. Next, I navigated back to the Map screen page and added two entries to the "Input/variable to data item parameter mapping" list.  The first maps the 'Radius' Input to the 'radius' Parameter and the other maps the 'Location' variable to the 'location' Parameter.
  6. After that I consumed the location and radius values in the Query condition script for my Data item to build the required query.

The biggest issue was step 6 and trying to parse the longitude and latitude values so that I could use them in my script.  I figured that I'd be able to use the same script as was used by the Available parts screen but that script threw and error when attempting to use the split method.  I can only assume that the GPS location string value is different when using legacy UI Parameters vs using Variables.  Digging deeper I found that the location string contained a value formatted as below:

{Latitude=51.119883333333334, Longitude=-0.18944333333333332} 

I was unable to find an easy way to parse the values and ended up with the following (thanks ChatGPT!)

//Convert the Location string into an object
var location = input.location;
// Create an empty object to hold the parsed key-value pairs
var obj = {};
// Use a regular expression to match key-value pairs
var regex = /(\w+)=([-\d.]+)/g;
var match;
while ((match = regex.exec(location)) !== null) {
	// match[1] is the key, match[2] is the value
	obj[match[1]] = parseFloat(match[2]); // Store the key-value pair in the object
}
var userLong = obj.Longitude;
var userLat = obj.Latitude;

If anyone is able to provide a neater way to do this then please do let me know!

The section of the script to build the query was largely taken from the original script for the Available parts screen:

var queryWithLocation = '';
if (userLat && userLong) {
      var latOffset = input.radius / 69;
      var longOffset = latOffset * Math.cos(userLat * (Math.PI / 180));
      var long1 = Number(userLong) + Number(longOffset);
      var long2 = Number(userLong) - Number(longOffset);
      var lat1 = Number(userLat) + Number(latOffset);
      var lat2 = Number(userLat) - Number(latOffset);
    
       queryWithLocation += "^location.longitude<=" + long1;
       queryWithLocation += "^location.longitude>=" + long2;
       queryWithLocation += "^location.latitude<=" + lat1;
       queryWithLocation += "^location.latitude>=" + lat2;
}
return queryWithLocation;

 

 

View solution in original post

1 REPLY 1

Robin Hearne
Tera Expert

I was able to figure this out as it didn't turn out to be too tricky,  I'll post some highlights here in case it's of help to anyone else.  If you need more detail then just let me know via a reply.

 

Here are the steps involved:

  1. Using Mobile App Builder, I navigated to my Map screen configuration page and created a new 'Input form screen'
  2. On the Input form screen configuration page I create a new Input named "Radius" of type Number
  3. Going back to the Input from screen configuration page I then created a new Variable named "Location" and type GPS Coordinates
  4. I then navigated to the Data item configuration page and created two Parameter records, one named "radius" and the other named "location".
  5. Next, I navigated back to the Map screen page and added two entries to the "Input/variable to data item parameter mapping" list.  The first maps the 'Radius' Input to the 'radius' Parameter and the other maps the 'Location' variable to the 'location' Parameter.
  6. After that I consumed the location and radius values in the Query condition script for my Data item to build the required query.

The biggest issue was step 6 and trying to parse the longitude and latitude values so that I could use them in my script.  I figured that I'd be able to use the same script as was used by the Available parts screen but that script threw and error when attempting to use the split method.  I can only assume that the GPS location string value is different when using legacy UI Parameters vs using Variables.  Digging deeper I found that the location string contained a value formatted as below:

{Latitude=51.119883333333334, Longitude=-0.18944333333333332} 

I was unable to find an easy way to parse the values and ended up with the following (thanks ChatGPT!)

//Convert the Location string into an object
var location = input.location;
// Create an empty object to hold the parsed key-value pairs
var obj = {};
// Use a regular expression to match key-value pairs
var regex = /(\w+)=([-\d.]+)/g;
var match;
while ((match = regex.exec(location)) !== null) {
	// match[1] is the key, match[2] is the value
	obj[match[1]] = parseFloat(match[2]); // Store the key-value pair in the object
}
var userLong = obj.Longitude;
var userLat = obj.Latitude;

If anyone is able to provide a neater way to do this then please do let me know!

The section of the script to build the query was largely taken from the original script for the Available parts screen:

var queryWithLocation = '';
if (userLat && userLong) {
      var latOffset = input.radius / 69;
      var longOffset = latOffset * Math.cos(userLat * (Math.PI / 180));
      var long1 = Number(userLong) + Number(longOffset);
      var long2 = Number(userLong) - Number(longOffset);
      var lat1 = Number(userLat) + Number(latOffset);
      var lat2 = Number(userLat) - Number(latOffset);
    
       queryWithLocation += "^location.longitude<=" + long1;
       queryWithLocation += "^location.longitude>=" + long2;
       queryWithLocation += "^location.latitude<=" + lat1;
       queryWithLocation += "^location.latitude>=" + lat2;
}
return queryWithLocation;