EasyForm is a MODX extra which provides basic form handling functionalities using Illuminate Validation
to handle the form validation which provides lots of default validation rules and you can easily provide custom error messages or create your own custom validator rules.
The Fenom parser provided by pdoTools is required in order to work with EasyForm.
More information about validation and all the, by default, built in validation rules please read the validation section from Laravel.
- pdoTools: pdoTools is required due to the Fenom parser it provides.
- File driven: Designed to work using PHP classes and file based chunks.
- Utilizes Illuminate validation which includes lots of default validation rules.
- Comes with useful default plugins
- Add Recaptcha plugin
- Add default login/registration plugins
The following plugins are included by default.
Plugin | Description |
---|---|
Use this plugin to send an email once the form has been submitted. | |
AutoResponder | Use this plugin to send an email once the form has been submitted. Works exactly the same as the Email plugin which it's extends. |
Redirect | Redirect the user after form submission by providing a resource id or URL. |
Create a plugin class that extends the BasePlugin class and make sure it's loaded by the snippet by adding the path to the scriptproperties.
{set $form = '!EasyForm' | snippet : [
'pluginPaths' => [
'{base_path}/customplugins/',
'{core_path}/customplugins/',
'{assets_path}/customplugins/'
],
'plugins' => [
'Redirect' => [
'to' => 2
],
'SomePlugin' => []
],
'submitVar' => 'submitvar',
'rules' => [
'name' => ['required'],
'email' => ['required', 'email']
]
]}
<?php
use Sterc\EasyForm\Plugins\BasePlugin;
class SomePlugin extends BasePlugin
{
public function onInitForm($form, $properties)
{
$form->request->set('name', 'some value');
return true;
}
}
The following plugin events are available.
Event | Description |
---|---|
onInitForm | Trigged while initialising the form, before rendering it. Can be used for pre-form validation or for setting form values before the form is loaded. |
onFormSubmitted | Triggered once form is submitted and validation has been passed. |
Adding your own custom validation rules can be done by creating a new class which implements the Rule
class:
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class Uppercase implements Rule
{
/**
* Determine if the validation rule passes.
*
* @param string $attribute
* @param mixed $value
* @return bool
*/
public function passes($attribute, $value)
{
return strtoupper($value) === $value;
}
/**
* Get the validation error message.
*
* @return string
*/
public function message()
{
return 'The :attribute must be uppercase.';
}
}
Then add the path where your rule class lives into the rulePaths array and the rule to the field you'd like to validate by defining the fully classified class name as a string, like so: 'new App\Rules\Uppercase'
.
{set $form = '!EasyForm' | snippet : [
'rulePaths' => [
'{base_path}/customrules/',
',
'rules' => [
'name' => ['required', 'new App\Rules\Uppercase'],
]
],
Please view this extensive example for all possible properties and usage:
{set $form = '!EasyForm' | snippet : [
'pluginPaths' => [
'{base_path}/customplugins/'
],
'rulePaths' => [
'{base_path}/customrules/'
],
'plugins' => [
'Email' => [
'tpl' => '@FILE email.tpl',
'to' => ['email' => '[email protected]', 'name' => 'John Doe To'],
'from' => ['email' => '[email protected]', 'name' => 'John Doe'],
'reply-to' => ['email' => '[email protected]', 'name' => 'John Doe Reply'],
'cc' => [
['email' => '[email protected]', 'name' => 'John Doe CC'],
['email' => '[email protected]', 'name' => 'John Doe CC2'],
['email' => '[email protected]']
],
'bcc' => ['email' => '[email protected]', 'name' => 'John Doe BCC'],
'html' => true,
'convertNewlines' => true,
'subject' => 'My subject - [[+name]] {$name}',
// 'subjectField' => 'topic', Can be used instead of subject in order to make a dynamic subject based on specified form field value.
'multiWrapper' => 'Before {$values} After',
'multiSeparator' => ', ',
'selectEmailToAddresses' => [
['email' => '[email protected]', 'name' => 'John Doe Receiver 1'],
['email' => '[email protected]', 'name' => 'John Doe Receiver 2'],
]
'selectEmailToField' => 'receiver',
'attachments' => [
'{base_path}/uploads/fallback.png',
'{base_path}/uploads/background.jpg'
],
'attachFilesToEmail' => true
],
'AutoResponder' => [
'tpl' => '@FILE email.tpl',
'to' => ['email' => '[email protected]', 'name' => 'John Doe To'],
'from' => ['email' => '[email protected]', 'name' => 'John Doe'],
'subject' => 'Autoresponder - [[+name]] {$name}',
'attachFilesToEmail' => true
],
'Redirect' => [
'to' => 'https://www.google.com?',
'scheme' => 'full',
'params' => [
'test' => 1,
'success' => 'value'
]
]
],
'submitVar' => 'submitvar',
'rules' => [
'name' => ['required', 'new App\Rules\Uppercase'],
'name2' =>['required', 'same:name'],
'topic' => ['required'],
'email' => ['required', 'email']
],
'messages' => [
'required' => 'This is a mandatory message field that overrides the default message.',
'name.required' => '":attribute" is a required field with a custom error message.'
]
]}
<form action="{$_modx->resource.id | url}" method="post" enctype="multipart/form-data" novalidate>
<input type="hidden" name="submitvar" value="submitted"/>
<div class="input-group mb-3">
<input type="text" class="form-control {$form->getError('name') ? 'is-invalid' : ''}" name="name" placeholder="Name" value="{$form->getValue('name')}"/>
{if $form->getError('name')}
<div class="invalid-feedback">{$form->getError('name')}</div>
{/if}
</div>
<div class="input-group mb-3">
<input type="text" class="form-control {$form->getError('name2') ? 'is-invalid' : ''}" name="name2" placeholder="Name2" value="{$form->getValue('name2')}"/>
{if $form->getError('name2')}
<div class="invalid-feedback">{$form->getError('name2')}</div>
{/if}
</div>
<div class="input-group mb-3">
<select class="form-control {$form->getError('topic') ? 'is-invalid' : ''}" name="topic" placeholder="Topic">
<option value=""></option>
<option value="General" {$form->getValue('topic') === 'General' ? 'selected' : ''}>General</option>
<option value="Sales" {$form->getValue('topic') === 'Sales' ? 'selected' : ''}>Sales</option>
</select>
{if $form->getError('topic')}
<div class="invalid-feedback">{$form->getError('topic')}</div>
{/if}
</div>
<div class="input-group mb-3">
<select class="form-control {$form->getError('receiver') ? 'is-invalid' : ''}" name="receiver" placeholder="Receiver">
<option value=""></option>
<option value="1" {$form->getValue('receiver') === '[email protected]' ? 'selected' : ''}>[email protected]</option>
<option value="2" {$form->getValue('receiver') === '[email protected]' ? 'selected' : ''}>[email protected]</option>
</select>
{if $form->getError('receiver')}
<div class="invalid-feedback">{$form->getError('receiver')}</div>
{/if}
</div>
<div class="input-group mb-3">
<select class="form-control {$form->getError('brands') ? 'is-invalid' : ''}" name="brands[]" placeholder="Brands" multiple>
<option value=""></option>
<option value="Audi" {$form->isSelected('brands', 'Audi') ? 'selected' : ''}>Audi</option>
<option value="BMW" {$form->isSelected('brands', 'BMW') ? 'selected' : ''}>BMW</option>
</select>
{if $form->getError('topic')}
<div class="invalid-feedback">{$form->getError('topic')}</div>
{/if}
</div>
<div class="input-group mb-3">
<div class="form-check">
<input class="form-check-input" name="interests[]" type="checkbox" value="Cars" id="cars" {$form->isSelected('interests', 'Cars') ? 'checked' : ''}>
<label class="form-check-label" for="cars">
Cars
</label>
</div>
<div class="form-check">
<input class="form-check-input" name="interests[]" type="checkbox" value="Games" id="games" {$form->isSelected('interests', 'Games') ? 'checked' : ''}>
<label class="form-check-label" for="games">
Games
</label>
</div>
</div>
<input type="file" id="testfile" name="filename">
<div class="input-group mb-3">
<input type="email" class="form-control {$form->getError('email') ? 'is-invalid' : ''}" name="email" placeholder="Email" value="{$form->getValue('email')}"/>
{if $form->getError('email')}
<div class="invalid-feedback">{$form->getError('email')}</div>
{/if}
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
{if $form->isSubmitted() && $form->hasErrors()}
<p>Form has errors.</p>
{/if}
Script to convert laravel-lang validation messages to MODX lexicon file
$array contains the laravel-lang validation messages array from https://github.com/overtrue/laravel-lang.
$output = [];
foreach ($array as $key => $value) {
if (!is_array($value)) {
$output[] = '$_lang[\'' . $key . '\'] = \'' . addslashes($value) . '\';';
} else {
foreach ($value as $childKey => $childValue) {
$output[] = '$_lang[\'' . $key . ':' . $childKey . '\'] = \'' . addslashes($childValue) . '\';';
}
}
}
var_dump(implode('<br/>', $output));
exit;