Forms & sign-ups
A church publishes a form — camp registration, serve sign-up, a survey, an RSVP for a non-event — and members fill it in their portal. The admin reads the submissions in one place.
Forms run on the Forms community module (Community settings). Turning the module off hides the member Forms surfaces — a member who opens the Forms page sees a disabled "forms aren't enabled" state, on web and mobile. The admin Forms section stays available so you can still build and manage forms; existing submissions stay in the database.
How do I build a form?
In the admin sidebar, open Community → Manage forms. Click New form. The builder has three parts:
- Title + description — the title is required (max 160 chars). The description renders above the form for members.
- Fields — drag the grip handle to reorder. Each field has a type (see below), a label, a stable key (lowercase, used in CSV exports), and a Required toggle.
- Save — saves the form as a Draft. Drafts are admin-only; members don't see them.
Field types
| Type | What members see |
|---|---|
| Short text | A single-line text input. |
| Long text | A multi-line textarea. |
| Number | A numeric input. Optional min / max. |
| A text input that validates email format. | |
| Phone | A text input that validates phone (loose; 7–20 digits). |
| Date | A date picker — the in-app calendar on both web and mobile. |
| Select | A dropdown of admin-curated options (pick one). |
| Multi-select | A list of admin-curated options where members can pick several. |
| Checkbox | A single yes/no checkbox. |
The renderer (web + mobile) validates each value as the member fills. Required fields block the Submit button until they're filled.
Draft with AI
Don't want to build every field by hand? In the form editor, click Draft with AI (top right, on new and existing forms). Describe the form in plain language — for example:
"A potluck sign-up. We need each person's name, how many guests they're bringing, what dish they'll bring, and any allergies to flag."
Click Generate draft and the assistant suggests a title, a short description, and a set of fields — picking sensible types for you (a Number for the guest count, Multi-select for allergies, and so on). Review the suggestion, then choose how to apply it:
- Replace form — overwrites the current title, description, and fields with the suggestion. Best when you're starting fresh.
- Add to form — appends the suggested fields to what you already have, and fills the title/description only if they're still blank. Best for fleshing out a form you've started.
Either way, nothing is saved automatically from the suggestion — every field lands in the editor where you can rename, reorder, retype, or delete it before you publish. AI drafting counts against your plan's monthly AI allowance, and is unavailable if AI isn't configured for your site.
Publishing + closing
In the admin Forms list, each form has a status:
- Draft — admin-only. The Publish button flips it to Open.
- Open — members see + can submit. The Close button flips it to Closed.
- Closed — members see the form (so they remember what they submitted) but cannot submit new responses.
A form can carry a close date (closes_at). After that time the form
auto-rejects new submissions even if its status is still Open, and the forms
list shows a "Closes <date>" hint. (Event-attached forms get their close date
from the event when you attach them.)
Archive soft-deletes the form and moves it to an Archived disclosure on the forms list, where each row has a Restore button to bring it back. Submissions are kept either way.
What members see
In the member portal, Forms in the sidebar (when module_forms is
on) lists the open and closed standalone forms, newest first.
Event-attached forms don't appear here — a member fills those from the
event itself, so submitting also registers their RSVP (see
Events). Tapping a standalone form opens the fill page:
- The form's title + description at the top.
- Each field rendered per its type, with required markers.
- A Submit button that fires per-field validation and then sends the answers.
A member can submit a form once. If they revisit, they see a summary of the answers they sent, with two actions while the form is still open:
- Edit answers — reopens the form pre-filled with their prior response; saving updates the same submission (it doesn't create a duplicate).
- Remove response — deletes their submission after a confirm dialog. They can fill the form in again while it's open.
If the form is Closed, the page keeps the answers summary visible (without Edit/Remove) and shows a "contact the church office to make changes" note; with no prior response it shows "This form isn't accepting new submissions."
Reading submissions
From the admin Forms list, Submissions on any form opens a table:
- Submitted timestamp.
- Submitter display name (resolved from
profiles). Anonymous submissions (only possible if a future direct-link flow lets signed-out visitors submit) show "—". - One column per field, in the same order as the form itself. Empty answers render as "—"; checkboxes as Yes/No; dates as the locale-formatted date.
Exporting submissions (a per-church data export bundle) is on the roadmap — it isn't built yet, so today you read submissions in this table. (Event registrations have their own CSV export on the event's Registrations tab.)
Who sees what
| Item | Members | Submitter | Admins |
|---|---|---|---|
| Draft form | ❌ | — | ✅ |
| Open form | ✅ | ✅ | ✅ |
| Closed form | ✅ | ✅ | ✅ |
| Trashed form | ❌ | ❌ | ✅ |
| Submit to an Open form | ✅ (own only) | — | — |
| Submit to a Closed form | ❌ (RLS rejects) | — | — |
| Own submission | — | ✅ | ✅ |
| Edit/remove own submission (form Open) | — | ✅ | — |
| Edit/remove own submission (form Closed or date passed) | — | ❌ (RLS rejects) | — |
| Another member's submission | ❌ | ❌ | ✅ |
RLS enforces every one of these on the database. A database trigger additionally validates every submission write — required fields must be answered and select/multi-select answers must come from the field's declared options — and, for event registrations, that the submission uses the event's attached form with the right per-date / per-series keying. A crafted API call can't register with blank or junk answers.
Future / fast-follows
- Payment-bearing forms — a camp fee that runs through
Giving. Out of scope this slice; would join
formsto Phase 2 giving + funds. - File-upload fields — out (needs Supabase Storage wiring + cleanup on submission/form delete).
- Conditional / branching logic — out; v1 forms are flat.
- A per-church data-export bundle (standalone-form submissions in one download) — roadmap; not built yet.
More topics