Introducing the Survey123 Web App JavaScript API

18973
38
03-05-2020 12:50 PM
IsmaelChivite
Esri Notable Contributor
10 38 19K

 

Updated August 19, 2020. Added link to the API reference documentation

Updated August 6, 2020. Documented mode (edit, view) property. New in 3.10

 

The Survey123 web app JavaScript API is designed to help you embed, style and interact with Survey123 smart forms within your own web applications. At a glance, here is what you can do with this API and a little bit of JavaScript magic:

 

  • Programmatically embed a Survey123 web form within a web page at run-time.
  • Apply a custom css to the embedded web form to make it look fit within your own web app.
  • Programmatically read and write values into the embedded web form from your own web application.
  • Subscribe to web form events such as onFormLoaded, onFormSubmitted or onValueChanged.

 

There are many applications for this new API. In the animation below, for example, a form is embedded within a web page used to report the speed of your internet connection. When the page is initially loaded, a big button is shown to help users initiate a quick internet speed test. One the connection speed is estimated, a Survey123 web form is loaded and the output of the speed test is automatically added into the form. At that point, the end user can complete the remaining questions and submit. The whole idea with this is that the logic to measure the internet speed of your connection sits in your web application, but when the time comes to submit data like your location or email contact, a Survey123 form is used for that. Through the Survey123 web app JavaScript API you can make your web app talk to the form and load the measured internet speed right away to make the process simpler.

 

Thanks to the Applications Prototype Lab for sharing the above example and making its source code available in GitHub!

                                       

You may also want to leverage the Web App JavaScript API to bring Survey123 forms into existing websites. Of course, you can always embed your survey by copying and pasting an embed link, but using the Web App API has the advantage that you can make your form interact with the website and vice-versa. For example, say you want to embed in the website of your city a form to capture incidents or issues that need attention. You can pre-populate certain questions in the form using information gathered from your own website. Similarly, you can feed your website with information entered by the user Survey123 while the form is being completed, or when the data is finally sent.

 

 

Getting Started (Hello World)

 

The following is about the simplest code snippet showing the basics of the Survey123 Web App JavaScript API. This sample loads a custom web form into a web page and pre-populates a couple of questions in it.

 

 

Lets have a closer look at the code:

 

  • Line 2: In this line we import the Survey123 web app JavaScript API. The address of the latest version of the API is http://survey123.arcgis.com/api/jsapi 
  • Line 5: Your web form needs a container in your web page. Typically, you will want to use a DIV HTML element. You can control the exact size of the the container in your page, although keep in mind that you cannot make it too small or otherwise your web form will not have room to display.
  • Lines 7-14: This is where we create a Survey123WebForm JavaScript object. The constructor requires at least the following attributes:
    • clientId: The client ID is a string that proves that you have explicitly authorized the use of Survey123 web app API from your web page. You need to create the Client ID through the https://developers.arcgis.com/ website. Check the Generating a Client ID section later in this article for details.
    • container: This is the HTML element in which you want your web form to be displayed. Typically a DIV.
    • itemID: This is the ArcGIS itemID of your web form. Check the Getting the ItemID of a web form section later in this article for details.
    • token: This attribute is only needed if you are targeting a private survey.

There are a number of optional attributes you can also set. In the example above, we added the defaultQuestionValue attribute to set the default value of a couple of questions.  Check the Web Form attributes section later in this document for a complete list.

 

Generating a Client ID

 

To authorize the use of the Survey123 web app JavaScript API within your web application, you must provide a valid Client ID. You can create a Client ID through ArcGIS for Developers  as follows:

 

  1. Login into ArcGIS for Developers and open the Dashboard.
  2. Create a New Application and switch to the Authentication tab
  3. Add your web application URL and/or domain to the list of Redirect URIs.
  4. Copy the Client ID.

 

 

Getting the ItemID of a Web Form

 

ItemIDs uniquely identify ArcGIS items within your organization. You can find more information about itemIDs in the https://community.esri.com/community/gis/web-gis/arcgisonline/blog/2019/06/06/where-can-i-find-the-i... article. To get the ItemID of your web form:

 

  1. Login to Survey123.arcgis.com.
  2. Open the Overview or Design tab of your survey
  3. The portion in the URL highlighted in the screenshot below is the itemID.

 

 

 

More details (Web Form attributes)

 

Here is the list of all attributes supported by the Web Form object. The complete reference is at https://developers.arcgis.com/survey123/api-reference/web-app 

 

Property Description

containerThe HTML element that will contain the web form, typically a DIV.
clientIdA valid Client ID for your domain registered in ArcGIS for Developers
itemIdThe ItemId of the web form you want to load.
mode

(Optional) Defines if the form will create a new record on submit or update the specified record through the globalid property. Values are 'edit' or 'view'. If this property is not specified the submit button adds a new record.

globalId

(Optional) Set this property only if mode='edit' or 'view'. Defines the record that should be loaded in the webform to be edited or viewed. For example:  globalId: '72dc4442-773e-4490-88e0-fd7ad5c6d234'.

portalUrl(Optional) The URL of your ArcGIS portal. If left empty, defaults to https://www.arcgis.com
tokenRequired if you work with private surveys.
hideElements

(Optional) Elements can be set to be hidden, including navbar, theme, header, subHeader.

    For example: ["navbar","header","subheader"]

You can also hide questions within your survey. For example:

    For example: ['field:yourQuestionName']

autoRefresh(Optional) Enable auto refresh the survey after submit successfully. You can set autoRefresh=3 which will refresh the survey after 3 second
defaultQuestionValue(Optional) Lets you populate questions in the form. For example: {field_0: 'value1', field_1: 'value2'}
isDisabledSubmitToFeatureService(Optional) Set this property to true and the web form will not send data to your feature service.
onFormLoaded(Optional) Invokes a callback function when loaded. For example: function({form:Form, contentHeight: number })   
onFormResized(Optional)
onFormSubmitted(Optional) Invokes a callback function when the form is submitted. For example: function({surveyFeatureSet: SurveyFeatureSet})
onQuestionValueChanged(Optional) Invokes a callback function when values in your form change. For example: function({field: string; value: any; path: string; repeatIndex: number; formId: string})
width(Optional) Takes a number in pixels. Controls the width of the survey although anything smaller than 660 will be ignored.

 

 

More details (Web Form methods)

 

Web Form methods allow you to set the value of questions within your form from a JavaScript function.  You can also use them to programmatically change the style of your form.

 

Method Description

.setQuestionValue

Used to set the value of a question, or questions, at run-time. For example:

 

webform.setQuestionValue({
  'field_1': 'test1',
  'field_2': 'test2'
});

.setGeopoint

Used to center the map and set the geopoint value to a given location. For example:

 

webform.setGeopoint({

   x=-117.34,

   y=43.78

});

 

It is commonly used in combination with the Geolocation API.

.setStyle

Used to apply CSS styling to your web form. For example:

 

webform.setStyle({
  '& .question-label': {
     'color': '#ff0000 !important',
     'font-size': '30px !important'
  },
  '& .form-header': {
     'color': '#ff0000 !important'
  }
});

 

Samples

 

  • Hello World: A bare bones sample showing how to embed a web form within a web page.
  • Speed Test: A more elaborate sample written by the Esri Geo Experience Center’s Applications Prototype Lab. It integrates a simple routine to estimate internet speed connection and then uses that estimation to pre-populate a question in a web form.

 

Version locking

 

In developer samples and throughout the blogs and documentation you will often see that the API is imported using this URL: http://survey123.arcgis.com/api/jsapi    This is the home of the API and always returns the latest available version of it (non-version locked).

If you rather lock the version of the API used in your web application to a specific version, all you need to do is to add the version number you want at the end of the URL. For example: http://survey123.arcgis.com/api/jsapi/3.13 will give you access to the 3.13 version specifically.

You may want to consider the use of version-locked imports in your code to avoid surprises when new releases are made available.

Tags (2)
38 Comments
TonyMonsour2
New Contributor

Thank you- I am very excited to using an official API to access Survey123 forms in our web applications.

In the blogpost- https://community.esri.com/groups/survey123/blog/2019/02/06/survey123-tricks-of-the-trade-web-form-u...  you show how to access existing surveys via URL parameters and also how to hide questions.  I was using this method when I was pulling the Survey123 webforms into web applications via iframes.  I'd like to take advantage of some of the new OnFormSubmitted callbacks since with the iframe there was a lot of coding around iframe OnLoad events to capture when a survey was (potentially) submitted. 

Is there a way to access existing surveys with this new API? Same with the other parameters outlined in the Tricks of the Trade post?

Thanks

IsmaelChivite
Esri Notable Contributor

Hi. Technically, you can use old versions of your surveys with the JS API. However, I would recommend that re-publish your surveys so they get updated to the latest version.  Some of the events such as onFormLoaded or onQuestionValueChange did not exist in the past, so the JS API will automatically update your old surveys on the fly. The update process takes time with long surveys, so it is not worth leaving that up to the JS API. It is best to have your survey in the latest version.

In regards with the functionality differences between query parameters and the JS API. You can do with the API everything you can do with query parameters, except changing the mode (edit, add, view) and default language. The JS API at this moment always loads your survey in add mode with the default language.  With the JS API you can hide elements, questions, and prepopulate questions.

I updated the web form attributes table in the blog post to include the syntax to hide a question in your survey. This was missing in the original post.

MaximeDemers
Occasional Contributor III

Hi!

Is the Survey123 API source is available on github or elsewhere, or it is only CDN for now?

Is there a way to host the whole survey123 application on our own server like we can do it with GeoForm? As I can see this API is very limited and we still cannot have access to the survey directly using javascript because it is embedded inside an iframe.

Thank you very much for this! That will be very useful.

ZhifangWang
Esri Regular Contributor

Hi Maxime Demers‌,

Currently, the web app JavaScript API is not available offline. And it is based on iframe for now.

One of the goals of the web app JavaScript API is to make the communication with the iframe (for now) transparent to developers, so you can still utilize the same code even we don't use an iframe in the future.

Would you mind sharing what is your use case or what you want to achieve through the API?

Thanks,

Zhifang

by Anonymous User
Not applicable

Is there any reference documentation available on the API?  Is it possible to edit an existing record using this method?

Thanks!

JamesTedrick
Esri Esteemed Contributor

Hi Dave,

We are working on bringing the JSAPI documentation formerly to ArcGIS for Developers; until then, this blog is serving as the documentation.  We are considering ways to enable editing via the JSAPI and will update once we have that ready.  

PatriceLabbé
Occasional Contributor

Hi,

 

Is it possible to use globalID and mode parameters to, let's say, edit an existing form or open a form in read-only mode? We need this for our web application. I've tried something like this but it doesn't work:

 

<script>
    let webform = new Survey123WebForm({
      globalId: 'aGlobalId',
      clientId: 'aClientId',
      container: 'mywebformDIV',
      itemId: 'anItemId',
      portalUrl: '',
      token: 'aToken',
      mode: 'view'
    });
  </script>

 

Thank you!

ZhifangWang
Esri Regular Contributor

Hi Patrice Labbé‌,

Thanks for the feedback.

mode=view and mode=edit is not currently supported in the API, we have the plan to support this in a near-future

release.

I've added your voice to our backlog issue.

Thanks,

Zhifang

by Anonymous User
Not applicable

For the Javascript API and URL parameters, I would love to have an option to only view fields that are not blank in the form itself. Some datasets that I use have hundreds of fields, with only 10 or so actually having values. It may be bad database design, but it is not something I have control over.

Right now there is a parameter to hide fields which is great. If this could be used in combination with a hideBlankFields parameter it would be very beneficial.

I'm working to do this right now with some Javascript, but it would be nice to not be reliant on this 🙂

by Anonymous User
Not applicable

A side question...can parameters be passed as post requests to the web form, or just as get requests? I can see myself exceeding the url length limit given how many fields I want to hide.

ZhifangWang
Esri Regular Contributor

Hi Michael,

Thanks for the feedback. I think this makes sense and will make the view mode of the web app equivalent to the individual response view on the Data page of the Survey123 website.

This is something not on our radar, I've logged an enhancement issue in our dev repo. In the meantime, it would help to lift the priority of this enhancement if you could raise a ticket to Esri Support Service.

Thanks,

Zhifang

JulioGaspar1
New Contributor III

Hi Folks,

Are there a step-by-step to use portal instead AGOL?

Thanks

by Anonymous User
Not applicable

Thanks a lot Zhifang - I have just logged this through support channels also.

Idea logged here: https://community.esri.com/ideas/18372 

Enhancement Number: TBC

ZhifangWang
Esri Regular Contributor

Hi Michael,

Just want to have double-check, in your case, does ?hide= parameter takes most of the length in your URL or there are also other long parameters in URL?

We saw that exceeding URL length is caused by passing default value to too many questions, such as ?field:q1=a&field:q2=b&field:q3=c... since "field:" got repeated to many times.

However, generally, there is no workaround of this issue so far. You can not use post since it requires you input the URL into a browser directly.

Thanks,

Zhifang

by Anonymous User
Not applicable

Hi Zhifang,

Thanks for following up.

In this case hide parameters that take up 90% of the URL characters. Having to insert field: before every field name takes up a decent amount of characters. Perhaps the length of the parameter could be minimized by adding a hideFields parameter like:

hideFields=field1,field2,field3

Having said that currently the URL I want to use stands at over 10,000 characters so this probably wouldn't be sufficient anyway. I am going to work something into the form itself with groups to minimize the number of fields I need to input, but it does mean I won't be able to hide all of the fields I want to hide, and will require additional coding to setup custom relevancy options.

Re: Post requests - I was thinking that behind the scenes the API may be able to handle larger requests via post.

Thanks again,

Mikie

PatriceLabbé
Occasional Contributor

I suggest adding a new mode=clone to enable pre-fill a form by a previous submitted form (globalId). We had to do it for our web application and we did it by using the REST API (query) on the featurelayer first and by using defaultQuestionValue afterwards. A mode=clone would be a great shortcut.

PatriceLabbé
Occasional Contributor

Hi,

Is it possible to add a setGeometry method instead of a setGeopoint to enable setting point, line or polygon geometry to leverage the new Map question type? We need this for our web application.

What's new in Survey123—Survey123 for ArcGIS | Documentation : Update April 2, 2020

Thanks!

Edit: Idea logged here : Survey123 Web - JavaScript API - Add a setGeometry method 

ZhifangWang
Esri Regular Contributor

Hi Michael,

Thanks for the additional information, I've added it to our backlog for consideration.

Wondering which browser did you use? It seems Chrome supports the longest max. length of URL:

For the Survey123 web app JavaScript API, some of the methods are/will be implemented by wrapping various kinds of URL parameters, so does this hiding question case. That is to say, the Survey123 web app JavaScript API will not help in this case for now.

Thanks,

Zhifang

by Anonymous User
Not applicable

Hi Zhifang,

Ah I was basing it off this. I just did some testing, and got it to work with URL's with just over 5650 characters. URLs with between 5650 and approx 8000 returned a HTTP 400 error as below:

8000 characters and above returned either a 413 error from CloudFront as below:

Or a server error:

All testing done in Chrome.

Appreciate your help with this. As I said, I have got around this by using relevancy in the form along with hiding groups. But a hideBlankFields option/extended parameter character allowances via the API would also be very useful.

Thanks,

Mikie

ZhifangWang
Esri Regular Contributor

Hi Patrice,

Thanks for the feedback.

Comparing to existing ?mode=view&globalId= and ?mode=edit&globalId=  URL parameters for the web app, would something like ?mode=add&globalId= (in both URL parameters and web app JS API) makes sense to you?

Thanks,

Zhifang

ZhifangWang
Esri Regular Contributor

Hi Patrice,

Thanks for the suggestion.

I've added your feedback to our backlog and will bring your idea to the discussion with the development team.

Thanks,

Zhifang

PatriceLabbé
Occasional Contributor

It totally makes sense. ?mode=add&globalId= or ?mode=clone&globalId=?. Beware of an issue I discovered with the pattern described above if draft mode is activated (query + defaultQuestionValue). I had to use onFormLoaded event and setQuestionValue with values of query because if I used defaultQuestionValue in constructor, draft mode would override values set with defaultQuestionValue. So using onFormLoaded event with queried values worked for me. Also, be sure to implement Repeats in the form (including Repeats for geometry fields). Thanks!

PatriceLabbé
Occasional Contributor

Hi,

Is it possible to use setQuestionValue to set values in Repeats (Repeats—Survey123 for ArcGIS | Documentation)? If so, how can we set, add or remove values or records of values?

Thank you!

EDIT : Idea logged here : https://community.esri.com/ideas/18437 

EricKerney
New Contributor

Hello ESRI, coming at this from a different angle with the API, and it doesn't sound like it is supported at this time: Working towards more automation, we are trying to accomplish most tasks with Python API in Jupyter Notebooks.  Each year we want to create a new 'copy' of a water monitoring Survey, the Survey is based on a related Feature Layer which are both cloned in Python, then the only manual edit is to change the submission url in SurveyConnect XLS form.  Looking for a method to update records in the XLS form using Python API or other resource.  Thanks!

JodyZhengLiu
Esri Contributor

Hi @PatriceLabbé ,

 

We have added a new copy mode to the Web app JS API: mode=copy&globalId=<globalId> which will copy data from an existing record to a new web form. This is available on survey123beta.arcgis.com now to test and will be released on production for our next update in December.

 

Thanks,

Jody Zheng Liu

AliciaWiltz
New Contributor

I keep getting the error that my survey does not exist. Any one else get this message? What am I missing. I think it has something to do with the code being that, coding is not my specialty. TIA

JodyZhengLiu
Esri Contributor

Hi @AliciaWiltz ,

Can you open the survey directly in a browser using the token you specified in code? Is the survey hosted in ArcGIS Online or an Enterprise portal?

 

Thanks,

Jody Zheng Liu

ParasKapoor
New Contributor

Hi there, I am doing same kind of integration. As per above discussion, automation not working right now as required.

I have some question:

1. Do we have python script to automate by api?

2. How can we populate survey data using api or online method to another survey in as field?


ScottGIS
New Contributor

I couldn't get OnFormSubmitted to work for the life of me.  I downloaded and checked the source API and there was a misspelling. I fixed it and it works as designed now. Curiously its in the API documentation as well.

 

https://developers.arcgis.com/survey123/api-reference/web-app#setOnFormSubmitter

 

Search on 'onFormSubmitter' and change it to 'onFormSubmitted'

JodyZhengLiu
Esri Contributor

Hi @ScottGIS ,

Thank you so much and we have modified the documentation, it will be updated with the next release.

Regards,

Jody Zheng Liu

JodyZhengLiu
Esri Contributor

Hi @ParasKapoor ,

For 1: the ArcGIS Python API has the survey123 module which can do some automatic workflows: https://developers.arcgis.com/python/api-reference/arcgis.apps.survey123.html

For 2, could you explain more about the requirements?

Thanks,

Jody Zheng Liu

kerenc
by
New Contributor II
Hi, Can I download the jsapi to a disconnected portal's survey123 website? Is it part of the installation? Can I access through 5443? when I try to access https://--machine  FQDN--:5443/api/jsapi it failed Thanks
cgrove
by
New Contributor II

@IsmaelChivite What's the best practice for embedding a survey that's only shared to the organization, without the user having to log in to AGOL? I have an OAUTH2 application with the correct Client ID, but the survey does not appear in the <div>, even when I pass the Temporary Token in the token field. Does the Survey123 Web App JS API work through the resource-proxy?

bemcalavera
New Contributor

Hi Ismael, I'm trying to customise Survey123 style via API, but I can't figure out how to do it. Is there any good documentation about how to use setStyle() and setTheme() functions? I mean, I would love to know the name of the properties I can modify (e.g. "backgroundOpacity", that isn't a standard css property...). 

I'd like to know if is possible to change font family of the survey element (via API), or how to set "display:none" to an element via css selectors with setStyle. I've tried something, but nothing worked for me...

For example:

survey.setStyle(
  {
    ".form-subHeader": { "display": "none" }, 
    "#validate-form": { "border-radius": "10px" }
  }
)
 
this code above (that I've put inside onFormLoaded func) doesn't work. Am I missing something?
 
Thank you very much, all the best!
Ale

 

cansucuoglu_2
New Contributor

 

Has the authentication methods changed since this article. ArcGIS for Developers looks different and has Auto 2.0 option.

Thanks

Andres_Florez
New Contributor

Hi!!

Does anybody know why my example looks like this? I mean, I have created the same example as this link https://www.youtube.com/watch?v=7Yyn-bqpCNc , but the frame just shows me a part of the screen.

AndresCamiloFlorez_0-1660006922810.png

 

AdrianDoss
New Contributor III

Yes, I have the same issue.

JorgeCejas
New Contributor

Hola Comunidad. No estoy pudiendo manipular los estilos CSS con setStyle. He intentado esto pero no funciona. Hay alguna forma de personalizar el fontfamily? documentación sobre esto?
Ayuda!!!

// Load the form by creating a Survey123WebForm object
webForm = new Survey123WebForm({
    itemId: "c39cafde40c342a8a929c2b4edfd002b",
    container: "formDiv",
    clientId: "DjGt8RrOkRLqs6em",
    defaultQuestionValue: { dni: 100, nombre: "test" },
    hideElements: ["theme", "navbar", "field:ubicacion", "header", "description", "footer"],
    autoRefresh: 5,
    onFormLoaded: (data) => {
        // https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API //
        if (navigator.geolocation) {
            // GET LOCATION FROM BROWSER //
            navigator.geolocation.getCurrentPosition(
                (position) => {
                    // SET LOCATION //
                    webForm.setGeopoint({
                        x: position.coords.longitude,
                        y: position.coords.latitude
                    });
                },
                () => {
                    console.error("No se puede encontrar su ubicación");
                }
            );
        } else {
            console.error("La geolocalización no es compatible con su navegador");
        }
    }
});
webForm.setStyle({
    '& .question-label': {
        "color": '#fx0300 !important',
        "font-size": "30px !important"
    },
    '& .form-header': {
        "color": "#ff0000 !important"
    }
});