Select to view content in your preferred language

Enforcing a workflow in Survey123

4476
7
11-07-2019 02:49 AM
DeonLengton
Esri Contributor
8 7 4,476

For the 2019 Esri Southern African User Conference I challenged myself and looked for a solution to a requirement that one of our clients have.

In a nutshell the client wants a survey that follows a preset workflow, for this example we will create a solution for a workflow that involves inspections done at regular intervals when a house is being built.

Survey Worflow

Let's consider the following status values for a building inspection survey:

Here are some user requirements for this survey:

  • The initial status is always Excavation
  • The inspector should not be able to skip a status
  • The inspector can only move on to the next status in the chain, not backwards
  • Inspection questions for a specific status can only be edited when that status is the active status

How will we go about forcing this workflow in Survey123?

There are some hidden challenges in getting this to work. The biggest hurdle is that in Survey123 you cannot compare a field to it's own or previous value, so you cannot tell Survey123 the next status can only be Foundation when the current status is Excavation. This has lots of design implications and one would be tempted to stop looking for a solution right here. But this is where you need to think a little bit out of the box...

So how does the end result work? Lets take a look:

In the above screenshot the following can be seen:

  • The survey initialises with only the Excavation status being visible in the select_one question. The inspector is not able to select any other status.
  • The survey only has the Excavation Checklist enabled
  • The inspector cannot skip a status or go back to any other status
  • The inspector cannot complete any other checklist of the survey - only the active status' checklist

The Solution

Lets look at the bits and pieces to make this work:

We need a way to only allow the inspector to choose one "next" status and this needs to be based on the "current" status. So we need a select_one that is filtered according to the "current" status:


Notice that we added a filter column called "prevval" to the choices for the "level" list. In this example "level" refers to the status of the inspection. Also you will notice that the levels run from 1 to 6 and the corresponding "prevval" filter is one level behind. So if the "prevval" or current status is zero (0) then the list will filter and only show Excavation as an option.

Ok, time for the interesting part of this solution. Since we cannot filter the list called "level" with itself we need to find a way of retrieving the inspection status into a new variable. This is done by quering the current status value from field "status" from the feature layer with a JavaScript pulldata function:

We do the max function so that for newly created records we start with a level of zero(0) - the pulldata returns nothing since there isnt a record created yet to query so we convert it to a 0 with the max function.

Basically this is it! There are some other work to be done, such as writing the JavaScript file to query the data from your hosted Feature Layer. If there's enough interest I will post the source files after cleaning it up a bit.

7 Comments
DougBrowning
MVP Esteemed Contributor

What you are doing here would not work offline right?

I think you could also do this in Collector with Arcade.  Arcade looks up the last status then creates a URL to pass that status to 123.  Form adjusts based on that status.  Then the inspector has a location map as well to help them get from job to job.  Could symbolize Collector with the current status. 

Note the Arcade lookup does not work offline yet (if going across feature classes) but they told me by the end of the year.  If all of this is in 1 FC then it may work offline.

DeonLengton
Esri Contributor

Hi Doug

Thanks for your feedback! Yes the solution requires an online connection. I will investigate your arcade proposal - sounds very intriguing.

JulienCHARBONNAUD
Regular Contributor

Hi Deon

I am interested in this part : the JavaScript file to query the data from your hosted Feature Layer

Thinks

DeonLengton
Esri Contributor

You have to get the token first.

Then you call the JS function in your JS file in the extensions directory of your survey:

The QueryFS.js file should be in your extensions directory and contain the runFSQuery function. You pass the value you want to query on in the ID field (in this case im querying on a guid field):

function runFSQuery(ID,Token){

var xmlhttp = new XMLHttpRequest();
var token = Token
var url = "https://services1.arcgis.com/812fTwS4iZzOR4Kg/arcgis/rest/services/service_8f0b74edb7564d61b0844fcfc...'" + ID + "'&objectIds=&time=&geometry=&geometryType=esriGeometryEnvelope&inSR=&spatialRel=esriSpatialRelIntersects&resultType=none&distance=0.0&units=esriSRUnit_Meter&returnGeodetic=false&outFields=*&returnHiddenFields=false&returnGeometry=true&featureEncoding=esriDefault&multipatchOption=xyFootprint&maxAllowableOffset=&geometryPrecision=&outSR=&datumTransformation=&applyVCSProjection=false&returnIdsOnly=false&returnUniqueIdsOnly=false&returnCountOnly=false&returnExtentOnly=false&returnQueryGeometry=false&returnDistinctValues=false&cacheHint=false&orderByFields=&groupByFieldsForStatistics=&outStatistics=&having=&resultOffset=&resultRecordCount=&returnZ=false&returnM=false&returnExceededLimitFeatures=true&quantizationParameters=&sqlFormat=none&f=pjson"
+ "&token=" + token

xmlhttp.open("GET",url,false);
xmlhttp.send();

if (xmlhttp.status!=200){
return "Error"
} else {
var responseJSON=JSON.parse(xmlhttp.responseText)
if (responseJSON.error){
return responseJSON.error;
} else {
if (responseJSON){
return responseJSON;
}
else{
return "";
}
}
}
}

DougBrowning
MVP Esteemed Contributor
BrunoGomes_de_Souza
Esri Contributor

Hey Deon, 

I have been tried to implement your suggestion, but my problem was the Token, it's too long and mess evertything. When I was submmitind the form this error occurs:

Frist log of survey 123 Connect :

Second error in submit the form in Survey 123:

I've stoped at this point because  the other steps depends on it.

How you figure it out?

Thanks a lot.

Bruno

JamesTedrick
Esri Esteemed Contributor

Hi Bruno,

I would strongly suggest not storing the token in the data submitted by the form.  If you are using the token in the form, you can set the bind:esri:fieldYpe for it to null, which will prevent it from storing the data.