Skip to main content

Submitting a form using AJAX

To submit a form using AJAX - pass the serialized form data as the payload when posting to any front-end URL.

This solution currently will not work with multi-page forms.

Return values

The AJAX request must be a post request and it will return a JSON object with the following values:

On successful single-page form post

  • success - A boolean value of true
  • finished - A boolean value of true
  • returnUrl - The return URL specified for the form
  • submissionId - An int value of the submission ID if one was generated

On form error

  • success - A boolean value of false
  • finished - A boolean value of false
  • errors - An object of field handles as keys and each containing an array of error messages.
    • An example, if the form's firstName and lastName fields were required, but not filled out, the returning object would be:
"errors": {
"firstName": ["This field is required"],
"lastName": ["This field is required"]
}

Usage in Templates

Here's a fully working Bootstrap form AJAX example:

<script>
var form = document.getElementById('my-form');
form.addEventListener('submit', function (event) {
let data = new FormData(form);
let request = new XMLHttpRequest();

// Safari hack - remove empty file upload inputs
// Otherwise an ajax call with empty file uploads causes immense lag
if (navigator.userAgent.indexOf('Safari') > -1) {
for (let i = 0; i < form.elements.length; i++) {
if (form.elements[i].type === 'file') {
if (form.elements[i].value === '') {
var elem = form.elements[i];
data.delete(elem.name);
}
}
}
}

var method = form.getAttribute('method');
var action = form.getAttribute('action');

request.open(method, action ? action : window.location.href, true);
request.setRequestHeader('Cache-Control', 'no-cache');

// Set the AJAX headers
request.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
request.setRequestHeader('HTTP_X_REQUESTED_WITH', 'XMLHttpRequest');

request.onload = () => {
if (request.status === 200) {
var response = JSON.parse(request.response);
var success = response.success;
var finished = response.finished;
var actions = response.actions ? response.actions : [];
var errors = response.errors;
var formErrors = response.formErrors;
var honeypot = response.honeypot;

if (!actions.length) {
if (success && finished) {
// Reset the form so that the user may enter fresh information
form.reset();

// ==================================
// Perform something after the
// form saves successfully
// ==================================
} else if (errors || formErrors) {
// ==================================
// Do something with the errors here
// ==================================

console.error(errors, formErrors);
}
}

// ==================================
// Honeypot update logic
// ==================================
if (honeypot) {
var honeypotInput = form.querySelector(
'input[name^=freeform_form_handle]'
);
if (honeypotInput) {
honeypotInput.setAttribute('name', honeypot.name);
honeypotInput.setAttribute('id', honeypot.name);
honeypotInput.value = honeypot.hash;
}
}
} else {
console.error(request);
}
};

request.send(data);

event.stopPropagation();
event.preventDefault();
return false;
});
</script>