FormIt is a powerful and flexible component for MODX that allows you to process forms on your website. With its help you can collect data from users, process it and save it to a database or send it to email. FormIt provides flexible customization, built-in validation and many other useful features such as:
- Form data processing.
- File attachment support.
- Save data to the database.
- Send email notifications, etc.
- Why use FormIt?
- Installation
- Development and bugs
- How to use
- Available properties (parameters)
- Data Validation
- Full list of built-in validators
- Custom Validators
- Custom Error Messages
- Hooks
- Using preHooks
- Using the renderHooks parameter
- Using Hooks
- Built-in hooks
- Email hook
- The redirect hook
- Spam Hook
- The math hook
- The recaptcha hook
- FormItAutoResponder Hook
- FormItSaveForm Hook
- Helper Snippets
- FormItRetriever
- Usage
- FormItRetriever Properties
- Example
- FormItCountryOptions
- Usage
- FormItCountryOptions Properties
- Priority Countries
- FormItStateOptions
- Usage
- FormItStateOptions Properties
- Advanced
- Handling Dropdowns, Checkboxes, and Radio Buttons
- Handling Dropdowns
- Handling checkboxes and radio buttons
- Using an empty field to prevent spam
- Conclusion
Why use FormIt?
- Easy to create forms: add the necessary fields, customize them, and get a working form in a few minutes.
- Built-in validation: make sure that users enter correct data.
- Data processing: save data to the database, send it to email, or process it as you need.
- Security: protect against spam and attacks with built-in mechanisms.
- Flexibility: integrates with other MODX components for expansion functionality.
Installation
FormIt can be downloaded via package manager from the main repository. To do this:
- Go to the MODX control panel.
- Open the “Installer” section.
- Find the FormIt component in the “Add-ons” section.
- Install and activate the component.
You can also download the transport package from the MODX repository here: https://modx.com/extras/package/formit.
Development and bugs
.
FormIt is stored and developed on GitHub and can be found here: https://github.com/Sterc/FormIt
You can post bugs here: https://github.com/Sterc/FormIt/issues.
API documentation can also be found here: https://api.modx.com/formit/.
How to use
.
Simply mark up the form you want to use and place a snippet FormIt call above it. Specify the “hooks” (or post-check processing scripts) in the Snippet call. Then add validation using parameters &validate
and &customValidators
.
Example, we have a simple HTML markup of a form:
<form action="[[~[[*id]]]]" method="post">
<label for="name">Name:</label>
<input type="text" name="name" id="name" required>
<label for="email">Email:</label>
<input type="email" name="email" id="email" required>
<label for="message">Message:</label>
<textarea name="message" id="message" required></textarea>
<button type="submit">Submit</button>
</form>
Next, place a FormIt
snippet call with the necessary parameters above the form, example:
[[!FormIt?
&hooks=`email`
&emailTo=`admin@example.com`
]]
<form action="[[~[[*id]]]]" method="post">
<label for="name">Name:</label>
<input type="text" name="name" id="name" required>
<label for="email">Email:</label>
<input type="email" name="email" id="email" required>
<label for="message">Message:</label>
<textarea name="message" id="message" required></textarea>
<button type="submit">Submit</button>
</form>
If you have multiple forms on a page, set the &submitVar
property in the snippet call to the name of the form element (e.g. &submitVar = form1-submit
). This tells FormIt to only process form requests if the submitted form fields (POST) have this variable. If you have multiple forms processed by Formit on a single page, you should use tags with INPUT type = “submit” name = “form1-submit”, button elements will not work.
See also: Contact Form Best Practices.
Available properties (parameters)
FormIt supports many parameters that can be customized depending on your needs. The most common ones are:
- &hooks — a chain of actions performed after the form is submitted (for example,
email
,spam
). - &emailTo — the email address to which the message will be sent.
- &validate — rules for validating form fields.
- &successMessage — a message about the successful submission of the form.
- &errorMessage — an error message.
Example of using parameters:
[[!FormIt?
&hooks=`email`
&emailTo=`admin@example.com`
&validate=`name:required,email:email`
&successMessage=`Your message has been sent successfully.`
&errorMessage=`An error has occurred. Please check your input.`
]]
The table below prescribes all available common properties for FormIt calls (not including properties specific to hooks):
Name | Description | Default value |
---|---|---|
preHooks | Which scripts to run, if any, after the form loads. This can be a comma-separated list of hooks, and if the first one fails, the following ones will not be used. A hook can also be the name of another Snippet that will execute this Snippet. | |
renderHooks | Which scripts to run, if any, after the form has loaded, the preHooks have completed, and all fields and errors have been set. This can be a comma-separated list of Hooks used to manipulate all form fields before everything is set based on data from other packages or prehooks. Hook can also be the name of a Snippet that will execute this Snippet. |
|
hooks | Which scripts to run, if any, after the form has been validated. This can be a list of comma-separated hooks, where if the first one fails, the next ones will fail as well. Hook can also be the name of a Snippet that will execute this Snippet. | |
submitVar | If set, form processing will not start unless this POST variable is passed. Note: this parameter is required if you are using the &store property (+ set the submit variable to input=”submit”!). |
|
validate | A comma-separated list of fields to validate, for each field in the form name:validator (for example: username: required, email: required ). Validators can also be chained, for example email:email:required . This property can also be specified on multiple lines. |
|
validationErrorMessage | A generic error message that should be set as a Placeholder[[!+fi.validation_error_message]] if validation fails. Can contain[[+errors]] if you want to list all errors. |
A form validation error occurred. Please check the values you entered. |
validationErrorBulkTpl | HTML tpl used for each individual error in the overall validation error message. | [[+error]] |
errTpl | HTML wrapper for error messages. Note: not a chunk, just plain HTML. | [[+error]] |
customValidators | A comma-separated list of custom validator names (snippets) you plan to use in this form. They must be explicitly specified here, otherwise they will not run. | |
clearFieldsOnSuccess | If specified, will clear fields on successful form submission without redirecting. | 1 |
store | If specified, data will be stored in cache for retrieval using the FormItRetriever snippet. | 0 |
storeTime | In seconds, if specified, specifies the number of seconds to store data after form submission. Default is five minutes. | 300 |
storeLocation | When using store this property specifies where the form will be stored after submission. Possible options are cache and session . |
cache |
placeholderPrefix | The prefix used for all Placeholders set by FormIt for fields. Remember to include “.” separator in your prefix. | fi. |
successMessage | If the redirect hook is not used, display this message after a successful submission. |
|
successMessagePlaceholder | The name of the Placeholder to set the success message for. | fi.successMessage |
redirectTo | The ID of a “Your form has been successfully submitted” page where the visitor can be sent after a successful form submission, but this parameter is read ONLY if you included redirect in the list hooks(parameter &hooks ). |
|
allowFiles | Specify whether file uploads are allowed. Uploaded files are stored in a temporary directory so that files are not lost if your form consists of several steps. | 1 |
attachFilesToEmail | Attaches uploaded files to an email, the form must have the attribute enctype="multipart/form-data" |
1 |
Data Validation
FormIt supports various types of form field validation via the &validate
parameter. The basic rules are:
- required — field is required.
- email — check email address is correct.
- minLength:X — minimum string length (X is a number).
- maxLength:X — maximum string length.
- isNumber — check for a number.
Example, to make the username field mandatory, you can do this:
&validate=`name:required`
Validators can also be “chained” or executed sequentially. The following example first checks whether the text
field value is passed, and then removes all tags from the message:
[[!FormIt? &validate=`text:required:stripTags`
Multiple fields and validators are separated by commas:
[[!FormIt?
&validate=`date:required:isDate=^%m/%d/%Y^,
name:required:testFormItValidator,
email:email:required,
colors:required,
subject:required,
username:required:islowercase,
message:stripTags,
numbers:required`
]]
FormIt allows validators to be split across multiple lines if you find that more convenient.
Note: Don’t use backticksinside the validation call (it will break the syntax markup). Use the
^` characters instead:
[[!FormIt? &validate=`date:required:isDate=^%m/%d/%Y^`]]
This will fix the call and make the validation work correctly.
A generic error message for validators, useful if no errors are displayed but validation fails, is used with the following placeholder:
[[!+fi.validation_error_message]]
It will contain a validation error message, which can be set using the &validationErrorMessage
property and using [[+errors]]
in the property value, which will be replaced by all errors in the field.
There is also a “Yes/No” placeholder:
[[!+fi.validation_error]]
Full list of built-in validators
Name | Function | Parameter | Example |
---|---|---|---|
blank | Is the field empty? | nospam:blank | |
required | Is the field not empty? | username:required | |
password_confirm | Does the field match the value of another field? | Field name password | password2:password_confirm=^password^ |
Is this a valid email address? | emailaddr:email | ||
minLength | Is the field at least X characters long? | Minimum length | password:minLength=^6^ |
maxLength | Is the field less than X characters long? | Maximum length | password:maxLength=^12^ |
minValue | Is the field value less than or equal to X? | Minimum value | donation:minValue=^1^ |
maxValue | Is the field value less than or equal to X? | Maximum value | cost:maxValue=^1200^ |
contains | Does the field contain string X? | String X. | title:contains=^Hello^ |
strip | Remove a specific string from the field. | The string to remove | message:strip=^badword^ |
stripTags | Remove all HTML tags from the field. Note that this is enabled by default. | Optional list of allowed tags | message:stripTags |
allowTags | Do not remove HTML tags in the field. Note that this is disabled by default. | content:allowTags | |
isNumber | Is the field a numeric value? | cost:isNumber | |
allowSpecialChars | Do not replace HTML special characters with their entities. This is disabled by default. | message:allowSpecialChars | |
isDate | Is the field a date? | Optional format for date formatting | startDate:isDate=^%Y-%m-%d^ |
regexp | Does the field match the expected format? | A valid regular expression to compare | secretPin:regexp=^/[0-9]{4}/^ |
Custom Validators
Validators can also be any custom snippets. You can do this by simply specifying the name of the snippet in the property customValidators
:
[[!FormIt? &customValidators=`isBigEnough`]]
All such custom validators must be specified in the customValidators
property, otherwise they will not run. And also as a validator for the &validate
property:
[[!FormIt? &validate=`cost:isBigEnough`]]
And the snippet itself, “isBigEnough”:
<?php
$value = (float)$value;
$success = $value > 1000;
if (!$success) {
// Note how we can add an error to the field here.
$validator->addError($key,'Not enough!');
}
return $success;
The validator will send the following properties to the snippet in the array $scriptProperties
:
Name | Function |
---|---|
key | The key of the field being checked. |
value | The value of the field that was passed in the $_POST array. |
param | If a parameter was specified for the validator, it will also be passed. |
type | Name of the validator (snippet) |
validator | Reference to the instance class fiValidator . |
Custom Error Messages
Since FormIt 2.0-pl, you can override the error messages displayed by validators by sending an appropriate property:
Validator | Property |
---|---|
blank | vTextBlank |
required | vTextRequired |
password_confirm | vTextPasswordConfirm |
vTextEmailInvalid, vTextEmailInvalidDomain | |
minLength | vTextMinLength |
maxLength | vTextMaxLength |
minValue | vTextMinValue |
maxValue | vTextMaxVal ue |
contains | vTextContains |
isNumber | vTextIsNumber |
isDate | vTextIsDate |
regexp | vTextRegexp |
You can also specify a message for each field by prefixing the property with the field key. For example, to override the “required” validator message, simply pass in your FormIt call:
[[!FormIt?
&vTextRequired=`Please provide a value for this field.`
&subject.vTextRequired=`Please enter a subject.`
]]
This will use &subject.vTextRequired
for the subject field, and then fall back to &vTextRequired
for all other fields.
Hooks
Hooks are basically scripts that run during FormIt processing. They are always executed in the order in which they are specified in the property. If, for example, you have an email hook followed by a validation hook, the email will be sent before validation occurs.
If any hook completes with an error, the hooks that follow it will not be executed.
There are three types of hooks:
- preHook, specified in the
preHooks
property of the FormIt snippet, which runs when the form is loaded. Useful for preloading values. - renderHook, specified in the
renderHooks
property of the FormIt snippet, which runs when the form is loaded and the preHooks hooks have completed. Useful for handling fields and errors before the form is rendered, as used in Formalicious. - Regular hook, specified in the
hooks
property of the FormIt snippet, which runs after the form is validated. Useful for custom post-processing.
Using preHooks
Just specify the preHook in the preHooks
property in the FormIt snippet call. There are no built-in preHooks hooks, but if you have, for example, a preHook called loadCustomValues
, then the call would be:
Formit will run the loadCustomValues
snippet before loading the form. You can set the fields in the form like this:
Or alternatively use ->setValues
:
<?php
$hook->setValues(array(
'name' => 'Ivan Petrov',
'email' => 'ivan.petrov@fake-emails.com',
));
return true;
Note that using the setValues()
method here will make the appropriate Placeholders available to your email block; manually setting the values is similar to adding hidden fields to your form.
You can also do whatever you want in the preHook. Remember to return true if your preHook or hook is successful. If you want to add an error message to the field:
$hook->addError('user','User not found.');
return $hook->hasErrors();
Using the renderHooks parameter
Simply specify the renderHook in the renderHooks
property in your FormIt snippet call. There are no built-in hooks for renderHooks
, but if you have, for example, a renderHook named buildSessionFields
, you can do it like this:
// Get the Formit configuration and possible specified values
$formit =& $hook->formit;
$values = $hook->getValues();
// Get session data
$values = array_merge($_SESSION['preset_fields_from_session'], $values);
$fields = array();
foreach ($values as $value) {
// $value = array('label' => '', 'name' => '')
$fields[] = $modx->getChunk('fieldChunk', $value);
}
$modx->toPlaceholder('extraFields', implode(PHP_EOL, $fields));
The new hook system makes it easier to build custom forms from sessions, database, or API data.
Using Hooks
Simply specify the hook in the hooks
property when calling the FormIt snippet. For example, the following call loads the spam hook and the send email hook:
Built-in hooks
Email hook
The email hook sends the contents of your HTML form to any email address.
Supported parameters
Name | Description |
---|---|
emailTpl | Required. The tpl chunk for the email message. If not specified, a list of fields with their values will be sent. |
emailSubject | The subject of the email. |
emailUseFieldForSubject | If “1” is specified and the subject field is passed, the value of this field will be used as the subject line of the email. |
emailTo | A comma-separated list of recipient email addresses. |
emailToName | Optional. A comma separated list of names to pair with the emailTo values. |
emailFrom | Optional. If set, the “From:” address for the email will be specified. If not set, the “email” form field will be searched first. If none is found, the system setting emailsender will be defaulted to. NOTE: Always set the system setting emailFrom to a valid email address (that is allowed to be sent from your server) to avoid emails being rejected due to SPF/DMARC violations. |
emailFromName | Optional. If set, will set the “From:” sender name for the email. |
emailHtml | Optional. Whether the email should be in HTML format. Defaults to 1. |
emailConvertNewlines | Optional. If set to 1, all newlines will be converted to <br> tags. |
emailReplyTo | The email to reply to. If not set, will look for the “email” form field first. If none is found, will default to the value set in emailFrom . NOTE. Set emailReplyTo to a valid email address from the same domain as emailFrom to avoid email rejections due to SPF/DMARC violations. |
emailReplyToName | Optional. The name of the field to reply to via “Reply-To:” |
emailCC | A comma-separated list of emails to send via “CC:”. |
emailCCName | Optional. A comma-separated list of names to pair with the emailCC values. |
emailBCC | A comma-separated list of email addresses to be sent via blind carbon copy (“BCC”). |
emailBCCName | Optional. A comma-separated list of names to pair with the emailBCC values. |
emailMultiWrapper | Wraps values passed in via checkboxes/multi-select lists with this value. Defaults to using only the value. (1.6.0+) |
emailMultiSeparator | Separates checkboxes/multi-select lists with this value. Defaults to a newline. (1.6.0+) |
emailSelectField | The name of the form field that selects the email addresses to send to. (4.2.5+) |
emailSelectTo | A semicolon-separated list of comma-separated email addresses to send to. (4.2.5+) |
emailSelectToName | A semicolon-separated list of email names to send to. (4.2.5+) |
Any of the email hook properties can contain placeholders for the names of fields from your form that will be processed.
Usage
Simply specify it as a hook in your FormIt call, and then specify the email properties in your FormIt call.
[[!FormIt?
...
&hooks=`email`
&emailTpl=`CentralizedDebtObligationEmailTpl`
&emailSubject=`Someone else bought a CDO package`
&emailTo=`sales@mortgagemoney.com`
&emailCC=`boss@mortgagemoney.com`
&emailBCC=`fbi@gov.com`
&emailBCCName=`CDO Fraud Reporter`
]]
Note that the &emailTpl
property points to the chunk name. In this block you will have placeholders for each field in your form. Our chunk might look like this:
<p>Hello,</p>
<p>[[+name]] just purchased a CDO package: [[+cdo_package]].</p>
<p>His email is: [[+email]]</p>
<p>Thanks!</p>
This of course assumes that you have “name”, “cdo_package” and “email” fields in your form.
Adding Dynamics to Addressing
FormIt, starting with version 4.2.5+, could select the recipient of the email by the numeric value of the field, i.e. by the value of the ‘select’ parameter. This way you can avoid creating a fake form field where the user can easily submit any email address. The user will only see a numbered list of recipients that will be redirected to the email addresses using the FormIt properties.
You can use the following FormIt properties for this:
&emailSelectTo=`mail1@my.domain,mail2@my.domain;different@my.domain`
&emailSelectToName=`Mail1,Mail2;Different`
&emailSelectField=`emailselect`
and the following form field
<select name="emailselect">
<option value="1" [[!+fi.emailselect:default=`1`:FormItIsSelected=`1`]]>Address 1</option>
<option value="2" [[!+fi.emailselect:default=`1`:FormItIsSelected=`2`]]>Address 2</option>
</select>
If Address 1 is selected, the mail will be sent to mail1@my.domain,mail2@my.domain
, if Address 2 is selected, the mail will be sent to different@my.domain
.
Using the Subject Field as the Email Subject Line
Suppose you have a subject field in your form. You want this to be the subject of the email that is sent. The email hook might do the following:
[[!FormIt?
...
&emailUseFieldForSubject=`1`
]]
This will search for a field named “subject” to use in the email. If it is not found or is empty, it will default to &emailSubject
.
Working with checkboxes and multiple selections in email
FormIt, starting with version 1.6.0+, automatically handles checkboxes and combines them into a single field. You can use the &emailMultiSeparator
and &emailMultiWrapper
properties to specify how they are combined. For example, to wrap checkboxes in <li>
tags:
[[!FormIt?
...
&emailMultiWrapper=`<li>[[+value]]</li>`
]]
Or simply split using BR tags:
[[!FormIt?
...
&emailMultiSeparator=`<br />`
]]
The redirect hook
This hook will redirect the user to the specified resource when their HTML form finishes submitting. It requires one parameter, redirectTo
, which should be the ID of the resource you want to redirect to. Form field values are not forwarded.
Supported Parameters
Name | Description |
---|---|
redirectTo | Required. The resource ID to redirect the user to when the HTML form is successfully submitted. |
redirectParams | A JSON object with the parameters to pass in the redirect URL. |
Note that this can also be used with the &store
property to send form values to the redirected page using the FormItRetriever snippet.
Usage
Simply include the redirect hook in the &hooks
property when calling FormIt. Then specify the resource ID to redirect to using the &redirectTo
property.
Redirect with Parameters
You can specify parameters to redirect to when using this hook. Simply use the &redirectParams
property:
[[!FormIt?
&hooks=`redirect`
&redirectTo=`212`
&redirectParams=`{"user":"123","success":"1"}`
]]
This will create a URL with these parameters. Let’s say resource ID 212 is in books.html
, then the redirect URL would be:
- books.html?user=123&success=1
Spam Hook
The hook checks all fields specified in the spamEmailFields
property against the spam filter via StopForumSpam. If the user is marked as a spammer, an error message will be shown for that marked field.
The hook requires support for either cURL or Sockets in your PHP installation (same requirements for Package Management).
Possible Parameters
name | description |
---|---|
spamEmailFields | Optional. A comma-separated list of email address fields to check. Defaults to “email”. |
spamCheckIp | If ‘true’, the sender IP will also be checked. Defaults to ‘false’. |
Usage
Just specify the “spam” hook in your FormIt call, and the snippet will do the rest.
[[!FormIt? &hooks=`spam`]]
Checking an IP Address for Spam
While it is highly discouraged to use an IP address for spam checking (since spammers can easily change IP addresses, and IP address checking often gives false positives), FormIt gives you the option. Just set the &spamCheckIp
parameter to 1 when calling FormIt.
The math hook
The math hook will allow you to have a math question in your form to prevent spam. It will display the math expression that needs to be calculated to answer correctly, namely:
12 + 23?
Supported Parameters
Name | Description | Default |
---|---|---|
mathMinRange | The minimum value for each number in the equation. | 10 |
mathMaxRange | The maximum value for each number in the equation. | 100 |
mathField | The name of the input field for the answer. | math |
mathOp1Field | Name field/placeholder for 1st number in equation. | op1 |
mathOp2Field | Field/placeholder name for 1st number in equation. | op2 |
mathOperatorField | Field/placeholder name for operator in equation. | operator |
Usage
Include it as a hook in FormIt call:
[[!FormIt? &hooks=`math`]]
To require a math expression to be evaluated, use a call like this:
[[!FormIt? &hooks=`math` &validate=`math:required`]]
Paste this sample HTML code into the part of the form where you want to include the math question:
<label>[[!+fi.op1]] [[!+fi.operator]] [[!+fi.op2]]?</label>
[[!+fi.error.math]]
<input type="text" name="math" value="[[!+fi.math]]" />
<input type="hidden" name="op1" value="[[!+fi.op1]]" />
<input type="hidden" name="op2" value="[[!+fi.op2]]" />
<input type="hidden" name="operator" value="[[!+fi.operator]]" />
A math question in place of the input field named “math”.
NOTE: The “op1”, “op2”, and “operator” form fields are no longer used starting with FormIt 2.2.11.
Customizing the Operation Description
If you don’t want to use just “-” or “+” as an operator and want to further hide it from spambots, you can use output filters to further ambiguate the math equation. Change the equation line to:
<label>[[!+fi.op1]] [[!+fi.operator:is=`-`:then=`minus`:else=`plus`]] [[!+fi.op2]]?</label>
This will make the equation look like “23 plus 41?” or “50 minus 12?” instead of the -/+ symbol, making it harder for spambots to find.
The recaptcha hook
The recaptcha hook will enable reCaptcha support for FormIt forms.
Usage
First, add recaptcha to the &hooks
parameter in the FormIt call. Then you will need to include the following placeholders in the form:
[[+formit.recaptcha_html]]
[[!+fi.error.recaptcha]]
The first placeholder is where the reCaptcha form will be displayed; the 2nd is the error message (if any) for reCaptcha.
Finally, you need to configure the reCaptcha private and public keys in the system settings. The following settings are available for reCaptcha:
Name | Description |
---|---|
formit.recaptcha_public_key | Your reCaptcha public key. |
formit.recaptcha_private_key | Your reCaptcha private key. |
formit.recaptcha_use_ssl | Whether to use SSL for reCaptcha requests. Default is “no”. |
Supported Parameters
The reCaptcha hook has several additional configuration parameters:
Name | Description | Default |
---|---|---|
recaptchaJs | A JSON object to pass to the RecaptchaOptions variable, which configures the reCaptcha widget. See the official reCaptcha documentation for more information. |
{} |
recaptchaTheme | The reCaptcha theme to use. | clean |
FormItAutoResponder Hook
The hook sends an auto-response to the sender via email.
Supported Parameters
The hook has the following parameters that need to be passed to the FormIt snippet call:
name | description |
---|---|
fiarTpl | Required. The name of the chunk for the auto-reply. |
fiarSubject | The subject of the email. |
fiarToField | The name of the form field that will be used as the sender’s email address. Defaults to “email”. |
fiarFrom | Optional. If set, the “From:” address for the email will be specified. Defaults to the system setting emailsender . |
fiarFromName | Optional. If set, the sender name for “From:” will be provided. |
fiarSender | Optional. Specify the email sender header. Defaults to the system setting emailsender . |
fiarHtml | Optional. Whether the email should be in HTML format. Defaults to 1. |
fiarReplyTo | Required. The email address to which a reply can be sent (“Reply-To:”). |
fiarReplyToName | Optional. Field name for “Reply-To:” reply |
fiarCC | Comma-separated list of emails to send via “CC:”. |
fiarCCName | Optional. Comma-separated list of names to pair with the fiarCC values. |
fiarBCC | Comma-separated list of email addresses to send via blind carbon copy (“BCC”). |
fiarBCCName | Optional. A comma separated list of names to pair with the fiarBCC values. |
fiarMultiWrapper | Wraps values passed via checkboxes/multi-select lists with this value. Defaults to just the value. |
fiarMultiSeparator | Separates checkboxes/multi-select lists with this value. Defaults to a newline. (“\n”) |
fiarFiles | Optional. A comma separated list of files to add as an attachment to the email. You can’t use a URL here, only a local file system path. |
fiarRequired | Optional. If set to false, the FormItAutoResponder handler does not stop when the field defined in fiarToField is left empty. Defaults to true. |
FormItSaveForm Hook
This hook will save submitted forms inside Formit CMP.
Supported Parameters
The hook has the following parameters that need to be passed to the FormIt snippet call:
Name | Description | Example |
---|---|---|
formName | Form name. Defaults to “form-{resourceid}”. | |
formEncrypt | If set to “1” (true), the submitted form will be encrypted before being saved to the database. | |
formFields | A comma-separated list of fields to save. By default, all fields will be saved, including the submit button. | |
fieldNames | Change the field name inside the CMP. For example, if the field name is “email2”, you can change the name to “alternate email address”. | &fieldnames=`fieldname==Field Name,anotherone==Another Field Name` |
Helper Snippets
FormItRetriever
FormItRetriever is a helper Snippet for FormIt that will retrieve the user’s last form submission data via FormIt. This is useful for pages where the user is redirected after submitting the form.
Usage
Simply add this Snippet to any page you are redirecting from (using FormIt’s &redirectTo
property), and set &store=1
in the FormIt call:
[[!FormItRetriever]]
Then display the form data with placeholders that refer to the field names, like this:
<p><Thanks to [[!+fi.name]] for your message. The email will be sent to your [[!+fi.email]].</p>
Don’t forget to set &store=1
in the FormIt call so the Snippet knows to store the value.
Be sure to call Placeholders uncached. This data changes on every request, so Placeholders should also change on every request.
FormItRetriever Properties
FormItRetriever has some default properties that you can override. Here’s what it says:
Name | Description | Default |
---|---|---|
placeholderPrefix | String to prefix all form field placeholders to be set by this Snippet. | fi. |
redirectToOnNotFound | If data not found and this property is set, redirect to the Resource with this ID. | |
eraseOnLoad | If specified, will erase saved form data on load. It is highly recommended to leave the value 0 unless you want the data to be loaded only once. |
|
storeLocation | Where to get the form data from. Should be equal to the storeLocation property of your FormIt Snippet call. Possible values are ‘cache’ and ‘session’. |
cache |
Example
We will submit the form with an automatic response and spam protection, then redirect to a thank you page where the last submitted form is loaded, and if it is not found, redirect to the Resource with the ID 444.
On your page with the form:
[[!FormIt?
&submitVar=`go`
&hooks=`spam,FormItAutoResponder,redirect`
&emailTo=`my@email.com`
&store=`1`
&redirectTo=`123`
]]
<form action="[[~[[*id]]]]" method="post">
<input type="hidden" name="nospam" value="" />
<label for="name">Name: [[!+fi.error.name]]</label>
<input type="text" name="name:required" id="name" value="[[!+fi.name]]" />
<label for="email">Email: [[!+fi.error.email]]</label>
<input type="text" name="email:email:required" id="email" value="[[!+fi.email]]" />
<label for="message">Message: [[!+fi.error.message]]</label>
<textarea name="message:stripTags" id="message" cols="55" rows="7">[[!+fi.message]]</textarea>
<br />
<input type="submit" name="go" value="Submit" />
</form>
On your confirmation page (Resource ID 123):
[[!FormItRetriever? &redirectToOnNotFound=`444`]]
<p>Thank you [[!+fi.name]] for your request. An email will be sent automatically to [[!+fi.email]]. Your request text:</p>
[[!+fi.message]]
FormItCountryOptions
FormItCountryOptions is a helper Snippet for FormIt, since version 1.7.0, for displaying a list of countries of the world. This is useful for forms that need, for example, a drop-down list of countries.
Currently, translated country lists are available for the following languages - English, French, Dutch, German, Belgian and Swedish.
Note: A list of countries in Russian will be available soon.
The language to use for the country list is determined by the value of the system variable cultureKey
, which defaults to English (the value of the key us
).
Usage
Just add the Snippet to your form inside the <select>
element:
<select name="country">
[[!FormItCountryOptions? &selected=`[[!+fi.country]]`]]
</select>
Note how we pass the value of the “fi.country” placeholder (which stores the value of the country field) to the selected option. This tells FormItCountryOptions to select the last selected option in the form.
FormItCountryOptions Properties
FormItCountryOptions has some default properties that you can override. Here’s what’s in there:
Name | Description | Default |
---|---|---|
selected | Country code to mark as selected | |
selectedAttribute | Optional. HTML attribute to add to the selected country. | selected=”selected” |
tpl | Optional. The code to use for each country dropdown option | |
useIsoCode | If 1, the abbreviation (country code) will be used for the value. If 0, the full name will be used | 1 |
prioritized | Optional. A comma separated list of ISO codes for countries that can be placed in a priority optiongroup at the top of the dropdown. This can be used for frequently selected countries. | |
prioritizedGroupText | Optional. If set and used, &prioritized will add a text label for the option group with priority. |
|
allGroupText | Optional. If set and used, &prioritized will add a text label for the option group for all other countries. |
|
optGroupTpl | Optional. If set and used, &prioritized will use this fragment to mark up the option group. |
optgroup |
toPlaceholder | Optional. Use this to set the output as a placeholder instead of outputting directly. |
Priority Countries
Sometimes you want certain countries to be displayed at the top of the list in an optiongroup
block. FormItCountryOptions supports this with the &prioritized
parameter. For example:
[[!FormItCountryOptions?
&selected=`[[+fi.country]]`
&prioritized=`US,GB,DE,RU,JP,FR,NL,CA,AU,UA`
]]
This will output a list that looks like this:
You simply pass the ISO codes of the countries you want to prioritize in the &prioritized
parameter. You can also customize the optiogroup
text using the &prioritizedGroupText
and &allGroupText
properties.
FormItStateOptions
FormItStateOptions is a helper Snippet for FormIt, since version 1.7.0+, that returns a list of regions. This is useful for forms that need such a list.
Currently, translatable region lists are available for the following countries – United States, France, Netherlands, Germany, Belgium, Sweden, and Canada.
Which list of regions to select is decided based on the value of the system variable cultureKey
, by default – US regions (the value of the key us
).
Usage
Simply add the Snippet to your form inside the <select>
element:
<select name="state">
[[!FormItStateOptions? &selected=`[[!+fi.state]]`]]
</select>
Notice how we pass the value of the placeholder “fi.state” (which stores the value of the state field) to the selected option. This tells FormItStateOptions to select the last selected option in the form.
FormItStateOptions Properties
FormItStateOptions has some default properties that you can override. Here’s what’s there:
Name | Description | Default |
---|---|---|
selected | State/region code to mark as selected | |
selectedAttribute | Optional. HTML attribute to add to the selected state. | selected=”selected” |
tpl | Optional. The code to use for each region dropdown option. | |
useAbbr | If ‘1’ is specified, the abbreviation (region code) will be used for the value. If 0, the full name will be used. | 1 |
toPlaceholder | Optional. Use this to set the output as a placeholder instead of outputting directly. |
Advanced
Handling Dropdowns, Checkboxes, and Radio Buttons
While FormIt can handle any type of field, dropdown selectors, radio buttons, and checkboxes require special instructions due to the nature of their meaning.
Handling Dropdowns
FormIt provides a utility Snippet called FormItIsSelected that can be used as a Output Filter to handle selected values (selected="selected"
). For example:
<select name="color">
<option value="blue" [[!+fi.color:FormItIsSelected=`blue`]] >Blue</option>
<option value="red" [[!+fi.color:FormItIsSelected=`red`]] >Red</option>
<option value="green" [[!+fi.color:FormItIsSelected=`green`]] >Green</option>
<!-- This could also work -->
<option value="yellow" [[!+fi.color:is=`yellow`:then=`selected`]]>Yellow</option>
</select>
This will automatically handle the selected field, remembering it during validation and error handling.
Handling checkboxes and radio buttons
Handling checkboxes and radio buttons is very similar to handling selectors, the only difference is that you are checking for “required” here. FormIt provides a helper output filter FormItIsChecked
, similar to FormItIsSelected
, to handle persistence of values.
This example will process checkboxes and persist their selected values:
<label>Color: [[!+fi.error.color]]</label>
<input type="checkbox" name="color[]" value="blue" [[!+fi.color:FormItIsChecked=`blue`]] > Blue
<input type="checkbox" name="color[]" value="red" [[!+fi.color:FormItIsChecked=`red`]] > Red
<input type="checkbox" name="color[]" value="green" [[!+fi.color:FormItIsChecked=`green`]] > Green
Note that the []
is removed when setting the “fi.error.color” placeholder.
Handling the required attribute on a checkbox
Since HTML does not submit a value unless the checkbox is checked, checking whether a checkbox is required can be tricky. Before doing this, you will need to add a hidden (type = hidden
) field so that at least an empty value is submitted:
[[!FormIt? &validate=`color:required`]] ...
<label>Color: [[!+fi.error.color]]</label>
<input type="hidden" name="color[]" value="" />
<input
type="checkbox"
name="color[]"
value="blue"
[[!+fi.color:FormItIsChecked="`blue`]]"
/>
Blue
<input
type="checkbox"
name="color[]"
value="red"
[[!+fi.color:FormItIsChecked="`red`]]"
/>
Red
<input
type="checkbox"
name="color[]"
value="green"
[[!+fi.color:FormItIsChecked="`green`]]"
/>
Green
This will successfully check that at least one checkbox is checked when the form is submitted.
Handling checkboxes and multi-selector in a custom hook
If you want to set an array field (i.e. a group of checkboxes with the same name or a multi-selector) in a preHook, you need to use json_encode
on the array value.
$hook->setValue('hobbies',json_encode(array('music','films','books')));
Using an empty field to prevent spam
Often, spambots fill in all form fields to pass validation. So, a good way to prevent spam is to add a field to your form and require it to be empty for it to be submitted successfully. You can use the blank
validator to do this, which you can use to add a nospam
field. Example:
<input type="hidden" name="workemail" value="" />
Then in the FormIt call, add a check for empty:
[[!FormIt? &validate=`workemail:blank`]]
If you want to display an error message, you can do so in the normal FormIt syntax (in this example it would be [[+fi.error.workemail]]
).
Make sure you don’t use an existing field name in your form for the nospam
field! This may break FormIt’s processing of your form.
Conclusion
FormIt is a versatile tool for working with forms in MODX. It is highly customizable, supports extensions, and is suitable for most form processing tasks. Using this documentation, you will be able to create and customize forms of any complexity.