Restricting duplicates for a field during repeats

1273
9
05-13-2019 07:23 AM
SeanYancey
New Contributor

The situation is that there will be a transect that has multiple stopping points to listen for birds. So the initial form will collect transect information, then with a repeat section to collect information at each individual stop. I'm hoping to see if there is functionality that will not allow users of the survey to accidentally duplicate the same stop point. Each seperate transect has 10 stopping points (1, 2, 3, 4, etc.). After conducting a stop and proceeding to the next repeat can I restrict the option to not allow the use of the same stop point? It's currently set up as a select_one field.

0 Kudos
9 Replies
by Anonymous User
Not applicable

Hi Sean,

Yes, this should be possible by using some additional text fields (possibly make them hidden or null so not written to feature service or visible on form) and using calculations to write all the values selected from those select ones questions in the repeat, into one text field as a list, and then use constraints to check if the values the user selects on next repeat record are already contained in that list. I have seen other users do this successfully to validate the entries entered into repeats from select one questions and avoid the same value being selected twice.

Phil.

0 Kudos
DougBrowning
MVP Esteemed Contributor
0 Kudos
SeanYancey
New Contributor

Thanks Doug,

That makes sense and I've created a text field that uses the join function to create a list the stop points that have already been recorded. I am having trouble writing an appropriate expression that either, removes the already recorded stop point from the select_one list or validating it with an error "invalid entry" when a stop point is attempting to be duplicated.

0 Kudos
DougBrowning
MVP Esteemed Contributor

You cannot remove it that is impossible.  Use a constraint to yell at them if they do it.  Note your text field needs to be outside the repeat.

It should all be in the post.  Put this is the constraint of the large text field

not(contains(substr(${AllPlantsCheck}, 0, string-length(${AllPlantsCheck}) - 3), ${SpeciesList})) 

Create a large txt (or note) field outside the repeat.  i did text so users can copy and paste it.

Add a calc joining the fields from the repeat join(", ", ${SpeciesList})

Set a constraint on this join field (not the field) - the trick here is to remove the last entry since it is the one you are trying to add currently. 

So like this not(contains(substr(${AllPlantsCheck}, 0, string-length(${AllPlantsCheck}) - 3), ${SpeciesList})) 

--If you do not do this it immediately adds to the list then complains it is already there.

--(note my plant codes are 4 chars. so if i remove the last 3 chars it will not find what I just added)

 

It can be funky if you go backwards and then change something but it still seems to work ok.

 

I even built on exceptions to the rule. If it contains a XXXXX generic code then the repeat is allowed.

Like contains(${SpeciesList}, "XXXX") or not(contains(substr(${AllPlantsCheck}, 0, string-length(${AllPlantsCheck}) - 3), ${SpeciesList}))

0 Kudos
SeanYancey
New Contributor

Thanks Doug,

I've been trying multiple variations of your argument in the constraint field to try and get an error to pop up and it just seems to not be behaving the way it should. The argument I am using in the constraint for the joined field is:

not(contains(substr(${stops_completed}, 0, string-length(${stops_completed}) - 2), ${stop_point}))

stops_completed is the joined text field that is generated from the stop_point field. So if I'm understanding this correctly, the contains function is looking for the text you are trying to input (in my case the point you are at {$stop_point}) and referencing it to a substring of the string that is being created which is (${stops_completed}, 0, string-length(${stops_completed}) - 2). The substring argument should return back the list ,minus 2 characters in this case to account for the text you are adding to the string so it automatically doesn't come back saying it is already contained in the list. I've tried altering the amount of characters removed at the end of the string from 0 to 3 and none will return an error message. As it is currently I can generate strings of 01,01,01,01 which is obviously not what I want. Am I missing something obvious?

Thanks for your time.

Sean

0 Kudos
DougBrowning
MVP Esteemed Contributor

It all looks good to me.  It could be you are now hitting the current bug in 3.3 that constraints are not working right.  Try this.  Put the ${stops_completed} question inside of a group that contains just that field - see if that will trigger it.  I did have to do this in my form due to the open bug (there are some posts about this).  Does it trigger when you try and send the form?

The calculation on ${stops_completed} is join(", ", $stop_point) or similar.  I just saw that mine is actually inside the repeat and in a small group so you can try that also.

0 Kudos
SeanYancey
New Contributor

Thanks again for your response Doug. When I put the the stops_completed field in it's on group outside the repeat it flags the constraint when I try to submit the overall form. I wish it would flag an error when a new repeat is trying to duplicate a value but this may have to work for the time being.

0 Kudos
DougBrowning
MVP Esteemed Contributor

Yep known bug that is killing me and others! 

You can actually use stops_completed inside the repeat (and inside a group) then it will catch it on a repeat add.  Sorry if I wrote this wrong before - it is just min and max that need to be outside the repeat.

Give it a shot.

0 Kudos
SeanYancey
New Contributor

This is my xls form for reference.

0 Kudos