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.