Form Builder
Build forms without code — with file uploads, reCAPTCHA and a log of every submission.
Form Builder
Build forms without code — with file uploads, reCAPTCHA and a log of every submission.
Form Builder Plugin
Build forms for your October CMS site without code — with file uploads, reCAPTCHA and a log of every submission.
Demo URL: https://october-demo.renatio.com/backend/backend/auth/signin
Login: formbuilder
Password: formbuilder
Contact forms, quote requests, job applications or surveys: put the form together from ready field types, place it on a page, and every submission lands in your inbox and in the backend.
Features
- Build and manage forms in the October CMS backend, reorder fields with drag and drop
- Live preview in a side panel of the form editor, at desktop or phone width, submittable without sending mail or writing a log
- 28 field types out of the box, including repeater, signature, geolocation and page breaks, each with editable HTML markup, plus custom field types
- Custom form template with the
form_field()helper for any layout - Native AJAX file uploads with attachments in the submission and in the mail
- Google reCAPTCHA v2 and v3, Cloudflare Turnstile and Spam Protection Plugin support
- Reply-to and autoresponder with their own mail templates
- Conditional fields, multi-page forms, live validation and prefill from the query string
- Webhooks posting each submission as signed JSON
- Bootstrap 5 and Tailwind CSS markup presets
- Form submissions log with e-mail preview, filters, CSV/JSON export and automatic pruning
- Import and export of forms and field types
- Granular backend permissions for forms, field types and submissions
- Events to override the form, the fields, the submitted data and the message
- Forms, fields and field types translated per site with the translations built into October CMS
- RainLab Location and RainLab Pages (form as a snippet) support
- Multilingual: English, Polish, German, French, Spanish, Brazilian Portuguese, Italian, Russian, Dutch and Czech translations included — more available on request
Requirements
This plugin requires October CMS 4.4 or newer and PHP 8.2 or newer.
If you are running October CMS 4.0–4.3, use the 5.x version of this plugin, and on October CMS 3.x the 4.x version.
Why is this a paid plugin?
Something that is free has little or no perceived value. Users do not commit to free products and only use them until something else that looks nice and is free comes along. When I invest my time in the development of a new plugin I commit to supporting and maintaining it. I ask my customers to do the same. I do not make money from this plugin by advertisements, upgrades or additional services like hosting or setup.
Did you know that 30% of your purchase or donation goes to help fund the October Project?
My plugins take many hours to develop (40-120+) and even more hours to document and maintain. My paid plugins have to pay for both this time, and the time I am spending on free plugins and less successful paid plugins. This means that it will take even a successful plugin years to become profitable. Please consider buying an extended license if you want me to continue to maintain these plugins for the very small fee I ask in return or hire me for adding functionality that you feel is missing but valuable.
Like this plugin?
If you like this plugin, give this plugin a like or make a donation with PayPal.
My other plugins
Please check my other plugins.
Support
Please use GitHub Issues Page to report any issues with the plugin.
Reviews should not be used for getting support or reporting bugs, if you need support please use the Plugin support link.
Icon made by Darius Dan from www.flaticon.com.
Installation via Command Line
php artisan plugin:install Renatio.FormBuilder
Documentation
Usage
After installation the plugin registers the Form Builder backend menu with four items: Forms, Field types, Form submissions and Settings. Two example forms are installed: a simple contact form and a default form with the basic field types.
Place the renderForm component on a CMS page, inspect it and choose the form.
The form is submitted through the AJAX Framework, so the layout must load it next to the page styles:
<head>
{% styles %}
</head>
<body>
...
{% framework extras %}
{% scripts %}
</body>
Example of placing form component on CMS page
/themes/demo/pages/contact.htm
url = "/contact"
layout = "default"
[renderForm contactForm]
formCode = "contact-form"
==
{% component 'contactForm' %}
Example of placing form component on CMS partial
/themes/demo/pages/contact.htm
url = "/contact"
layout = "default"
[renderForm contactForm]
formCode = "contact-form"
==
{% ajaxPartial "contact" %}
/themes/demo/partials/contact.htm
{% component 'contactForm' %}
Important note: The form handler works only inside
{% ajaxPartial %}, not inside a plain{% partial %}.
Forms
Choose a Mail Template in the Recipients tab to mail each submission; a form with a template needs at least one recipient. Without a template nothing is mailed and every submission is logged. Pick the reply-to and autoresponder fields in the E-mail tab once the form is saved with its fields.
Live preview
Press Preview at the top of a saved form to open it in a side panel over the editor, rendered by the theme in the locale of the site selected in the backend, at desktop or 390 px phone width. It reloads after the form is saved and after a field is added, edited, deleted, reordered or hidden, so only unsaved changes in the main form are missing.
Submitting from the preview runs the validation and shows the success message, but sends no e-mail, calls no webhook, writes no submission log and follows no redirect. The panel needs the Update forms permission.
The theme's default layout is used; when the theme has more layouts, pick another one, or none, in the panel's
toolbar.
The preview is a close approximation, not the live page: it is served from the backend, so the cms.page.* events
run but the frontend route middleware does not. In particular the Spam Protection checks (honeypot, timing, blocked
submissions) are skipped there, so test them on a real page.
Spam Protection
Install the Spam Protection Plugin to protect every Form Builder form with a honeypot, content rules, a single-use form token and a per-visitor rate limit. It works out of the box.
A submission identical to one accepted within the last minute is answered with the success message but is neither logged nor mailed again, so a double click or a page refresh after sending does not produce duplicates.
Custom template
The plugin generates the form template while the Custom Template field is empty. To replace that markup, write your
own template there and render each field with the form_field() function, which takes the field name. The tab appears
once the form is saved.
A visible field the template leaves out is not validated, logged or mailed, and saving the form or a field lists such
fields. A Logged in user field is always saved and a captcha always stays required. A field written as its own
<input name="...">, or a template printing form.fields, keeps every field as before.
Example that will display two fields in one row:
<div class="row">
<div class="col-6">{{ form_field('first_name') }}</div>
<div class="col-6">{{ form_field('last_name') }}</div>
</div>
The names of the form's own fields are listed above the editor; clicking one inserts its form_field() call at the
cursor. The list follows the Fields tab, so a field added, renamed or deleted there shows up at once. In the editor,
type {{ or press Ctrl+Space for the same fields, the form object, Twig filters and tags.
Floating labels
Turn on Floating labels in the form's Options tab to render Bootstrap floating labels. The theme must use Bootstrap 5 and the field types the Bootstrap 5 markup preset; other presets ignore the option.
Prefill from query string
Turn on Prefill from query string in the form's Options tab to fill fields from URL parameters of the same
name, for example a campaign link /contact?subject=Offer&email=jan@example.com. It is off by default.
A parameter that matches no field is ignored, values longer than 255 characters are cut, and checkbox, geolocation, repeater, file upload, signature, captcha, submit, section and page fields are never prefilled. Hidden fields are, so a link can carry UTM or campaign identifiers; treat them as visitor input, like any posted value. The fields set as the autoresponder or reply-to e-mail are never prefilled either, so a crafted link cannot redirect a copy of the submission. The value replaces the field's default value literally (it is not translated), and the markup escapes it like any other default. Country and state selects ignore it, because their markup renders the selected option itself.
Live validation
Turn on Live validation in the form's Options tab to check a field as soon as the visitor leaves it. The check
runs on the server with the same rules and messages as the submission, so a field never passes here and fails there.
Nothing is logged and no email is sent. A field the visitor has not filled in yet is left alone until it has a value or
has already failed once, file, captcha and hidden fields are only checked on submission, and a field its conditions
hide is not checked at all. An error stays until the server clears it, and fixing a field also rechecks the failed
fields whose rules refer to it, such as same:email. The check sends only the form's own fields, so Spam Protection
does not count it as a submission and the form's single-use token stays valid.
Webhooks
Add an address in the form's Webhooks tab to have every submission posted there as JSON, without writing a listener in PHP. The body is:
{
"id": "9d3f6c1e-8b2a-4f57-a1c4-2e6b0d7f5a93",
"form": {"code": "contact-form", "name": "Contact Form"},
"data": {"email": "john@example.com", "email_raw": "john@example.com"},
"submitted_at": "2026-09-13T09:41:02+00:00"
}
data holds the submitted values under the field names, each also as <name>_raw with the value as it was posted.
File upload fields are not included. It is the same data the mail gets, after formBuilder.extendFormData, so a field
a listener removes from the mail is not sent to a webhook either, and a submission formBuilder.beforeSendMessage
cancels is neither mailed, logged nor sent to a webhook. Turn on Send the visitor's IP address to add an ip key;
it is off by default, as the address is personal data.
id is unique to each call and is also sent in the X-Webhook-Id header. A queued call that is retried keeps its
id, so the receiver can drop a delivery it has already processed.
With a Signing secret the body is signed with HMAC-SHA256 and the signature is sent in the X-Signature header,
so the receiver can tell a genuine call from a forged one. The secret is stored encrypted with the application key:
hash_equals(
hash_hmac('sha256', file_get_contents('php://input'), $secret),
$_SERVER['HTTP_X_SIGNATURE'] ?? ''
);
The signature covers the body alone, so a captured call stays valid if it is replayed. Reject a call whose
submitted_at is not recent when that matters to you.
The address must be https and public: private and reserved ranges (IPv4 and IPv6), localhost, *.local,
*.internal, *.home.arpa, single-label names and shorthand IPv4 forms such as 127.1 are refused. The check runs
again right before each call, and the call goes only to the addresses it approved, so a name repointed inside the
network is not followed, and neither is a redirect.
A webhook that fails or does not answer within 5 seconds never changes what the visitor sees; the failure is logged
under Settings → Logs with the scheme and host only, as the path often carries a token. Send through the queue
is on by default and makes up to three attempts, 10 and 60 seconds apart, after a timeout, a lost connection, a 5xx,
408 or 429. Without a queue worker (sync driver) the calls run inline and in parallel, and a slow DNS server holds
the submission, because PHP has no timeout for the lookup.
Return false from formBuilder.beforeSendWebhook to drop a call (see Events).
A form export carries its webhooks without the signing secret. Imported back into the same installation, a webhook keeps its secret; on another installation set it again, as the import report reminds you.
Fields
Custom HTML markup for fields
The default markup of every field type uses Bootstrap 5 form classes. For a Tailwind CSS theme, switch to the Tailwind preset (see below). On a theme with another CSS framework, or none, change the HTML markup of each field type under Form Builder → Field types. The recommended approach is to duplicate the field type and modify the copy.
Markup presets
A preset is a set of field type templates for one CSS framework. The plugin ships Bootstrap 5 (the default) and Tailwind CSS. To switch, open Form Builder → Field types, press Restore system fields and pick the preset. The markup of every system field type is replaced with the preset's; field types you created or duplicated are left alone. The Restore markup to default button of a single system field type offers the same choice.
The presets differ only in CSS classes. Field IDs, data-* attributes and ARIA attributes the plugin's JavaScript
relies on are the same, and the Tailwind preset styles an invalid field through the aria-invalid: variant. Floating
labels are a Bootstrap feature, so the Tailwind preset ignores that form option. The preset files hold markup only: the
reCAPTCHA v3 and Turnstile scripts live in the plugin's form.js and find their fields by the data-recaptcha-sitekey
attribute and the formbuilder-turnstile class, so keep those in markup you write yourself.
The preset of the last restore is remembered: the restore dialog offers it first, and field types added by later plugin updates are created with its markup.
Tailwind CSS generates only the classes it finds in files, and the markup of field types is stored in the database. Point Tailwind (v4) at the preset files in the theme's stylesheet:
@import "tailwindcss"; @source "../../plugins/renatio/formbuilder/presets/tailwind";
The path is relative to the stylesheet, so adjust the number of ../ to where it sits. Classes you add by hand in the
backend — to a field type's markup or to a field's CSS classes and Wrapper CSS classes — are not in those files;
list them with @source inline("...") or in a file under @source, or Tailwind will leave them out.
Field types carry no outer margin, so a new form's CSS classes (Options tab) start with the spacing of the preset
last restored: row g-3 for Bootstrap 5, space-y-4 for Tailwind CSS.
The form's own wrappers still use Bootstrap classes where Bootstrap has them: the seeded demo forms set wrapper classes
such as col-md-6, and the success and error messages of the component are Bootstrap alerts. Change the wrapper
classes of the fields and override the component's message.htm partial in the theme when using Tailwind.
To add a preset of your own, create presets/<name>/ in the plugin with one <field_type_code>.htm file per field
type, for example presets/bulma/text.htm. It appears in the restore dialog without any code change; a field type with
no file in the preset keeps its markup. Files added inside the plugin directory are overwritten by plugin updates, so
keep a copy.
Custom field types
Create a field type under Form Builder → Field types with the New field type button. For example, an Email
field type is the markup of Text with the input type changed to email. Once saved, it can be used in any form.
The markup is Twig with the variables below. They are listed above the editor — click one to insert it — and suggested
as you type {{ or press Ctrl+Space, together with Twig filters and tags.
| Property | Type | Description |
|---|---|---|
| label | String | Label for the field. |
| field_id | String | Unique field ID useful when pairing labels with inputs. |
| required | Bool | Whether the validation rules include required or accepted. |
| label_class | String | Label CSS classes. |
| name | String | HTML name attribute. Also used in mail template. |
| default | String | Default value for the field. |
| comment | String | Help block for the field. |
| class | String | HTML class. |
| wrapper_class | String | HTML wrapper class. |
| placeholder | String | Placeholder for the field. |
| options | Array | Options for dropdown, radio list, checkbox list. |
| custom_attributes | String | Custom HTML attributes. For example id="my-field". |
| field | Array | All attributes of the field record, for example field.id. |
| settings | Array | Public captcha settings, for example settings.site_key. |
| location_plugin_enabled | Bool | Whether RainLab.Location is installed. |
| has_floating_labels | Bool | Whether the form uses floating labels. |
| has_multiple_files | Bool | Whether a file upload field accepts several files. |
| messages | Array | Translated texts of the geolocation, signature, page and repeater fields, for example messages.signature.label. |
| rows | Array | Repeater rows rendered at start, each with index, number, label and html. |
| row_template | Array | Repeater row cloned for each added row, with __index__ and __number__ placeholders. |
| min_items | Int | Minimum rows of a repeater. |
| max_items | Int | Maximum rows of a repeater (50 when empty). |
Conditional fields
A field can show or hide itself depending on what the visitor answered in other fields — the classic case being an Other option in a dropdown that reveals a textarea. Open the field's Conditions tab and choose:
- Action — Show this field when or Hide this field when the conditions are met,
- Match — whether all conditions or any condition has to be met,
- the conditions themselves: another field, an operator (is equal to, is not equal to, contains, is empty, is not empty) and a value. For a dropdown or a list the value is the option key, not its label.
An empty, unchecked or missing field has no value at all, so test it with is empty / is not empty rather than is equal to an empty value. A field hidden by its conditions no longer counts as answered, so the fields that depend on it are evaluated as if it were empty.
Inputs of a hidden field are disabled in the browser, so their values are never submitted. The server evaluates the
same conditions, drops whatever a hidden field still sent (including uploaded files) before validation, and skips its
validation rules — a required rule on a field the visitor cannot see does not block the form, and its value never
reaches the submission log, the e-mails or formBuilder.* listeners. reCAPTCHA and Turnstile fields ignore
conditions and are always validated.
Conditions work with custom field types without editing their markup — the rendered field is wrapped in a
<div data-field-conditions> with display: contents, so it does not affect a grid layout. Renaming a field updates
the conditions that refer to it; a condition may only refer to a field of the same form.
Validation
Every field carries its own rules in the Validation tab, one per row, in the
Laravel syntax —
required, max:255, regex:/^\d+$/. The rule field suggests the rules the installation supports, including those
other plugins register. Leave the message empty to use the built-in wording.
Saving a field is refused when a rule does not exist, misses its parameters, carries a broken regular expression or
points exists/unique at another database connection, so those mistakes never reach the front end. Rules registered
outside the backend request — a Validator::extend() call in CMS page code, for example — are unknown there, and a
field using one cannot be saved.
A fresh install seeds the Contact Form and Default Form with the recommended set (an upgrade only adds the length limits to seeded fields whose rules were never changed):
| Field type | Rules |
|---|---|
| Text, Subject | required, max:255 |
required, email, max:255 |
|
| Phone number | max:30 |
| URL | required, url, max:255 |
| Numeric | required, numeric |
| Date, Datetime | required, date |
| Time | required, date_format:H:i,H:i:s |
| Textarea | required, max:5000 |
A length limit on every text field is what keeps a form from accepting a megabyte of text, so add one even where the value is optional.
Accessibility
The default field types link labels, help text and validation errors to the field, mark fields with a required or
accepted rule as required, and group checkbox and radio lists in a fieldset. Add autocomplete through Custom
attributes on fields that collect personal data, for example autocomplete="email".
Available field types
| Field type | Renders |
|---|---|
| Text | a single-line text input |
| Textarea | a multi-line text box |
| E-mail, Phone number, URL, Numeric | an email, tel, url or number input |
| Date, Time, Datetime | a date, time or datetime-local input |
| Color Picker | a color input |
| Dropdown | a dropdown with the given options |
| Checkbox | a single checkbox |
| Checkbox List | a list of checkboxes |
| Radio List | a list of radio options, where only one can be selected |
| Hidden | a hidden input |
| Logged in user | see below |
| Section | a heading and subheading for grouping fields |
| Page break, Page progress | see below |
| Repeater | see below |
| Submit | the submit button |
| Geolocation, Signature, reCaptcha, Turnstile, File upload, Country select, State select | see below |
Logged in user
The Logged in user field type saves an attribute of the signed-in visitor with the submission — their address, name
or id — without showing an input. Pick the attribute in Logged in user attribute on the field's Attributes tab;
it defaults to email. Only these attributes can be picked: id, email, username, login, first_name,
last_name, full_name, company, phone and created_at (saved as Y-m-d H:i:s). Anything else on the user
model - password, persist and activation codes, IP addresses, notes - is never read. company and phone stay empty
unless a plugin adds those columns to the user.
The value is read from the session when the form is submitted and replaces whatever the request carried under the
field's name, so it cannot be changed by whoever posts the form, and conditions, validation, the log, the mail and
every formBuilder.formSubmitted listener reading post() see the same value. With nobody signed in, or without
RainLab.User installed, it is empty.
Give the field a required validation rule to accept the form only from someone signed in: the rule is checked
against the value the server resolved, so it fails exactly when nobody is. The field renders only the element that
shows this validation message, so set a message that tells the visitor to sign in.
Leave Visible on. An invisible field is dropped from the form altogether and then records no value.
For the same reason the field ignores conditions, cannot be the field another field's conditions test, and is never prefilled from the query string.
Geolocation
Renders a read-only input with a button that asks the browser for the coordinates of the visitor. Nothing is read without the visitor pressing the button and allowing access in the browser prompt.
The submission and the mail carry the coordinates together with a link to the place on OpenStreetMap:
52.2297, 21.0122 (https://www.openstreetmap.org/?mlat=52.2297&mlon=21.0122)
The _raw value is the bare latitude,longitude pair, which is what you want when the mail template builds a link of
its own. Form Builder checks the value on every submission and empties anything that is not a pair of coordinates on
the globe, so the log, the mail, the webhooks and the validation rules all see the same checked value.
- The coordinates are shown in a read-only input next to the button, so the visitor sees what is being submitted.
- The browser is asked for a regular, not a high-accuracy position, and the coordinates are rounded to 4 decimal places, which is about 11 m - close enough for an address without pinpointing the visitor.
- The field is never prefilled, neither from its Default value nor from the query string, so only a location the visitor shared is ever submitted.
- Add
requiredto the validation rules to insist on a location. A visitor who refuses the browser prompt can still submit the form as long as the field is not required. - The button label and the status messages come from the plugin translations, so the markup stays the same in every language.
Note: Browsers only expose the location over HTTPS.
Signature
Renders a canvas the visitor signs with a mouse, a pen or a finger, plus a button clearing it. The drawing is saved as a PNG attached to the submission, exactly like an uploaded file: it shows under Attachments in the form submission and is attached to the mail unless Send uploaded files as mail attachments (Upload Options tab) is unchecked. Deleting the submission deletes the file.
The field carries no value in the mail template — {{ name }} is empty, because the signature is a file rather than
text.
- Add
requiredto the validation rules to insist on a signature. An untouched canvas, and a drawing the plugin refuses, both fail that rule rather than going through as an empty submission. - Drawings over 256 KB and anything that is not a PNG are rejected, so a payload put into the hidden input by hand never reaches the disk.
- The file is stored as a protected attachment, unlike an uploaded file, so it is not served from a public URL.
- The height of the canvas is a
styleattribute in the field type markup; change it there for a taller signature box.
Accessibility: a signature needs a pointer — mouse, pen or finger — so the field cannot be completed with a keyboard alone. Do not make it the only way to finish a form that has to be usable without one; offer a second route (a typed name, a call back) alongside it.
Page break and Page progress
Two fields splitting a long form into pages the visitor moves through without the page reloading. Everything is still submitted in one request at the end, so nothing changes for the mail template or the submission log.
Put a Page break field wherever the form should be cut. It renders the Previous and Next buttons and hides the one that has nowhere to go, so two breaks give three pages. Set the field's Label for the text on the Next button and its Placeholder for Previous; left empty they use the plugin translations.
A Page progress field renders a progress bar with a Step 2 of 3 caption, announced to screen readers on every page change. It stays visible on every page wherever you place it, and it renders nothing at all on a form with a single page.
Next asks the server to validate the fields of the current page and moves on only once they pass, whether or not the form has live validation turned on; Enter in a field does the same. The submission still validates every field, and if one on an earlier page fails, the form jumps back to that page with the error shown.
Put the break where a page really ends: a break placed after the Submit field leaves a last page with no way to send the form, and two breaks in a row make an empty page.
Note: page breaks are found in the rendered form, so in a custom form template every
{{ form_field() }}of a page and the breaks themselves have to sit at the same level. When the breaks do not share one parent element, the form is shown as a single page with the page buttons hidden, and the browser console carries a warning. A component template overridingdefault.htmhas to keep thedata-page-validationattribute of the form, or Next moves on without checking the page.
Repeater
A group of fields the visitor can add several times, such as the attendees of an event or several addresses. Save the repeater field first, then open it again: its Repeater tab lists the fields of each row, added and reordered like the fields of the form. Minimum rows makes the visitor fill in that many rows, Maximum rows caps them at up to 50; the form starts with as many rows as the minimum, so an optional repeater shows only its Add another button. Set the field's Placeholder to change the text of that button.
Every row posts its fields as attendees[0][name], attendees[1][name] and so on, and the validation rules of a row
field apply to each row on its own, with the error shown next to the input of that row. A row whose fields are all
left empty is ignored.
The mail and the submission log list every row. {{ attendees }} holds one line per row,
Name: Ann; E-mail: ann@example.com, and {{ attendees_raw }} the rows themselves, for a custom mail template laying them out its own way:
{% for attendee in attendees_raw %}
{{ loop.index }}. {{ attendee.name }} ({{ attendee.email }})
{% endfor %}
A repeater cannot hold another repeater, nor a field needing a file, a server value or a request of its own: File upload, Signature, Geolocation, Logged in user, reCaptcha, Turnstile, Submit, Page break, Page progress and State select. The fields of a row cannot have conditions, neither they nor the repeater can drive the conditions of other fields, and rows are checked when the form is submitted or a page left, not by live validation.
reCaptcha
Renders Google reCAPTCHA, either v2 (checkbox) or v3 (invisible and score-based, no user interaction).
Create the keys on the reCAPTCHA site — v2 and v3 keys are not interchangeable — and enter them under Settings → Form Builder, tab reCaptcha:
- Version — reCAPTCHA v2 (Checkbox) or reCAPTCHA v3 (Invisible).
- Site Key and Secret Key — must match the selected version.
- Score Threshold (v3 only) — minimum score from 0.0 (likely bot) to 1.0 (likely human) needed to pass. Default is 0.5.
- Language — language of the widget.
- Theme — light or dark v2 checkbox widget.
A fresh install is filled with Google's v2 test keys, which always pass and show a testing notice in the widget. Replace them before going live.
Important note: This field must have g-recaptcha-response as field name, and two rows in its validation section — required and recaptcha — to work properly. One rule per row; a rule written as
required|recaptchais rejected.
Turnstile
Renders a Cloudflare Turnstile widget — a captcha that sets no cookies, needs no Google account and is free at any volume. Use it instead of reCaptcha, not next to it.
Create a widget in the Cloudflare dashboard and enter the keys under Settings → Form Builder, tab Turnstile:
- Site Key and Secret Key — from the widget you created.
- Theme —
autofollows the visitor's colour scheme, or forcelight/dark. - Widget size —
normal,flexible(fills the width of its container) orcompact.
A fresh install is filled with Cloudflare's test keys, which always pass and show a testing notice in the widget. Replace them before going live.
Important note: The field name is up to you, but the field needs two rows in its validation section — required and turnstile. Without
turnstilethe token is never verified, and withoutrequiredan empty token passes.
File upload
Renders a file input.
Filter files selected by a user
To limit the file picker, add an accept custom attribute, for example accept=".pdf,.doc" for PDF and Word files or
accept="image/*" for images.
Validation
Add the rules in the field's validation section:
required— a file must be chosen,max:512— at most 512 KB,mimes:pdf— PDF files only,image— images only.
See the available validation rules for more.
Multiple files
To accept more than one file, check Allow multiple files in the Upload Options tab. Then check Nested array
based form input next to each rule so it applies to every uploaded file, except the required rule.
Send uploaded files as mail attachments
Uploaded files are attached to the mail by default. Uncheck the option to send the mail without them.
Display mode
Tells the backend how to show the uploaded files in a form submission. Choose image when only images are allowed.
Country select
Renders a dropdown with country options.
Important note: You must install Location Plugin to use this field.
State select
Renders a dropdown with state options. This field depends on country select.
Important note: You must install Location Plugin to use this field.
Translations
Forms, fields and field types are translated with the model translations built into October CMS, one language per site, so no extra plugin is needed. Add a site for each language under Settings → Sites.
There are two ways to fill in a translation in the backend:
- switch the site with the site selector in the backend and edit the record as usual — every translated attribute is saved for the language of that site,
- click the globe icon next to a translated field to edit its value for another site in a popup.
Recipients, options and validation messages are repeaters, which the popup cannot edit, so translate them with the site selector. Each site keeps its own copy of the whole list, so after changing an option key or a validation rule on the default site, change it on the translated sites too.
| Record | Translated attributes |
|---|---|
| Form | name, description, from name, from e-mail, recipients including CC and BCC, success and error message, redirect URL |
| Field | label, default value, placeholder, comment, options, validation messages |
| Field type | name, description |
An attribute left empty in a language falls back to the value of the default site, so a form translated only partially never renders blank labels or messages. Duplicating a form copies the translations of the form and of all its fields.
The Translations column of a form's field list shows a flag for each site with its own label; hover it for the text. It is hidden when there is only one site.
Using form data in mail templates
Every submitted field is available in the mail template under its name. For a field named name:
{{ name }}
The value is already processed by Form Builder: dropdowns and radio lists return the label of the selected option,
checkbox lists the selected labels separated by commas, a checkbox Yes or No, and country and state selects the
name. The value exactly as the browser sent it is available with the _raw suffix:
{{ name_raw }}
Form Submissions
Every submission is stored under Form Builder → Form submissions with the submitted values, the uploaded files, the sender IP address and a preview of the sent e-mail. The autoresponder is stored as a separate submission, marked with the Autoresponder column and filter. Turn logging off per form in the Options tab; a form without a mail template always logs, because the submission would otherwise be lost.
Submissions are pruned by a daily scheduled job after Prune period in days from Settings → Form Builder.
It only runs if October's scheduler is running (php artisan schedule:run every minute). Leave the period empty to
keep submissions forever.
The list can be filtered by form, autoresponder, send date and IP address.
Submissions can be exported to CSV or JSON from the toolbar. The export follows the filter panel, so filter first to export a subset. The search term and the row checkboxes are not applied to it.
Settings
Plugin settings are available at Settings → Form Builder.
- reCAPTCHA version, Site key, Secret key, Score threshold, Language, Theme — see the reCaptcha field type above. The pre-filled demo keys work with v2 only.
- Turnstile Site key, Secret key, Theme, Widget size — see the Turnstile field type above.
- Prune period in days — how long submissions are kept. Default:
30.
Permissions
| Permission | Grants |
|---|---|
| Manage Forms | the Forms list; create, update, delete and import/export have their own permission each |
| Manage field types | the Field types list; create, update, delete and import/export have their own permission each. Update also covers restoring the default markup |
| Manage form submissions | the Form submissions list; preview, delete, truncate and export have their own permission each |
| Manage Settings | the plugin settings page |
Every backend action checks its permission on the server, so a user without it gets a 403 even when the button is reached by hand.
Events
| Event | Fired when | Payload |
|---|---|---|
formBuilder.overrideForm |
before the form markup is rendered | &$form — replace or change the model |
formBuilder.overrideField |
before each field is rendered | &$field, $form |
formBuilder.formSubmitted |
the submission passed validation | &$form |
formBuilder.extendFormData |
before the mail and webhook data is built; return the array to replace it | $data |
formBuilder.beforeSendMessage |
before the mail is sent; return false to skip the mail, the autoresponder, the submission log and the webhooks |
$form, $data |
formBuilder.beforeSendWebhook |
before each webhook is called; return false to cancel it |
$form, $webhook, $payload |
Listen in your plugin's boot() method:
Event::listen('formBuilder.overrideForm', function ($form) {
$form->css_class = 'form-horizontal';
});
Event::listen('formBuilder.overrideField', function ($field, $form) {
if ($field->name === 'currency') {
$field->default = 'USD';
}
});
Event::listen('formBuilder.formSubmitted', function ($form) {
Log::info("Form {$form->code} submitted", $form->getDataArray());
});
Event::listen('formBuilder.extendFormData', function ($data) {
$data['foo'] = 'bar';
return $data;
});
Event::listen('formBuilder.beforeSendMessage', function ($form, $data) {
$form->from_email = 'john.doe@example.com';
$form->from_name = 'John Doe';
});
Event::listen('formBuilder.beforeSendWebhook', function ($form, $webhook, $payload) {
return $payload['data']['email'] !== 'spam@example.com';
});
-
Petr Široký
great plugin and support. recommend
-
Renatio author
Thank you, Petr, for the kind words and the recommendation!
-
William Thomas
I tested the contact form and clicked submit, I can see the form submitted in Form Logs with all fields filled but unable to receive the contact form via email. Is there a guide for newbie like me to properly setup the contact form configuration?
-
Renatio author
Hi William, thanks for the review, and sorry for the very late reply. I'm answering here mostly for anyone who runs into the same problem.
If a submission appears in the log but no e-mail arrives, the form works and the problem is e-mail delivery:
- In the form's Recipients tab, replace the demo address
admin@domain.tldwith your own. - On the Details tab, set Sender email to an address on your domain, or leave it empty to use the mail settings default.
- Configure Settings → Mail Configuration and send a test from Settings → Mail Templates. Errors are listed in Settings → Event Log.
If it still doesn't work, please open an issue at GitHub.
- In the form's Recipients tab, replace the demo address
-
Jess Murphy
Hi, How can override Raw markup Code From latest plugin. In plugin updates said,
You can override the partial by creating a file in our theme called partials/renderform/fields.htm. and pasting below markup.
How can update for each form contact-form, subscribe-form, like that
-
Renatio author
Hi Jess, thanks for the review, and sorry for the very late reply. I'm answering mostly for anyone with the same question.
The
partials/renderform/fields.htmoverride is gone in current versions. Each form now has its own Custom Template tab. Leave it empty to use the generated markup, or write your own layout and render each field by its name:<div class="row"> <div class="col-6">{{ form_field('first_name') }}</div> <div class="col-6">{{ form_field('last_name') }}</div> </div>So
contact-formandsubscribe-formcan each have a different layout. To change the HTML of a field type for every form, edit it under Form Builder → Field types. It's best to duplicate a type first and edit the copy.If you need more help, please open an issue at GitHub.
-
Martijn de Vries
Thanks for the update to support OctoberCMS V2! I have one more problem with the error below. Can you help with this?
Uncaught ReferenceError: resetForm is not defined
-
Renatio author
Hi Martijn, thanks for the review!
resetFormlives in the plugin'sform.js, which the component adds to the page through{% scripts %}. This error means the layout doesn't output it. Make sure the layout contains:{% framework extras %} {% scripts %}More details in this issue.
-
Danny Baharuddin
So far had no problem.
-
Renatio author
Thank you, Danny, glad to hear it works well for you!
-
Julian Parge
Support for this plugin is non-existent. They never reply to the forum - I've had simple, open tickets for months. Don't waste your money. For the "#1" paid plugin of all time, this is a complete joke.
-
Renatio author
Hi Julian, you're right, and I'm sorry. Support back then was far too slow.
This has changed since. Every report now goes through GitHub Issues, where I answer and track it. The plugin is actively maintained for October CMS 4. The latest release, 5.2.0, adds security fixes, new languages and reworked documentation.
If you ever give it another try, I'd be glad to help.
-
Remko Posthuma
Just starting my first project with this plugin but I like it so far
-
Renatio author
Thank you, Remko! Hope the project went well. If anything comes up, you'll find help on GitHub Issues.
-
PLACE IT Jacek Bartoszek
Great plugin! Thank you for your help. Is any chance to add option for duplicate created already form??
Best
-
Renatio author
Thank you, Jacek! Duplicating a form is available: use the copy button in the Actions column of the forms list. Since version 5.2.0 the copy also keeps the RainLab Translate translations.
-
Morten Saanum Bessesen
There is an error when installing.
-
Renatio author
Hi Morten, sorry for the trouble. The installation error was caused by a change in the October version released at that time and was fixed in version 1.5.0. Current versions install cleanly on October CMS 4.
If you run into any problem, please report it on GitHub Issues and I'll help you there.
-
Auris
Absolutely not Working, the Error while installing can only be fixed with a plugin:refresh. This Might work for out development environnement, but how would you ever get this to work in Production? Absolutely ridiculous.
-
Renatio author
Hi Auris, you're right,
plugin:refreshis no fix for a production site, and I'm sorry for the trouble. The installation error was caused by a change in the October version released at that time and was fixed in version 1.5.0, so no refresh is needed. Current versions install and update cleanly on October CMS 4 withphp artisan october:migrate.If you run into any problem, please report it on GitHub Issues and I'll help you there.
-
Igor Yaroslavtsev
No updates for 2 years? Why? We need to add 3 and more recipients in forms. Maybe you can add repeater field in recipients?
-
Renatio author
Hi Igor, thanks for the suggestion! It's done: the Recipients tab now has repeaters for To, CC and BCC with no limit on the number of addresses, and since version 5.2.0 the submission log stores recipient lists of any length. The plugin is actively maintained again, now for October CMS 4.
-
Glide Agency
Custom support is non-existent, very disappointed.
-
Renatio author
Sorry for the disappointing experience back then. Support has changed since: every report now goes through GitHub Issues, where I answer and track it, and the plugin is actively maintained for October CMS 4. If you ever give it another try, I'd be glad to help.
-
Shohabbos
За 5 баксов плагин норм
-
Renatio author
Спасибо за отзыв! Кстати, начиная с версии 5.2.0 плагин полностью переведён на русский язык.
-
Ronny Skog
Great plugin and easy to use. I'm missing a simple way to store form data in a database though. It can be done width events but requires coding.
-
Renatio author
Thank you, Ronny! This is built in now: every submission is stored in the database under Form Builder → Form submissions, with the submitted values, uploaded files, sender IP and a preview of the sent e-mail. Submissions can be filtered and exported to CSV or JSON without any coding.
-
luis mezarine
This pluging resets the page every time the persons hits SUBMIT. I do not recommend it
-
Renatio author
Hi Luis, sorry for the trouble. The form is submitted with AJAX, so the page is not reloaded: the success message appears in place of the form, and a redirect happens only when you set one in the form options. If the page does reload, the layout is missing the AJAX framework. Make sure it contains:
{% framework extras %} {% scripts %}If you need help, please open an issue on GitHub Issues.
-
Allan Neuendorf
Brilliant and impressive plugin!
Intuitive to setup and easy to customise (once you discover the html code in Field Types).
One question - would it be possible to make calculating fields as a field type?
-
Renatio author
Thank you, Allan! Calculating fields aren't built in yet. For now you can create a custom field type under Form Builder → Field types with a small script in its markup that computes the value from other inputs, for example into a read-only or hidden field, which then gets stored with the submission. If you'd like it as a built-in field type, please add it as a feature request on GitHub Issues.
-
Lutte Patrick
after installation I have this error
No hint path defined for [martin.forms]. C:\laragon\www\btp\vendor\laravel\framework\src\Illuminate\View\FileViewFinder.php line 112
What is the problem ?
-
Renatio author
Hi Patrick, sorry for the short reply back then. The error doesn't come from Form Builder:
martin.formsis the namespace of another plugin, Magic Forms. It usually means a page, partial or mail template still references that plugin after it was removed or disabled. Remove the reference and clear the cache withphp artisan cache:clear.If Form Builder gives you any trouble, please report it on GitHub Issues.
-
Richard Clark
Great work question? can you do model binding to a form
-
Renatio author
Thank you, Richard! There's no built-in model binding, but events cover both directions. Fill fields from any model before rendering, and save the submission to your own model after validation:
Event::listen('formBuilder.overrideField', function ($field, $form) { if ($field->name === 'email' && $user = Auth::getUser()) { $field->default = $user->email; } }); Event::listen('formBuilder.formSubmitted', function ($form) { Lead::create(post()); });See the Events section of the documentation for details.
-
Ran Michael
This is a great plug-in, works out of the box. I had some issues with bilingual forms (which originated from the Translate plug-in), which were fixed. Come to think of it, Renatio added a fix although the issue wasn't on this plug-in !
Another great surprise was a snippet which enables you (your clients) to insert any form created with this plug in into a Static Page with ease.
- Lacking feature: Duplicate form.
All in all - great work ! Well worth it ! Thanks a lot Renatio !
-
Renatio author
Thank you, Ran, for the kind words! Duplicating a form is available now: use the copy button in the Actions column of the forms list. Since version 5.2.0 the copy also keeps the RainLab Translate translations.
-
Madars Pujats
Can i add flags to country select?
-
Renatio author
Hi Madars, thanks for the question! Not out of the box: the Country select field uses RainLab Location's
form_select_country(), which renders a native<select>, and native selects can't show images. You can create a custom field type under Form Builder → Field types that wraps the select with a JavaScript select library supporting option templates (for example Tom Select) and adds the flags there. If you'd like it built in, please add a feature request on GitHub Issues. -
Dinesh
Everything is fine but you can not add country and state. If you could provide any documentation for the same will be best.
-
Renatio author
Hi Dinesh, thanks for the review! Both are available as field types:
- Install the RainLab Location plugin.
- Add a Country select field and a State select field to your form.
The state list refreshes automatically when a country is chosen, and the mail and the submission log show the country and state names. Both field types are described in the plugin documentation.
-
Web Master
please, update formbuilder it's have some problem
-
Renatio author
Sorry for the unhelpful reply back then. The plugin has been updated many times since and is actively maintained for October CMS 4. If you still run into a problem, please describe it on GitHub Issues and I'll help you there.
-
Paddy Sherry
I lost a full day trying to build a form with the Ajax framework that validates and accepts file uploads.
Then I found this plugin, copied the default form and the task was complete in 15 minutes.
Excellent extension!
-
Renatio author
Thank you, Paddy! Glad it saved you the day. That's exactly what the plugin is for.
-
Kai
Dearest Author of the plugin
thank you for your work for all of us. Im searching a not to difficult possibility (Im on a low programmer level) to create a form that saves data into a corresponfing table, were row can be edited. 0) Where is the support area to ask you in the correct way? 1) Is that possible? 2) Would you create a plugin with the form builder and then connect the form with the table somehow? But how? I do not see a field for the action of the form itself.
Thanx a lot
Kai
-
Renatio author
Hi Kai, thank you, and sorry for the very late reply.
- Please ask on GitHub Issues.
- Yes. Every submission is already stored in the database under Form Builder → Form submissions, where you can view, filter and export it, but not edit it.
- For editable rows, create a Tailor blueprint (October CMS 3 and 4) for your table. You get the backend list and edit form without writing a plugin. Then copy each submission into it with one event listener:
Event::listen('formBuilder.formSubmitted', function ($form) { if ($form->code === 'my-form') { $entry = \Tailor\Models\EntryRecord::inSection('Leads'); $entry->fill(post()); $entry->save(); } });The form has no action field because it's submitted with AJAX to the component. Events are the way to hook into it.
-
Sally Lin
Useful plugin but I have some issues:
- Plugin needs css bootstrap to display "actions" but doesn't mention this in doc's.
- Captcha does not display label so I had to inject a ::before css
- Need more info in the doc's about mail templates and mail services etc?! Would be nice if there was a video demo of the plugin.
Useful plugin will buy again, but please update your doc's info a bit more...
-
Renatio author
Hi Sally, thank you for the detailed feedback, and sorry for the very late reply. Most of it is addressed now:
- The reCAPTCHA field renders its label.
- The documentation covers using form data in mail templates, and the mail itself is sent through October's Settings → Mail Configuration.
- Instead of a video, there's a live demo; the login details are in the plugin description.
The default field markup uses Bootstrap 5 classes. With another CSS framework, edit the markup under Form Builder → Field types. Thanks for pointing it out, I'm adding it to the documentation.
-
UpTop
For basic use, FormBuilder works great. It's a very powerful plugin, but it lacks in overall stability. Too frequently it throws errors if you have Rainlab.Translate installed which is were this plugin should excel.
We'd give it 3/5 but still a not useful as we are disappointed every time we try to use it in combination with Translate.
-
Renatio author
Hi, thanks for the honest review, and sorry for the trouble back then. The errors came from RainLab Translate itself and were worked around in 1.2.9. Today Form Builder works with RainLab Translate and October's multisite: form names, labels, options, messages and validation messages are translatable, and since 5.2.0 duplicating a form keeps its translations. Support for October's native translations is on the roadmap.
If anything still breaks, please report it on GitHub Issues.
-
Gerald Baumeister
Great Plugin and great support! Thank you!
-
Renatio author
Thank you, Gerald!
-
Gerald Schandl
Great Plugin and really easy to use!!! Thanks to the developer, this plugin makes Forms much easier!
-
Renatio author
Thank you, Gerald, for the kind words! By the way, the plugin is fully translated into German.
-
Mercer Digital
Very good product. Great features.
-
Renatio author
Thank you, glad you like it!
-
Vijay Patel
Perfect Plugin to handle most complex forms. It covers almost every aspect which is required to build a complex forms. Great work Renato.
-
Renatio author
Thank you, Vijay, for the kind words!
-
Metro Ren
Very nice plugin!
-
Renatio author
Thank you!
-
Tyson Rude
Great plugin with a lot of flexibility for custom projects. Also, the support is timely and very helpful. I definitely recommend this plugin for OctoberCMS forms.
-
Renatio author
Thank you, Tyson, for the kind words and the recommendation!
-
Nick
Great plugin! Works as expected. Would recommend allowing users to style labels directly though!
-
Renatio author
Thank you, Nick! Labels can be styled per field now: set Label CSS classes in the field's HTML & CSS tab. For full control, the label markup of each field type is editable under Form Builder → Field types.
-
Elian
Awesome plugin! Very well made. Simple to use and highly costumizable.
Would recommend it to anyone. Well worth the money!
-
Renatio author
Thank you, Elian, for the kind words and the recommendation!
-
Juan Timana
This is an incredibly useful and very well done plugin. I recommend it to everyone that need to build forms that are easy to build and easy to maintain.
-
Renatio author
Thank you, Juan, for the kind words and the recommendation!
-
MyeongCheol Kwon
Very good plugin! Thanks.
-
Renatio author
Thank you, MyeongCheol!
-
Servers
Great plugin, very easy to use and integrate :)
-
Renatio author
Thank you, glad to hear it!
-
Marina Sokolova
There is awesome plugin and the best support I've ever seen. Thank you very much for your job.
-
Renatio author
Thank you, Marina, that means a lot! By the way, since version 5.2.0 the plugin is fully translated into Russian.
-
inIT
Very good plugin. Powerful and easy to use.
-
Renatio author
Thank you for the kind words!
-
Andy Barker
This is a professionally written plugin that is really useful if you need lots of forms.
-
Renatio author
Thank you, Andy, glad it serves you well!
-
Potting Shed
Excellent plugin, and excellent support from Renatio. I would ALL of Renatio's plugins are a must for any serious OctoberCMS developer.
-
Renatio author
Thank you so much for the kind words and for recommending my plugins!
-
Gavin Foster
Simply a SUPERB plugin! The ability to customise each form, right down to the styles, layouts, and classes is just fantastic. The one support question I had was answered remarkably quickly. I've got multiple contact forms assigned to individual partials that the client is able to drop into their pages using the "Snippets" section of the Rain.Lab Pages plugin. Developer and client very happy. Highly recommended!
-
Renatio author
Thank you, Gavin, for the kind words! A small tip: the form component is now registered as a RainLab Pages snippet itself, so clients can drop any form into a page and choose it there, without a separate partial for each form.
-
Daniel ody
lake of stuff like date, time...input and setting the column..make wizard form!
-
Renatio author
Hi Daniel, sorry for the reply back then. All three are covered now:
- Date, Time and Datetime are built-in field types, together with E-mail, Phone, URL, Numeric and Color Picker.
- Columns: give each field a wrapper class such as
col-md-6, or lay the form out freely in the form's Custom Template tab. - Wizard (multi-page) forms are on the roadmap.
If you need help, please ask on GitHub Issues.
-
| 6.0.1 |
Fix links with several query parameters in e-mails, keep the rules and option keys of the default site on translated sites, export webhooks without their secret. Nov 01, 2026 |
|---|---|
| 6.0.0 |
Translate forms, fields and field types with the translations built into October 4.4 instead of RainLab.Translate. Nov 01, 2026 |
| 5.3.0 |
Improve form accessibility with linked error messages, marked required fields and fieldset groups. Nov 01, 2026 |
| 5.2.0 |
Security release. Escape submitted values in the submission preview, sandbox the e-mail preview and check the create, update, delete and truncate permissions in every AJAX handler. Sep 11, 2026 |
| 5.1.6 |
Rename the FormLogs e-mail preview action to preview_email. Sep 09, 2026 |
| 5.1.5 |
Add reCAPTCHA v3 support with score-based verification, expose only site_key, version, theme and lang to field markup, fix the 404 on the FormLogs e-mail preview under October 4.3.5 and later, stop the ajax:promise listener throwing on element-less requests, save the autoresponder in its own form log with a list filter. Sep 09, 2026 |
| 5.1.4 |
Add type hints, refactor code, expand test coverage, replace bkwld/cloner with native duplicate() methods. Sep 09, 2026 |
| 5.1.3 |
Fix validation and add tests. Dec 29, 2025 |
| 5.1.2 |
Fix field type validation. Dec 01, 2025 |
| 5.1.1 |
Fix passing form model to mail template. Dec 01, 2025 |
| 5.1.0 |
Add raw field values (fieldname_raw) support. Dec 01, 2025 |
| 5.0.5 |
Refactor to use pluck() function. Oct 07, 2025 |
| 5.0.4 |
Parse form markup with Twig. Thanks @apinard Aug 29, 2025 |
| 5.0.3 |
Update dependencies. Jul 12, 2025 |
| 5.0.2 |
Add compatibility. Jul 07, 2025 |
| 5.0.1 |
Require October 4. Jun 30, 2025 |
| 4.0.8 |
Fix minor issues with form.js. Fix using external property values for formCode property. May 02, 2025 |
| 4.0.7 |
Fix removing form log when using attachOne relation file upload field. Oct 01, 2024 |
| 4.0.6 |
Allow to completely override form in plugin events. Thanks @m49n May 11, 2024 |
| 4.0.5 |
Add hidden field type. Add events to override form and fields before rendering form markup. Mar 05, 2024 |
| 4.0.4 |
Allow to select forms and field types for export. Feb 22, 2024 |
| 4.0.3 |
Fix scroll after form submission. Nov 11, 2023 |
| 4.0.2 |
Add setting to turn off sending uploaded files as mail attachment. Oct 08, 2023 |
| 4.0.1 |
Minor fix. Sep 21, 2023 |
| 4.0.0 |
Remove responsiv/uploader-plugin support with native October ajax file upload. Sep 21, 2023 |
| 3.1.3 |
Add support for October snippets. Sep 07, 2023 |
| 3.1.2 |
Allow to disable form logs. Jun 01, 2023 |
| 3.1.1 |
Fix permissions. Nov 23, 2022 |
| 3.1.0 |
Major rework of the plugin. See upgrade guide for list of changes. Nov 23, 2022 |
| 3.0.0 |
Require October CMS 3.0. Nov 23, 2022 |
| 2.2.0 |
Rewrite querying mail templates. May 17, 2022 |
| 2.1.7 |
Fix for October 3.x. Apr 24, 2022 |
| 2.1.6 |
Fix raw fields markup for PHP < 7.4. Dec 02, 2021 |
| 2.1.5 |
Minor fix. Nov 28, 2021 |
| 2.1.4 |
Minor fix. Nov 28, 2021 |
| 2.1.3 |
Raw fields markup. Nov 27, 2021 |
| 2.1.2 |
Improve reset field type to default. Nov 25, 2021 |
| 2.1.1 |
Minor fixes. Nov 25, 2021 |
| 2.1.0 |
Add patch 2.0 console command for easy upgrade process. Nov 20, 2021 |
| 2.0.1 |
Add support for October v2.0. Drop support for October v1.0. Nov 20, 2021 |
| 1.5.0 |
Elevate plugin permissions. Sep 16, 2020 |
| 1.4.9 |
Fix issue with field options. Jul 23, 2018 |
| 1.4.8 |
Fix issue with ReCaptchaServiceProvider class. Jul 21, 2018 |
| 1.4.7 |
Fix multilingual fields. Jul 18, 2018 |
| 1.4.6 |
Generate form code automatically. Jul 18, 2018 |
| 1.4.5 |
Use October Default Mail Layout for example Templates. Jul 18, 2018 |
| 1.4.4 |
Improve RainLab.Location plugin integration. Jul 18, 2018 |
| 1.4.3 |
Dynamic form reply to fields. Jul 13, 2018 |
| 1.4.2 |
Fix fields and sections translation. Jan 31, 2018 |
| 1.4.1 |
Set default reCaptcha keys for testing. Jan 31, 2018 |
| 1.4.0 |
!!! Nicer form field validation. Oct 18, 2017 |
| 1.3.1 |
Fix example forms seeding. Apr 22, 2017 |
| 1.3.0 |
Allow to use CMS filters and functions in field templates. Apr 22, 2017 |
| 1.2.9 |
Fix RainLab.Translate compatibility issues. Mar 19, 2017 |
| 1.2.8 |
Fix sending email with file attachment for October build 401+ Mar 12, 2017 |
| 1.2.7 |
Improve seeding mail templates. Add Contact Form and Default Form. Update Mail Layout. Mar 12, 2017 |
| 1.2.6 |
Export form logs to CSV file. Feb 08, 2017 |
| 1.2.5 |
Allow to duplicate a form. Sep 19, 2016 |
| 1.2.4 |
Minor changes. May 14, 2016 |
| 1.2.3 |
German translation. Feb 10, 2016 |
| 1.2.2 |
Allow to manually specify url for redirect. Feb 03, 2016 |
| 1.2.1 |
Allow for custom validation messages. Feb 01, 2016 |
| 1.2.0 |
Dutch translation. Jan 29, 2016 |
| 1.1.9 |
Add comment to fields. Jan 22, 2016 |
| 1.1.8 |
Add HTML preview in logs. Jan 08, 2016 |
| 1.1.7 |
Add sections feature. Jan 08, 2016 |
| 1.1.6 |
Add reply to and autoresponse functionality. Dec 08, 2015 |
| 1.1.5 |
Add Event to extend default functionality. Nov 09, 2015 |
| 1.1.4 |
RainLab Location Plugin support. Nov 09, 2015 |
| 1.1.3 |
Minor changes. Oct 19, 2015 |
| 1.1.2 |
Allow for multiple forms on the same cms page. Fix required validation rule for fileuploader field type. Oct 19, 2015 |
| 1.1.1 |
Use Twig::parse() facade. Only update for October build 300 and above. Oct 05, 2015 |
| 1.1.0 |
!!! Important update Oct 05, 2015 |
| 1.0.4 |
Add simple logs. Sep 14, 2015 |
| 1.0.3 |
Add file attachment field type. Sep 14, 2015 |
| 1.0.2 |
Reference __SELF__ in component partial. Sep 06, 2015 |
| 1.0.1 |
First version of Form Builder plugin. Aug 24, 2015 |
Upgrade guide
Versions not listed here need no action. Back up the database before upgrading.
Upgrading To 2.0.1
Requires October CMS 2.x and PHP 7.3. Upgrading from 1.5.0 needs a reinstall or php artisan formbuilder:patch 2.0.
Upgrading To 3.0.0
Requires October CMS 3.0 and PHP 8.0.
Upgrading To 3.1.0
- Field types are rewritten for Bootstrap 5; forms rendered with an older framework need their markup adjusted.
- Permissions are now granular, so review the roles after the upgrade.
- Validation uses the AJAX Framework extras (
{% framework extras %}in the layout).
Upgrading To 4.0.0
Upgrade to 3.1.3 first and back up the database.
- The
responsiv/uploader-pluginintegration is replaced by native AJAX file uploads: the migration adds the new upload field type and moves the old upload fields to it. Check the forms with uploads afterwards.
Upgrading To 5.0.1
Requires October CMS 4.x.
Upgrading To 5.1.0
Field IDs are now unique per form. Restore the field types to the default markup to pick this up; customised field
types need the field_id variable added by hand.
Upgrading To 5.1.4
Forms and field types are duplicated with native duplicate() methods instead of bkwld/cloner, so the cloner::cloning and cloner::cloned events are no longer fired.
Upgrading To 5.1.5
Run php artisan october:migrate.
- Field type markup receives only
settings.site_key,settings.version,settings.themeandsettings.lang; customised reCAPTCHA markup must be restored to default or updated by hand to support v3. - The autoresponder is saved as its own form submission, so a form with both switches on produces two entries per submission.
Upgrading To 5.2.0
Security release. Upgrade every installation running 5.1.x. Requires PHP 8.2. Run php artisan october:migrate.
- Submitted values are now escaped in the submission preview, and every backend AJAX handler checks its permission on the server.
- Users who duplicate forms or field types, toggle field visibility or restore the default markup now need the matching Create or Update permission; Clear form submissions needs Truncate form submissions. Review the roles under Settings → Administrators → Roles.
- Field names must be unique within the form and use only letters, digits, dashes and underscores; rename an older field that breaks this rule (and its variable in the mail template) when saving it fails.
- Field HTML is inserted after the form template is parsed, so Twig syntax typed into a label or a default value is rendered literally.
- Merge the changes into
form.jsif you ship a customised copy: validation errors now clear as the visitor corrects the field, and a second submit is blocked while the first is pending.
Upgrading To 5.3.0
Run php artisan october:migrate.
- Field types still on the default markup are refreshed automatically; restore customised ones under
Form Builder → Field types or add the error and help ids,
aria-*attributes and the newrequiredvariable by hand. - Required fields now show an asterisk, checkbox and radio lists render as a
fieldsetwith alegendand option ids{field_id}-option-{key}, and the Section heading is anh2styled ash4, so check theme CSS and JS that target these elements. - Merge the
form.jschanges if you ship a customised copy.
Upgrading To 6.0.0
Requires October CMS 4.4. Run php artisan october:migrate.
- The migration installs the new field types and adds length limits to unchanged fields of the seeded forms.
- It also copies the RainLab.Translate translations of forms, fields and field types into October's built-in
translations, leaving the old rows untouched. Do not run
php artisan translate:import-attributeswithout--modelafterwards, as it overwrites those translations. - Merge the
form.jschanges if you ship a customised copy. - A customised default mail template prints a repeater as one line per row.
- A geolocation value reaches mail templates and
formBuilder.*listeners as aTwig\Markupobject; cast it with(string)before comparing.
Upgrading To 6.0.1
Validation rules and option keys of a field are shared by all sites; a translated site translates only the validation messages and option labels. A field that had different rules on a translated site now uses the rules of the default site.