Freeform Freeform for Craft

Forms & Fields

Surveys & Polls Form Type ProImproved in 5.0+

Expand the possibilities of Freeform with the Surveys & Polls form type! If you have the Pro edition of Freeform, this is a plug and play feature that instantly adds access to a special reporting area inside the Freeform control panel that allows you to view stats and charts for each field type. The reports can be customized to use different chart types and hide specific fields. You can even generate a PDF exported document to share with other members of your team.

TIP

If you already have some forms used as surveys or polls, simply switch the Form Type setting from Regular to Surveys & Polls and you'll instantly and retroactively have reports available for these forms!

Surveys & Polls form type

Key Features

The following features are unique to the Surveys & Polls form type:

  • Review and customize survey or poll results with rich chart options for each form in the control panel.
  • Show users on the front end the results for the survey or poll for each form.
  • Export survey results as a PDF file to share with other team members.
  • Plug and play with existing forms used as surveys to retroactively unlock rich reporting instantly.

The following features are available for any form in Freeform, but become even more powerful when combined with the Surveys & Polls form type:

Eligible Field Types

While you can certainly use any field type in your survey and poll forms, Freeform will only recognize certain field types to apply special handling for charts and other stats.

Field Type CP Reports Charts Average Score*
Checkboxes
Radios
Dropdown
Multiple Select
Opinion Scale
Rating
Text (includes Email, Number, Phone, Regex, Website)
Textarea

*Average score available when the field contains only numeric option values, e.g. 1, 2, 3.

There is currently no support for displaying the following field types in reports: Date & Time, File Upload, File Upload Drag & Drop, Hidden, Invisible, Signature, and Table.

Reports Improved in 5.0+

When a form is assigned a Form Type of Surveys & Polls, its form card on the dashboard will include a Survey Results link to access the results.

Surveys & Polls Dashboard

An individual report page is available for each Survey & Poll form, which will show the results of the survey or poll as a report summary. Applicable field types will appear as charts and graphs, and you'll have the option to change the chart type for each question/field to whatever suits it better (changes are saved and apply to all users). And finally, an option to generate a PDF export is available if you wish to share the results with other team members.

Charts can be used with Checkboxes, Radios, Dropdown, Multiple Select, Opinion Scale, and Rating field types. Available chart types are:

  • Horizontal Bar
  • Vertical Bar
  • Pie
  • Donut
  • Hidden (entire question and results are hidden in report)

Text option display is available for simpler text-based field types, including Text, Textarea, Email, Number, Phone, Regex, and Website.

  • Text
  • Hidden (entire question and results are hidden in report)

Surveys & Polls Reports

Creating a Survey

With the magnitude of features and options Freeform offers, there isn't any one way to create a survey or poll form. So many approaches are available to you:

  • Will this be a single page form or will you break up your surveys into multiple pages so users don't get overwhelmed?
  • Which field types will you use? A wide variety of options are available to suit every kind of question and flow.
  • Will you conditionally show and hide some questions or skip pages entirely, based on the selection of other fields?
  • Does the survey have a close date?

Create a New Survey

To create a new survey, the process is almost identical to creating a regular form, but be aware of a few things that are necessary for Freeform to properly handle and recognize your survey forms:

  • Be sure to have the Pro edition of Freeform installed.
  • Inside the form builder (or form wizard), be sure to set the Type setting to Surveys & Polls from the available options.
  • For questions you want to show up as charts in reports, stick to using the Checkboxes, Radios, Dropdown, Multiple Select, Opinion Scale, and Rating field types.
  • For questions you want to show up as text in reports, be sure to use only Text, Textarea, Email, Number, Phone, Regex, and Website fields. All other field types such as File Upload, Signatures, etc will not appear in the Surveys & Polls reports area.
  • If you want to restrict people from submitting the survey more than once, be sure to select an option in the Duplicate Check setting, which is located in the form builder's SettingsLimits tab.
  • If you want to stop people from submitting the survey after a certain date, be sure to specify a date in the Stop Submissions After Date setting, which is located in the form builder's SettingsLimits tab.

Convert an Existing Form

To convert an existing form to be a Surveys & Polls form, simply follow the instructions below:

  1. Go to the Forms page in the Freeform control panel.
  2. Click on the form to edit it inside the form builder.
  3. Inside the Settings tab, change the Form Type setting from Regular to Surveys & Polls.
  4. Save the form.

Configuration

The Surveys & Polls form type offers a handful of settings that help you set defaults and styling for reports.

TIP

This page and its settings all become inaccessible when the Craft allowAdminChanges config setting is set to false.

Surveys & Polls Settings

Setting Description
Highlight Highest Ranking Option The highest ranking option chosen for each question will be highlighted with an alternate color.
Default Chart Types Select the default chart types for each field type. These can be overridden for each form in the report view.

TIP

For page usibility, the Surveys & Polls report page will automatically switch the default chart type from vertical bar to horizontal bar if the field contains more than 10 values. You can change it back to vertical bar inside the report page if you wish.

Usage in Templates

The surveyResults method becomes available for use in your templates though the Form query query:

  • Iterate over all results ({% for result in form.surveyResults %}):
    • votes - get the total number answers for this field.
    • skipped - get the total number of skipped answers for this field.
    • average - get the average numeric value across all answers for this field.
      • This will return null if any of the answers aren't numeric.
    • max - get the highest numeric value this field may contain.
      • Useful when displaying the average answer chosen to be able to show the max value (e.g. 4.3 / 5)
    • Access field object:
      • field.id
      • field.label
      • etc
    • breakdown - access breakdown of answers ({% for answer in result.breakdown %}):
      • Limiting and ordering results (typically used for text fields):
        • breakdown - will show all responses in order they were added
        • breakdown(3) - fetch only the 3 highest ranked answers
        • breakdown(-3) - fetch only the 3 lowest ranked answers
        • breakdown(true) - order all answers by highest rank
        • breakdown(false) - order all answers by lowest rank
      • Properties:
        • label - label of the given answer (will use the answer value for text fields).
        • value - value of the given answer.
        • votes - number of times this answer was selected.
        • percentage - calculated percentage of times this answer was selected against all other options.
        • ranking - number of the rank for this answer, with 1 being the top answer.

Examples

The following are several examples of how to iterate over fields' submission data and display survey results for each.

Extract Specific Field Results

The following example will generate survey or poll results for a specific field.

{% set form = freeform.form("myFormHandle") %}

{% set field = form.get('myFieldHande') %}
{% set result = form.surveyResults(field) %}

{% for answer in result.breakdown %}
    <h6 class="mt-4">{{ answer.label }} <small>({{ answer.votes }} votes)</small></h6>
    <div class="progress" style="height: 30px;">
        <div class="progress-bar" role="progressbar" style="width: {{ answer.percentage|round(1) }}%" aria-valuenow="{{ answer.percentage|round(1) }}" aria-valuemin="0" aria-valuemax="100">{% if answer.percentage > '0' %}{{ answer.percentage|round(0) }}%{% endif %}</div>
    </div>
{% endfor %}
1
2
3
4
5
6
7
8
9
10
11

Example with Bootstrap Library

The below example uses the Bootstrap library to generate charts with your survey or poll questions and responses for all eligible survey/poll field types.

Surveys & Polls Template Report

<style>
    .chart-textarea-responses {
        max-height: 300px;
        overflow-y: scroll;
    }
</style>

{% set form = freeform.form("myFormHandle") %}
{% set results = form.surveyResults %}

<h1>Survey Results for <b>{{ form.name }}</b> form</h1>
<p>There are a total of {{ freeform.submissions({form}).count }} responses.</p>

{% for result in results %}
<div class="container">
    {% set field = result.field %}
    <h2>{{ field.label }}</h2>
    <p>
        {{ result.votes }} responses, {{ result.skipped }} skipped
        {% if result.average|length %}
            <br />Average: <b>{{ result.average|round(1) }}</b> / {{ result.max }}
        {% endif %}
    </p>
    {% if field.type not in ["text", "textarea", "email", "phone", "website", "number", "regex"] %}
        {% for answer in result.breakdown %}
            <h6 class="mt-4">{{ answer.label }} <small>({{ answer.votes }} resp.)</small></h6>
            <div class="progress" style="height: 30px;">
                <div class="progress-bar{{ answer.ranking == 1 ? ' bg-danger' }}" role="progressbar" style="width: {{ answer.percentage|round(1) }}%" aria-valuenow="{{ answer.percentage|round(1) }}" aria-valuemin="0" aria-valuemax="100">{% if answer.percentage > '0' %}{{ answer.percentage|round(0) }}%{% endif %}</div>
            </div>
        {% endfor %}
    {% elseif field.type in ["text", "email", "phone", "website", "number", "regex"] %}
        <p>Top 10 text responses:</p>
        <ul>
        {% for answer in result.breakdown(10) %}
            <li>{{ answer.value }} ({{ answer.votes }})</li>
        {% endfor %}
        </ul>
    {% elseif field.type == "textarea" %}
        <p>Long answer responses (scroll to see all):</p>
        <ul class="chart-textarea-responses">
        {% for answer in result.breakdown %}
            <li>{{ answer.value }}</li>
        {% endfor %}
        </ul>
    {% endif %}
</div>
<hr class="mt-4" />
{% endfor %}
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

Example with Chart.js Library

The below example uses the Chart.js library to generate charts with your survey or poll questions and responses for all eligible survey/poll field types.

<style>
    .chart-textarea-responses {
        max-height: 300px;
        overflow-y: scroll;
    }
</style>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

{% set form = freeform.form("myFormHandle") %}
{% set results = form.surveyResults %}

<h1>Survey Results for <b>{{ form.name }}</b> form</h1>
<p>There are a total of {{ freeform.submissions({form}).count }} responses.</p>

{% for result in results %}
<div class="container">
    {% set field = result.field %}
    <h2>{{ field.label }}</h2>
    <p>
        {{ result.votes }} responses, {{ result.skipped }} skipped
        {% if result.average|length %}
            <br />Average: <b>{{ result.average|round(1) }}</b> / {{ result.max }}
        {% endif %}
    </p>
    {% if field.type not in ["text", "textarea", "email", "phone", "website", "number", "regex"] %}
        <canvas id="chart{{ field.handle }}" width="800" height="300"></canvas>
        <script>
            const chart{{ field.handle }}labels = [
            {% for answer in result.breakdown %}
                '{{ answer.label }}',
            {% endfor %}
            ];
            const chart{{ field.handle }}data = {
                labels: chart{{ field.handle }}labels,
                datasets: [{
                label: '{{ field.label }}',
                backgroundColor: 'rgb(255, 99, 132)',
                borderColor: 'rgb(255, 99, 132)',
                data: [
                {% for answer in result.breakdown %}
                    {{ answer.votes }},
                {% endfor %}
                ],                        
                }]
            };
            const chart{{ field.handle }}config = {
                type: 'bar',
                data: chart{{ field.handle }}data,
                options: {
                    indexAxis: 'x',
                    responsive: false,
                    barThickness: 50,
                    plugins: {
                        legend: {
                            display: false,
                        }
                    },
                    scales: {
                        x: {
                            grid: {
                                display: false,
                            }
                        }
                    },
                }
            };
        </script>
        <script>
            const chart{{ field.handle }} = new Chart(
                document.getElementById('chart{{ field.handle }}'),
                chart{{ field.handle }}config
            );
        </script>
    {% elseif field.type in ["text", "email", "phone", "website", "number", "regex"] %}
        <p>Top 10 text responses:</p>
        <ul>
        {% for answer in result.breakdown(10) %}
            <li>{{ answer.value }} ({{ answer.votes }})</li>
        {% endfor %}
        </ul>
    {% elseif field.type == "textarea" %}
        <p>Long answer responses (scroll to see all):</p>
        <ul class="chart-textarea-responses">
        {% for answer in result.breakdown %}
            <li>{{ answer.value }}</li>
        {% endfor %}
        </ul>
    {% endif %}
</div>
<hr />
{% endfor %}
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
83
84
85
86
87
88
89
90
91

Iterate Over All Field Types

The following example will iterate over all fields, compatible with Survey & Polls special behavior or not.

{% set form = freeform.form("myFormHandle") %}

{% for row in form %}
    <div>
        {% for field in row %}
            {% set results = form.surveyResults(field) %}
            <div>
                <label>{{ field.label }}</label>
                {% if results %}
                    <ul>
                        {% for answer in results %}
                            <li>{{ answer.label }} ({{ answer.votes }})</li>
                        {% endfor %}
                    </ul>
                {% else %}
                    <div>
                        No survey results for this field.
                    </div>
                {% endif %}
            </div>
        {% endfor %}
    </div>
{% endfor %}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23