Symfony Forms helps you create and process HTML forms by abstracting all the
hard and repetitive stuff. It also provides many utilities to render form contents,
from the render-all {{ form(form) }}
instruction to the individual form helpers:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
{{ form_start(form) }}
<div class="my-custom-class-for-errors">
{{ form_errors(form) }}
</div>
<div class="form-control">
<i class="fa fa-calendar"></i> {{ form_label(form.dueDate) }}
{{ form_widget(form.dueDate) }}
<small>{{ form_help(form.dueDate) }}</small>
<div class="form-error">
{{ form_errors(form.dueDate) }}
</div>
</div>
{{ form_end(form) }}
The form_*()
helpers render each part of the form field, including all its
needed HTML elements. Most developers like this behavior, but some designers
struggle with it, because it hides all the HTML in form themes which are not
easy to manage by them.
That's why Symfony 5.2 introduces new Twig form helpers to render the value of each form field part without adding any HTML around it:
field_name
field_value
field_label
field_help
field_errors
field_choices
(an iterator of the field choices; e.g. for<select>
)
When using these helpers, you must write all the HTML contents for all form fields, which some people prefer to better control the generated HTML without having to deal with form themes:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
<input
name="{{ field_name(form.username) }}"
value="{{ field_value(form.username) }}"
placeholder="{{ field_label(form.username) }}"
class="form-control"
/>
<select name="{{ field_name(form.country) }}" class="form-control">
<option value="">{{ field_label(form.country) }}</option>
{% for label, value in field_choices(form.country) %}
<option value="{{ value }}">{{ label }}</option>
{% endfor %}
</select>
It's great to have more flexibility here, thank you for this nice addition!
Just a technical details: at which point will be form field be considered as "rendered"? After calling
field_value
? Canfield_value
be called many times (of instance for the select example, to select the correct option)?Hello @Romain!
It's based on the field_name function: once called, the field is considered rendered.
Am I right to assume that I have to manually define the selected state for
@Daniel yes, indeed! If you're using value inputs (text, date, textarea, ...) a direct call to form_value is enough. For choice inputs (select, radio, checkbox, ...) it requires a little bit more work to iterate over the choices and check if the choice is currently selected, but nothing too difficult.
Really appreciate this feature. Much easier than putting in overrides. Such much to look forward to in 5.2
Nice! A good alternative to themes for lighter needs
Nice ! But how it's work with nesteed forms ? dot call : field_name(form.person.username) tab call : field_name(form.person[username]) other ?