AJAX Forms with Freeform

Welcome to the guide for submitting your forms using AJAX. The good news is that we've made it easy to plug and play!

Overview

Freeform has its own built-in automated AJAX support. To enable it, simply check the Enable AJAX checkbox in the Form Settings tab inside Composer and Freeform will then handle the rest. Freeform includes its own javascript plugin which handles AJAX functionality and all other JS needed (such as Date fields, Stripe payments and more). Much of the default functionality (formatting, language, etc) can be overridden if necessary. See customization reference guide below.

TIP

Be sure to check out the Freeform Javascript plugin documentation, to learn how to further extend Freeform's functionality.

WARNING

AJAX currently will not work with multi-page forms.

Customization

The built-in AJAX functionality lets you completely customize the way your forms work if you're not satisfied with anything in the provided defaults. If you only need to customize the error messages, you can do so by overriding the defaults like this:

// Find the form element
const form = document.getElementById('#my-form');

// Attach an on-ready listener
// Be sure to do load this script before freeform JS initiates
form.addEventListener('freeform-ready', function(event) {
  const freeform = event.target.freeform;

  // Customize the error and success messages
  freeform.setOption('successBannerMessage', 'My custom success message');
  freeform.setOption('errorBannerMessage', 'My custom error message');
});
1
2
3
4
5
6
7
8
9
10
11
12

A more elaborate example below shows how you can customize the way error and success messages are rendered:

// Find the form element
const form = document.getElementById('#my-form');

// Attach on-ready listener
// Be sure to do load this script before freeform JS initiates
form.addEventListener('freeform-ready', function(event) {
  const freeform = event.target.freeform;

  // Override the error and success message element class names
  freeform.setOption('errorClassBanner', 'my-custom-error-banner');
  freeform.setOption('errorClassList', 'my-custom-errors-list');
  freeform.setOption('errorClassField', 'this-field-has-errors');
  freeform.setOption('successClassBanner', 'my-custom-success-banner');

  // Override the way those messages are removed
  freeform.setOption('removeMessages', function() {
    this.form.querySelectorAll('.my-custom-error-banner').remove();
    this.form.querySelectorAll('.my-custom-success-banner').remove();
    this.form.querySelectorAll('.my-custom-errors-list').remove();
  });

  // Override the way form submit success message is displayed
  freeform.setOption('renderSuccess', function() {
    const successMessage = document.createElement("div");
    successMessage.classList.add("my-custom-success-banner");
    successMessage.appendChild(document.createTextNode("Form submitted successfully"));

    this.form.insertBefore(successMessage, this.form.childNodes[0]);
  });

  // Override the way form errors are displayed
  freeform.setOption('renderFormErrors', function(errors) {
    const errorBlock = document.createElement("div");
    errorBlock.classList.add("my-custom-errors-banner");

    const paragraph = document.createElement("p");
    paragraph.appendChild(document.createTextNode("Form contains errors!"));
    errorBlock.appendChild(paragraph);

    if (errors.length) {
      const errorsList = document.createElement("ul");
      for (let messageIndex = 0; messageIndex < errors.length; messageIndex++) {
        const message = errors[messageIndex];
        const listItem = document.createElement("li");

        listItem.appendChild(document.createTextNode(message));
        errorsList.appendChild(listItem);
      }

      errorBlock.appendChild(errorsList);
    }

    this.form.insertBefore(errorBlock, this.form.childNodes[0]);
  });

  // Override the way field errors are displayed
  freeform.setOption('renderFieldErrors', function(errors) {
    for (const key in errors) {
      if (!errors.hasOwnProperty(key) || !key) {
        continue;
      }

      const messages = errors[key];
      const errorsList = document.createElement("ul");
      errorsList.classList.add("my-custom-errors-list");

      for (let messageIndex = 0; messageIndex < messages.length; messageIndex++) {
        const message = messages[messageIndex];
        const listItem = document.createElement("li");
        listItem.appendChild(document.createTextNode(message));
        errorsList.appendChild(listItem);
      }

      const inputList = this.form.querySelectorAll("*[name=" + key + "], *[name='" + key + "[]']");
      for (let inputIndex = 0; inputIndex < inputList.length; inputIndex++) {
        const input = inputList[inputIndex];
        input.classList.add("this-field-has-errors");
        input.parentElement.appendChild(errorsList);
      }
    }
  });
});
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82

Advanced

To attach your own functionality when the AJAX form successfully submits or fails, you have to register your callbacks in the Freeform JS plugin. For instance, redirecting after an AJAX submit is finished:

// Find the form element
const form = document.getElementById('#my-form');

// Attach on-ready listener
// Be sure to do load this script before freeform JS initiates
form.addEventListener('freeform-ready', function(event) {
  const freeform = event.target.freeform;

  // Do something on a successful ajax submit
  freeform.addOnSuccessfulAjaxSubmit(function(event, form, response) {
    // Redirect the user
    window.location.href = response.returnUrl;
  })

  // Do something on a failed ajax submit
  freeform.addOnFailedAjaxSubmit(function(event, form, response) {
    // Do whatever checks on errors you need to do, if any
    var errors = response.errors;

    // Redirect the page using the response's return URL
    window.location.href = response.returnUrl;
  })

  // Do something after every ajax submit is completed, regardless of it being successful or not
  freeform.addOnAfterAjaxSubmit(function(event, form, response) {
    // Redirect the page using the response's return URL
    window.location.href = response.returnUrl;
  })
});
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
29
Last Updated: 6/19/2019, 8:20:57 PM