Closed maartenheideman closed 4 months ago
I don't tend to use the Form Field like that, but the variable is available on the parent template calling the macro, so you can do something like that.
{# _entry.twig #}
{{ entry.pageContent }}
{% import "partials/form.twig" as form %}
{{ form.render(entry, errors ?? []) }}
{# partials/form.twig #}
{% macro errorList(errors) %}
{% if errors %}
<ul class="errors">
{% for error in errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
{% endmacro %}
{% macro render(entry, errors = []) %}
{% from _self import errorList %}
{% set form = entry.forms.setConfig({
redirect: 'contact/thanks'
}) %}
{{ form.open() }}
{{ errors['form'] is defined ? errorList(errors['form']) }}
{{ errors['recaptcha'] is defined ? errorList(errors['recaptcha']) }}
{{ errors['honeypot'] is defined ? errorList(errors['honeypot']) }}
{% for field in form.fields %}
{{ field.render() }}
{{ errors[field.name] is defined ? errorList(errors[field.name]) }}
{% endfor %}
{{ form.close() }}
{% endmacro %}
Another alternative is to use AJAX, and when the errors return in the response, display them dynamically on your templates.
I also use it this way but my macro also uses an import for the form. Therefore I need to pass the error
object from the layout to the page to the macro to the include. I thought maybe there is a easier way. I though maybe there is a way to get the errors with a function like craft.wheelform.getErrors... something like that. I'll do this this way right now:
Lay-out
<!doctype html>
{% apply spaceless %}
{% set wheelformErrors = (wheelformErrors is defined and wheelformErrors|length) ? wheelformErrors : null %}
{% endapply %}
<html>...</html>
Entry
{# Entry template #}
{% extends '_layout' %}
{% block content %}
<div class="row">
{% if entry.contentBlocks|length %}
{{ contentBlocks.show( entry.contentBlocks, entry.id, wheelformErrors ) }}
{% endif %}
</div>
{% endblock %}
Macro
{% macro show( blockField, entryId, wheelformErrors ) %}
{% if blockField|length -%}
{% for block in blockField.all() -%}
{% switch block.type.handle -%}
{# Wheelform widget #}
{% case 'form' -%}
{% if form|length %}
<div class="block-form__content">
{% include "_includes/form" with {
formId: form.id, f
ormRedirect: redirect,
formSubmitLabel: 'Send',
wheelformErrors
} %}
</div>
{% endif %}
{% endswitch -%}
{% endfor -%}
{% endif %}
{% endmacro %}
Include
{# form include #}
{% if formId is defined %}
{% macro errorList(errors) %}
{% if errors %}
<ul class="form__errors">
{% for error in errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
{% endmacro %}
{% from _self import errorList %}
{% set form = wheelform.form({
id: formId,
redirect: (formRedirect is defined)? formRedirect : '',
submitButton: {
attributes: {
value: (formSubmitLabel is defined) ? formSubmitLabel : 'send'|t,
class: 'button button--primary'
}
}
}) %}
{{ form.open("",{'novalidate': 'novalidate'}) }}
{{ wheelformErrors['form'] is defined ? errorList(wheelformErrors['form']) }}
{{ wheelformErrors['recaptcha'] is defined ? errorList(wheelformErrors['recaptcha']) }}
{{ wheelformErrors['honeypot'] is defined ? errorList(wheelformErrors['honeypot']) }}
{% for field in form.fields %}
{{ field.render() }}
{{ wheelformErrors[field.name] is defined ? errorList(wheelformErrors[field.name]) }}
{% endfor %}
{{ form.close() }}
{% endif %}
I understand. We use Flash Messages (messages that only display on the next request). Maybe we can save the errors on the next request on the Form Object and have them available through a helper-getter function. I will look into this.
Thanx for your quick reply. How can I use this fix? craft.wheelform.getErrors()
?. Does this fix als work in version 3 of wheelform for craft 4?
Older versions of the plugin go into Maintenance Mode (only critical fixes). New features will only be applied to the latest version.
In regards of your question on usage: You use it by calling the getter function from the Form Service, so something like:
{% set form = entry.forms.setConfig({
redirect: 'contact/thanks'
}) %}
{{ form.open() }}
{% set errors = form.getErrors() %}
{{ errors['form'] is defined ? errorList(errors['form']) }}
{{ errors['recaptcha'] is defined ? errorList(errors['recaptcha']) }}
{{ errors['honeypot'] is defined ? errorList(errors['honeypot']) }}
Most of the time I use the matrix field in combination with the wheelform form field. This allows flexible layouts. WheelformErrors is available in the top level twig files but not in imports and macros. Is there a function that can retrieve the wheelform errors regardless of the template you are in? Currently, I have a variable in the layout that I pass to the entry template which then retrieves macros to which you have to pass that variable again and the form is in an import which also requires the error variable. Or am I overcomplicating things and is there a simpler way to achieve this.