Forms
v1.4.8A drag-and-drop form builder with branching multi-step flows, conditional logic, file uploads, a searchable entries inbox and built-in spam protection — all from one WPStack panel, with no external form service.
Overview
The Forms module builds anything from a quick contact box to a branching, multi-step intake — and keeps every submission in a searchable inbox.
Build a form by dragging in fields, or switch to Flow mode for a multi-step form that branches on the visitor’s answers. Place it with a shortcode or the Elementor widget, and collect submissions in the Entries inbox and by email.
| Title | Type | Items | Entries | Shortcode |
|---|---|---|---|---|
Get a quote #3 | FLOW | 5 steps | 46 | [stack_form id="3"] |
Website intake #2 | SIMPLE | 12 fields | 64 | [stack_form id="2"] |
Contact #1 | SIMPLE | 5 fields | 18 | [stack_form id="1"] |
What you can do
- Build simple forms with a drag-and-drop field list — text, email, phone, dropdowns, files and more
- Build branching flows on a visual canvas of choice and group nodes
- Add conditional logic to show or hide any field based on another answer
- Collect submissions in a searchable Entries inbox with CSV export
- Email a notification to your team and an optional confirmation to the submitter
- Keep spam out with a honeypot, rate limiting and an auto Blocked IPs list
[stack_form id="…"] shortcode. Flip a form between Simple and Flow at any time from the builder tabs.Requirements & compatibility
Forms runs on any modern WordPress host with no external service.
| Requirement | Minimum | Recommended |
|---|---|---|
| WordPress | 6.0 | 6.5 or newer |
| PHP | 7.4 | 8.1 or newer |
| Elementor | Optional | For the drag-in form widget |
| SMTP | Optional | For reliable notification delivery |
Installation & activation
Forms ships inside WPStack — switch it on per site from the modules panel.
Open the WPStack modules panel
In your WordPress admin, go to WPStack → Modules and find Forms.
Activate Forms
Flip the Forms toggle to on. A new Forms item appears in the WPStack menu.
Create a form
Open WPStack → Forms → New form, name it, and add fields (or switch to Flow mode).
Set notifications
Under the form’s Notifications and After submit panels, set the notify email, success message and any confirmation.
Place the shortcode
Copy the form’s [stack_form id="…"] shortcode onto any page, or add the Elementor widget.
The field builder
Simple forms are a drag-and-drop list of fields. Click a field to edit it in a popover, drag its edge to set the width, and drag the handle to reorder.
Field types
- Text, Email, Phone, Textarea, Number
- Dropdown, Radio, Checkboxes, Single checkbox
- Date, File upload (with allowed extensions), Hidden
- Section break to group and title parts of the form
Editing a field
Click a field to open its editor popover — a floating panel that never resizes the tile or pushes the other fields. Set the Field Name (the visible label), an optional Placeholder (a toggle shown only for text-style fields), the Field Key used in entries and emails, the Width, whether it is Required, and any Conditional logic.
Field widths & layout
Every field has a width from 10% to 100%. Pick one from the Width dropdown, or just drag the blue handle on a field’s right edge — fields tile live, so you see the layout as you build.
- Two 50% fields sit side by side; three 33% share a row
- A 100% field takes its own row
- Snap presets: 10, 20, 25, 33, 40, 50, 60, 66, 75, 80, 90, 100%
- Everything stacks to full width on mobile automatically
email, email_2…) and a blank key is generated from the label, so entries and notification emails stay unambiguous.Conditional logic
Every field can show or hide based on another field’s answer — no code, enforced on the front end and re-checked on submit.
Open a field, enable Conditional logic, and add rules: this field will show or hide when all or any of your conditions match.
| Operator | Matches when the source field… |
|---|---|
equals / not equals | is exactly / is not the value |
contains / not contains | includes / does not include the value |
is empty / is not empty | has no value / has any value |
Flow mode (steps & branches)
Flow turns a form into a branching, multi-step experience built on a visual canvas.
- Choice nodes branch the flow — each option leads to a different next node
- Group nodes hold the fields for a step; drag field types from the palette
- The visitor only sees the path their answers lead to
- A progress bar, Back and Next are built in; only the visited path is submitted
[stack_form id="…"] shortcode as a simple form — switch a form between Simple and Flow from the builder tabs at any time.Entries inbox
Every submission is stored, searchable and exportable — with source intelligence for each lead.
- Filter by form; read / unread state per entry
- Source intelligence — UTM, referrer, device and IP
- Export CSV of the entries
- Per-row delete
Spam protection & Blocked IPs
Two layers keep junk out with no CAPTCHA: a silent honeypot and per-IP rate limiting.
- A hidden honeypot field silently drops bot submissions
- Rate limiting — an IP that exceeds 15 submissions a minute is blocked
- Blocked addresses appear under Blocked IPs, where you can Unblock them
Notifications & confirmations
Email your team on every submission, and optionally confirm to the person who submitted.
- Notify email and subject for the team notification (a branded HTML table of the entry)
- Confirm to submitter — an optional confirmation email sent to the submitted email address
- Button text and a success message, or a redirect URL after submit
Shortcode & Elementor
Place a form with a shortcode or the native Elementor widget.
Render a form (simple or flow) anywhere.
[stack_form id="2"]Settings reference
Each form has its own Notifications and After-submit settings.
| Setting | Type | Default | What it does |
|---|---|---|---|
| Notify email | Admin email | Where the submission notification is sent. Leave as the site admin or set a team inbox. | |
| Subject | text | New form submission | Subject line of the notification email. |
| Confirm to submitter | toggle | Off | Send a confirmation email to the address submitted in the form. |
| Button text | text | Send Message | Label of the form’s submit button. |
| Success message | text | Thank you! … | Shown in place of the form after a successful submission. |
| Redirect URL | url | — | Optional. Send the visitor to this URL after submit instead of showing the success message. |
Webhooks & integrations
Send every submission straight to Make, Zapier, n8n or your own CRM, the moment it arrives.
With the Connect module enabled, each entry can be posted to any address you give it — a row in a spreadsheet, a Slack message, a contact in your mailing list, a deal in your CRM. Set it up under WPStack → App Connect → Integrations: paste the URL your tool generated, pick Forms from the module list, tick the events, and press Send test so your tool can learn the field structure.
Events you can subscribe to
| Event | Sent when |
|---|---|
form.submitted | A visitor submits any form. |
form.entry_deleted | An entry is removed. The full record is included, since it no longer exists afterwards. |
What a delivery contains
Alongside the answers, every delivery carries the source of the lead — page_url, referrer, device and the full UTM set (utm_source, utm_medium, utm_campaign, utm_term, utm_content). That is what lets a CRM attribute where the enquiry actually came from.
The answers arrive twice, in two shapes, because the two are useful in different places:
| Key | Shape | Use it when |
|---|---|---|
fields | A list of { name, label, value, type } | One endpoint receives several forms. The structure is identical for every form, so nothing breaks when a different form comes in. |
values | An object keyed by field name — values.email | One endpoint receives one form. Far easier to map, but the keys are whatever that form defines. |
values follows the form — so if one endpoint receives a contact form and a quote form, map against fields, or add a filter on form_id in your scenario.values is keyed by the field’s name, not its visible label. Renaming “Email” to “Your email address” in the builder will not break a mapping you have already made.X-WPStack-Signature header your receiver can verify.For developers
Both events are also standard WordPress actions, so you can handle them in a plugin or your theme without Connect — they are fired by the Forms module itself. Note the wpsf_ prefix: it is the module’s own, and predates the wpstack_ naming used by Booking and Events.
| Hook | Type | Description |
|---|---|---|
| wpsf_entry_created | action | $entry_id, $form_id, $data — a form was submitted. $data is [ name => [ label, value, type ] ]. |
| wpsf_entry_deleted | action | $entry_id, $entry — fires just before the row is removed, so $entry still holds the record with data and meta decoded. |
add_action( 'wpsf_entry_created', function ( $entry_id, $form_id, $data ) {
$email = $data['email']['value'] ?? '';
if ( ! $email ) {
return;
}
// …add to a mailing list, open a ticket, write to your own table…
}, 10, 3 );add_action() is how many arguments your callback receives. Leave it off and WordPress hands you only the first.FAQ
A simple form is a single flat list of fields. A flow is a branching, multi-step form built on a visual canvas, where each answer leads down its own path. Both render with the same [stack_form] shortcode.
To the Entries inbox — searchable, filterable by form, with CSV export — and to the notify email you set. You can also confirm to the submitter.
A silent honeypot drops bots, and per-IP rate limiting blocks any address that exceeds 15 submissions a minute. Blocked addresses are listed under Blocked IPs, where you can release them.
Yes — every field has conditional-logic rules to show or hide it based on another field, enforced on the front end and re-checked on submit.