Freeform Documentation

Learn the basics, and get to know Freeform inside and out.

Freeform 1.x Docs

Form object

The Form object contains its metadata and field objects. You can either render the form using the pre-selected formatting template by calling form.render() or achieve a more fine-grained control over it by iterating over its rows and fields and using form.renderTag and form.renderClosingTag methods.

Watch Tutorial VideoWatch the Rendering a Freeform Form Manually tutorial on CraftQuest!

NOTE: Freeform will automatically insert javascript in the footer of the page for features such as Spam Protection, Submit disable on click, and other special fieldtypes. If you prefer to have this load inside the <form></form> tags, you can adjust the Freeform Javascript Insertion Location setting.

Properties #

  • name #
    • Outputs the name of the form.
  • handle #
    • Outputs the handle of the form.
  • id #
    • Outputs the unique ID of the form.
  • description #
    • Outputs the description of the form.
  • submissionTitleFormat #
    • Outputs the submissionTitleFormat used when creating new submissions based on this form.
  • returnUrl #
    • Outputs the returnUrl of the form.
  • hasErrors #
    • A bool variable, which will be true if there are any errors in any of the fields or the form.
    • Might be true even if form.errors list is empty, (e.g. if one or more fields have an error).
    • Can be used in conjunction with the Errors object for displaying special and general errors.
  • pages #
    • Returns a list of Page objects each containing its label and index.
  • currentPage #
    • Returns the current Page object containing its label and index.
  • Custom Attributes #
    • The following properties are available to ease the customizability of field rendering if set as parameters (each one is null if not set):
      • id #
        • The ID attribute of the HTML form tag.
      • class #
        • The CLASS attribute of the HTML form tag.
      • method #
        • The METHOD attribute for the form tag.
      • action #
        • The ACTION attribute for the form tag.
      • status #
        • The status ID or Handle.
      • returnUrl #
        • Allows overriding the return URL of the form upon successful submit.
      • rowClass #
        • The CLASS attribute of all HTML row tags.
      • columnClass #
        • The CLASS attribute of all HTML column tags.
      • submitClass #
        • The CLASS attribute of submit field input elements.
      • inputClass #
        • The CLASS attribute of all HTML input fields.
      • labelClass #
        • The CLASS attribute of all HTML label fields.
      • errorClass #
        • The CLASS attribute of all HTML error lists.
      • instructionsClass #
        • The CLASS attribute of all instruction fields.
      • instructionsBelowField #
        • A boolean value. Set to true to render instructions below, not above the input field.
      • overrideValues #
        • An object of override values for any field's defaultValue in case you need a context specific default value. Examples provided below...
      • formAttributes #
        • An object of attributes which will be added to the form.
        • Ex: formAttributes: { "novalidate": true, "data-form-id": "test" }
      • inputAttributes #
        • An object of attributes which will be added to all input fields.
        • Ex: inputAttributes: { "readonly": true, "data-field-id": "test" }
      • useRequiredAttribute: true #
        • Adds required attribute to input fields that have been set to be required in Composer.

When iterating over the form, you will iterate through Row objects for the currently active Page, each Row can be iterated over to get Field objects. Check the Field documentation to see available parameters for those objects.

Usage in Templates #

Render the form using its formatting template:

{{ form.render() }}

Render the form using its formatting template, but overriding some classes and default values:

{{ form.render({
    labelClass: "form-label",
    inputClass: "form-control",
    instructionsBelowField: true,
    submitClass: "btn btn-success",
    overrideValues: {
        hiddenFieldHandle: entry.id,
        stateSelect: "AZ",
    },
    formAttributes: {
       "novalidate": true,
       "data-form-id": "whatever",
    },
    inputAttributes: {
       "readonly": true,
       "data-field-id": field.id,
    }
}) }}

Manually iterate through form fields:

{{ form.renderTag({rowClass: "sample-row-class"}) }}

{% if form.hasErrors %}
    <div class="freeform-form-has-errors">
        {{ "Error! Please review the form and try submitting again."|t('freeform') }}

        {% if form.errors|length %}
            <ul>
                {% for error in form.errors %}
                    <li>{{ error }}</li>
                {% endfor %}
            </ul>
        {% endif %}
    </div>
{% endif %}

{% for row in form %}
    <div class="{{ form.customAttributes.rowClass }}">
        {% for field in row %}
            {% set columnClass = "sample-column " ~ form.customAttributes.columnClass %}
            {% if field.type == "submit" %}
                {% set columnClass = columnClass ~ " submit-column" %}
            {% endif %}

            <div class="{{ columnClass }}">
                {{ field.render({
                    class: field.type != "submit" ? "freeform-input" : "",
                    labelClass: "sample-label" ~ (field.required ? " required" : ""),
                    errorClass: "sample-errors",
                    instructionsClass: "sample-instructions",
                }) }}
            </div>
        {% endfor %}
    </div>
{% endfor %}

{{ form.renderClosingTag }}

Use session success flash message variable (displays only once) for when form is successfully submitted:

{% set form = craft.freeform.form("composerForm") %}

{% if form.submittedSuccessfully %}
    <div>You've successfully submitted this form!</div>
{% endif %}

{{ form.render }}