A form on Core dna is a record like a page: a tree of steps, groups and elements, with its own layout and layout areas, revisions and publishing. Submissions are stored as records too, and what happens next is the job of the Orchestration module. This guide follows a form from building it to acting on what it collects.
Who this guide is for
Theme developers who render and style forms, content modellers who build them in the admin, and integrators who send submissions on to other systems. It assumes you know layouts and templates (Input types, layouts, components and images) and, for the last unit, jobs (Automation, jobs and integration). Every template example is given in both engines.
The units, in order
- Building a form: how a form is put together and placed on a page, its fields, groups and static elements, and multi-step forms.
- Validating answers: what the server checks, how a rejected submission comes back, and accessible error messages.
- Branching forms: showing and hiding fields, groups and steps by earlier answers.
- Presenting a form: the markup the platform prints, styling it, client-side helpers and the captcha.
- Storing submissions: reading and exporting them, file uploads, retention and privacy, and submitting through the API.
- Acting on a submission: jobs, notifications and confirmations, creating records, pushing to a CRM, and taking payments.
- Reference: every input type, and the platform's three form scripts.
The platform supports two submission models, and the choice affects almost everything else in this guide. The form layout decides which one a form uses.
| Page per step | All steps in one page (JS) |
| How it submits | An ordinary POST to the page the form is on, one step at a time | The platform's /assets/forms/js-forms.js moves between steps in the browser, then sends every step in one JSON POST to /cdna-api/forms/submission/<form id> |
| Stored between steps | Yes: each step is saved as it is submitted, and a token in the page ties the steps together | Nothing, until the final submit. A reload loses everything typed |
| Back to an earlier step | No. The server always shows the first step that is not yet valid | Yes: .navigate-previous and .go-to-step links |
| Conditions that look at an earlier step | Not on the server, which sees only the current step's answers. See Conditional logic | Yes: every answer arrives together |
| Works without JavaScript | Yes | No |
| Validation errors | The step is rendered again with the answers kept and an error under each failing field | Returned as JSON. Add the handling on Validation rules and error handling so that the visitor's answers are kept |
Use page per step for one-step forms and for anything that must work without JavaScript. Use the JS layout for multi-step forms whose later steps depend on earlier answers, or that need a back button, together with the error handling on the validation page. The details of each are on Multi-step forms.
Five things to know first
- Every form needs a layout with a template. Check the layout first when you place a form (How a form is put together).
- Branching on an earlier step needs the JS model. The server sees only the current step's answers, so a condition that looks further back needs the JS submission model (Conditional logic).
- The CSRF token is for signed-in members only. Public forms are not CSRF-checked, and
_csrfToken exists only when someone is signed in, so print it guarded (How a form is put together).
- Uploaded files are public. A form's uploads go to the file manager, where anyone with the link can read them (File uploads).
- What follows a submission is a job. Notifications, records and CRM pushes are jobs on the form's submissions, and run in the background by default (Jobs, notifications and confirmations).