The Form Builder is the core of CampaignCanvas. It provides a visual editor for creating and managing forms within the Umbraco backoffice. This guide covers form creation, multi-page layouts, conditional logic, grid positioning, revision history, and duplication.
Creating Forms
Every form in CampaignCanvas starts with a handful of core properties that identify it across the system.
Form Properties
| Property | Description |
|---|---|
| Name | A human-readable label shown in the backoffice. Can contain spaces and special characters. |
| Alias | A URL-safe, unique identifier for the form. Used in API endpoint paths (/api/v1/campaigncanvas/public/submit/{alias}) and when referencing the form from the view component (Component.InvokeAsync("CampaignCanvasRenderer", new { formAlias = "contact-us" })). Must be lowercase, alphanumeric, and may contain hyphens. No two forms can share the same alias. |
| Description | An optional internal note. Not rendered on the front end — useful for documenting the form’s purpose for other editors. |
Choose your alias carefully. While it can be changed later, any existing API integrations or ViewComponent references that use the old alias will break. Treat aliases like URL slugs — short, descriptive, and stable.
Form Folders
As your form library grows, use folders to keep things organized. Folders are purely cosmetic — they group forms in the backoffice tree but have no effect on aliases, API paths, or rendering. You can nest folders and drag forms between them at any time.
Sort Order
Each form has a numeric sort order that controls its position within a folder. Lower numbers appear first. When multiple forms share the same sort order, they fall back to alphabetical sorting by name.
Forms Overview
The Forms overview lists your forms with their number of fields and submissions, and when each was Last updated. Click the Name, Fields, Submissions or Last updated header to sort the list by that column, and click it again to reverse the order. Names sort the way people read them, so Form 2 comes before Form 10. Until you pick a column, the list keeps its usual order.
Archiving
Forms can be archived instead of deleted. An archived form is hidden from the main list and excluded from API endpoints, but its data (submissions, revisions, settings) is preserved. You can unarchive a form at any time to restore it to active duty.
TipArchive seasonal or campaign forms when they’re no longer needed rather than deleting them. This keeps your submission data intact for future reporting.
Where a Form Is Used
Before you change or archive a form, check where it appears. Open the form’s Settings tab: the Info section at the top lists the pages that use the form under Used on. Click a page to open it in a new tab. Each page shows its status:
| Status | Meaning |
|---|---|
| Published | The live page shows the form. |
| Draft only | The page’s latest version uses the form, but that version isn’t published yet. |
| Removed in draft | The live page still shows the form, but its latest version no longer does. |
The list covers pages that pick the form in a CampaignCanvas Form Picker, directly or inside blocks. A form added straight from a template isn’t listed.
Multi-Page Forms
CampaignCanvas supports splitting a form across multiple pages, which is useful for long or complex forms like onboarding wizards, multi-step checkouts, or detailed surveys.
Page Structure
Internally, a form’s schema is stored as Schema.Pages — an ordered array of page objects. Each page has:
- Title(optional) — displayed as a heading above the page’s fields. If omitted, no heading is rendered.
- Fields — the list of field definitions that belong to this page.
Even single-page forms use this structure — they simply have one page in the array.
Managing Pages
In the form builder UI:
- Click the “+ Add page” button to append a new page.
- Use the arrow buttons on each page header to reorder pages.
- Remove a page by clicking its delete action. Fields on a deleted page are removed with it — move them first if you want to keep them.
Step Indicator
You can configure how users see their progress through a multi-page form by setting the step indicator mode:
| Mode | Value | Behavior |
|---|---|---|
| None | "none" | No visual indicator is shown. Users navigate blind — suitable for very short forms (2 pages). |
| Numbered | "numbered" | Displays numbered step pills, e.g. Step 1 of 3. Best for forms where each page represents a distinct section. |
| Progress | "progress" | Shows a progress bar with a percentage. Ideal for longer forms where the exact step number matters less than overall completion. |
Navigation and Validation
Multi-page forms render Previous and Next buttons for navigation. The Submit button only appears on the last page.
Validation is per-page: when the user clicks Next, only the fields on the current page are validated. The user cannot advance until all visible, required fields on the current page pass validation. This prevents users from being overwhelmed by errors from fields they haven’t seen yet.
TipCombine multi-page forms with conditional logic to create adaptive wizards. For example, a first page can ask “Are you an individual or a business?” and subsequent pages can show different fields based on the answer.
Conditional Logic
Conditional logic lets you show or hide fields based on other fields’ values. This keeps forms concise by only presenting questions that are relevant to the user’s situation.
How It Works
Any field can have a VisibleWhen condition attached to it. A condition is a simple rule composed of three parts:
- Field Alias — the alias of the field to evaluate.
- Operator— how to compare the field’s value.
- Value — the expected value (not required for all operators).
In the field inspector, pick the field to check under Visible when, then the operator and, where needed, the value. To check more than one field, click Add condition and choose under Combine rules with whether all rules must match (AND) or any rule can match (OR).
On a multi-page form, the field lists under Visible when and Add condition include the fields from every page, grouped under each page’s title (or “Page 1”, “Page 2” and so on for a page without one). A field on a later page can depend on an answer given on page 1.
Available Operators
| Operator | Description | Requires Value |
|---|---|---|
equals | Case-insensitive match against the target value | Yes |
notequals | Case-insensitive non-match against the target value | Yes |
contains | Substring match (case-insensitive) | Yes |
isempty | True when the field value is null or whitespace | No |
isnotempty | True when the field has any non-whitespace value | No |
A checkbox list can have several options ticked. For these fields, equals and contains match when any ticked option matches the value, notequals matches when that option isn’t ticked, and isempty matches when nothing is ticked. The browser and the server apply the same rules, so a field that appears in the browser also keeps its answer on submit. Conditions on single checkboxes and radio buttons compare the one value as usual.
Behavior When Hidden
When a field’s VisibleWhen condition evaluates to false, the following happens:
- The field is not rendered on the page — it is completely removed from the DOM, not just visually hidden.
- The field is not validated — required rules and other validators are skipped for hidden fields.
- Any submitted values for hidden fields are silently droppedon the server. This prevents data poisoning attacks where a malicious user manually submits values for fields they shouldn’t see.
Client-Side Evaluation
Conditions evaluate in real-time on the client as the user types or selects values. There is no round-trip to the server — fields appear and disappear instantly as conditions are met or unmet.
Example
Suppose you have a Dropdown field with alias typeand options “Individual” and “Business”. You want to show a Textfield called “Company Name” only when the user selects “Business”.
Configure the “Company Name” field’s condition as:
- Field Alias:
type - Operator:
equals - Value:
Business
Now the “Company Name” field remains hidden until “Business” is selected, and any value entered into it is discarded if the user switches back to “Individual”.
Grid Layout
By default, every field occupies the full width of the form. Each field has a Width property that places it on a 12-column grid, so related fields can sit on one row.
Width Property
Pick a width in the field inspector. Existing forms that used only full or half keep the same layout — omitted width still means full, and unknown values fall back to full so older forms are not rewritten on load.
| Value | Columns | Behavior |
|---|---|---|
"full" | 12 | The field spans the entire row (default). It always starts on a new line. |
"twoThirds" | 8 | Two-thirds of the row. Pairs with a third-width field on the same row. |
"half" | 6 | Half of the row. Two consecutive half-width fields sit side by side. |
"third" | 4 | One third of the row. Three consecutive third-width fields sit side by side. |
"quarter" | 3 | One quarter of the row. Four consecutive quarter-width fields sit side by side. |
CSS Grid Implementation
The form renderer uses CSS Grid with twelve tracks:
grid-template-columns: repeat(12, minmax(0, 1fr));A "full" field spans 12 columns, "twoThirds" spans 8, "half" spans 6, "third" spans 4, and "quarter" spans 3. You can mix these in any order — the grid places each field in the next available space.
Common Patterns
- First Name + Last Name — both set to
"half". - Title + First Name + Last Name — three fields set to
"third". - Two-thirds + Third — a long field next to a short one, for example street and house number.
- Day + Month + Year + Code — four fields set to
"quarter". - Address Line 1 —
"full", spanning the entire width.
Tip. Width is a desktop layout hint. Below 640px of form container width, thirds and quarters become half-width so they stay usable in a sidebar. At 560px everything stacks to a single column — the same phone breakpoint as before. You do not configure extra mobile widths.
Field Groups
A group is a layout container for related fields. Its name is backoffice-only unless you turn on Show group title on form in the group inspector. That toggle is off by default, so existing forms do not grow unexpected headings. When it is on, the group label renders as a heading above the group's fields.
Revisions
CampaignCanvas automatically tracks every meaningful change to a form through an immutable revision history. This gives you a complete audit trail and the ability to roll back to any previous state.
Automatic Snapshots
Every time you save a form, CampaignCanvas compares the current schema and settings against the last saved version using JSON equality. If anything has actually changed — a field added, a label edited, a setting toggled — a new revision is created. If nothing changed (e.g. you clicked Save without making edits), no revision is created. This keeps the history clean and meaningful.
What Revisions Track
Each revision stores:
- Version number — an auto-incrementing integer (1, 2, 3, ...).
- Form name — the name of the form at the time of the revision.
- Schema — the complete page and field structure.
- Settings — all form-level settings (submission behavior, notifications, etc.).
- Timestamp — when the revision was created.
- Created by — the Umbraco user who made the change.
Viewing Revisions
Open the Revisions panel in the form builder to see a chronological list of all revisions. Each entry shows the version number, timestamp, and the user who created it.
Restoring a Revision
You can restore any revision to revert the form to that point in time. When you restore:
- A new revision of the current state is created first (so you never lose your current work).
- The form’s schema and settings are then overwritten with the values from the selected revision.
This means restoring is always safe — you can restore a restore if needed.
Immutability
Revisions are append-only. Once created, a revision cannot be edited or deleted individually. Revisions are only removed when the parent form itself is permanently deleted.
TipBefore making large structural changes to a form (like reorganizing pages or removing fields), note the current version number. If anything goes wrong, you can restore to that version in one click.
Duplication
Duplicating a form creates an independent copy that you can modify without affecting the original. This is useful for creating variations of an existing form (e.g. a localized version) or using a form as a template.
How It Works
Click the Duplicate action on any form. CampaignCanvas performs a deep clone of the entire form, including:
- All schema data (pages, fields, conditions, grid widths).
- All settings (submission behavior, notifications, workflows).
ID Regeneration
During duplication, all internal identifiers are regenerated — page IDs, field IDs, and workflow IDs all receive fresh values. This ensures the duplicate is fully independent and won’t conflict with the original in the database or API.
Naming
The duplicate receives an auto-generated name and alias based on the original:
- Name:
"{Original Name} (Copy)" - Alias:
{original}-copy
If a form with that alias already exists, a numeric suffix is appended: {original}-copy-2, {original}-copy-3, and so on.
Duplication does not copy submissions or revision history. The new form starts with a clean slate — zero submissions and a single initial revision.