Symfony 2 form theme with choice field - php

I have problem. I want to do choices country with flag ico but I don't know how to create custom theme for form choice filed.
I created test form :
->add('name', 'choice', array('choices' =>array('en' => 'England', 'de' => 'Deutshland')))
Next in my view I try
{% block _send_name_widget %}
<select>
{% for f in form %}
{{ loop.index }}
{%endfor%}
</select>
{% endblock%}
{{ form_widget(form.name) }}
And in my html code I've got:
<select>
1
2
</select>
<select>
</select>
Could you tell me why?
How can I render only one select with parameters?

The variable "options" didn't exist in my choice_widget_options template. The fact is that "options" IS NOT the correct name of the variable. If you take a look at \vendor\symfony\symfony\src\Symfony\Bundle\FrameworkBundle\Resources\views\Form\choice_widget_options.html.php, you'll find Symfony use a variable called 'choices'.
The corrected version of the previous code is :
{% block choice_widget_options %}
{% spaceless %}
{% for group_label, choice in choices %}
{% if choice is iterable %}
<optgroup label="{{ group_label|trans({}, translation_domain) }}">
{% set options = choice %}
{{ block('choice_widget_options') }}
</optgroup>
{% else %}
<option value="{{ choice.value }}"{% if choice is selectedchoice(value) %} selected="selected"{% endif %}>
<img src="/images/flags/{{ choice.label }}.jpg" />
{{ choice.label|trans({}, translation_domain) }}
</option>
{% endif %}
{% endfor %}
{% endspaceless %}
{% endblock choice_widget_options %}

Override the choice template:
{% block choice_widget_options %}
{% spaceless %}
{% for group_label, choice in choices %}
{% if choice is iterable %}
<optgroup label="{{ group_label|trans({}, translation_domain) }}">
{% set options = choice %}
{{ block('choice_widget_options') }}
</optgroup>
{% else %}
<option value="{{ choice.value }}"{% if choice is selectedchoice(value) %} selected="selected"{% endif %}>
<img src="/images/flags/{{ choice.label }}.jpg" />
{{ choice.label|trans({}, translation_domain) }}
</option>
{% endif %}
{% endfor %}
{% endspaceless %}
{% endblock choice_widget_options %}
more info about form theming in the Symfony2 docs

Related

get first item in loop

I am looping through an array and would like to add a class if it is the first item.
I have tried
{% if field|first %}
{% if field.first %}
{% if field.first() %}
{% if loop|first %}
{% if loop.first %}
{% if loop.first() %}
none work, please help. (the reason I don't use css pseudo first is that this is a grid layout and I have am doing responsive layout things with it)
{% for field in row.fields %}
<div class="c-product-table__item {% if field|first %}{{ first_item }}{% endif %} ">
<span class="c-product-table__text">{{ field.text }}</span>
</div>
{% endfor %}
I don't know why twig filters are not working, I solved it another way. I set a var and made it blank after first loop
{% set thiscount = 'first_item' %}
{% for field in row.fields %}
<div class="c-product-table__item {{ thiscount }}">
<span class="c-product-table__text">{{ field.text }}</span>
</div>
{% set thiscount = '' %}
{% endfor %}

Twig Setting Select Option on a dropdown

I am currently writing a php mvc from scratch and using twig as my template engine and need some assistance setting the selected option on a drop down list. Currently in my model I have an sql query that pull all list of supervisors and drops them in my drop down list using the twig for loop but I need to some how select a user’s supervisor if it matches up.
I apologize now as I am new to twig
View:
<select class="form-control" id="supervisor">
{% for supervisor in supervisor %}
<option value="{{supervisor.fname}} {{supervisor.lname}}" >{{supervisor.fname}} {{supervisor.lname}}</option>
{% endfor %}
</select>
Tried:
<select class="form-control" id="supervisor">
{% for supervisor in supervisor %}
{% if {{supervisor.fname}} {{supervisor.lname}} == {{ user.supervisor }} %}
<option value=”{{supervisor.fname}} {{supervisor.lname}}” selected>{{supervisor.fname}} {{supervisor.lname}}</option>
{% else %}
<option value=”{{supervisor.fname}} {{supervisor.lname}}”>{{supervisor.fname}} {{supervisor.lname}}</option>
{% endif %}
{% endfor %}
</select>
May be you can try something like this:
Replace supervisor variable name by oneSupervisor in the loop and test oneSupervisor with user.supervisor.
<select class="form-control" id="supervisor">
{% for oneSupervisor in supervisor %}
{% set selected = '' %}
{% if (oneSupervisor.fname ~ ' ' ~ oneSupervisor.lname) == user.supervisor %}
{% set selected = 'selected' %}
{% endif %}
<option value="{{oneSupervisor.fname}} {{oneSupervisor.lname}}" {{ selected }}>{{oneSupervisor.fname}} {{oneSupervisor.lname}}</option>
{% endfor %}
</select>
Assuming you have a form called form and therein a select field called field, You could simply do the following:
{% do form.field.setRendered %}
<select id="{{ form.field.vars.id }}"
name="{{ form.field.vars.name }}">
{% for option in form.field.vars.choices %}
<option {{ form.field.vars.value == option.value ? 'selected' : '' }}
value="{{ option.value }}">
{{ option.label }}
</option>
{% endfor %}
</select>

Is it possible to design the html from form builder

I made select form in buildForm()
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('icon','entity',
array(
'class' => 'UserBundle:IconPics',
'property' => 'label',
'expanded' => true,
'data' => $defaultIcon,
'multiple' => false,
'label' => 'form.icon',
'query_builder' => function ($repository) {
return $repository->createQueryBuilder('i')
->add('where', 'i.enabled = true');
},
));
in twig.
{{ form_widget(form.icon) }}
it shows the radiobutton selector html like this.
<div id="fos_user_registration_form_icon">
<input type="radio" id="fos_user_registration_form_icon_3" name="fos_user_registration_form[icon]" required="required" value="3" checked="checked" />
<label for="fos_user_registration_form_icon_3" class="required">male</label>
<input type="radio" id="fos_user_registration_form_icon_4" name="fos_user_registration_form[icon]" required="required" value="4" />
<label for="fos_user_registration_form_icon_4" class="required">female</label>
<input type="radio" id="fos_user_registration_form_icon_5" name="fos_user_registration_form[icon]" required="required" value="5" />
<label for="fos_user_registration_form_icon_5" class="required">old male</label>
<input type="radio" id="fos_user_registration_form_icon_6" name="fos_user_registration_form[icon]" required="required" value="6" />
</div>
However,this html is not cool,just align the radio button.
I would like to design this html.
such as using table or something
<table><tr>
<td>Button1</td>
<td>label</td>
</tr></table>
Is it possible?
Thanks for your reply
I have read the link and choose the most simple way.
put this at the top of twig and made some progress.
But I am facing two problems
{% form_theme form _self %}
{% block radio_widget %}
<td>
<input type="radio" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}/>
</td>
{% endblock radio_widget %}
it shows the html like this
<td style="border-style:none;">
<input type="radio" id="fos_user_registration_form_icon_3" name="fos_user_registration_form[icon]" required="required" value="3"/></td>
<label for="fos_user_registration_form_icon_3" class="required">male</label>
1.problem
radio button is inside the td tag (good!!),but label is out side the
where does this label appears?????
how can I delete or control this???
I understood this label is defferent from the 'label' that I can choose at the formBuilder.
2) problem
when I use 'checked' as sample says
{% if checked %} checked="checked"{% endif %}
it says like this checked property is used in even normal
form_div_layout.html.twig
I have no clue about this.
Please help me . thanks
Variable "checked" does not exist in FOSUserBundle:Registration:register_content.html.twig at line 7
500 Internal Server Error - Twig_Error_Runtime
You can override the form theme in twig by using your new form layout like
{% form_theme formObject 'NamespaceYourBundle:Form:form_div_layout.html.twig' %}
and in form_div_layout.html.twig redefine your field blocks like for radio button you can customize it
{% block radio_widget %}
{% spaceless %}
<td>
<input type="radio" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />
</td>
{% endspaceless %}
{% endblock radio_widget %}
For label block you can use it like
{% block form_label %}
{% spaceless %}
{% if label is not sameas(false) %}
{% if not compound %}
{% set label_attr = label_attr|merge({'for': id}) %} /* you can skip this part for td */
{% 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 %}
<td {% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>{{ label|trans({}, translation_domain) }}</td>
{% endif %}
{% endspaceless %}
{% endblock form_label %}
And now finally override the expanded widget
{% block choice_widget_expanded %}
{% spaceless %}
<table {{ block('widget_container_attributes') }}>
{% for child in form %}
<tr>
{{ form_widget(child) }}
{{ form_label(child) }}
</tr>
{% endfor %}
</table>
{% endspaceless %}
{% endblock choice_widget_expanded %}
Edit to override label block for choice_widget_expanded you can define your block and use it like in below
{% block choice_widget_expanded %}
{% spaceless %}
<table {{ block('widget_container_attributes') }}>
{% for child in form %}
<tr>
{{ form_widget(child) }}
{{ form_label_custom(child) }}
</tr>
{% endfor %}
</table>
{% endspaceless %}
{% endblock choice_widget_expanded %}
And for the custom label too form_label_custom now for every choice field with expanded property (not all fields) your new label will be in action
{% block form_label_custom %}
{% spaceless %}
{% if label is not sameas(false) %}
{% if not compound %}
{% set label_attr = label_attr|merge({'for': id}) %} /* you can skip this part for td */
{% 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 %}
<td {% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>{{ label|trans({}, translation_domain) }}</td>
{% endif %}
{% endspaceless %}
{% endblock form_label_custom %}
How to customize Form Rendering
Check out Form theming.
You have to create fields.html.twig and include into yout twig file like:
{% form_theme form with 'AcmeTaskBundle:Form:fields.html.twig' %}
In fileds.html.twig add radio widget (check out). Here you can now add tables, divs etc. Inside {% block radio_widget %}.
{% block radio_widget %}
{% spaceless %}
<input type="radio" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />
{% endspaceless %}
{% endblock radio_widget %}

Symfony2 Form Builder - Remove label, make it placeholder

I am playing with Symfony's form builder, and I can't find a way to not display a label. Further, I am interested in actually setting a placeholder for each input box. Is this possible? I have researched a bit and found nothing.
My form:
<form action="{{ path('searchPeople') }}" method="post" class="form-inline">
{{ form_errors(form) }}
{{ form_row(form.first_name) }}
{{ form_row(form.last_name) }}
{{ form_rest(form) }}
<br />
<button type="submit" class="btn btn-primary" /><i class="icon-search"></i>Search</button>
</form>
I know it's already answered, but might help somebody who is looking for a different solution for placeholders, if you don't want to change anything in your twig template:
$builder->add(
'name',
'text',
array(
'attr' => array(
'placeholder' => 'Your name',
),
'label' => false,
)
);
If you're outputting the field with form_rest you'll have to set the label for the the field to false in the form builder with something like
$builder->add('first_name', 'text', array(
'label' => false,
));
If you output the fields individually, you can omit the form_label for that field in the twig template, or set it to an empty string.
{{ form_label(form.first_name, '') }}
Convert label to placeholder
{% use 'form_div_layout.html.twig' with widget_attributes as base_widget_attributes %}
{% block widget_attributes %}
{% set attr = {'placeholder': label|trans({}, translation_domain)} %}
{{- block('base_widget_attributes') -}}
{% endblock widget_attributes %}
I did this recently! :) You'll want to create a new fields template, for form_row and one for form_widget. Then remove the form_label part, and add your placeholder.
http://symfony.com/doc/current/cookbook/form/form_customization.html
You can do it per field, or set it for all of them.
Or you can also skip the removing the form_label from the form_row template, and just do form_widget() where you're currently calling form_row()
for other that come across this label-question:
you could use form theme to override the form_row tag for every form you want. However I recommend to just set it invisible for page reader optimization. my example with bootstrap:
{% block form_row %}
{% spaceless %}
{{ form_label(form, null, {'label_attr': {'class': 'sr-only'}}) }}
{{ form_errors(form) }}
{{ form_widget(form) }}
{% endspaceless %}
{% endblock form_row %}
don't forget to include your formtheme in config.yml and template.
For those NOT using form_row, you can always add the placeholder as an attribute directly when adding the input to the builder. Like so:
$task = new Task();
$form = $this->createFormBuilder($task)
->add('first_name', 'text', array(
'required' => true,
'trim' => true,
'attr' => array('placeholder' => 'Lorem Ipsum')
)->getForm();
Symfony 2.8 & above
Remove form_label
{% block form_row %}
<div>
{{ form_errors(form) }}
{{ form_widget(form) }}
</div>
{% endblock form_row %}
Add placeholder attribute
{% block form_widget_simple %}
{% set type = type|default('text') %}
<input placeholder="{{ translation_domain is same as(false) ? label : label|trans({}, translation_domain) }}" type="{{ type }}" {{ block('widget_attributes') }} {% if value is not empty %}value="{{ value }}" {% endif %}/>
{% endblock form_widget_simple %}
Expanding on Léo's answer:
{% use 'form_div_layout.html.twig' %}
{% block widget_attributes %}
{% spaceless %}
{% set attr = attr|merge({'placeholder': label}) %}
{{ parent() }}
{% endspaceless %}
{% endblock widget_attributes %}
trans filter has been removed because it is included in the parent.
You must render the form manually.
Here's an example:
<form id="form-message" action="{{ path('home') }}" method="post" {{ form_enctype(form) }}>
{{ form_label(form.name) }}
{% if form_errors(form.name) %}
<div class="alert alert-error">
{{ form_errors(form.name) }}
</div>
{% endif %}
{{ form_widget(form.name) }}
{{ form_row(form._token) }}
<input type="submit" class="btn" value="Submit">
</form>
Related documentation
To sums it up:
Titi's answer is the most simple ;
Mick, Léo & Quolonel's answers are the most effective but are incomplete (for symfony > 2.6) :
If you use the label_format option in your *Type::configureOptions, their solution does not work. You need to add the content of the form_label block to handle all the label possibilities.
The full & most effective answer (code used w/ symfony 3.3) :
Remove form_label
{% block form_row %}
<div>
{{ form_errors(form) }}
{{ form_widget(form) }}
</div>
{% endblock form_row %}
Edit the widget_attribute block
{% block widget_attributes %}
{% spaceless %}
{% if label is not same as(false) -%}
{% 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 -%}
{% set attr = attr|merge({'placeholder': label}) %}
{%- endif -%}
{{ parent() }}
{% endspaceless %}
{% endblock widget_attributes %}
Notes :
Do not translate the labels into the widget_attributes block, otherwise they will appear as missing translations.
The solution does not work for checkboxes or radio buttons, you'll want to add something like :
{%- block checkbox_widget -%}
{{ parent() }}
{{- form_label(form) -}}
{%- endblock checkbox_widget -%}
Bootstrap Forms
In my case best is mix aswers of #Cethy and #Quolonel Questions
{% form_theme form _self %}
{% use 'bootstrap_4_layout.html.twig' %}
{% block widget_attributes %} {# set placeholder #}
{% spaceless %}
{% set attr = attr|merge({'placeholder': label}) %}
{{ parent() }}
{% endspaceless %}
{% endblock widget_attributes %}
{% block form_row %} {# remove label #}
<div class="form-group">
{{ form_errors(form) }}
{{ form_widget(form) }}
</div>
{% endblock form_row %}
It looks the following
It works with translations
You can also copy the labels into the placeholder attribute before rendering the form:
$formView = $form->createView();
foreach($formView->getIterator() as $item) {
/** #var $item FormView */
if ($item->vars['label']) {
$item->vars['attr']['placeholder'] =$item->vars['label'];
}
}

How to get form variables in custom form field in symfony2

I have this custom form field
{# src/Acme/DemoBundle/Resources/views/Form/fields.html.twig #}
{% block gender_widget %}
{% spaceless %}
{% if expanded %}
<ul {{ block('widget_container_attributes') }}>
{% for child in form %}
<li>
{{ form_widget(child) }}
{{ form_label(child) }}
</li>
{% endfor %}
</ul>
{% else %}
{# just let the choice widget render the select tag #}
{{ block('choice_widget') }}
{% endif %}
{% endspaceless %}
{% endblock %}
This renders the checkboxes. But i am not able to find how can i get the value of checkbox
i.e child.form.value is not working.
Suppose i have entities which is named as tasks in the form.
how can i get the value of the taskid.
something like
child.form.vars.task.id
It seems to be in {{ choice.value }}
Have a look at this to see how the inheritance works.
<option value="{{ choice.value }}"{% if choice is selectedchoice(value) %} selected="selected"{% endif %}>{{ choice.label|trans({}, translation_domain) }}</option>

Categories