Completion Behavior
Completion behavior controls what respondents see or where they go after the form is submitted. Use root survey properties for the normal completion flow and triggers when the form should finish early.
Thank-You Page
Section titled “Thank-You Page”Use showCompletePage and completedHtml for the default post-submit screen.
{ "showCompletePage": true, "completedHtml": "<h3>Thanks, {firstName}.</h3><p>We received your request for {projectName}.</p>"}completedHtml is localizable and supports dynamic text placeholders.
Conditional Completion HTML
Section titled “Conditional Completion HTML”Use completedHtmlOnCondition when different respondents should see different completion messages. The first matching item can override completedHtml.
{ "completedHtml": "<h3>Thanks for your response.</h3>", "completedHtmlOnCondition": [ { "expression": "{eligible} = 'No'", "html": "<h3>Thanks for your time.</h3><p>You do not meet the current eligibility criteria.</p>" }, { "expression": "{scorePercent} >= 80", "html": "<h3>Passed</h3><p>Your score was {score}/{totalScore}.</p>" } ]}Redirects
Section titled “Redirects”Use navigateToUrl to redirect all respondents after completion. Use navigateToUrlOnCondition for conditional redirects.
{ "navigateToUrl": "https://example.com/thanks", "navigateToUrlOnCondition": [ { "expression": "{eligible} = 'No'", "url": "https://example.com/not-eligible" }, { "expression": "{plan} = 'enterprise'", "url": "https://example.com/sales" } ]}Early Completion
Section titled “Early Completion”Use a root complete trigger when a respondent should finish before reaching the last page, such as a screen-out flow.
{ "triggers": [ { "type": "complete", "expression": "{eligible} = 'No'" } ]}Prefer visibleIf and requiredIf for local branching. Use a complete trigger when the desired action is to submit or end the survey.
Preview Before Submit
Section titled “Preview Before Submit”Use showPreviewBeforeComplete to show an answer preview before final submission. Use previewMode to choose whether the preview includes all questions or only answered questions. Customize button captions with previewText, editText, and completeText where needed.
{ "showPreviewBeforeComplete": true, "previewMode": "answeredQuestions", "previewText": "Review answers", "editText": "Edit answers", "completeText": "Submit"}Response Variables
Section titled “Response Variables”Formspace sets these variables when a response is submitted:
| Variable | Value |
|---|---|
{responseNumber} |
The response’s number within the form, such as 42. |
{score} |
Points scored. Quizzes only. |
{totalScore} |
Points available. {maxScore} is the same value. Quizzes only. |
{scorePercent} |
The score as a percentage from 0 to 100. Quizzes only. |
In text, {correctAnswers} and {incorrectAnswers} also show a quiz’s answer counts.
The variables are empty while the respondent fills in the form. They have values on the thank-you page and in redirect URLs, in the dashboard’s response view and editor, in My Submissions, and in response PDFs. Use them in completion HTML, redirect URLs, HTML questions, conditions, and calculated values:
{ "calculatedValues": [{ "name": "reference", "expression": "'REF-' + {responseNumber}" }], "elements": [ { "type": "html", "name": "referenceBlock", "visibleIf": "{responseNumber} notempty", "html": "<p>Reference: {reference}</p>" } ], "completedHtml": "<h3>Thanks! Your reference is {reference}.</h3>", "navigateToUrl": "https://example.com/thanks?ref={responseNumber}"}To keep a value made from these variables with the response, use an expression question. It is saved with the response’s number and score, so it is a column in the submissions table and exports, and webhooks and integrations receive it:
{ "completedHtml": "<h3>Your score: {score}/{totalScore} ({scorePercent}%)</h3>", "elements": [ { "type": "expression", "name": "result", "title": "Result", "visibleIf": "{scorePercent} notempty", "expression": "iif({scorePercent} >= 70, 'Pass', 'Fail')" } ]}- Show content that uses these variables with
visibleIf: "{responseNumber} notempty"(or{scorePercent} notempty), so it appears only once the response is submitted. A placeholder without a value shows as written, such as{responseNumber}. - Everything the form makes from these variables (calculated values,
expressionquestions,setValueIf/setValueExpression/resetValueIfrules andsetvalue/copyvalue/runexpressiontriggers) is worked out from the submitted answers once, when the response is saved, and the thank-you page and redirect URL show the same values. Viewing or editing a saved response, and its PDF, show what was saved without running those rules and triggers again. - A calculated value with
includeIntoResultis also saved, and sent to webhooks and integrations, but has no column in the submissions table or exports. - Don’t use these variables in validators or
requiredIf: the respondent can’t satisfy them before submitting. - Questions and calculated values can’t use the name
responseNumber, and quizzes can’t use the quiz variable names either. - Submitted values under these names, such as from a prefilled link, are ignored when the response is saved. Forms that aren’t quizzes keep values named like the quiz variables, such as a prefilled
score. - Response numbers count up within each form, so showing one tells respondents roughly how many responses the form has had.
Respondent Variables
Section titled “Respondent Variables”On forms that respondents sign in to (email verified, organization or invite-only access), Formspace sets these variables as soon as the respondent has signed in:
| Variable | Value |
|---|---|
{respondentEmail} |
The respondent’s verified email address. |
{respondentName} |
The name from the respondent’s Microsoft or Google sign-in. Empty for email code sign-ins. |
Both are empty for anonymous respondents. Use them in default values, conditions, HTML, calculated values and completion HTML:
{ "completedHtml": "<h3>Thanks, {respondentName}!</h3>", "elements": [ { "type": "text", "name": "email", "title": "Email", "inputType": "email", "defaultValueExpression": "{respondentEmail}", "enableIf": "{respondentEmail} empty" }, { "type": "text", "name": "name", "title": "Name", "defaultValueExpression": "{respondentName}" }, { "type": "text", "name": "phone", "title": "Phone", "visibleIf": "{respondentEmail} empty" } ]}defaultValueExpressionfills in an empty answer only: saved progress, prefilled links and anything the respondent already typed are kept.enableIf: "{respondentEmail} empty"makes the email read-only once it’s known, and leaves it editable on anonymous forms. It doesn’t stop a respondent sending a different value, but every response also records the verified email itself, in the submissions table’s Email column.- Empty variables show as nothing in text, so
Thanks, {respondentName}!readsThanks, !when the name isn’t known. Useiif({respondentName} notempty, ...)or avisibleIfcondition to word it differently. - Rules and triggers that react to these variables, such as
setValueIf, arunexpressiontrigger or a trigger on a calculated value made from them, run once, when the form first gets them. Saving, grading, resuming or showing the response doesn’t run them again, and quizzes grade the questions the respondent’s details showed them. - Internal-use questions aren’t in the respondent’s form, so their default values never apply (the designer hides them), and
setValueIfandsetValueExpressionrun as the team edits the response but can’t be relied on when it’s submitted. To record the respondent’s details in an internal field, use an internal Expression question, such as{ "type": "expression", "name": "submittedBy", "expression": "{respondentEmail}", "formspaceInternal": true }. It’s worked out as the response is submitted and saved with it. - Resumed progress keeps its answers, and questions without one get their defaults, so a question added since the progress was saved is filled in. A default the respondent cleared is filled in again.
- The dashboard, My Submissions and response PDFs show a response with the email and name it was submitted with. The builder’s Preview uses your own email and name, unless respondents stay anonymous.
- Questions and calculated values can’t use the names
respondentEmailandrespondentName, and submitted values under these names are ignored.
Generation Notes
Section titled “Generation Notes”- Use Dynamic Text and Answer Piping when completion copy should include submitted answers.
- Use Localizable Strings for multilingual completion messages and button labels.
- Use Trigger for early completion rules.
- Avoid redirects when the respondent should see Formspace’s confirmation, saved-state, or quiz result page.