Stop Survey123 Entry if Duplicate Project ID Entered

1183
8
Jump to solution
03-07-2022 01:36 PM
erica_poisson
Occasional Contributor III

Hi - 

I am hoping to add some functionality into my XLSForm that would prevent data entry if a duplicate Project ID is entered into Survey123. I would like this to happen as soon as the user enters a Project ID into the form as the form is quite long (it would really stink to get to the end and then see this error!). 

I feel like a JavaScript function would be the best method for doing this, however I am struggling to find an example and really do not know how to write one myself. 

I do not think pulldata() would be a reasonable solution for this as it would be extremely cumbersome to maintain the external CSV - new projects are being entered weekly. The ideal solution would be a way to look back at the hosted feature service, check the field and see if the Project ID already exists. 

I am also wondering if the "Unique" setting could be used to accomplish this; I suspect that it would not cause error until going to submit the survey form. 

erica_tefft_0-1646688944871.png

Any advice would be welcome!

Thank you,

Erica
1 Solution

Accepted Solutions
erica_poisson
Occasional Contributor III

I was able to get some help and figure out how to do this. I wanted to post the result here in case it is helpful to others.

I am using a custom JavaScript function and a series of hidden and relevant questions in the XLSForm to accomplish my goal - prevent the submission of a new Survey123 form if the file number entered is a duplicate value. 

First, here is the JS function:

/*
* JavaScript functions for Survey123
*/

function returnFeatures(DCR_File_Number, token, debugmode) {

    // Output value.  Initially set to an empty string (XLSForm null)
               let outValue = "";

               let layerURL = "https://URL GOES HERE/FeatureServer/0";
               let response ="";
               
               // Set up query parameters
               let f = "f=json";
               let where = `where=DCR_File_Number='${DCR_File_Number}'`; 
               let outFields = "outFields=*";
               let returnGeometry = "returnGeometry=false";
               let returnCount = "returnCount=1";
               let parameters = [f,where,outFields,returnGeometry,returnCount].join("&");
               
               let url = `${layerURL}/query?${parameters}`;
               

if (token){
     url = url + "&token=" + token;
    }

               // Create the request object
               let xhr = new XMLHttpRequest();
               // Make the request.  Note the 3rd parameter, which makes this a synchronous request
               xhr.open("GET", url, false);
               xhr.send();
               
               
               // Process the result
               if (xhr.readyState === xhr.DONE) {
                              if (xhr.status !== 200) {
                                             // The http request did not succeed
                                             return "bad request: " + url
                              } else {
                                                            // Parse the response into an object
                                             response = JSON.parse(xhr.responseText);
                                             if (response.error) {
                                                            return (debugmode? JSON.stringify(response.error):"");
                                             } else {
                                                            if (response.features[0]) {
                                                                           return "DCR File number is not unique"
                                                                           //JSON.stringify(response.features[0]);
                                                            } else {
                                                                           if (DCR_File_Number !== "") {
                                                                           return "DCR File number is unique"}
                                                                           //(debugmode? "No Features Found":"");
                                                            }
                                             }
                              }
               }
               
}

 

Next, I configured the XLSForm - here is what all of the populated columns look like (I hid all of the empty/non-relevant columns to fit this into one image):

erica_tefft_0-1648470843942.png

When the user goes to enter a file number, if it is invalid (AKA a duplicate), they will see this message in the Survey123 form:

erica_tefft_1-1648470948538.png

Because of line 6 in the XLSForm, they are prevented from submitting their form until they correct the DCR File Number so that it is unique. 

When a unique DCR File Number is entered, this message appears and the user is able to submit:

erica_tefft_2-1648471029609.png

This seems to work very well for my use case. Since this is a web-only form (users only complete from a desktop PC) this works perfectly. 

Erica

View solution in original post

8 Replies
erica_poisson
Occasional Contributor III

I was able to get some help and figure out how to do this. I wanted to post the result here in case it is helpful to others.

I am using a custom JavaScript function and a series of hidden and relevant questions in the XLSForm to accomplish my goal - prevent the submission of a new Survey123 form if the file number entered is a duplicate value. 

First, here is the JS function:

/*
* JavaScript functions for Survey123
*/

function returnFeatures(DCR_File_Number, token, debugmode) {

    // Output value.  Initially set to an empty string (XLSForm null)
               let outValue = "";

               let layerURL = "https://URL GOES HERE/FeatureServer/0";
               let response ="";
               
               // Set up query parameters
               let f = "f=json";
               let where = `where=DCR_File_Number='${DCR_File_Number}'`; 
               let outFields = "outFields=*";
               let returnGeometry = "returnGeometry=false";
               let returnCount = "returnCount=1";
               let parameters = [f,where,outFields,returnGeometry,returnCount].join("&");
               
               let url = `${layerURL}/query?${parameters}`;
               

if (token){
     url = url + "&token=" + token;
    }

               // Create the request object
               let xhr = new XMLHttpRequest();
               // Make the request.  Note the 3rd parameter, which makes this a synchronous request
               xhr.open("GET", url, false);
               xhr.send();
               
               
               // Process the result
               if (xhr.readyState === xhr.DONE) {
                              if (xhr.status !== 200) {
                                             // The http request did not succeed
                                             return "bad request: " + url
                              } else {
                                                            // Parse the response into an object
                                             response = JSON.parse(xhr.responseText);
                                             if (response.error) {
                                                            return (debugmode? JSON.stringify(response.error):"");
                                             } else {
                                                            if (response.features[0]) {
                                                                           return "DCR File number is not unique"
                                                                           //JSON.stringify(response.features[0]);
                                                            } else {
                                                                           if (DCR_File_Number !== "") {
                                                                           return "DCR File number is unique"}
                                                                           //(debugmode? "No Features Found":"");
                                                            }
                                             }
                              }
               }
               
}

 

Next, I configured the XLSForm - here is what all of the populated columns look like (I hid all of the empty/non-relevant columns to fit this into one image):

erica_tefft_0-1648470843942.png

When the user goes to enter a file number, if it is invalid (AKA a duplicate), they will see this message in the Survey123 form:

erica_tefft_1-1648470948538.png

Because of line 6 in the XLSForm, they are prevented from submitting their form until they correct the DCR File Number so that it is unique. 

When a unique DCR File Number is entered, this message appears and the user is able to submit:

erica_tefft_2-1648471029609.png

This seems to work very well for my use case. Since this is a web-only form (users only complete from a desktop PC) this works perfectly. 

Erica
EricaNova
Occasional Contributor

This is great! I've got it very close to working in my test case. Are you missing something in your screenshot of the xls form? I noticed that you have a "required message" and I don't see that in the form. I also wondered how to get the required error message to show up as they are entering data - mine only shows up if they try and submit.

0 Kudos
erica_poisson
Occasional Contributor III

@EricaNova -

Within the Hint column, I also have this for the "not_valid_value_check" which was not included above: <font color="#850419">*This is required!*</font>

Other than that, nothing is missing. 

Erica
0 Kudos
EricaNova
Occasional Contributor

Ah, ok - thanks!

0 Kudos
EricaNova
Occasional Contributor

Also, I noticed that if I try to edit the record, the user cannot submit it because it is reading it as a duplicate. That's odd.

0 Kudos
erica_poisson
Occasional Contributor III

I only use this within a "new entry" form. For my "update form" (which is used within a Dashboard) I've published a totally new Survey123 form where this function is not included. The DCR_File_Number attribute field is read only (and so are some other fields) to prevent editing of those values. 

Erica
EricaNova
Occasional Contributor

You've really got it all worked out! I'd like to keep this fairly straightforward, so I think I'll modify it so this is just a warning and cross my fingers... sigh. Wish that Survey123 could do this, it seems like such a simple ask.

0 Kudos
PierreloupDucroix
Occasional Contributor II

Thanks for your work, I've been looking exactly for this for 2 days.

It works like a charm !

0 Kudos