Form Events

If you wish to extend the capabilities of Forms in Express Forms, feel free to use any of the events listed below:

Rendering the Opening tag

The EVENT_RENDER_OPENING_TAG event is called when rendering the form's opening tag. By using this hook, you could add more metadata to your forms based on it's parameters. You can even easily add encrypted form metadata to each form.

TIP

Express Forms uses this event to attach a CSRF token to a form.

use Solspace\ExpressForms\models\Form;
use Solspace\ExpressForms\events\forms\FormRenderTagEvent;

Event::on(
    Form::class,
    Form::EVENT_RENDER_OPENING_TAG,
    function (FormRenderTagEvent $event) {
        // Get Craft's configured token name and its current value
        $csrfTokenName = \Craft::$app->config->general->csrfTokenName;
        $csrfToken     = \Craft::$app->request->getCsrfToken();

        // Append it to the output
        $event->appendToOutput('<input type="hidden" name="' . $csrfTokenName . '" value="' . $csrfToken . '" />');

        // !Note: you can also use ::prependToOutput() to put something before the form's opening tag
    }
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

Rendering the Closing tag

The EVENT_RENDER_CLOSING_TAG event is called when rendering the form's closing tag. This is a useful event if you wish to attach some styles or scripts after or before the form's closing tag. You could also perform something after it has fully been rendered on the page.

TIP

Express Forms uses this event to attach reCAPTCHA javascript after the form's closing tag only if reCAPTCHA is enabled and rendered.

use Solspace\ExpressForms\models\Form;
use Solspace\ExpressForms\events\forms\FormRenderTagEvent;
use Solspace\ExpressForms\objects\Form\Recaptcha;

Event::on(
    Form::class,
    Form::EVENT_RENDER_CLOSING_TAG,
    function (FormRenderTagEvent $event) {
        $settings = $this->getSettings();
        if ($settings->recaptchaEnabled && $settings->recaptchaLoadScript) {
            $form = $event->getForm();

            /** @var Recaptcha $recaptcha */
            $recaptcha = $form->getExtraParameters()->get(self::FORM_RECAPTCHA_KEY);
            if ($recaptcha && $recaptcha->isRendered()) {
                $form->getParameters()->add(self::FORM_RECAPTCHA_KEY, true);
                $event->appendToOutput('<script src="https://www.google.com/recaptcha/api.js" async defer></script>');
            }
        }
    }
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

Compiling HTML Form Attributes

The EVENT_COMPILE_HTML_ATTRIBUTES event is called when rendering the form's open tag. This event lets you attach any HTML attributes to the form before the opening tag is compiled.

TIP

Express Forms uses this event to attach an enctype="multipart/form-data" attribute whenever there's a file upload field present.

use Solspace\ExpressForms\models\Form;
use Solspace\ExpressForms\fields\File;
use Solspace\ExpressForms\events\forms\FormCompileTagAttributesEvent;

Event::on(
    Form::class,
    Form::EVENT_COMPILE_HTML_ATTRIBUTES,
    function (FormCompileTagAttributesEvent $event) {
        $form = $event->getForm();
        foreach ($form->getFields() as $field) {
            if ($field instanceof File) {
                $form->getHtmlAttributes()->add('enctype', 'multipart/form-data');

                return;
            }
        }
    }
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

Before a Form is Submitted

The EVENT_BEFORE_SUBMIT event is called right when the form is submitted, but before any validation takes place. Useful for tampering with the submitted data, doing any pre-validation, etc.

use Solspace\ExpressForms\models\Form;
use Solspace\ExpressForms\events\forms\FormSubmitEvent;

Event::on(
    Form::class,
    Form::EVENT_BEFORE_SUBMIT,
    function (FormSubmitEvent $event) {
        $form = $event->getForm();
        $submittedData = $event->getSubmittedData();
        $submittedData['name'] = $submittedData['firstName'] . ' ' . $submittedData['lastName'];

        // Set the modified data back into the event
        $event->setSubmittedData($submittedData);

        // Fail the form for good measure, by adding an error message
        $form->addError('Fail the form just for fun.');

        // Mark it as spam, so that it does not get saved
        $form->markAsSpam();
    }
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

Field Validation

The EVENT_VALIDATE_FIELD event is called right after the form has been submitted for each field that is attached to the form. This might be good for attaching any special validation that your site requires.

TIP

Express Forms uses this event for validating email, required and file upload fields.

use Solspace\ExpressForms\models\Form;
use Solspace\ExpressForms\fields\Email;
use Solspace\ExpressForms\events\fields\FieldValidateEvent;

Event::on(
    Form::class,
    Form::EVENT_VALIDATE_FIELD,
    function (FieldValidateEvent $event) {
        $field = $event->getField();

        if ($field instanceof Email && !empty(trim($field->getValue()))) {
            $value = trim($field->getValue());

            if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
                $field->addValidationError($this->translate('Email address is not valid'));
            }
        }
    }
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

Form Validation

The EVENT_VALIDATE_FORM event is called right after the form has been submitted and all of its fields have run through their validation processes. Useful for adding any error messages for the whole form, if the form meets some criteria that should prevent it from validating.

TIP

Express Forms uses this event for validating Honeypot and reCAPTCHA spam protection inputs.

use Solspace\ExpressForms\ExpressForms;
use Solspace\ExpressForms\models\Form;
use Solspace\ExpressForms\services\Honeypot;
use Solspace\ExpressForms\events\forms\FormValidateEvent;

Event::on(
    Form::class,
    Form::EVENT_VALIDATE_FORM,
    function (FormValidateEvent $event) {
        $settings = ExpressForms::getInstance()->getSettings();
        if (!$settings->honeypotEnabled) {
            return;
        }

        $honeypotName = $settings->honeypotInputName;
        $behaviour    = $settings->honeypotBehaviour;

        $form = $event->getForm();

        if (!empty($this->request->post($honeypotName))) {
            $form->markAsSpam();

            if ($behaviour === Honeypot::BEHAVIOUR_SHOW_ERRORS) {
                $form->addError('Form has triggered spam control');
            }
        }
    }
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

After Form Submits

The EVENT_AFTER_SUBMIT event is called after the form has been submitted and all of the validation has taken place.

TIP

Express Forms uses this event to move any uploaded files to their respective Craft Asset Volumes.

use Solspace\ExpressForms\models\Form;
use Solspace\ExpressForms\fields\File;
use Solspace\ExpressForms\events\forms\FormSubmitEvent;

Event::on(
    Form::class,
    Form::EVENT_AFTER_SUBMIT,
    function (FormSubmitEvent $event) {
        $form = $event->getForm();

        if ($form->isSuccess()) {
            foreach ($form->getFields() as $field) {
                if (!$field instanceof File) {
                    continue;
                }

                if ($field->isValid()) {
                    $field->setValue($this->fileUploadProvider->upload($field));
                }
            }
        }
    }
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

When Form has Completed Fully

The EVENT_FORM_COMPLETED event happens when the form has finished validating, is successful, and has built and stored (if enabled) the submission. This event is valuable for doing something after the form has fully completed successfully.

TIP

Express Forms uses this event to implement the Dynamic Recipients and Dynamic Notifications functionality.

use Solspace\ExpressForms\controllers\SubmitController;
use Solspace\ExpressForms\events\forms\FormCompletedEvent;

Event::on(
    SubmitController::class,
    SubmitController::EVENT_AFTER_SUBMIT,
    function (FormCompletedEvent $event) {
        $form              = $event->getForm();
        $dynamicRecipients = $form->getParameters()->get('dynamicRecipients');

        if (null === $dynamicRecipients) {
            return;
        }

        foreach ($dynamicRecipients as $fieldHandle => $data) {
            // Collect data here, parse it
            // Send an email notification
        }
    }
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

When the Form is Ready for Being Redirected

The EVENT_REDIRECT event is called after the EVENT_FORM_COMPLETED event, letting others determine where to redirect the form afterwards, if at all.

TIP

Express Forms uses this event to implement the Return URL functionality.

use Solspace\ExpressForms\controllers\SubmitController;
use Solspace\ExpressForms\events\forms\FormRedirectEvent;

Event::on(
    SubmitController::class,
    SubmitController::EVENT_REDIRECT,
    function (FormRedirectEvent $event) {
        $returnUrl = $event->getForm()->getParameters()->get('return');
        if ($returnUrl) {
            $event->setRedirectUrl($returnUrl);
        }
    }
);
1
2
3
4
5
6
7
8
9
10
11
12
13

When the Form Fails

The EVENT_FORM_INVALID event gets called if the form did not successfully submit. This could happen if it had any errors or if any of the fields had any errors. One might use this to collect data on failed forms.

use Solspace\ExpressForms\controllers\SubmitController;
use Solspace\ExpressForms\events\forms\FormInvalidEvent;

Event::on(
    SubmitController::class,
    SubmitController::EVENT_FORM_INVALID,
    function (FormInvalidEvent $event) {
        $form = $event->getForm();
        $postData = $event->getPostData();

        // Do something with the data..
    }
);
1
2
3
4
5
6
7
8
9
10
11
12
13

When Populating a Form from Array Data

Before Building the Form Model

The EVENT_BEFORE_BUILD_FROM_ARRAY event happens when the form is being built -- usually from the database.

TIP

This is a cancelable event, so you could cancel the form building process if needed.

use Solspace\ExpressForms\factories\FormFactory;
use Solspace\ExpressForms\events\forms\FormBuildFromArrayEvent;

Event::on(
    FormFactory::class,
    FormFactory::EVENT_BEFORE_BUILD_FROM_ARRAY,
    function (FormBuildFromArrayEvent $event) {
        // Override all form names, just for kicks.
        $formData = $event->getData();
        $formData['name'] = 'A static form name';

        $event->setData($formData);
    }
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14

After Building the Form Model

The EVENT_AFTER_BUILD_FROM_ARRAY event is fired after the form is built and before it's returned.

TIP

This is a cancelable event, so you could cancel the form building process if needed.

use Solspace\ExpressForms\factories\FormFactory;
use Solspace\ExpressForms\events\forms\FormBuildFromArrayEvent;

Event::on(
    FormFactory::class,
    FormFactory::EVENT_AFTER_BUILD_FROM_ARRAY,
    function (FormBuildFromArrayEvent $event) {
        $form = $event->getForm();

        // Do something here...
    }
);
1
2
3
4
5
6
7
8
9
10
11
12
Last Updated: 4/23/2019, 10:35:37 AM