Skip to content

Form Capability Patterns

Use this page when a request describes what a form should do rather than naming a specific question type or property. For exact property definitions, use the linked schema pages.

Use expressions for show/hide logic, read-only logic, conditional required fields, skips, and early completion.

  • visibleIf shows or hides questions, panels, pages, choices, matrix rows, and matrix columns.
  • enableIf makes a question, panel, page, or choice editable only when an expression is true.
  • requiredIf makes a question, panel, or page required only when an expression is true.
  • Root triggers support branch-style actions such as skip and complete.
  • Prefer visibleIf, enableIf, and requiredIf for local logic. Use triggers when the respondent should jump to another page/question or finish the form.
{
"title": "Branching intake",
"pages": [
{
"name": "screen",
"elements": [
{
"type": "radiogroup",
"name": "eligible",
"title": "Are you eligible?",
"choices": ["Yes", "No"],
"isRequired": true
}
]
},
{
"name": "details",
"elements": [
{
"type": "comment",
"name": "notes",
"title": "Tell us more",
"visibleIf": "{eligible} = 'Yes'",
"requiredIf": "{eligible} = 'Yes'"
}
]
}
],
"triggers": [{ "type": "complete", "expression": "{eligible} = 'No'" }]
}

Related pages: Expression Syntax, Trigger, Completion Behavior, Shared Question Properties, Page, Panel.

Defaults, Calculations, and Derived Values

Section titled “Defaults, Calculations, and Derived Values”

Use static defaults for fixed values, expression defaults for dynamic values, calculated values for reusable hidden results, and expression questions for visible calculated output.

  • defaultValue sets a fixed initial answer.
  • defaultValueExpression calculates an initial answer, such as a date relative to today.
  • setValueIf and setValueExpression update a question value when a condition becomes true.
  • resetValueIf clears a question when a condition becomes true.
  • calculatedValues define reusable hidden values on the form root.
  • expression question elements display calculated values to respondents.
{
"title": "Project dates",
"calculatedValues": [
{
"name": "durationDays",
"expression": "dateDiff({startDate}, {endDate}, 'days')",
"includeIntoResult": true
}
],
"pages": [
{
"name": "dates",
"elements": [
{ "type": "text", "name": "startDate", "title": "Start date", "inputType": "date", "defaultValueExpression": "today()" },
{ "type": "text", "name": "endDate", "title": "End date", "inputType": "date", "defaultValueExpression": "today(14)" },
{ "type": "expression", "name": "duration", "title": "Duration", "expression": "{durationDays}", "displayStyle": "decimal" }
]
}
]
}

Related pages: Expression Syntax, Calculated Value, Expression Question, Text.

Use carry-forward properties when later choice questions should reuse choices from an earlier question.

  • choicesFromQuestion names the source question.
  • choicesFromQuestionMode controls whether to copy all, selected, or unselected choices.
  • choiceValuesFromQuestion and choiceTextsFromQuestion select fields when the source is a dynamic matrix or dynamic panel.
  • Use hideIfChoicesEmpty when a follow-up question should disappear if there are no choices to show.
  • For ranking, use selectToRankEnabled when respondents should rank only a subset of carried-forward choices.
{
"pages": [
{
"name": "priorities",
"elements": [
{
"type": "tagbox",
"name": "selectedProducts",
"title": "Which products do you use?",
"choices": ["Forms", "Templates", "Approvals", "Analytics"],
"maxSelectedChoices": 3
},
{
"type": "ranking",
"name": "productPriority",
"title": "Rank the selected products",
"choicesFromQuestion": "selectedProducts",
"choicesFromQuestionMode": "selected",
"selectToRankEnabled": true,
"hideIfChoicesEmpty": true
}
]
}
]
}
{
"pages": [
{
"name": "line_items",
"elements": [
{
"type": "matrixdynamic",
"name": "lineItems",
"title": "Line items",
"columns": [
{ "name": "sku", "title": "SKU", "cellType": "text" },
{ "name": "label", "title": "Label", "cellType": "text" }
]
},
{
"type": "dropdown",
"name": "featuredSku",
"title": "Featured item",
"choicesFromQuestion": "lineItems",
"choiceValuesFromQuestion": "sku",
"choiceTextsFromQuestion": "label"
}
]
}
]
}

Related pages: Shared Choice Question Properties, Ranking, Tagbox, Matrix Dynamic, Panel Dynamic.

Use dynamic matrices for repeatable tabular rows. Use dynamic panels for repeatable groups of mixed questions.

  • matrixdynamic is best for line items, scorecards, schedules, and grids with repeated columns.
  • paneldynamic is best for repeated objects with multiple question types, such as dependents, jobs, events, or contacts.
  • rowCount, minRowCount, and maxRowCount constrain dynamic matrix rows.
  • panelCount, minPanelCount, and maxPanelCount constrain dynamic panel entries.
  • copyDefaultValueFromLastEntry can make each new row/panel start from the previous entry.
  • keyName and keyDuplicationError help prevent duplicate row or panel keys.
  • rowsVisibleIf filters matrix rows; templateVisibleIf filters dynamic panels.
  • templateTabTitle and tabTitlePlaceholder create useful dynamic panel tab labels.
{
"type": "paneldynamic",
"name": "dependents",
"title": "Dependents",
"minPanelCount": 1,
"maxPanelCount": 5,
"displayMode": "tab",
"templateTabTitle": "{panel.fullName}",
"tabTitlePlaceholder": "Dependent",
"templateElements": [
{ "type": "text", "name": "fullName", "title": "Full name", "isRequired": true },
{ "type": "text", "name": "birthDate", "title": "Birth date", "inputType": "date" }
]
}

Related pages: Matrix Dynamic, Matrix Dropdown, Matrix Column, Panel Dynamic, Expression Syntax.

Use matrix columns with numeric cell inputs for per-row values, expression columns for row-level calculated cells, column total properties for matrix footer totals, and calculated values or expression questions for form-level totals.

{
"type": "matrixdynamic",
"name": "expenses",
"title": "Expenses",
"columns": [
{ "name": "description", "title": "Description", "cellType": "text" },
{ "name": "quantity", "title": "Quantity", "cellType": "text", "inputType": "number" },
{ "name": "unitPrice", "title": "Unit price", "cellType": "text", "inputType": "number" },
{
"name": "lineTotal",
"title": "Line total",
"cellType": "expression",
"expression": "{row.quantity} * {row.unitPrice}",
"totalType": "sum",
"totalDisplayStyle": "currency",
"totalCurrency": "USD"
}
]
}
{
"calculatedValues": [
{
"name": "expenseTotal",
"expression": "sumInArray({expenses}, 'lineTotal')",
"includeIntoResult": true
}
],
"pages": [
{
"name": "summary",
"elements": [
{ "type": "expression", "name": "totalDisplay", "title": "Expense total", "expression": "{expenseTotal}", "displayStyle": "currency", "currency": "USD" }
]
}
]
}

Related pages: Matrix Dynamic, Matrix Dropdown, Matrix Column, Calculated Value, Expression Syntax.

Use inputType for native HTML input behavior and use masks when the answer must follow a stricter format.

  • Common inputType values include text, email, url, tel, number, date, time, datetime-local, month, and week.
  • min, max, and step constrain numeric and date inputs.
  • minValueExpression and maxValueExpression calculate date or numeric limits dynamically.
  • maskType can be pattern, datetime, numeric, or currency; maskSettings stores the mask-specific configuration.
  • Use validators even when an input mask is present if invalid data must be blocked at submit time.
{
"type": "text",
"name": "appointmentDate",
"title": "Appointment date",
"inputType": "date",
"minValueExpression": "today()",
"maxValueExpression": "today(90)",
"isRequired": true
}

Related pages: Text, Input Masks, Validators, Expression Syntax.

Section titled “Navigation, Progress, Numbering, and Randomization”

Use root, page, and panel settings to control how respondents move through a form.

  • firstPageIsStartPage turns the first page into a welcome/start page.
  • showNavigationButtons controls Start, Next, Previous, and Complete buttons.
  • completeText, pageNextText, pagePrevText, and related localizable strings can customize navigation copy where supported.
  • showProgressBar and progressBarLocation show progress.
  • showQuestionNumbers controls numbering style.
  • questionOrder: "random" randomizes questions at the survey, page, or panel level.
  • Choice questions can use choicesOrder: "random" to randomize choices.
  • Matrix questions can use row ordering properties such as rowsOrder where supported.
  • showCompletePage, completedHtml, completedHtmlOnCondition, navigateToUrl, and navigateToUrlOnCondition control post-submit flow.
{
"title": "Application",
"firstPageIsStartPage": true,
"showProgressBar": true,
"progressBarLocation": "topbottom",
"showQuestionNumbers": "onPage",
"completedHtml": "<h3>Thanks for applying.</h3>",
"pages": [
{ "name": "intro", "title": "Before you begin", "elements": [{ "type": "html", "name": "introText", "html": "<p>Have your documents ready.</p>" }] },
{ "name": "questions", "questionOrder": "random", "elements": [] }
]
}

Related pages: Form Root, Completion Behavior, Page, Panel, Choice Item.

Use layout properties to control density and grouping without changing data shape.

  • pages, panels, and nested elements define form structure.
  • startWithNewLine, width, minWidth, and maxWidth place questions beside each other or force new rows.
  • indent offsets nested content.
  • questionTitleLocation, questionDescriptionLocation, and questionErrorLocation control title, description, and error placement.
  • html elements display rich instructions and do not submit a value.
  • image elements display images or video and do not submit a value.
  • theme, cssVariables, and header settings control visual styling.
{
"type": "panel",
"name": "contactRow",
"elements": [
{ "type": "text", "name": "firstName", "title": "First name", "width": "50%" },
{ "type": "text", "name": "lastName", "title": "Last name", "startWithNewLine": false, "width": "50%" }
]
}

Related pages: Panel, Shared Question Properties, HTML, Image, Theme Configuration, Theme CSS Variables.

Use localizable strings when a form needs multiple languages.

  • Localizable properties include titles, descriptions, placeholders, choice text, button text, error text, completedHtml, and many custom labels.
  • locale selects the active locale.
  • Formspace renders a respondent language selector when the survey uses multiple locales.
  • Keep question name and choice value stable across languages; translate display title, description, text, and other localizable labels instead.
{
"locale": "en",
"title": { "default": "Event registration", "es": "Registro del evento" },
"pages": [
{
"name": "attendee",
"elements": [
{
"type": "text",
"name": "fullName",
"title": { "default": "Full name", "es": "Nombre completo" },
"isRequired": true
}
]
}
]
}

Related pages: Localizable Strings, Form Root, Shared Question Properties, Choice Item.

Use isRequired for mandatory answers and validators for specific constraints.

  • numeric validates number ranges.
  • text validates text length.
  • answercount validates checkbox/tagbox/ranking selection count.
  • regex validates a pattern.
  • email validates email format.
  • expression validates custom cross-field rules.
  • text, minErrorText, maxErrorText, and other error labels are localizable.
{
"type": "text",
"name": "endDate",
"title": "End date",
"inputType": "date",
"validators": [
{
"type": "expression",
"text": "End date must be after the start date.",
"expression": "{startDate} < {endDate}"
}
]
}

Related pages: Validators, Expression Validator, Text Validator, Numeric Validator, Answer Count Validator, Regex Validator, Email Validator.

Use file and signature questions for respondent-provided assets. Use image, image picker, and HTML for presentation or media selection.

  • file collects attachments. Use acceptedTypes, acceptedCategories, allowMultiple, maxFiles, maxSize, and sourceType.
  • allowImageMarkup lets respondents annotate image uploads before submit.
  • imagepicker lets respondents select images or videos as answers.
  • image displays an image or video without submitting a value.
  • signaturepad collects drawn input and can store png, jpeg, or svg data.
  • html can embed instructions, links, or media but should only include trusted content.
{
"type": "file",
"name": "photos",
"title": "Upload site photos",
"acceptedCategories": ["image"],
"allowMultiple": true,
"maxFiles": 5,
"allowImageMarkup": true
}

Related pages: File Upload, Image Picker, Image, Signature Pad, HTML.

Use Formspace secure quiz fields when a form needs grading.

  • Add correctAnswer to a value-producing question to make it part of quiz grading.
  • Add score only when a question should be worth more or less than the default 1 point.
  • Formspace removes answer keys and scores from respondent-facing payloads and grades server-side.
  • Use post-submit variables such as {score}, {totalScore}, {scorePercent}, {correctAnswers}, and {incorrectAnswers} in completedHtml or completedHtmlOnCondition.
  • Do not use choices[].score for secure Formspace quiz grading.
{
"elements": [
{
"type": "radiogroup",
"name": "capital",
"title": "What is the capital of France?",
"choices": ["Berlin", "Madrid", "Paris", "Rome"],
"correctAnswer": "Paris",
"score": 2
}
],
"completedHtml": "<h3>Your score: {score}/{totalScore} ({scorePercent}%)</h3>"
}

Related pages: Completion Behavior, Shared Question Properties, Quizzes and Scoring.