A newer version of

Freeform

is available.

Try Freeform 5 now →

Templating

Submissions Queries

The Submissions query fetches a list of submissions based on some or no criteria.

Submissions

User Guide:

Need to display the total number of submissions for the form?

Parameters

The following parameters are available for use:

id

An ID of a submission, or array of ID's, e.g. [54, 62, 68].

form

Handle of the form, e.g. "myForm".

formId

An ID of the form, e.g. 2.

limit

Supply an int to limit the amount of submissions returned.

orderBy

Use any field handle to order by that value and include the ASC or DESC parameter in the string, e.g. orderBy: "firstName ASC" or orderBy: "rand()".

status

Specify status to fetch submissions with a certain status, e.g .status: "open" if you have a status with a handle open.

token

Specify a token to more securely fetch a specific submission. A common use-case would be when you want to display submission data in a success page, by loading the newly created token in the return URL. Can be used in conjunction with or in place of id.

fieldSearch

Specify an object of field handles as keys and search parameters as values to search the submissions that contain specific field values.

  • Please use the original field handle name for searches, e.g. if you reused a field named firstName and renamed it to just name, make sure your search query uses firstName.
  • You can use a wildcard * to search for values that contain different values. For example *car or doc*.
  • When searching on fields that store data as arrays, please wrap wildcards (*) around the values, e.g. candy: "*licorice*".
  • See searching example below.

Usage in Templates

Simple List

Display a simple list of submissions:

{% set submissions = craft.freeform.submissions({
  orderBy: "firstName ASC, lastName DESC",
  status: ["pending", "closed"],
}) %}

<ul>
{% for submission in submissions %}
  <li>{{ submission.title }} - {{ submission.firstName }}</li>
{% endfor %}
</ul>
1
2
3
4
5
6
7
8
9
10

Check if Fields Exist

Display all submissions and check if fields exist for the submitted form, before displaying them:

{% set submissions = craft.freeform.submissions({
  orderBy: "firstName ASC, lastName DESC",
  status: ["pending", "closed"],
}) %}

{% for submission in submissions %}
  <div>
    <div>{{ submission.title }} - {{ submission.form.name }}</div>

    {% if submission.firstName is not null %}
      {{ submission.firstName.label }}: {{ submission.firstName }}<br>
    {% endif %}

    {% if submission.lastName is not null %}
      {{ submission.lastName.label }}: {{ submission.lastName }}<br>
    {% endif %}
  </div>
{% endfor %}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

Pagination

To paginate submissions, use Craft's Pagination. Here's an example:

{% paginate craft.freeform.submissions({limit: 5}) as pageInfo, submissions %}

{% for submission in submissions %}
  <div>
    <div>{{ submission.title }} - {{ submission.form.name }}</div>
  </div>
{% endfor %}

{% if pageInfo.prevUrl %}
  <a href="{{ pageInfo.prevUrl }}">Previous Page</a>
{% endif %}
{% if pageInfo.nextUrl %}
  <a href="{{ pageInfo.nextUrl }}">Next Page</a>
{% endif %}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

Single Submission

To display a single submission (see Submission object for more info):

{% set submissionId = craft.app.request.segment(5) %}
{% set submission = craft.freeform.submissions({id: submissionId}).one() %}

{% if submission %}
  {% set form = submission.form %}

  <h3>{{ form.name }} - {{ submission.title }}</h3>

  <table class="table table-striped">
    {% for field in submission %}
      <tr>
        <th style="width: 20%;">{{ field.label ? field.label : "no-label" }}</th>
        <td>
          {% set fieldValue = submission[field.handle].value %}
          {% if fieldValue is iterable %}
            <ul>
              {% for value in fieldValue %}
                <li>{{ value }}</li>
              {% endfor %}
            </ul>
          {% else %}
            {{ fieldValue }}
          {% endif %}
        </td>
      </tr>
    {% endfor %}
  </table>

{% else %}

  <div class="alert alert-danger">
    <p class="lead">
      Sorry, no submission was found.
    </p>
  </div>

{% endif %}
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

Display Uploaded Assets

The following is an example that shows how to render uploaded Assets in your form submissions:

{% set formHandle = 'yourFormHandle' %}
{% set submissions = craft.freeform.submissions({
  form: formHandle,
}) %}

<h3>Submissions for {{ form.name }}</h3>

{% if submissions is empty %}
  <div>There are no submissions</div>
{% else %}
  <table class="table">
    <thead>
      <tr>
        <th>#</th>
        <th>Title</th>
        {% for field in (submissions|first) %}
          <th>{{ field.label }}</th>
        {% endfor %}
      </tr>
    </thead>
    <tbody>
    {% for submission in submissions %}
      <tr>
        <td>{{ submission.id }}</td>
        <td>
          <a href="{{ siteUrl }}freeform_demo/bootstrap/{{ form.handle }}/submissions/{{ submission.id }}">
            {{ submission.title }}
          </a>
        </td>
        {% for field in submission %}
          <td>
            {% if field.type == "file" %}
              {% set assetId = submission[field.handle] %}
              {% set asset = craft.assets.id(assetId).one() %}
              {% if asset %}
                {% if asset.kind == "image" %}
                  <img src="{{ asset.url }}" />
                {% else %}
                  <a href="{{ asset.url }}">{{ asset.filename }}</a>
                {% endif %}
              {% endif %}
            {% else %}
              {{ submission[field.handle] }}
            {% endif %}
          </td>
        {% endfor %}
      </tr>
    {% endfor %}
    </tbody>
  </table>
{% endif %}
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

Loop Through Field Options

If you wish to loop through multi-option fields such as Selects, Checkbox Groups, Radios, etc, to show all options and then highlight which options were selected, you can use submission[field.handle].options to loop through the values and option.checked to indicate which options were selected.

<ul>
{% for option in submission[field.handle].options %}
    <li{% if option.checked %} class="selected"{% endif %}>{{ option.value }}</li>
{% endfor %}
</ul>
1
2
3
4
5

If you wish to omit the empty options, you can do something like this instead:

{#
    Create empty array
    Add the checked items to array
    Only show field label and values if array|length
#}
{% set opts = [] %}
{% for option in item[field.handle].options %}
    {% if option.checked %}{% set opts = opts|merge([option.value]) %}{% endif %}
{% endfor %}
{% if opts|length %}
    {{ field.label }}:
    {% for key in opts %}{{ key }}, {% endfor %}
{% endif %}
1
2
3
4
5
6
7
8
9
10
11
12
13

Searching Submissions

Only select submissions that have Bill as the first name and has their favorite food end with pie.




 
 
 
 








{% set submissions = craft.freeform.submissions({
  orderBy: "firstName ASC, lastName DESC",
  status: ["pending", "closed"],
  fieldSearch: {
    firstName: "Bill",
    favoriteFood: "*pie",
  }
}) %}

{% for submission in submissions %}
  <div>
    <div>{{ submission.title }} - {{ submission.form.name }}</div>
  </div>
{% endfor %}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

Limit by Date Range

If you'd like to limit submission results by a date range, e.g. last 2 weeks until today, you can use something like this:

{% set start = now|date_modify('-2 weeks')|atom %}
{% set end = now|atom %}

{% set submissions = craft.freeform.submissions({form: "myFormHandle"}).dateCreated(['and', ">= #{start}", "< #{end}"]) %}
<ul>
{% for submission in submissions %}
    <li>{{ submission.title }}</li>
{% endfor %}
</ul>
1
2
3
4
5
6
7
8
9