### Product Field Configuration Example Source: https://github.com/verbb/formie/blob/craft-5/src/templates/integrations/feedme/fields/products.html Example of how to configure the product field, including default settings for element selection. ```html {# Available Variables #} {# Attributes: #} {# type, name, handle, instructions, attribute, default, feed, feedData #} {# Fields: #} {# name, handle, instructions, feed, feedData, field, fieldClass #} {% import 'feed-me/\_macros' as feedMeMacro %} {% import '\_includes/forms' as forms %} {% if field is defined %} {% set default = default ?? { type: 'elementselect', options: { elementType: fieldClass.elementType, selectionLabel: "Default Product"|t('feed-me'), sources: field.sources ?? '\*', }, } %} {% endif %} {% extends 'feed-me/\_includes/fields/\_base' %} ``` -------------------------------- ### Install Formie via Composer Source: https://github.com/verbb/formie/blob/craft-5/docs/get-started/installation-setup.md Install Formie using Composer and then install it within Craft CMS. ```shell cd /path/to/project ``` ```shell composer require verbb/formie && php craft plugin/install formie ``` -------------------------------- ### Page Start Hook Example Source: https://github.com/verbb/formie/blob/craft-5/docs/developers/hooks.md This hook allows inserting content at the start of a page, before the page legend. You can modify the context or return a string for rendering. ```php Craft::$app->getView()->hook('formie.page.start', function(array &$context) { // Add a variable to be accessible in the context object. $context['foo'] = 'bar'; // Optionally return a string return '

Hey!

'; }); ``` -------------------------------- ### Complete Form Template Example Source: https://github.com/verbb/formie/blob/craft-5/docs/theming/custom-rendering.md A comprehensive example demonstrating how to fetch a form, register assets, handle submissions, display messages and errors, and render form fields with custom attributes. ```twig {# Fetch the form we require #} {% set form = craft.formie.forms.handle('contactUs').one() %} {# Ensure the CSS/JS is rendered, according to the Form Template location #} {% do craft.formie.registerAssets(form.handle) %} {# Fetch the current submission - if there is one #} {% set submission = form.getCurrentSubmission() %} {% set submitted = craft.formie.plugin.service.getFlash(form.id, 'submitted') %} {# Show any error or success messages for the submission #} {% set flashNotice = craft.formie.plugin.service.getFlash(form.id, 'notice') %} {% set flashError = craft.formie.plugin.service.getFlash(form.id, 'error') %} {% if flashNotice %}
{{ flashNotice | raw }}
{% endif %} {% if flashError %}
{{ flashError | raw }}
{% endif %} {# Generate required attributes for the `
` element #} {% set attributes = { method: 'post', 'data-fui-form': form.configJson, } %} {{ actionInput('formie/submissions/submit') }} {{ hiddenInput('handle', form.handle) }} {{ csrfInput() }} {# Ensure we update the same submission on subsequent saves (if validation fails) #} {% if submission and submission.id %} {{ hiddenInput('submissionId', submission.id) }} {% endif %} {# Show any validation errors for the form #} {% set errors = submission.getErrors('form') ?? null %} {% if errors %} {% for error in errors %} {{ error }} {% endfor %} {% endif %} {# Render each field, according to its field template #} {% for field in form.getFields() %} {# Fetch the value if one exists, or use the default #} {% set value = attribute(submission, field.handle) ?? field.defaultValue ?? null %} {% set errors = submission.getErrors(field.handle) ?? null %} {{ field.getFrontEndInputHtml(form, value) }} {# Show any field-specific errors #} {% if errors %} {% for error in errors %} {{ error }} {% endfor %} {% endif %} {% endfor %} {% hook 'formie.buttons.before' %}
``` -------------------------------- ### Form Start Hook Example Source: https://github.com/verbb/formie/blob/craft-5/docs/developers/hooks.md Use this hook to insert content at the beginning of the form element, before the form title. It allows adding variables to the context or returning a string to be rendered. ```php Craft::$app->getView()->hook('formie.form.start', function(array &$context) { // Add a variable to be accessible in the context object. $context['foo'] = 'bar'; // Optionally return a string return '

Hey!

'; }); ``` -------------------------------- ### Example Email Marketing Integration Source: https://github.com/verbb/formie/blob/craft-5/docs/developers/custom-integration.md This example demonstrates how to create a custom email marketing integration by extending the `EmailMarketing` class. It includes methods for display name, icon, description, settings HTML, fetching form settings, and sending payloads. ```php getAssetManager()->getPublishedUrl("@modules/mymodule/resources/icon.svg", true); } public function getDescription(): string { return Craft::t('formie', 'This is an example email marketing integration.'); } public function getSettingsHtml(): string { $variables = $this->getSettingsHtmlVariables(); return Craft::$app->getView()->renderTemplate('path/to/settings', $variables); } public function getFormSettingsHtml($form): string { $variables = $this->getFormSettingsHtmlVariables($form); return Craft::$app->getView()->renderTemplate('path/to/form-settings', $variables); } public function fetchFormSettings() { $settings = []; // Fetch your lists from your provider's API $lists = $this->request('GET', 'lists'); foreach ($lists as $list) { // Fetch your lists' fields from your provider's API $fields = $this->request('GET', 'fields'); // Add some standard fields not included from the API $listFields = [ new IntegrationField([ 'handle' => 'email', 'name' => Craft::t('formie', 'Email'), 'required' => true, ]), ]; // Add the custom fields to our collection foreach ($fields as $key => $field) { $listFields[] = new IntegrationField([ 'handle' => $field['id'], 'name' => $field['name'], 'type' => $field['type'], ]); } // Add a new collection to our settings, including fields specific for it $settings['lists'][] = new IntegrationCollection([ 'id' => $list['id'], 'name' => $list['name'], 'fields' => $listFields, ]); } return new IntegrationFormSettings($settings); } public function sendPayload(Submission $submission): bool { // Fetch the form settings for our field mapping $fieldValues = $this->getFieldMappingValues($submission, $this->fieldMapping); // Construct a payload to send $payload = [ 'listId' => $this->listId, 'contact' => $fieldValues, ]; // Send the payload to our API endpoint via POST request. This also handles the before/after sending payload // events, which we can check on next $response = $this->deliverPayload($submission, 'subscribe', $payload); // The response might have failed, or an event returned this as invalid if ($response === false) { return false; } return true; } } ``` -------------------------------- ### Custom Automation Integration Example Source: https://github.com/verbb/formie/blob/craft-5/docs/developers/custom-integration.md Extends the base Automation class to create a custom integration. This example demonstrates defining display names, icons, descriptions, and custom settings HTML. It also includes methods for fetching form settings and sending payloads. ```php getAssetManager()->getPublishedUrl("@modules/mymodule/resources/icon.svg", true); } public function getDescription(): string { return Craft::t('formie', 'This is an example Automation integration.'); } public function getSettingsHtml(): string { $variables = $this->getSettingsHtmlVariables(); return Craft::$app->getView()->renderTemplate('path/to/settings', $variables); } public function getFormSettingsHtml($form): string { $variables = $this->getFormSettingsHtmlVariables($form); return Craft::$app->getView()->renderTemplate('path/to/form-settings', $variables); } public function fetchFormSettings() { // Fetch the form from our POST param $formId = Craft::$app->getRequest()->getParam('formId'); $form = Formie::$plugin->getForms()->getFormById($formId); // Generate a new submission $submission = new Submission(); $submission->setForm($form); // Populate the submission with fake data, for testing Formie::$plugin->getSubmissions()->populateFakeSubmission($submission); // Use Formie's function to generate a payload to send $payload = $this->generatePayloadValues($submission); $response = $this->getClient()->request('POST', $this->url, $payload); $json = Json::decode((string)$response->getBody()); return new IntegrationFormSettings([ 'response' => $response, 'json' => $json, ]); } public function sendPayload(Submission $submission): bool { // Generate a payload of values to send to the url $payload = $this->generatePayloadValues($submission); // Send the content to the URL $response = $this->getClient()->request('POST', $this->url, $payload); return true; } } ``` -------------------------------- ### Example Captcha Integration Source: https://github.com/verbb/formie/blob/craft-5/docs/developers/custom-integration.md Implement a custom Captcha integration by extending the `Captcha` class. This example shows how to define its handle, name, icon, description, and front-end/back-end HTML. ```php getAssetManager()->getPublishedUrl("@modules/mymodule/resources/icon.svg", true); } public function getDescription(): string { return Craft::t('formie', 'This is an example captcha.'); } public function getSettingsHtml(): string { $variables = $this->getSettingsHtmlVariables(); return Craft::$app->getView()->renderTemplate('path/to/settings', $variables); } public function getFrontEndHtml(Form $form, $page = null): string { return ''; } public function getFrontEndJsVariables(Form $form, $page = null) { $src = Craft::$app->getAssetManager()->getPublishedUrl('path-to-js.js', true); $onload = 'new MyCustomFunction();'; return [ 'src' => $src, 'onload' => $onload, ]; } public function validateSubmission(Submission $submission): bool { // Check the provided value $value = Craft::$app->getRequest()->post('example-captcha'); if ($value !== 'Testing captcha') { return false; } return true; } } ``` -------------------------------- ### Example Email Content Variables Source: https://github.com/verbb/formie/blob/craft-5/docs/feature-tour/email-notifications.md Demonstrates how to pull dynamic content from Craft CMS and form submissions into email notifications. This example shows common fields like 'First Name', 'Last Name', 'Email', and 'Message'. ```html **First Name:** Peter **Last Name:** Sherman **Email** psherman@wallaby.com **Message** Just wanted to say, I love the new website! ``` -------------------------------- ### Comparison Operators Examples Source: https://github.com/verbb/formie/blob/craft-5/docs/feature-tour/fields.md Shows examples of comparison operators used in the Calculations field for validating or comparing field values. These operators include equality, inequality, and greater/less than comparisons. ```Calculations {field1} == {field2} ``` ```Calculations {field1} > {field2} ``` -------------------------------- ### Create a Submission Query (PHP) Source: https://github.com/verbb/formie/blob/craft-5/docs/getting-elements/submission-queries.md Instantiate a new submission query object in PHP. This is the starting point for fetching submissions. ```php // Create a new submission query $myQuery = \verbb\formie\elements\Submission::find(); ``` -------------------------------- ### Text Field with Validation Source: https://github.com/verbb/formie/blob/craft-5/docs/developers/custom-field.md Example of creating a text field using SchemaHelper, including a label, help text, name, and validation rules. The validation requires the field to be filled and start with 'Some Value'. ```php SchemaHelper::textField([ 'label' => Craft::t('formie', 'Placeholder'), 'help' => Craft::t('formie', 'The text that will be shown if the field doesn’t have a value.'), 'name' => 'placeholder', 'validation' => 'required|starts_with:Some Value' ]), ``` -------------------------------- ### Create a Submission Query Source: https://github.com/verbb/formie/blob/craft-5/docs/getting-elements/submission-queries.md Instantiate a new submission query object. This is the starting point for fetching submissions. ```twig {# Create a new submission query #} {% set myQuery = craft.formie.submissions() %} ``` -------------------------------- ### Example Address Provider Implementation Source: https://github.com/verbb/formie/blob/craft-5/docs/developers/custom-integration.md This PHP code demonstrates how to create a custom Address Provider by extending the `AddressProvider` class. It includes methods for display name, icon URL, description, settings HTML, and front-end HTML/JavaScript variables. ```php getAssetManager()->getPublishedUrl("@modules/mymodule/resources/icon.svg", true); } public function getDescription(): string { return Craft::t('formie', 'This is an example address provider.'); } public function getSettingsHtml(): string { $variables = $this->getSettingsHtmlVariables(); return Craft::$app->getView()->renderTemplate('path/to/settings', $variables); } public function getFrontEndHtml($field, $options): string { return ''; } public function getFrontEndJsVariables(Form $form, $field = null) { $src = Craft::$app->getAssetManager()->getPublishedUrl('path-to-js.js', true); $onload = 'new MyCustomFunction();'; return [ 'src' => $src, 'onload' => $onload, ]; } } ``` -------------------------------- ### Global Email Template Example Source: https://github.com/verbb/formie/blob/craft-5/docs/template-guides/email-templates.md This is an example of a global HTML email template. It acts as a wrapper for the email content and can utilize variables like siteName and contentHtml. Place this file in a designated email template folder (e.g., templates/_emails/index.html). ```twig Thanks for your email

Thanks for your email enquiry. The below email was sent from {{ siteName }}.

{{ contentHtml }} ``` -------------------------------- ### Install vue-accessible-tabs with Yarn or NPM Source: https://github.com/verbb/formie/blob/craft-5/src/web/assets/forms/src/js/vendor/vue-accessible-tabs/README.md Shows the commands to add the vue-accessible-tabs package to your project using either Yarn or NPM. ```bash # yarn yarn add vue-accessible-tabs # npm npm install vue-accessible-tabs ``` -------------------------------- ### Fetch Submissions for a Specific Form Source: https://github.com/verbb/formie/blob/craft-5/docs/getting-elements/submission-queries.md Example of creating a submission query, setting the 'form' and 'limit' parameters, fetching submissions, and looping through them to display their titles. ```twig {# Create a submissions query with the 'form' and 'limit' parameters #} {% set submissionsQuery = craft.formie.submissions() .form('contactForm') .limit(10) %} {# Fetch the Submissions #} {% set submissions = submissionsQuery.all() %} {# Display their contents #} {% for submission in submissions %}

{{ submission.title }}

{% endfor %} ``` -------------------------------- ### Populate a Form with Default Values Source: https://github.com/verbb/formie/blob/craft-5/docs/template-guides/populating-forms.md Fetch a form by its handle and then populate its fields with default values before rendering. This is the basic setup for pre-populating any form. ```twig {# Fetch the form with the handle `contactForm` #} {% set form = craft.formie.forms({ handle: 'contactForm' }).one() %} {# Sets the field with handle `text` to "Some Value" for the form #} {% do craft.formie.populateFormValues(form, { text: 'Some Value' }) %} {# Render the form after calling `populateFormValues()` #} {{ craft.formie.renderForm(form) }} ``` -------------------------------- ### Example PDF Template Source: https://github.com/verbb/formie/blob/craft-5/docs/template-guides/pdf-templates.md This is a basic Twig template for rendering PDF content. It includes variables for site name and email content. ```twig

Thanks for your email enquiry. The below email was sent from {{ siteName }}.

{{ contentHtml }} ``` -------------------------------- ### Advanced Theme Configuration Example Source: https://github.com/verbb/formie/blob/craft-5/docs/theming/theme-config.md Shows advanced theme configuration options including removing the form wrapper, resetting form classes, changing the form container tag, and adding custom classes to fields and inputs. ```twig {{ craft.formie.renderForm('contactForm', { themeConfig: { formWrapper: false, form: { resetClass: true, attributes: { id: 'my-form', }, }, formContainer: { tag: 'fieldset', }, field: { attributes: { class: 'p-4 w-full mb-4', }, }, fieldInput: { attributes: { class: 'border border-red-500', }, }, }, }) }} {# Rendering #}
Some instructions
``` -------------------------------- ### String Concatenation Example Source: https://github.com/verbb/formie/blob/craft-5/docs/feature-tour/fields.md Demonstrates string concatenation using the '~' operator in the Calculations field. This is useful for combining text from different fields into a single output. ```Calculations {field1} ~ " " ~ {field2} ``` -------------------------------- ### Create a New Form Query Source: https://github.com/verbb/formie/blob/craft-5/docs/getting-elements/form-queries.md Instantiate a new form query builder. This is the starting point for fetching forms. ```twig {# Create a new form query #} {% set myQuery = craft.formie.forms() %} ``` ```php // Create a new form query $myQuery = \verbb\formie\elements\Form::find(); ``` -------------------------------- ### Globally Register Tab Components in Vue Source: https://github.com/verbb/formie/blob/craft-5/src/web/assets/forms/src/js/vendor/vue-accessible-tabs/README.md Provides an example of how to globally register all tab components from 'vue-accessible-tabs' with Vue. ```javascript import { Tabs, Tab, TabList, TabPanels, TabPanel } from 'vue-accessible-tabs' // Globally register Vue.component('Tabs', Tabs) Vue.component('Tab', Tab) Vue.component('TabList', TabList) Vue.component('TabPanels', TabPanels) Vue.component('TabPanel', TabPanel) ``` -------------------------------- ### Buttons Before Hook Example Source: https://github.com/verbb/formie/blob/craft-5/docs/developers/hooks.md Use this hook to insert content before the buttons container. It supports context modification and returning renderable strings. ```php Craft::$app->getView()->hook('formie.buttons.before', function(array &$context) { // Add a variable to be accessible in the context object. $context['foo'] = 'bar'; // Optionally return a string return '

Hey!

'; }); ``` -------------------------------- ### Configure Rich Text Field (Specific) Source: https://github.com/verbb/formie/blob/craft-5/docs/get-started/configuration.md Example of configuring a specific rich text field, setting its buttons and rows. Create a `formie` folder in your `/config` directory and a `rich-text.json` file within it. ```json { "forms": { "errorMessage": { "buttons": ["bold"], "rows": 3 } } } ``` -------------------------------- ### Importing and Initializing Formie in Vue.js Source: https://github.com/verbb/formie/blob/craft-5/docs/developers/javascript-api.md Bundle Formie's JavaScript into your Vue.js application for custom initialization and payload control. This example shows how to import the library, create an instance, initialize a form, and destroy it. ```javascript import Vue from 'vue'; import { Formie } from '../../../vendor/verbb/formie/src/web/assets/frontend/src/js/formie-lib'; new Vue({ el: '#app', data() { return { FormieInstance: null, } }, mounted() { var $form = document.getElementById("formie-form-1"); // Create an instance of our Formie JS library - the "factory" this.FormieInstance = new Formie(); // Initialise a form from its DOM element this.FormieInstance.initForm($form); }, methods: { destroyForm() { var $form = document.getElementById("formie-form-1010"); this.FormieInstance.destroyForm($form) } }, }); ``` -------------------------------- ### Provide Front-End JavaScript for Integrations (PHP) Source: https://github.com/verbb/formie/blob/craft-5/docs/developers/javascript-api.md Similar to custom fields, integrations can provide front-end JavaScript using `getFrontEndJs`. This example shows how to load a reCAPTCHA v3 script and initialize it with settings. ```php public function getFrontEndJs(Form $form) { $settings = [ 'siteKey' => $this->settings['siteKey'], ... ]; $src = Craft::$app->getAssetManager()->getPublishedUrl('@verbb/formie/web/assets/captchas/dist/js/recaptcha-v3.js', true); $onload = 'new FormieRecaptchaV3(' . Json::encode($settings) . ');'; return [ 'src' => $src, 'onload' => $onload, ]; } ``` -------------------------------- ### Example Custom Integration Element Source: https://github.com/verbb/formie/blob/craft-5/docs/developers/custom-integration.md This PHP code demonstrates a basic custom integration element by extending the `Element` class. It includes methods for display name, icon, description, settings HTML, fetching form settings, and sending payloads. ```php getAssetManager()->getPublishedUrl("@modules/mymodule/resources/icon.svg", true); } public function getDescription(): string { return Craft::t('formie', 'This is an example element.'); } public function getSettingsHtml(): string { $variables = $this->getSettingsHtmlVariables(); return Craft::$app->getView()->renderTemplate('path/to/settings', $variables); } public function getFormSettingsHtml($form): string { $variables = $this->getFormSettingsHtmlVariables($form); return Craft::$app->getView()->renderTemplate('path/to/form-settings', $variables); } public function fetchFormSettings() { $customFields = []; // Create `IntegrationField` instances for every field foreach ($elementGroup->getFields() as $field) { $fields[] = new IntegrationField([ 'handle' => $field->id, 'name' => $field->name, 'type' => get_class($field), 'required' => $field->required, ]); } return new IntegrationFormSettings([ 'elements' => $customFields, 'attributes' => $this->getElementAttributes(), ]); } public function getElementAttributes() { return [ new IntegrationField([ 'name' => Craft::t('app', 'Title'), 'handle' => 'title', ]), new IntegrationField([ 'name' => Craft::t('app', 'Slug'), 'handle' => 'slug', ]), ]; } public function sendPayload(Submission $submission): bool { $element = new YourElement(); // Fetch the attribute values from mapping $attributeValues = $this->getFieldMappingValues($submission, $this->attributeMapping, $this->getElementAttributes()); // Populate the attributes from attribute-mapping foreach ($attributeValues as $elementFieldHandle => $fieldValue) { $element->{$elementFieldHandle} = $fieldValue; } // Fetch the form settings for `elements` - we need this to parse values correctly $fields = $this->getFormSettingValue('elements')->fields ?? []; // Fetch the field values from mapping $fieldValues = $this->getFieldMappingValues($submission, $this->fieldMapping, $fields); // Populate the custom field values $element->setFieldValues($fieldValues); // Save the element if (!Craft::$app->getElements()->saveElement($element)) { return false; } return true; } } ``` -------------------------------- ### Arithmetic Operators Example Source: https://github.com/verbb/formie/blob/craft-5/docs/feature-tour/fields.md Demonstrates the use of arithmetic operators within the Calculations field. This field supports various operators for creating read-only content based on other fields. ```Calculations 10 + 10 + 22 ``` -------------------------------- ### Define Label and Handle Fields Source: https://github.com/verbb/formie/blob/craft-5/docs/developers/custom-field.md Utilize SchemaHelper::labelField() and SchemaHelper::handleField() for common field components like labels and handles. These helpers streamline the setup for universally required field properties. ```php return [ SchemaHelper::labelField(), SchemaHelper::handleField(), ]; ``` -------------------------------- ### Default Form Structure Example Source: https://github.com/verbb/formie/blob/craft-5/docs/theming/theme-config.md Illustrates the default HTML structure of a Formie form, including elements for pages, rows, fields, labels, instructions, inputs, and errors. ```twig
Some instructions
``` -------------------------------- ### Address Field Template Example Source: https://github.com/verbb/formie/blob/craft-5/src/templates/integrations/feedme/fields/address.html This template snippet demonstrates how to render an address field within a Formie Feed-Me integration. It handles variable scoping and iterates through available fields. ```html {# ------------------------ #} {# Available Variables #} {# ------------------------ #} {# Attributes: #} {# type, name, handle, instructions, attribute, default, feed, feedData #} {# ------------------------ #} {# Fields: #} {# name, handle, instructions, feed, feedData, field, fieldClass #} {# ------------------------ #} {% import 'feed-me/\_macros' as feedMeMacro %} {% import '\_includes/forms' as forms %} {# Special case when inside another complex field (Matrix) #} {% if parentPath is defined %} {% set prefixPath = parentPath %} {% else %} {% set prefixPath = [handle] %} {% endif %} {% set classes = ['complex-field'] %} {{ name }} {% namespace 'fieldMapping[' ~ prefixPath | join('][') ~ ']' %} {% endnamespace %} {% for option in field.getFields() %} {% if option.enabled %} {% set nameLabel = option.label %} {% set instructionsHandle = handle ~ '[' ~ option.handle ~ ']' %} {% set path = prefixPath | merge([ 'fields', option.handle ]) %} {% set default = default ?? { type: 'text', } %} {% embed 'feed-me/_includes/fields/_base' %} {% block additionalFieldSettings %} {% endblock %} {% block fieldSettings %} {% endblock %} {% endembed %} {% endif %} {% endfor %} ``` -------------------------------- ### Custom Form Submission Logic with Event Handlers Source: https://github.com/verbb/formie/blob/craft-5/docs/developers/javascript-api.md This example demonstrates how to use Formie events like `onBeforeFormieSubmit` and `onFormieValidate` to implement custom validation and control form submission flow, including manual submission or error triggering. ```JavaScript let $form = document.querySelector('#formie-form-1'); let submitHandler = null; // Setup our event listeners $form.addEventListener('onBeforeFormieSubmit', onBeforeSubmit); $form.addEventListener('onFormieValidate', onValidate); function onBeforeSubmit(e) { // Save for later to trigger real submit submitHandler = e.detail.submitHandler; } function onValidate(e) { // Prevent the form from submitting while we check some things e.preventDefault(); // Some custom validation logic... if (invalid) { // Show that the form is invalid submitHandler.formSubmitError(); } else { // Otherwise, tell Formie to submit the form. Because we have stopped the process, // we need to manually start it back up again. submitHandler.submitForm(); } } ``` -------------------------------- ### Defining IntegrationFormSettings Collections Source: https://github.com/verbb/formie/blob/craft-5/docs/developers/custom-integration.md Example of creating an IntegrationFormSettings object with multiple collections (contact, deal, lead) for mapping form fields. Each collection contains IntegrationField objects defining the available data attributes. ```php $contactFields = [ new IntegrationField([ 'handle' => 'name', 'name' => Craft::t('formie', 'Name'), 'required' => true, ]), // ... ]; $dealFields = [ new IntegrationField([ 'handle' => 'name', 'name' => Craft::t('formie', 'Name'), 'required' => true, ]), // ... ]; $leadFields = [ new IntegrationField([ 'handle' => 'name', 'name' => Craft::t('formie', 'Name'), 'required' => true, ]), // ... ]; $settings = new IntegrationFormSettings([ 'contact' => $contactFields, 'deal' => $dealFields, 'lead' => $leadFields, ]) ``` -------------------------------- ### Get Current User's Submissions Source: https://github.com/verbb/formie/blob/craft-5/docs/template-guides/editing-submissions.md Fetches all submissions for a specific form associated with the currently logged-in user's email address. Ensure the form handle and email field handle are correct for your setup. ```twig {% set submissions = craft.formie.submissions.form('contactUs').email(currentUser.email).all() %} {% for submission in submissions %} Edit {{ submission.title }} {% endfor %} ``` -------------------------------- ### Formie v2 Custom Validation Logic Example Source: https://github.com/verbb/formie/blob/craft-5/docs/get-started/upgrading-from-v2.md An example of a custom validation rule in Formie v2, demonstrating the `minLength` validation logic. ```javascript // Formie v2 function customRule() { return { minLength(field) { // Don't trigger this validation unless there's the `data-limit` attribute if (!field.getAttribute('data-limit')) { return false; } return !(field.value.length > 5); }, }; } ``` -------------------------------- ### Run Formie Integration Source: https://github.com/verbb/formie/blob/craft-5/src/templates/submissions/_edit.html Initializes a Garnish MenuBtn for triggering integrations. It prompts the user for confirmation before sending an AJAX request to run the selected integration for the submission. Handles success by reloading the page and displays errors if they occur. ```javascript $integrationsSelect = $('#integrations-menu-btn'); new Garnish.MenuBtn($integrationsSelect, { onOptionSelect: function(data) { var integrationId = $(data).data('integration-id'); var submissionId = $(data).data('submission-id'); var label = $(data).data('label'); var $spinner = $('.integrations-menu-spinner'); var data = { submissionId: submissionId, integrationId: integrationId }; if (window.confirm(Craft.t('formie', 'Are you sure you want to trigger the {name} integration?', { name: label }))) { $spinner.removeClass('hidden'); Craft.sendActionRequest('POST', 'formie/submissions/run-integration', { data }) .then((response) => { window.location.reload(); }) .catch(({response}) => { if (response && response.data && response.data.message) { Craft.cp.displayError(response.data.message); } else { Craft.cp.displayError(); } }) .finally(() => { $spinner.addClass('hidden'); }); } } }); ``` -------------------------------- ### Listen for Rich Text Editor Initialization Source: https://github.com/verbb/formie/blob/craft-5/docs/developers/javascript-api.md Use the `afterInit` event to access the initialized Pell rich text editor instance for multi-line text fields. ```javascript // Fetch all Multi-Line Text fields - specifically the textarea. Events are bound on the textarea element let $fields = document.querySelectorAll('[data-field-type="multi-line-text"] textarea'); // For each field, bind on the `afterInit` event $fields.forEach($field => { $field.addEventListener('afterInit', (e) => { let richText = e.detail.richText; }); }); ``` -------------------------------- ### Get Form Settings in Twig Source: https://github.com/verbb/formie/blob/craft-5/docs/developers/custom-integration.md Use `getFormSettings()` to retrieve cached settings in your templates. Call `fetchFormSettings()` to bypass the cache and get fresh data. ```twig {% set handle = integration.handle %} {% set formSettings = integration.getFormSettings().getSettings() %} // ... ``` -------------------------------- ### Formie v3 Custom Validation Logic Example Source: https://github.com/verbb/formie/blob/craft-5/docs/get-started/upgrading-from-v2.md An example of a custom validation rule in Formie v3, showing the `minLength` validation logic with the new return value convention. ```javascript // Formie v3 function({ input }) { // Don't trigger this validation unless there's the `data-limit` attribute if (!input.getAttribute('data-limit')) { return true; } return input.value.length > 5; } ``` -------------------------------- ### Configure Theme Settings Source: https://github.com/verbb/formie/blob/craft-5/docs/get-started/configuration.md Supply a nested array for the configuration form and fields should use when rendering. ```php 'themeConfig' => [ 'form' => [ 'class' => 'border border-red-500', ], 'field' => [ 'class' => 'uppercase', ], ] ``` -------------------------------- ### Equivalent Field Template Paths Source: https://github.com/verbb/formie/blob/craft-5/docs/theming/template-overrides.md Demonstrates that a field template can be placed directly in the fields directory or within a subfolder named after the field, with an index.html file. ```text fields/date.html - Is the same as - fields/date/index.html ``` -------------------------------- ### Local Testing Proxy Redirect URI Example Source: https://github.com/verbb/formie/blob/craft-5/docs/integrations/miscellaneous.md This example shows how Formie's Proxy Redirect URI modifies a local development URL to enable OAuth testing for integrations that require a public domain. ```text http://formie.test/actions/formie/integrations/callback ``` ```text https://proxy.verbb.io?return=http://formie.test/actions/formie/integrations/callback ``` -------------------------------- ### Listen for Date Picker Initialization Source: https://github.com/verbb/formie/blob/craft-5/docs/developers/javascript-api.md Use the `afterInit` event to access the initialized Flatpickr date picker instance and its options. ```javascript // Fetch all Date fields - specifically the input. Events are bound on the input element let $fields = document.querySelectorAll('[data-field-type="date-time"] input'); // For each field, bind on the `afterInit` event $fields.forEach($field => { $field.addEventListener('afterInit', (e) => { let datePickerField = e.detail.datepicker; let options = e.detail.options; }); }); ``` -------------------------------- ### Get Instructions Position Source: https://github.com/verbb/formie/blob/craft-5/docs/template-guides/available-variables.md Determines and returns the positioning information for a field's instructions. ```twig {% set instructionsPosition = craft.formie.getInstructionsPosition(field, form) %} {% if instructionsPosition.shouldDisplay('below') %} ... ... ``` -------------------------------- ### Get Label Position Source: https://github.com/verbb/formie/blob/craft-5/docs/template-guides/available-variables.md Determines and returns the positioning information for a field's label. ```twig {% set labelPosition = craft.formie.getLabelPosition(field, form) %} {% if labelPosition.shouldDisplay('above') %} ... ``` -------------------------------- ### Status Menu Initialization (JavaScript) Source: https://github.com/verbb/formie/blob/craft-5/src/templates/forms/_panes/settings.html Initializes a Garnish MenuBtn for the status selection, allowing users to pick a default status and update the UI accordingly. ```javascript {% js %} $(function () { $colorSelect = $('#status-menu-btn'); new Garnish.MenuBtn($colorSelect, { onOptionSelect: function(data) { var val = $(data).data('val'); var label = $(data).data('label'); var color = $(data).data('color'); $('#defaultStatusId').val(val); var html = '' + label; $colorSelect.html(html); } }); }); {% endjs %} ``` -------------------------------- ### Include Preview Partial Source: https://github.com/verbb/formie/blob/craft-5/src/templates/sent-notifications/_includes/resend-modal.html Includes a partial for previewing the email content. ```html {% include 'formie/sent-notifications/\_includes/preview' %} ``` -------------------------------- ### Get Field Render Options Source: https://github.com/verbb/formie/blob/craft-5/docs/template-guides/available-variables.md Retrieves the render options for a specific field from the main options array. ```twig craft.formie.getFieldOptions(field) ``` -------------------------------- ### Handle Table Row Removal Source: https://github.com/verbb/formie/blob/craft-5/docs/developers/javascript-api.md Use the 'remove' event on table fields to get information about the row that was just removed. ```javascript // Fetch all Table fields let $fields = document.querySelectorAll('[data-field-type="table"]'); // For each field, bind on the `append` event $fields.forEach($field => { $field.addEventListener('remove', (e) => { let tableField = e.detail.table; let $row = e.detail.row; let $form = e.detail.form; }); }); ``` -------------------------------- ### Import All Formie Forms from Folder Source: https://github.com/verbb/formie/blob/craft-5/docs/developers/console-commands.md Imports all Formie form JSON files from a specified folder. Use the `--create` flag to create new forms. ```shell ./craft formie/forms/import-all ``` -------------------------------- ### Querying Nested Field Content Source: https://github.com/verbb/formie/blob/craft-5/docs/developers/graphql.md This example shows how to query nested Repeater and Group field content within submissions. ```graphql { formieSubmissions (handle: "contactForm") { title ... on contactForm_Submission { groupFieldHandle { myFieldHandle } repeaterFieldHandle { rows { myFieldHandle } } } } } ``` -------------------------------- ### Add Custom Attributes to Form Field Source: https://github.com/verbb/formie/blob/craft-5/docs/developers/custom-field.md Example of adding custom attributes like 'inputClass' and 'data-value' to a Formie field schema. ```php [ // ... 'inputClass' => 'some-class', 'data-value' => 'some-value', ] ``` -------------------------------- ### Handle Table Field Initialization Source: https://github.com/verbb/formie/blob/craft-5/docs/developers/javascript-api.md Use the 'init' event to perform actions just before a table field is fully initialized. ```javascript // Fetch all Table fields let $fields = document.querySelectorAll('[data-field-type="table"]'); // For each field, bind on the `init` event $fields.forEach($field => { $field.addEventListener('init', (e) => { let tableField = e.detail.table; }); }); ``` -------------------------------- ### Customize Ajax Client for Submission Source: https://github.com/verbb/formie/blob/craft-5/docs/developers/javascript-api.md The `modifyAjaxClient` event allows you to customize the XMLHttpRequest client used for Ajax submissions, for example, by setting `withCredentials`. ```JavaScript let $form = document.querySelector('#formie-form-1'); $form.addEventListener('modifyAjaxClient', (e) => { e.detail.client.withCredentials = true; // ... }); ``` ```jQuery $('#formie-form-1').on('modifyAjaxClient', function(e) { e.detail.client.withCredentials = true; // ... }); ``` -------------------------------- ### Listen to afterFetchFormSettings Event Source: https://github.com/verbb/formie/blob/craft-5/docs/developers/events.md Triggered after an integration fetches its available settings for form settings. Access the integration and settings. ```php use verbb\formie\events\IntegrationFormSettingsEvent; use verbb\formie\integrations\emailmarketing\Mailchimp; use yii\base\Event; Event::on(Mailchimp::class, Mailchimp::EVENT_AFTER_FETCH_FORM_SETTINGS, function(IntegrationFormSettingsEvent $event) { $integration = $event->integration; $settings = $event->settings; // ... }); ``` -------------------------------- ### Field Before Hook Example Source: https://github.com/verbb/formie/blob/craft-5/docs/developers/hooks.md This hook is placed before the field container, allowing for content insertion. Context variables can be added, and strings can be returned for rendering. ```php Craft::$app->getView()->hook('formie.field.field-before', function(array &$context) { // Add a variable to be accessible in the context object. $context['foo'] = 'bar'; // Optionally return a string return '

Hey!

'; }); ``` -------------------------------- ### Get Submissions Related to an Entry Source: https://github.com/verbb/formie/blob/craft-5/docs/template-guides/relations.md Fetch all Formie submission elements that are related to a given Craft CMS entry element using `getSubmissionRelations()`. ```twig {% set entry = craft.entries.id(2242).one() %} Submissions related to {{ entry.title }} {% for elementRelation in craft.formie.getSubmissionRelations(entry) %} {{ elementRelation.title }} {% endfor %} ``` -------------------------------- ### Fetch Login Form by Handle Source: https://github.com/verbb/formie/blob/craft-5/docs/template-guides/craft-forms.md Retrieve a specific Formie form using its handle. This is the initial step before rendering the form in a template. ```twig {% set form = craft.formie.forms.handle('login').one() %} ``` -------------------------------- ### Display Form Instructions Conditionally Source: https://github.com/verbb/formie/blob/craft-5/src/templates/_special/form-template/_includes/instructions.html Conditionally renders form instructions if they exist and the display position is valid. Uses Formie's `getInstructionsPosition` to determine visibility. ```html {% set instructionsPosition = (instructionsPosition ?? craft.formie.getInstructionsPosition(field, form)) %} {% if field.instructions and instructionsPosition.shouldDisplay(position) %} {{ fieldtag('fieldInstructions', { text: field.instructions | t('formie') | trim | md, }) }} {% endif %} ``` -------------------------------- ### Get All Pages for a Form Source: https://github.com/verbb/formie/blob/craft-5/docs/template-guides/rendering-pages.md Fetch all pages associated with a specific form using its handle. This is useful for iterating through pages when a direct handle is not available for individual pages. ```twig {% set form = craft.formie.forms.handle('contactUs').one() %} {% for page in form.getPages() %} {{ page.name }} {% endfor %} ``` -------------------------------- ### Import Formie Form from File Source: https://github.com/verbb/formie/blob/craft-5/docs/developers/console-commands.md Imports a Formie form from a JSON file. Specify the `fileLocation` and use the `--create` flag to create a new form. ```shell ./craft formie/forms/import formie-contact-form.json ```