In choiceType field I have parameter - choice label
'choice_label' => function ($pay, $key, $index) {
return "<b>".$pay->getName()."</b><br />";
},
And render function of fields in twig:
{{form_widget(field)}}
{{form_errors(field)}}
Of course I want to render getName in bold characters,
I have try with twig autoescape and {{form_widget(field)|raw}} - without success
You have to custom the choice_label form in a custom theme (ex : radioHTML.html.twig) => I just add |raw to the label text
{%- 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 -%}
<{{ element|default('label') }}{% if label_attr %}{% with { attr: label_attr } %}{{ block('attributes') }}{% endwith %}{% endif %}>
{%- if translation_domain is same as(false) -%}
{{- label|raw -}}
{%- else -%}
{{- label|trans({}, translation_domain)|raw -}}
{%- endif -%}
</{{ element|default('label') }}>
{%- endif -%}
{%- endblock form_label -%}
Your form type just return html string in the choice_label option :
$builder->add('fieldName', EntityType::class, array(
'required' => true,
'class' => 'AppBundle\EntityName',
'choice_label' => function (EntityName $entity) {
$html = '<div>';
$html .= $entity->getName();
$html .= '</div>';
return $html;
},
'data' => null,
'multiple' => false,
'expanded' => true)
And then use it for your specific field like that in your twig TPL :
{% form_theme from.fieldNalme 'form/radioHTML.html.twig' %}
Related
With a form including a checkboxes field and an email or save action set up, is there a way to access the individual checkboxes' labels from within the template?
So far, I've only been able to access the ids and values of the checkboxes, like so:
{%- for field in form.fields -%}
{%- set value = form.value(field.name) -%}
{%- if field.type == "checkboxes" -%}
{%- for key in in value|keys -%}
{{- key ~ ": " ~ value[key] ~ "\r\n" -}}
{%- endfor -%}
{%- endif -%}
{%- endfor -%}
To get the default values and labels of a checkboxes field, you could try the following:
The field definition of the form:
fields:
...
myfield:
type: checkboxes
label: A 'checkboxes' field
default:
option1: true
option2: false
options:
option1: Option 1
option2: Option 2
use: keys
Inside Twig template:
{% for field in form.fields %}
{% if field.type == 'checkboxes' %}
{% for key, label in field.options %}
<p>{{ label ~ ': ' ~ (field.default[key] ? 'true' : 'false') }}</p>
{% endfor %}
{% endif %}
{% endfor %}
Result in browser:
I have a pb with a translation containing parameters (link href). I have added a |raw but I see the html displayed.
My code :
{{ form_row(form.valid, {
'label' : 'annonces.form.valide_cgu_cgv' | trans ({
'cgu_link' : path('page_statique', {'page' : 'cgu'}),
'cgv_link' : path('page_statique', {'page' : 'cgv'})
}) | raw }) }}
What I see :
Je reconnais accepter les Conditions générales d'utilisation et Conditions générales de vente
Any idea ?
Thank you !
As the form_label use trans() without the raw inside of its code
{%- block form_label -%}
{# [...] #}
<label{% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>{{ label|trans({}, translation_domain) }}</label>
{%- endif -%}
{%- endblock form_label -%}
You need either to use a custom form_label or 'manually' display the label
I am working on Symfony 3 and I have some trouble with my form.
When I create a Symfony form with a field not required, here is my code :
I create the form :
$form = $this->createFormBuilder()
->add('prenom' TextType::class, array(
'label' => 'Votre prénom',
'required' => false
)
->getForm();
Here is the code in my view for this field:
{{ form_label(form.prenom) }}
{{ form_errors(form.prenom) }}
{{ form_widget(form.prenom) }}
And this is the HTML I have :
<label class="control-label" for="contact_prenom">Votre prénom</label>
<input type="text" id="contact_prenom" name="contact[prenom]" class="form-control"/>
Now if I do the same without the 'require' => false on my FormBuilder, here is the HTML I get:
<label class="control-label required" for="contact_prenom">Votre prénom</label>
<sup class="required" title="Champ obligatoire">
<i class="fa fa-asterisk"></i>
</sup>
<input type="text" id="contact_prenom" name="contact[prenom]" required="required" class="form-control" />
Is it possible to control the "sup" tag so the asterisk * can be with my label?
I guess I can do it with jQuery, but I'd like to know if it is possible to do it on my form builder or in Twig?
In the doc there is a specific section here http://symfony.com/doc/current/form/form_customization.html#adding-a-required-asterisk-to-field-labels
You can even do with CSS only
label.required:before {
content: "* ";
}
As of Symfony 5.1 you can do the following
->add('name', TextType::class, [
'label' => 'Name <span class="badge badge-danger badge-pill">Required</span>',
'label_html' => true
])
The label_html (bool) property will allow HTML to be injected into the label directly and render on the form output.
Documentation - https://symfony.com/doc/current/reference/forms/types/form.html#label-html
Yes, you could override the twig template or the block that symfony uses to render your widget, have a look at:
http://symfony.com/doc/current/templating/overriding.html
In your case, you're looking for
vendor/symfony/symfony/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig
And this would be the block you want to override:
{%- 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{% if label_attr %}{% with { attr: label_attr } %}{{ block('attributes') }}{% endwith %}{% endif %}>{{ translation_domain is same as(false) ? label : label|trans({}, translation_domain) }}</label>
{%- endif -%}
{%- endblock form_label -%}
Symfony2 uses some twig templates when rendering forms.
In particular, in order to render the choice form field collapsed, symfony2 uses the following snippet of code (from form_div_layout.html.twig):
{%- 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 != '' ? 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 -%}
In my application, I want to create a new form type, that extends the default collapsed choice type, but where choice list has custom formatting.
In other words, for my form field type, named places_widget, extending choice_widget_collapsed block but redefining choice_widget_options.
I already tried:
/* My first attempt */
{%- block places_widget -%}
{% block choice_widget_options %}
{{ block('choice_places_widget_options') }}
{% endblock choice_widget_options %}
{{ block('choice_widget_collapsed') }}
{%- endblock places_widget -%}
/* My other attempt */
{%- block places_widget -%}
{{ block('choice_widget_collapsed', { 'choice_widget_options' => choice_places_widget_options }) }}
{%- endblock places_widget -%}
/* together with */
{%- block choice_places_widget_options %}
// code here
{%- endblock choice_places_widget_options -%}
None of the two solutions is working, and actually I have the feeling I am doing things in the wrong way.
Does anyone have any idea on how to achieve the goal?
Thank you in advance
Forms can be customized using themes (see the doc here: http://symfony.com/doc/current/cookbook/form/form_customization.html#form-theming-in-twig)
In your case, it seems you need to load your own theme with:
{% form_theme form _self %}
Note that you could externalize these blocks in another file (refer to http://symfony.com/doc/current/cookbook/form/form_customization.html#method-2-inside-a-separate-template to see how to do that)
To validate a form I am using a standard:
{{ form_widget(form.save, {'attr': {'class': 'btn btn-sm btn-danger'}, 'label': 'Submit form'}) }}
I want to insert a fontawsome icon in the button. I tried:
{{ form_widget(form.save, {'attr': {'class': 'btn btn-sm btn-danger'}, 'label': '<i class="fa fa-envelope-o"></i> Submit form'}) }}
But it is not working; obviously
Any idea how to that?
I would define a new form template in the same view (or in a template if you need to reuse the code). More details here
{% extends '::base.html.twig' %}
{% form_theme form _self %}
{%- block submit_widget -%}
{%- set type = type|default('submit') -%}
{%- 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 -%}
<button type="{{ type|default('button') }}" {{ block('button_attributes') }}>
<i class="fa fa-envelope-o"></i>
{{ label|trans({}, translation_domain) }}
</button>
{%- endblock submit_widget -%}
{% block content %}
{# ... render the form #}
{{ form_row(form.age) }}
{% endblock %}
EDIT
You can also extend ButtonType to allow icon_before and icon_after in order to add icons easily in form definition :
$form->add('submitReportV2Show', SubmitType::class, array(
'label' => 'My test',
'icon_before' => 'fa-refresh',
'icon_after' => 'fa-refresh',
'attr' => array('class' => 'btn btn-sm btn-success'
)));
Create a new class src/bundle/Form/Extension:
namespace YourBundle\ToolBoxBundle\Form\Extension;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\ButtonType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolver;
class IconButtonExtension extends AbstractTypeExtension
{
public function getExtendedType()
{
return ButtonType::class;
}
public function buildView(FormView $view, FormInterface $form, array $options)
{
$view->vars['icon_before'] = $options['icon_before'] ?? '';
$view->vars['icon_after'] = $options['icon_after'] ?? '';
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'icon_before' => null,
'icon_after' => null
]);
}
}
Declare it in service src/bundle/Resources/config/service.yml
bundle.tools.form.type_extension.icon_button:
class: YourBundle\ToolBoxBundle\Form\Extension\IconButtonExtension
tags:
- { name: 'form.type_extension', extended_type: 'Symfony\Component\Form\Extension\Core\Type\ButtonType' }
app/Resources/views/Form/fields.html.twig
{%- block button_widget -%}
{%- if label is empty -%}
{%- if label_format is not empty -%}
{% set label = label_format|replace({
'%name%': name,
'%id%': id,
}) %}
{%- elseif label is same as(false) -%}
{% set translation_domain = false %}
{%- else -%}
{% set label = name|humanize %}
{%- endif -%}
{%- endif -%}
<button type="{{ type|default('button') }}" {{ block('button_attributes') }}>
{% if icon_before is defined and icon_before is not null %}
<i class="fa {{ icon_before }}"></i>
{% endif %}
{{ translation_domain is same as(false) ? label : label|trans({}, translation_domain) }}
{% if icon_after is defined and icon_after is not null %}
<i class="fa {{ icon_after }}"></i>
{% endif %}
</button>
{%- endblock button_widget -%}
sdespont's answer is the correct answer and worthy of being selected. I have, however, extended the functionality of it to include adding the custom fa class icon as well as whether the icon is placed to the left or right of the button text.
Since this functionality accepts variables the best thing to do is to create a template to be reused instead of customising just the view.
Form template: app/Resources/views/form/submit.html.twig
{# app/Resources/views/form/submit.html.twig #}
{% block submit_widget %}
{% set type = type|default('submit') %}
{% 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 %}
<button type="{{ type|default('button') }}" {{ block('button_attributes') }}>
{% if fa is defined %}
{% if left is defined and left %}
<i class="fa {{ fa }}"></i>
{% endif %}
{{ translation_domain is same as(false) ? label : label|trans({}, translation_domain) }}
{% if right is defined and right %}
<i class="fa {{ fa }}"></i>
{% endif %}
{% else %}
{{ translation_domain is same as(false) ? label : label|trans({}, translation_domain) }}
{% endif %}
</button>
{% endblock submit_widget %}
Controller:
$form = $this->createFormBuilder($user)
...
->add('submit', SubmitType::class, array(
'attr'=> array('class'=>'myclass')
))
->getForm();
Twig template:
{{ form_widget(form.submit, {'fa' : 'fa-long-arrow-right','right' : true}) }}
You can set any old fa icon and even sizing like so: fa-long-arrow-right fa-2x
The easiest, you can put your button with html and form vars:
<button type="submit" name="{{ form.send.vars.full_name }}" id="{{ form.send.vars.id }}" class="btn btn-sm btn-danger"><i class="fa fa-envelope-o"></i></button><
You can just add a new custom service css class per icon
/*
* css selector for a class attribute that starts with "btn-fa-" or has " btn-fa-" in it:
*/
[class^="btn-fa-"]:before,
[class*=" btn-fa-"]:before
{
font-family: "Font Awesome 5 Free";
font-weight: bold;
margin: 0 6px 0 2px;
}
/*
* And then only 1 setting per font awesome class
*/
.btn-fa-plus:before {
content: '\f067';
}
And add the class to the ButtonType
->add('Add an item', ButtonType::class, [
'attr' => [
'class' => 'btn btn-primary btn-fa-plus',
]
])
In YourFormType.class -> buildForm
->add('submit', SubmitType::class, [
'attr' => [
'class' => 'main-btn primary-btn',
],
'label' => '<i class="fas fa-search"></i> Search',
'label_html' => true,
])