Twig Form - Don't show label for checkbox - symfony

This might be simple but I have a label and checkbox overriden blocks in my form theme (among many others). I want all label to be handled by the form_label block except for checkboxs'.
I am currently wrapping the label rendering in an if statement which I don't want to do as it doesn't "feel clean":
{%- if form.vars.block_prefixes.1 is not defined or form.vars.block_prefixes.1 != 'checkbox' -%}
Here is are my overridden blocks, any chance I can disable the label in the checkbox_widget block?
{#
############# Checkbox #############
#}
{%- block checkbox_widget -%}
{% spaceless %}
<label for="{{ id }}"><input type="checkbox" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />{{ label|raw }}</label>
{% endspaceless %}
{%- endblock checkbox_widget -%}
{#
############# Labels #############
#}
{%- block form_label -%}
{% if label is not sameas(false) -%}
{% set label_attr = label_attr|merge({'class': ('FormItem-label' ~ label_attr.class|default(''))|trim}) %}
{% if not compound -%}
{% set label_attr = label_attr|merge({'for': id}) %}
{%- endif %}
{% if required -%}
{% set label_attr = label_attr|merge({'class': (label_attr.class|default('') ~ ' is-required')|trim}) %}
{%- endif %}
{% if label is empty -%}
{%- if label_format is not empty -%}
{% set label = label_format|replace({
'%name%': name,
'%id%': id,
}) %}
{%- else -%}
{% set label = name|humanize %}
{%- endif -%}
{%- endif -%}
{%- if form.vars.block_prefixes.1 is not defined or form.vars.block_prefixes.1 != 'checkbox' -%}
<label{% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>{{ label|trans({}, translation_domain) }}</label>
{%- endif -%}
{%- endif -%}
{%- endblock form_label -%}
{%- block button_label -%}{%- endblock -%}

You should use:
{{ form_label(form.terms_and_conditions) }}
Documentation

Added it to the twig template manually so as not to mess with the form theme.
{% block field_row %}
<div class="Grid-cell">
<div class="FormItem FormItem--checkbox is-required" required="required">
<label for="terms_and_conditions">
{{ form_widget(form.terms_and_conditions) }}
{% autoescape false %}{{ form.terms_and_conditions.vars.label }}{% endautoescape %}
</label>
{{ form_errors(form.terms_and_conditions) }}
</div>
</div>
{% endblock %}

Related

how to check in twig if a form field has label

when a form field is generated via an iteration:
{% for field in form %}
{{ form_widget(field); }}
{% endform %}
then it will encapsulates a div block surround the field's input type, and a label (if it has a label).
I want to seperate this into label, and widget:
<div class="form-group">
{% if field.vars.label is not null %}
{{ form_label(field) }}
{% endif %}
{{ form_widget(field) }}
</div>
but the field.vars.label is always null. BTW when I generates without the condition, then it's shows labels correctly.
How do I get the label's value for the condition check?
Thank you in advance.
Change the label to false and the form_label() twig function will automatically ignore it.
Here's a code snippet from the form_div_layout.html.twig file (see line 2):
{%- block form_label -%}
{% if label is not same as(false) -%}
{% if not compound -%}
{% set label_attr = label_attr|merge({'for': id}) %}
{%- endif -%}
{% if required -%}
{% set label_attr = label_attr|merge({'class': (label_attr.class|default('') ~ ' required')|trim}) %}
{%- endif -%}
{% if label is empty -%}
{%- if label_format is not empty -%}
{% set label = label_format|replace({
'%name%': name,
'%id%': id,
}) %}
{%- else -%}
{% set label = name|humanize %}
{%- endif -%}
{%- endif -%}
<label{% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>{{ translation_domain is same as(false) ? label : label|trans({}, translation_domain) }}</label>
{%- endif -%}
{%- endblock form_label -%}
According to the doc of Form Variables Reference,
Try with:
{% if field.vars.attr.label is not null %}
instead of:
{% if field.vars.label is not null %}

Customising form labels in Symfony

I have a symfony page where I display a form, and I would like to add an
* in the labels of all fields that are required.
So I have my form.php.twig, that looks like this:
{% extends "::layout.php.twig" %}
{% block body %}
<div class="row">
{% use 'form_div_layout.html.twig' with form_label as base_form_label %}
{% block form_label %}
{{ block('base_form_label') }}
{% if required %}
<span class="required" title="This field is required">*</span>
{% endif %}
{% endblock %}
</div>
{% endblock %}
I followed the exact documentation of the symfony cookbook on how to customise labels, which is http://symfony.com/doc/current/cookbook/form/form_customization.html#cookbook-form-theming-methods.
But I keep getting this error
Variable "label" does not exist in form_div_layout.html.twig at line 206
I don't have any label variable in the code of my form.php.twig so I don't see why I get this error. And when I remove the
{{ block('base_form_label') }}
I get
Variable "required" does not exist in ATPlatformBundle:Session:create.php.twig
Can anyone help me on this? I don't see where is my mistake? I am not looking to customise it with css, but to add the * .
I have checked the form_div_layout.html.twig at line 206 and this is what there is
{%- block form_label -%}
{% if label is not sameas(false) -%}
{% if not compound -%}
{% set label_attr = label_attr|merge({'for': id}) %}
{%- endif %}
{% if required -%}
{% set label_attr = label_attr|merge({'class': (label_attr.class|default('') ~ ' required')|trim}) %}
{%- endif %}
{% if label is empty -%}
{%- if label_format is not empty -%}
{% set label = label_format|replace({
'%name%': name,
'%id%': id,
}) %}
{%- else -%}
{% set label = name|humanize %}
{%- endif -%}
{%- endif -%}
<label{% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>{{ translation_domain is sameas(false) ? label : label|trans({}, translation_domain) }}</label>
{%- endif -%}
{%- endblock form_label -%}
Thank you in advance.
Did you try defining the label from inside your form builder?! The below field is a required one because unless you mention required => false, your field will be rendered as required.
Something like:
->add('name', 'text', array('label' => '* name'))
With Twig, you should have to test the existence of a variable before using it:
Variable "required" does not exist
{% if required is defined and ... }
You need to test this because you field isn't always required.
if you want further information, you have this page of the documentation:
http://twig.sensiolabs.org/doc/tests/defined.html
Ok, so at the end, I didn't manage to change labels within my form.php.twig (which is the template I use to display my form), but I used another technique.
I created a new file named fields.php.twig, which I put in MyBundle/Resources/views/Form.
At the beginning of my fields.php.twig, I then added
{% extends 'form_div_layout.html.twig' %}
and below it, I added
{% block form_label %}
{{ parent() }}
{% if required %}
<span> * </span>
{% endif %}
{% endblock form_label %}
Then in my form.php.twig, I added
{% form_theme form 'MyBundle:Form:fields.php.twig' %}
{{ form_start(form) }}
Myform here with {{ form_label(form.property) }}
{{ form_errors(form.property) }}
{{ form_widget(form.property) }}
{{ form_end(form) }}
It works perfectly, but I had to create the fields.php.twig.

Symfony2 form entity style each option differently (collapse)

I have an entity field (visitors) in a form. I would like to highlight a person according to its status.
->add('visitors', 'entity', array(
'class' => "T2m3Bundle:Person",
'multiple' => true,
'property' => 'entireName',
'required' => false,
)
I have a method getStatus, that returns 4 states. On every state I want to put different "style" in an option tag.
Here is the example:
<select>
<option value="1">Mary</option>
<option value="2" class="alert alert-danger">John</option>
<option value="3" class="alert alert-success">Peter</option>
<option value="4" class="alert alert-warning">Robert</option>
</select>
So I want to do something like this:
{% for visitor in form.visitors %}
{% set index = visitor.vars.value %}
{% set entity = form.visitors.vars.choices[index].data %}
{% if entity.status == 1 %}
{{ form_widget(visitor) }}
<span class="alert alert-warning">{{ entity.entireName }}</span>
{% endif %}
{% if entity.status == 2 %}
{{ form_widget(visitor) }}
<span class="alert alert-danger">{{ entity.entireName }}</span>
{% endif %}
....
{% endfor %}
This example works for 'expanded' => true but not for collapse type. I would be really thankful for an answer.
Thanks in advance!
EDIT:
Expanded use this template with form_widget(...):
{% block choice_widget_expanded -%}
<div {{ block('widget_container_attributes') }}>
{%- for child in form %}
{{- form_widget(child) -}}
{{- form_label(child) -}}
{% endfor -%}
</div>
{% endblock choice_widget_expanded %}
but I don't know how to render manually collapsed type, where there is no {{- form_widget(...) -}}
Try to override the twig choice widget : refer to this link to find the according block. It's something like this
{% block choice_widget_collapsed -%}
{% if required and placeholder is none and not placeholder_in_choices and not multiple -%}
{% set required = false %}
{%- endif -%}
<select {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %}>
{% if placeholder is not none -%}
<option value=""{% if required and value is empty %} selected="selected"{% endif %}>{{ placeholder|trans({}, translation_domain) }}</option>
{%- endif %}
{%- if preferred_choices|length > 0 -%}
{% set options = preferred_choices %}
{{- block('choice_widget_options') -}}
{% if choices|length > 0 and separator is not none -%}
<option disabled="disabled">{{ separator }}</option>
{%- endif %}
{%- endif -%}
{% set options = choices -%}
{{- block('choice_widget_options') -}}
</select>
{%- endblock choice_widget_collapsed %}
{% block choice_widget_options -%}
{% for group_label, choice in options %}
{%- if choice is iterable -%}
<optgroup label="{{ group_label|trans({}, translation_domain) }}">
{% set options = choice %}
{{- block('choice_widget_options') -}}
</optgroup>
{%- else -%}
{# HERE we define the class based on the status #}
{% if status is defined %}
{% if status == 1 %}
{% set status_class = 'alert alert-warning' %}
{% elseif status == 2 %}
{% set status_class = 'alert alert-danger' %}
{% elseif ... %}
....
{% endif %}
{% endif %}
<option value="{{ choice.value }}"{% if choice is selectedchoice(value) %} selected="selected"{% endif %} {% if status_class is defined %} class="{{ status_class }}" {% endif %} >{{ choice.label|trans({}, translation_domain) }}</option>
{%- endif -%}
{% endfor %}
{%- endblock choice_widget_options %}
Finally in your template, call the widget like this :
{% for visitor in form.visitors %}
{% set index = visitor.vars.value %}
{% set entity = form.visitors.vars.choices[index].data %}
{{ form_widget(visitor, {'status': entity.status}) }}
....
{% endfor %}
This is not tested, but should work. Let me know.

Symfony2 - form theming based on field name

I want to create a choice_widget_collapsed theme, but only for one type of field, it can be checked by name, or by class name (it's entity field). Other choice field should be rendered by standard widget.
I've tried FIELDNAME_widget, CLASSNAME_widget, and I've searched in Google, but with no results.
EDIT
This is code of choice_widget_colapsed:
{% block choice_widget_collapsed -%}
{% if required and empty_value is none and not empty_value_in_choices and not multiple %}
{% set required = false %}
{% endif %}
<select {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %}>
{% if empty_value is not none -%}
<option value=""{% if required and value is empty %} selected="selected"{% endif %}>{{ empty_value|trans({}, translation_domain) }}</option>
{%- endif %}
{%- if preferred_choices|length > 0 -%}
{% set options = preferred_choices %}
{{- block('choice_widget_options') -}}
{% if choices|length > 0 and separator is not none -%}
<option disabled="disabled">{{ separator }}</option>
{%- endif %}
{%- endif -%}
{% set options = choices -%}
{{- block('choice_widget_options') -}}
</select>
{%- endblock choice_widget_collapsed %}
I want to modify HTML of this widget, only for fields named color.
Problem solved.
When you want to change html of widget, based by field name, you have to overwrite block:
{% block _FORMNAME_FIELDNAME_widget -%}
{# your html #}
{%- endblock %}

How to show label for overrided checkbox in Symfony Twig

I've overrided the Twig template for my forms in my symfony application so that I could have more control over the labels for checkboxes.
However, I am having problems with the checkbox label.
Here is the code I overrided in my custom template file:
{# Labels #}
{% block form_label %}
{% spaceless %}
{% if label is not sameas(false) %}
{% if not compound %}
{% set label_attr = label_attr|merge({'for': id}) %}
{% endif %}
{% if required %}
{% set label_attr = label_attr|merge({'class': (label_attr.class|default('') ~ ' required')|trim}) %}
{% endif %}
{% if label is empty %}
{% set label = name|humanize %}
{% endif %}
{% endif %}
{% if 'checkbox' not in block_prefixes %}
<label{% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>{{ label|trans({}, translation_domain) }}</label>
{% endif %}
{% endspaceless %}
{% endblock form_label %}
{# Checkboxes #}
{% block button_label %}{% endblock %}
{% block checkbox_widget %}
{% spaceless %}
<label for="{{ id }}">
<input type="checkbox" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />
{{ label }}</label>
{% endspaceless %}
{% endblock checkbox_widget %}
It works fine but I can't get the label text node for checkboxes working.
When I have a checkbox it generates something like:
<label><input type="checkbox"/></label>
Where it should be:
<label><input type="checkbox"/>Label Here</label>
Any clue on how to make the label string apear after the checkbox?
Edit:
I came to a solution, that worked pretty fine, but I am not sure if it the best.
{% block form_row %}
{% spaceless %}
<div>
{{ form_errors(form) }}
{% if 'checkbox' in block_prefixes %}
{{ form_widget(form) }}
{{ form_label(form) }}
{% elseif 'radio' in block_prefixes %}
{{ form_widget(form) }}
{{ form_label(form) }}
{% else %}
{{ form_label(form) }}
{{ form_widget(form) }}
{% endif %}
</div>
{% endspaceless %}
{% endblock form_row %}
You can remove the label in {% block choice_widget %} to prevent it from appearing in the default spot.
{% block choice_widget %}
{% spaceless %}
{% if expanded %}
<div {{ block('widget_container_attributes') }}>
{% for child in form %}
{{ form_widget(child) }}
{{ form_label(child) }} {# HERE #}
{% endfor %}
</div>
{% else %}
//....
{% endspaceless %}
{% endblock choice_widget %}
If you do so, you would have to override the {% block radio_widget %} too. Otherwise it won't have a label.
<label for="{{ id }}"><input type="radio" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />{{ label|trans }}</label>
You can then remove the {% if 'checkbox' not in block_prefixes %} line you put in {% block form_label %}.
It worked for me.
Symfony2 - How to put label and input for checkboxes/radios in a same line?
Edit :
it seems that they split the {% block choice_widget %} in 2.3.3. You have to edit the choice_expanded block now, and remove the label line as above.
{% block choice_widget_expanded %}
{% spaceless %}
<div {{ block('widget_container_attributes') }}>
{% for child in form %}
{{ form_widget(child) }}
{{ form_label(child) }} {# There #}
{% endfor %}
</div>
{% endspaceless %}
{% endblock choice_widget_expanded %}

Resources