In some cases, you may wish to render specific pages, rather than an entire form. Pages will also include the submit button and captchas. For multi-page forms, this can be multiple buttons for going back to a previous page, or to continue to the next page.
Rendering a page can be achieved with the following Twig.
{% set form = craft.formie.forms.handle('contactUs').one() %}
{% for page in form.getPages() %}
{{ craft.formie.renderPage(form, page) }}
{% endfor %}
Here, we fetch the Form object, call getPages()
to fetch all the pages the form has, and loop through them. Even for single-page forms, getPages()
will return an array of Page objects.
This may be particularly useful if you want control over the <form>
element of a form, rather than rely on craft.formie.renderForm()
.
{% set form = craft.formie.forms.handle('contactUs').one() %}
<form method="post" data-fui-form="{{ form.configJson }}">
{{ csrfInput() }}
{{ actionInput('formie/submissions/submit') }}
{{ hiddenInput('handle', form.handle) }}
<h2>Please fill out the form below</h2>
{% for page in form.getPages() %}
{{ craft.formie.renderPage(form, page) }}
{% endfor %}
</form>
Let's run through a few things of note:
data-fui-form
attribute are required, and Formie's JavaScript relies on this to initialise the form.<form>
element, such as csrfInput()
, actionInput()
. This is to ensure Formie can process the content of the form and create a submission from it.Make sure to include the data-fui-form
attribute with JSON configuration from the form. Without this attribute, Formie's JavaScript will fail to initialise, meaning client-side validation, captchas and more will not work.
You'll probably notice your form is looking a little plain and some aspects of it won't work like validation, captchas and more. That's because unlike calling craft.formie.renderForm()
, rendering just form pages won't automatically add Formie's CSS or JavaScript to the webpage for you.
To address this, we just need to include a call to ensure Formie's CSS and JS is added to the webpage.
{% set form = craft.formie.forms.handle('contactUs').one() %}
{% do craft.formie.registerAssets(form) %}
<form method="post" data-fui-form="{{ form.configJson }}">
This will respect the Form Template setting you may have on your form, which controls where to render the CSS and JS.
It's important to include this registerAssets
before the <form>
rendering tag. You could also include them separately as below:
{% set form = craft.formie.forms.handle('contactUs').one() %}
{% do craft.formie.renderFormCss(form) %}
{% do craft.formie.renderFormJs(form) %}
<form method="post" data-fui-form="{{ form.configJson }}">
Read further on the registerAssets()
, renderFormCss()
and renderFormJs()
functions.
A second argument to renderPage()
allows you to pass in variables used as Render Options.
{% set renderOptions = {
someOption: 'someValue',
} %}
{% set form = craft.formie.forms.handle('contactUs').one() %}
{% for page in form.getPages() %}
{{ craft.formie.renderPage(form, page, renderOptions) }}
{% endfor %}
You can also dynamically override any settings for the page using setPageSettings()
. You'll need to use the "handle" of the page, which is automatically derived from the Page Title as a kebab-delimited string. So if your page has the label "Contact Details" the handle would be contact-details
.
{% set form = craft.formie.forms.handle('contactForm').one() %}
{% do form.setPageSettings('page-1', {
{# Override the submit button text for "Page 1" #}
submitButtonLabel: 'Click here to submit',
}) %}
{{ craft.formie.renderForm(form) }}
Check out the Page object for all available settings.
You can render rows for a page, rather than relying on the render function to output them. In this instance, you would want to Render the Field, rather than the entire page.
{% set form = craft.formie.forms.handle('contactUs').one() %}
<form method="post" data-fui-form="{{ form.configJson }}">
{{ csrfInput() }}
{{ actionInput('formie/submissions/submit') }}
{{ hiddenInput('handle', form.handle) }}
{% for page in form.getPages() %}
<div class="page" data-page-id="{{ page.id }}">
{% for row in page.getRows() %}
<div class="row">
{% for field in row.fields %}
<div class="col">
{{ craft.formie.renderField(form, field) }}
</div>
{% endfor %}
</div>
{% endfor %}
</div>
{% endfor %}
</form>
As shown above, we can fetch all available pages on a form using form.getPages()
.
{% set form = craft.formie.forms.handle('contactUs').one() %}
{% for page in form.getPages() %}
{{ page.name }}
{% endfor %}
Because pages don't have a unique handle to fetch by, you need to rely on this function to fetch all the pages for a form. If you want to find a specific page to use in your templates, you can either rely on the id
, the name
or the sortOrder
of a Page object.
You can also use some additional functions for multi-page forms:
{% set currentPage = form.getCurrentPage() %}
{% set nextPage = form.getNextPage() %}
{% set prevPage = form.getPreviousPage() %}
Each function will return a Page object. When there aren't next or previous pages, null
will be returned.
For more fine-grained control over rendering of a form, see Rendering Fields