I am trying to create a survey for people to RSVP for an event. What I’m trying to do is enable a field that shows specific items that other users have provided in their answers as a viewable field in new forms. That way if someone says they are bring ‘X’ item, someone can see that and not bring the same item. Does anyone know how I can do this?
I've attempted to have it pull data from the results but it only pulls one entries results and not all of them
Solved! Go to Solution.
@Mario, if you are comfortable authoring in Survey123 Connect and using pulldata() with custom JavaScript functions, then here is a potluck survey example that might be a helpful model on which you can build. When a user is filling out the survey to indicate what type of dish they are bringing to the potluck, it displays a table of the dish types and counts that have already been submitted:
Note that Survey123 custom JavaScript functions impose some key constraints on the approach outlined here: the survey cannot be shared publicly, and only members of the survey's owner's organization can submit responses (see Known limitations.)
To create your survey in Survey123 Connect, you can put the following in the XLS form's survey tab:
The calculation for others_dishes uses pulldata with the custom JavaScript function others_dishes (see below). The function returns a HTML-formatted table with the dish type counts, which is displayed to the user via the dishes note type question.
Pair the above with something like the following set of dish type options on the choices tab:
And, in the Scripts section of Survey123 Connect, provide the following custom JavaScript function:
/*
* JavaScript functions for Survey123
*/
function others_dishes(token) {
let counts = {};
let result = "";
// Set up query parameters.
let f = "f=json";
let where = "where=1=1"; // retrieve all records
let outFields = "outFields=your_dish";
let returnGeometry = "returnGeometry=false";
let query_parameters = [f,where,outFields,returnGeometry].join("&");
if( token ) {
query_parameters = query_parameters + `&token=${token}`;
}
// Query URL for the ArcGIS REST API
// (Obtain the appropriate URL from your feature layer's Item details page.)
// For ArcGIS Online, the URL will be of the form:
// https://<server>/<org_id>/arcgis/services/<service_name>FeatureServer/<layer_id>
let layer_url = "your_feature_layer_url"
let url = `${layer_url}/query?${query_parameters}`;
// Make request to the ArcGIS REST API
let xhr = new XMLHttpRequest();
xhr.open("GET",url,false);
xhr.send();
// Process request result, if status code is 200 or OK.
if( xhr.status === 200) {
// Convert reponse text to a JSON object
let response = JSON.parse(xhr.responseText);
// If response is not an error, proceed.
if( !response.error ) {
if( response ) {
// If successful, response is a Feature Set.
// Retrieve array of dishes (features).
let other_dishes = [];
response.features.forEach(function(feature) {
other_dishes.push(feature.attributes.your_dish);
});
// Calculate count for each type of dish as dictionary.
for( const dish of other_dishes ) {
if( counts[dish] ) {
counts[dish]++;
} else {
counts[dish] = 1;
}
}
}
}
}
// Convert dish count dictionary into an HTML table for display in a note.
if( Object.keys(counts).length === 0 ) {
result = "No other dishes yet...";
} else {
result = '<table>';
result = result + '<tr>';
result = result + '<th style="text-align:left;">Dish</th>';
result = result + '<th style="text-align:right;">Count</th>';
result = result + '</tr>';
Object.entries(counts).forEach(function([key,value]) {
result = result + '<tr>';
result = result + `<td style="text-align:left;">${key}</td>`;
result = result + `<td style="text-align:right;">${value}</td>`;
result = result + '</tr>';
});
result = result + '</table>';
}
return result;
}
pulldata("@layer") can retrieve more than one result.
Something like this could be what you are looking for (check link above for more details):
pulldata("@layer", "getRecord", "<URL>", "<WHERE clause>")
@abureaux I would love to learn otherwise, however, the doc you linked to appears to confirm that one cannot retrieve more than one result in a single call to pulldata("@layer",...):
@PeterKnoop There is an example at the bottom here (https://community.esri.com/t5/arcgis-survey123-blog/survey123-tricks-of-the-trade-pulldata-quot-laye...) that explains how to get a count from a pulldata query.
Presumably you could could set up a query for each category by adding a where clause to get totals.
@Mario Here is a working example of using the pulldata @layer query with the statistics parameters, and a where clause for groups.
From this point you could hide all the calculations and aggregate them in a nice html table in a note field to save space.
Another option could be a dynamic choice using the search() appearance
@Mario, if you are comfortable authoring in Survey123 Connect and using pulldata() with custom JavaScript functions, then here is a potluck survey example that might be a helpful model on which you can build. When a user is filling out the survey to indicate what type of dish they are bringing to the potluck, it displays a table of the dish types and counts that have already been submitted:
Note that Survey123 custom JavaScript functions impose some key constraints on the approach outlined here: the survey cannot be shared publicly, and only members of the survey's owner's organization can submit responses (see Known limitations.)
To create your survey in Survey123 Connect, you can put the following in the XLS form's survey tab:
The calculation for others_dishes uses pulldata with the custom JavaScript function others_dishes (see below). The function returns a HTML-formatted table with the dish type counts, which is displayed to the user via the dishes note type question.
Pair the above with something like the following set of dish type options on the choices tab:
And, in the Scripts section of Survey123 Connect, provide the following custom JavaScript function:
/*
* JavaScript functions for Survey123
*/
function others_dishes(token) {
let counts = {};
let result = "";
// Set up query parameters.
let f = "f=json";
let where = "where=1=1"; // retrieve all records
let outFields = "outFields=your_dish";
let returnGeometry = "returnGeometry=false";
let query_parameters = [f,where,outFields,returnGeometry].join("&");
if( token ) {
query_parameters = query_parameters + `&token=${token}`;
}
// Query URL for the ArcGIS REST API
// (Obtain the appropriate URL from your feature layer's Item details page.)
// For ArcGIS Online, the URL will be of the form:
// https://<server>/<org_id>/arcgis/services/<service_name>FeatureServer/<layer_id>
let layer_url = "your_feature_layer_url"
let url = `${layer_url}/query?${query_parameters}`;
// Make request to the ArcGIS REST API
let xhr = new XMLHttpRequest();
xhr.open("GET",url,false);
xhr.send();
// Process request result, if status code is 200 or OK.
if( xhr.status === 200) {
// Convert reponse text to a JSON object
let response = JSON.parse(xhr.responseText);
// If response is not an error, proceed.
if( !response.error ) {
if( response ) {
// If successful, response is a Feature Set.
// Retrieve array of dishes (features).
let other_dishes = [];
response.features.forEach(function(feature) {
other_dishes.push(feature.attributes.your_dish);
});
// Calculate count for each type of dish as dictionary.
for( const dish of other_dishes ) {
if( counts[dish] ) {
counts[dish]++;
} else {
counts[dish] = 1;
}
}
}
}
}
// Convert dish count dictionary into an HTML table for display in a note.
if( Object.keys(counts).length === 0 ) {
result = "No other dishes yet...";
} else {
result = '<table>';
result = result + '<tr>';
result = result + '<th style="text-align:left;">Dish</th>';
result = result + '<th style="text-align:right;">Count</th>';
result = result + '</tr>';
Object.entries(counts).forEach(function([key,value]) {
result = result + '<tr>';
result = result + `<td style="text-align:left;">${key}</td>`;
result = result + `<td style="text-align:right;">${value}</td>`;
result = result + '</tr>';
});
result = result + '</table>';
}
return result;
}
Thank you for this. This seems to be exactly what I'm needing, however, I am 1) on a company computer and don't have the rights to have survey123 connect installed and 2) would require the form to be publicly shared so that also defeats the purpose. I'll keep looking into it and see what I can figure out but this is a good place to start