diff --git a/content/collections/fieldtypes/form.md b/content/collections/fieldtypes/form.md index 741e08936..6f486ab95 100644 --- a/content/collections/fieldtypes/form.md +++ b/content/collections/fieldtypes/form.md @@ -22,7 +22,7 @@ options: name: query_scopes type: string description: > - Allows you to specify a [query scope](/extending/query-scopes-and-filters#scopes) which should be applied when retrieving selectable assets. You should specify the query scope's handle, which is usually the name of the class in snake case. For example: `MyAwesomeScope` would be `my_awesome_scope`. + Allows you to specify a [query scope](/extending/query-scopes-and-filters#scopes) which should be applied when retrieving selectable forms. You should specify the query scope's handle, which is usually the name of the class in snake case. For example: `MyAwesomeScope` would be `my_awesome_scope`. related_entries: - fdb45b84-3568-437d-84f7-e3c93b6da3e6 - aa96fcf1-510c-404b-9b63-cea8942e1bf8 @@ -31,10 +31,14 @@ related_entries: The Form fieldtype is gives your users a way to pick a form to include along with the current entry. How that form is implemented or shows up on the page is up to you. +Not to be confused with [form fieldtypes](/forms#form-fieldtypes) — the fields you add _inside_ a form when building it. This fieldtype is for selecting an entire form from elsewhere, like an entry. + ## Data Storage The Form fieldtype stores the `handle` of a single form as a string, or an array of handles if `max_items` is greater than 1. +When an entry overrides a [unique instances](/frontend/forms-pro#unique-instances) form's settings, the value is stored as an array with `form` and `config` keys instead. + ## Templating The Form fieldtype provides a few useful variables: @@ -45,4 +49,27 @@ The Form fieldtype provides a few useful variables: * `api_url` * `honeypot` -You can use the [`form:create`](/tags/form-create) tag to render a `
` on your page. +You can pass the `handle` to the [`{{ form:create }}`](/tags/form-create) tag to render a `` on your page: + +::tabs + +::tab antlers +```antlers +{{ form:create :in="form_fieldtype:handle" }} + ... +{{ /form:create }} +``` +::tab blade +```blade + + ... + +``` +:: + +## Unique Instances + +When the selected form has [Unique Instances](/frontend/forms-pro#unique-instances) enabled (a [Forms Pro](/frontend/forms-pro) feature), the fieldtype does a little more on the entry's publish form: + +- A **Configure** option lets you override the form's Access settings — close date, submission limit, closed message, and require login — and its [connections](/forms#connections), for that entry. Anything you leave blank, or any connection you don't touch, falls back to the form's setting. +- A **View Submissions** button opens the entry's submissions in a stack. diff --git a/content/collections/pages/build-a-form-fieldtype.md b/content/collections/pages/build-a-form-fieldtype.md new file mode 100644 index 000000000..7e3d451ce --- /dev/null +++ b/content/collections/pages/build-a-form-fieldtype.md @@ -0,0 +1,83 @@ +--- +id: afd9fcd1-e9b3-41f4-b4a9-1bec95cd5f2e +blueprint: page +title: 'Build a Form Fieldtype' +template: page +intro: "Form fieldtypes adapt Statamic's fieldtypes for collecting input from visitors. When the built-in options don't quite fit, build your own and make it feel right at home in the Form Builder." +related_entries: + - 83786f60-def6-11e9-aaef-0800200c9a66 + - fdb45b84-3568-437d-84f7-e3c93b6da3e6 + - ecf1c18e-cdc6-4120-b19a-af1c3851ea53 +--- + +Each form fieldtype wraps a regular [fieldtype](/fieldtypes/build-a-fieldtype) and tailors it for use in forms. + +You can build your own by creating a class in the `app/FormFieldtypes` directory that extends `Statamic\Forms\Fields\FormFieldtype`. Statamic will discover it automatically. + +```php + ['display' => 'Minimum', 'type' => 'integer'], + 'max' => ['display' => 'Maximum', 'type' => 'integer'], + ]; + } + + public function toFieldArray(): array + { + return [ + 'type' => 'range', + 'min' => $this->config('min'), + 'max' => $this->config('max'), + ]; + } + + public function example(): ?array + { + return [ + 'config' => [ + 'display' => 'How confident are you about your answer?', + 'min' => 1, + 'max' => 5, + ], + 'value' => 3, + ]; + } +} +``` + +## Properties + +| Property | Description | +| --- | --- | +| `$fieldtype` | The handle of the regular fieldtype this form fieldtype wraps. | +| `$description` | A short description shown in the Form Builder. | +| `$categories` | The categories the fieldtype is grouped under in the Form Builder. Should be an array. | +| `$icon` | The icon shown in the Form Builder. | +| `$order` | Controls the fieldtype's position within its category. | + +## Methods + +| Method | Description | +| --- | --- | +| `configFieldItems()` | The configuration fields shown when editing the field in the Form Builder. | +| `toFieldArray()` | Translates the form fieldtype's config into a regular field definition. | +| `example()` | An example configuration used to preview the field in the Form Builder. Optional. | +| `view()` | The front-end view used to render the field. Optional. | + +:::tip +When [Forms Pro](/frontend/forms-pro) is installed, form fieldtypes can also opt into [form summaries](/frontend/forms-pro#charting-your-own-fieldtypes) with a default chart, chart options, and insights. +::: diff --git a/content/collections/pages/conditional-fields.md b/content/collections/pages/conditional-fields.md index 18f0bc369..99a374af1 100644 --- a/content/collections/pages/conditional-fields.md +++ b/content/collections/pages/conditional-fields.md @@ -391,4 +391,4 @@ For more advanced conditional validation, take a look at Laravel's `required_if` ## Templating -You can take advantage of Conditional Fields on your front-end Forms to automatically generate dynamic forms and logic. [Learn more about it](/tags/form-create#conditional-fields). +You can take advantage of Conditional Fields on your front-end Forms to automatically generate dynamic forms and logic. [Learn more about it](/tags/form-create#logic-conditional-fields). diff --git a/content/collections/pages/events.md b/content/collections/pages/events.md index 105c71191..e1c26bdb7 100644 --- a/content/collections/pages/events.md +++ b/content/collections/pages/events.md @@ -559,6 +559,18 @@ public function handle(FormBlueprintFound $event) } ``` +### FormCreated +`Statamic\Events\FormCreated` + +Dispatched after a form has been created. + +``` php +public function handle(FormCreated $event) +{ + $event->form; +} +``` + ### FormCreating `Statamic\Events\FormCreating` @@ -1138,7 +1150,7 @@ public function handle(StaticCacheCleared $event) ### SubmissionCreated `Statamic\Events\SubmissionCreated` -Dispatched after a form submission has been created. This happens after a form has been submitted on the front-end. +Dispatched after a form submission (including [partial submissions](/repositories/form-submission-repository#partial-submissions)) has been created. This happens after a form has been submitted on the front-end. ``` php public function handle(SubmissionCreated $event) @@ -1152,7 +1164,7 @@ If you're looking to prevent a form being submitted or trigger validation errors ### SubmissionCreating `Statamic\Events\SubmissionCreating` -Dispatched before a submission is created. You can return `false` to prevent it from being created. +Dispatched before a submission (including [partial submissions](/repositories/form-submission-repository#partial-submissions)) is created. You can return `false` to prevent it from being created. ``` php public function handle(SubmissionCreating $event) @@ -1161,6 +1173,20 @@ public function handle(SubmissionCreating $event) } ``` +### SubmissionFinalized +`Statamic\Events\SubmissionFinalized` + +Dispatched when a submission is finalized — either when a regular form is submitted, or when the final page of a multi-page form is submitted and its [partial submission](/repositories/form-submission-repository#partial-submissions) becomes complete. + +Unlike `SubmissionCreated`, this event never fires for partial submissions, making it the best place to hook in logic that should only run once a submission is truly complete. + +``` php +public function handle(SubmissionFinalized $event) +{ + $event->submission; +} +``` + ### SubmissionDeleted `Statamic\Events\SubmissionDeleted` diff --git a/content/collections/pages/forms-pro.md b/content/collections/pages/forms-pro.md new file mode 100644 index 000000000..9b7d3ab77 --- /dev/null +++ b/content/collections/pages/forms-pro.md @@ -0,0 +1,894 @@ +--- +id: ecf1c18e-cdc6-4120-b19a-af1c3851ea53 +blueprint: page +title: Forms Pro +template: page +intro: 'Build polished multi-page experiences, publish branded forms without creating a template, explore responses with charts and insights, and send submissions directly to the tools you already use.' +related_entries: + - fdb45b84-3568-437d-84f7-e3c93b6da3e6 +--- + +[Forms Pro](https://statamic.com/addons/statamic/forms-pro) turns forms into complete experiences and workflows — not just places to collect a name and email address. + +- **Launch without building a page.** [Automagic Forms](#automagic-forms) gives every form its own branded, shareable URL. +- **Make long forms feel manageable.** Split them into [multiple pages](#multi-page-forms) and guide visitors down different paths based on their answers. +- **See what people are telling you.** Turn responses into customizable [charts and insights](#form-summaries) inside the Control Panel. +- **Put submissions to work.** Send them directly to [Google Sheets, HubSpot, Mailchimp, Slack, and more](#connections). +- **Reuse one form across many entries.** Give every event, listing, or entry [its own submissions, limits, and notifications](#unique-instances). +- **Collect better data.** Add [address autocomplete](#address-fieldtype), additional fieldtypes, and [Cloudflare Turnstile](#cloudflare-turnstile) protection. + +You can try every Forms Pro feature locally for free. When you're ready, installation takes two commands. + +## Installation + +1. Install the Forms Pro add-on via Composer: + + ```bash + composer require statamic/forms-pro + ``` + +2. Publish the configuration file to `config/statamic/forms-pro.php`: + + ```bash + php artisan vendor:publish --tag=forms-pro-config + ``` + +That's it. Forms Pro's features are now ready and waiting in the Control Panel. + +## Connections + +Alongside the Email and Webhook connections that ship with Statamic, Forms Pro adds connections for a number of third-party services. You'll find them in the same **Connect** area of your form. + +When you set each one up, it'll guide you through getting everything connected. + +
+ Statamic's form connect area + Statamic's form connect area +
The Connect area
+
+ +### Google Sheets + +Adds submissions as rows in a [Google Sheet](https://workspace.google.com/products/sheets/). You paste the spreadsheet's address, choose a tab, and pick which fields become columns — or leave that empty to include everything. + +Rows are added to the bottom, so your existing rows are left alone. Columns are named after field handles, and appear the first time a field is submitted. + +### HubSpot + +Sends submissions to a form in your [HubSpot](https://www.hubspot.com) account, so any workflows and follow-up emails attached to that form run as normal. + +You choose which of the HubSpot form's properties to map to your fields, and if it collects GDPR consent, you can map those options too. + +If you've added HubSpot's tracking code to your site, submissions will be linked to the visitor's browsing history. You'll want to turn off "Collect data from website forms" in HubSpot, otherwise it'll record its own copy of every submission. + +### Kit + +Subscribes people to your [Kit](https://kit.com) account. You can map custom fields and apply tags to subscribers — they'll need to exist in Kit first so you can pick them. + +Subscribers can also be attributed to a Kit form, so any automations linked to it will run. + +### Mailchimp + +Subscribes people to a [Mailchimp](https://mailchimp.com) audience. You can apply tags, map fields to the audience's merge fields, add people to groups based on what they chose, and record GDPR marketing permissions against the contact. + +New subscribers are added as pending until they confirm by email, unless you turn on "Skip Confirmation Email". + +### Mailcoach + +Subscribes people to a [Mailcoach](https://www.mailcoach.app) email list. You can apply tags and store extra values as attributes. + +For lists using double opt-in, "Skip Confirmation Email" subscribes people immediately rather than asking them to confirm. + +### Slack + +Posts submissions to a [Slack](https://slack.com) channel, with a button linking through to the submission in the Control Panel. You can write your own heading and choose which fields to include. + +### Twilio + +Sends a text message via [Twilio](https://www.twilio.com) when the form is submitted. Text a fixed number, or pick a form field to text whoever submitted. The message body can include values from the submission. + +## Address fieldtype + +Forms Pro ships an **Address** fieldtype with localized field labels and autocomplete powered by [Google Places](https://developers.google.com/maps/documentation/places/web-service/place-autocomplete) or [Geoapify](https://www.geoapify.com/). + +### Localization + +Address formats differ by country, so the field adapts itself to country changes: + +- The "Region" label becomes "State", "Province", "County", "Prefecture", and so on. It's hidden entirely for countries that don't use one. +- The "Postcode" label becomes "ZIP Code", "Postal Code", "Eircode", and so on. It's likewise hidden where it doesn't apply. +- Some countries (the US, Canada, China, and Italy) require a region, so it's marked as required even when the field as a whole is optional. + +You can set a **Default Country** in the field's configuration to control which country — and therefore which labels — are shown by default. + +### Autocomplete + +To enable autocomplete, specify a provider and publishable API key in your `.env`: + +```env +FORMS_PRO_ADDRESS_AUTOCOMPLETE_PROVIDER=google # or: geoapify +FORMS_PRO_ADDRESS_AUTOCOMPLETE_KEY=your-key +``` + +Typing into the "Line 1" field suggests addresses; picking one fills in the rest of the fields. Forms Pro supports two autocomplete providers: + +- **Google Places** — the best data, and the only provider that returns unit numbers, handles UK postal towns, and per-country administrative levels. A billing account (payment method) is required to obtain an API key. +- **Geoapify** — free up to 3,000 requests per day. It doesn't have the concept of a "subpremise" — the sub-unit of a building, like a flat number in the UK — so it won't fill in Line 2. + +### Customizing the front-end + +Like Statamic's own form fieldtypes, the Address fieldtype ships with basic stubs to get up and running. If you wish to customize how the field is rendered, you may publish the Antlers/Blade views into your project with: + +```bash +php artisan vendor:publish --tag=forms-pro-fields +``` + +The stubs will be published to `resources/views/vendor/forms-pro/forms`. + +You'll also need to publish Forms Pro's JS and add it to your layout. Without it, the field still renders and submits, but labels won't localize and autocomplete won't work: + +```bash +php artisan vendor:publish --tag=forms-pro-frontend +``` + +```html + +``` + +Forms Pro binds what it needs to `data` attributes, so as long as you keep them, you're free to customize the markup: + +- `data-forms-pro-address` — the root element. +- `data-address-field` — wraps a sub-field, so it can be hidden for countries that don't use it. +- `data-address-input` — the ``/`