In this article we will cover how Fluent Forms submission Life-cycle happens under the hood. From submit button click to get confirmation message.
If you are an advanced user open the file app/Modules/Form/FormHandler.php file and check the onSubmit() method to see the full implementation.
The following steps completed one by one
In this step, Fluent Forms set-up the form data, available inputs and submitted data from the browser. No major hooks fired in this step.
// Parse the url encoded data from the request object. parse_str($this->app->request->get('data'), $data); // Merge it back again to the request object. $this->app->request->merge(['data' => $data]); $formId = intval($this->app->request->get('form_id')); $this->setForm($formId); // Parse the form and get the flat inputs with validations. $fields = FormFieldsParser::getInputs($this->form, ['rules', 'raw']); // Sanitize the data properly. $this->formData = fluentFormSanitizer($data, null, $fields);
In this step, Fluent Forms validate the submitted the data. If there has any error or validation failed then it send error response to client with in details errors object as JSON.
private function validate(&$fields) { // Validate the form restrictions $this->validateRestrictions($fields); // Validate the form nonce. By default it does not verify as many people use caching $this->validateNonce(); // If recaptcha enabled then it verify it. $this->validateReCaptcha(); // Validate the required fields and offer each element to do their own validation. // Please check the source code to get elements level validation filter hook. }
In this step Fluent Forms prepare the data to insert in the database. You can use the following hooks to alter/format the data as per your need.
Please check the corresponding filter hook doc for more information and their structure.
In this step Fluent Forms provide action hook before insert data, insert the data and as well as after submission hook. It’s an important hook for developers to do extended validations and post custom integrations.
Before Insert Action Hook: fluentform_before_insert_submission
After Insert Action Hook: fluentform_submission_inserted
If you want to do extended validation please use the fluentform_before_insert_submission hook. Check the corresponding hook documentation for more details.
This is the final step as everything is done and all the integrations and notifications being processed. Fluent Forms finds the appropriate confirmation and send response accordingly. You can use fluentform_submission_confirmation filter to alter the confirmation programatically.
The hooks are fired as bellow (Step by Step)
When you click the submit button the following steps completed as step by step
var $inputs = $formSubmission .find(':input').filter(function (i, el) { return !$(el).closest('.has-conditions').hasClass('ff_excluded'); }); validate($inputs); var formData = { data: $inputs.serialize(), action: 'fluentform_submit', form_id: $formSubmission.data('form_id') }; $(formSelector + '_success').remove(); $(formSelector + '_errors').html(''); $formSubmission.find('.error').html(''); $formSubmission .find('.ff-btn-submit') .addClass('disabled') .attr('disabled', 'disabled') .parent() .append('<div class="ff-loading"></div>'); $.post(fluentFormVars.ajaxUrl, formData) .then(function (res) { $theForm.trigger('fluentform_submission_success', { form: $theForm, response: res }); if ('redirectUrl' in res.data.result) { if (res.data.result.message) { $('<div/>', { 'id': formId + '_success', 'class': 'ff-message-success' }) .html(res.data.result.message) .insertAfter($theForm); $theForm.find('.ff-el-is-error').removeClass('ff-el-is-error'); } location.href = res.data.result.redirectUrl; return; } else { $('<div/>', { 'id': formId + '_success', 'class': 'ff-message-success' }) .html(res.data.result.message) .insertAfter($theForm); $theForm.find('.ff-el-is-error').removeClass('ff-el-is-error'); if (res.data.result.action == 'hide_form') { $theForm.hide(); } else { $theForm[0].reset(); } } }) .fail(function (res) { $theForm.trigger('fluentform_submission_failed', { form: $formSubmission, response: res }); showErrorMessages(res.responseJSON.errors); scrollToFirstError(350); if ($theForm.find('.fluentform-step').length) { var step = $theForm .find('.error') .not(':empty:first') .closest('.fluentform-step'); let goBackToStep = step.index(); updateSlider(goBackToStep, 350, false); } }) .always(function (res) { $formSubmission .find('.ff-btn-submit') .removeClass('disabled') .attr('disabled', false) .siblings('.ff-loading') .remove(); // reset reCaptcha if available. if (window.grecaptcha) { grecaptcha.reset( getRecaptchaClientId(formData.form_id) ); } });
Powered by BetterDocs