Custom radio button id in Twig - symfony

Code of rendered Twigs radio button set form usually looks like...
This:
{{ form_widget(formTitle.radioSet) }}
To this...
<input type="radio" id="formTitle_radioSet_0" name="formTitle[radioSet]" value="fooValue">
<input type="radio" id="formTitle_radioSet_1" name="formTitle[radioSet]" value="booValue">
... and a few more rows like this
I want to make it work with JS easier. Is it possible to render customized radio buttons with IDs reffered to the value of radio and my own preferences like this??
<input type="radio" id="radioSet_fooValue" name="formTitle[radioSet]" value="fooValue">
<input type="radio" id="radioSet_booValue" name="formTitle[radioSet]" value="fooValue">

After about half an hour of exploring article recommended by Carlos Granados got a solution. The target is to override twigs template of renderind radio inputs.
In a few words, code below, pasted at the beginning of your web page template will override ALL radio's render the way it described in question.
{% form_theme form _self %}
{%- block radio_widget -%}
<input type="radio" name="{{ full_name }}" id="radio_{{ value }}" value="{{ value }}"{% if checked %} checked="checked"{% endif %} />
{%- endblock radio_widget -%}

Use custom form rendering
You will just need to customize the widget_radio block using one of the techniques described in that cookbook entry

Related

Can I repeat a Symfony form in a loop with Twig, or do I have to build it manually?

I am totally new to Symfony and Twig; just yesterday I was thrown into a legacy project that uses them.
I have a list, produced by a template loop, of Orders, each order having a priority from 1-5.
I want to add a single dropdown Select to each Order row which submits a form updating that Order's priority and refreshes the page.
My question is, can I use Symfony's buildForm in conjunction with this architecture? For now I have the following form constructed manually. Is it even possible to build a series of identical forms like this with Twig?:
{% for order in orders %}
<form method="post" action="{{ path('change_priority') }}" style="margin: 0; padding: 0;">
<div class="form-group">
<select name="priority" style="width: 35px; height: 20px;" onchange="this.form.submit()">
<option value="1" {% if order.currentBody.priority == 1 %} selected {% endif %}>1 - Low</option>
<option value="2" {% if order.currentBody.priority == 2 %} selected {% endif %}>2 - Normal</option>
<option value="3" {% if order.currentBody.priority == 3 %} selected {% endif %}>3 - High</option>
<option value="4" {% if order.currentBody.priority == 4 %} selected {% endif %}>4 - Critical</option>
<option value="5" {% if order.currentBody.priority == 5 %} selected {% endif %}>5 - No Priority</option>
</select>
<input name="order_id" value="{{order.serial}}" type="hidden" />
</div>
</form>
{% endfor %}
And here is an image of what I'm after. Changing the priority of any of the Order row items changes that Order's priority and then refreshes the page.
you have to add them in the form type.
You can not do that in your twig template.
If you render a field with something like {{ form_row(form.select) }}, it will be flagged as displayed and will not be rendered a second time, even if you call {{ form_row(form.select) }} again.

form not uploading with widget_tweaks django

im trying to style my form a bit and came across this widget_tweaks. I installed it and now im able to access each form tag and give them css classes and so on but when I try to submit the form its not working. Like the page is just reloading but nothing happens... Do I have to rewrite the view or make some changes in the model? Hope somebody can help me.
{% load widget_tweaks %}
<form name="form" method='POST' enctype='multipart/form-data'>
{% csrf_token %}
{% for field in form %}
<div class="md-form-group float-label">
{% render_field field class="md-input" %}
<label>{{ field.label_tag }}</label>
</div>
{% endfor %}
<input type="submit" class="btn btn-default" value='Create Post' />
</form>
When I use the {{form}} everything works except tat I cannot style the tags...
Every comment is welcome.
If it works with {{ form }} it should also work with widget-tweaks without altering your view code.
Edit:
The correct way to add classes in widget_tweaks is:
{% render_field field_name class+="css_class_1 css_class_2" %}
Or
{{ form.field_name|add_class:"css_class_1 css_class_2" }}
And to be complete: you can show the errors by manually adding {{ field.errors }} for the fields you want to display error messages

CSS for Symfony2 forms: "Hello World" equivalent

How to alter the fields.html.twig template?
I am only looking for the "hello world" equivalent to see the first ever change to the form.
What's working (within a bundle view as add.Article.html.twig):
<div class="well;">
<form method="post" {{ form_enctype(form) }}>
{{ form_widget(form,{attr: {class:'test'}} ) }}
<input type="submit" class="btn btn-primary" />
</form>
</div>
The test class is only doing a CSS .test{background-color:grey;}. I am normally using Bootstrap.
In fields.html.twig I have:
{% block aliquam_input %}
{% spaceless %}
<div>
{{ form_label(form) }}
{{ form_errors(form) }}
{{ form_widget(form, { 'attr': {'class': 'test'} }) }}
</div>
{% endspaceless %}
{% endblock %}
and in app/config/config.yml:
# Twig Configuration
twig:
//..
form:
resources:
- 'AliquamSummaryBundle:Form:fields.html.twig'
The fields.html.twig is rendered ok to the main twig as I get an error when removing one of the hash in the fields twig.
What's not working (i.e. class test doesn't show) is when I try to make the fields.html.twig take effect on Article.html.twig:
{% block aliquam_input %}
{% spaceless %}
<div class="well;">
<form method="post" {{ form_enctype(form) }}>
{{ form_widget(form) }}
<input type="submit" class="btn btn-primary" />
</form>
</div>
{% endspaceless %}
{% endblock %}
As all forms will have the same format, I'd prefer to not set all html attributes to every single line. But what is the way to get the class "test" taking effect from the fields.html.twig template?
___________________________ Update for David _____________
Thanks #David, but unfortunately adding the name as form.name doesn’t change anything. The CSS attribute is still not transferred to the form in html. Well spot for the semicolon after well; it was a late night typo, but not related to the problem.
Here is what I have figured so far. I might have to end up having to enter bootstrap CSS to each individual row in a form (horrible thought) or figure how to do this by entities options, which comes almost to the same horrible thought as doing it for every row. Since the doc offers to enter a template for all forms via app/config/config.yml there should be a far simpler way, but I don’t get it.
The below is the only direction so far which made CSS work a little, i.e. class .test{background-color: black;} is doing its job:
{# ..\addArticle.html.twig #}
<div class="well">
<form method="post" {{ form_enctype(form) }}>
{{ form_widget(form) }}
<input type="submit" class="btn btn-primary" />
</form>
</div>
NB: there is no {% block .. %} around the div, which makes sense as I put the fields.html.twig to be included to the symphony standard widgets through app/config/config.yml. The above goes with the fields.html.twig below.
{# ..\fields.html.twig #}
{% block widget_attributes %}
{% spaceless %}
{{" class=\'test\'" }}
{% endspaceless %}
{% endblock widget_attributes %}
So far only fields with textarea show black color, bit it’s kind of “hello world”. I am not sure if this is right way to proceed as I have not found anything alike in this and other forums and the doc only states to look at form_div_layout.html.twig on git to decide which attribute to change, which is not really helpful (to me).
First change your well; class to well in your add.Article.html.twig.
In order to put a class on your widget I think you can try
{{ form_widget(form.name, {'attr': {'class': 'test'}}) }}
The difference with your code is the form.name parameter. If you only give the form it will not apply passed options. See the doc
Changing the fields.html.twig as
{# ..\fields.html.twig #}
{% block widget_attributes %}
{% spaceless %}
{{" class=\'test\'" }}
{% endspaceless %}
{% endblock widget_attributes %}
is indeed correct in what concerns Symfony and the reason that with bootstrap-CSS only the textareas show the class="test" is that bootstrap assigns mandatorily (all other than textareas) with the bootstrap specific one.
As I don't want to alter the bootstrap as such I ended up assigning the attributes per widget from within the entities - anything else would probably opening a can of worms.

Change html select in twig+formbuilder

I would like know how can I change this:
<select id="mifid-proprio" name="mifid-proprio">
<option value="{{ personne.id }}">{{ personne.prenom }} {{ personne.nom }}</option>
{% for key, proprietaire in proprietaires %}
<option value="{{ proprietaire.destination.id }}">{{ proprietaire.destination.prenom }} {{ proprietaire.destination.nom }}</option>
{% endfor %}
</select>
into Twig + Formbuilder (Symfony 2).
I think you want to build that widget in the FormBuilder. If I am right you should take a look at the documentation of the choice Field Type. When the data you want to display in that select box comes from a database you should take a look at the entity Field Type. If you have never worked with the FormBuilder before, you should also read how to create form classes.
If you build that widget in the FormBuilder you can output it in Twig with:
{{ form_widget(form.field_name) }}
When you are not satisfied with the generated HTML code you can overwrite it, either on a per-template or global basis. You can read more about form theming.

Symfony2 how to render Checkboxes?

I have a formbuilder form with a multiple choice list of countries. When I render them on my form like this:
{{ form_widget(edit_form.countries) }}
They appear like this:
<input type="checkbox" name="..." value="AD" /><label for="...">Andorra</label>
<input type="checkbox" name="..." value="AE" /><label for="...">United Arab Emirates</label>
<input type="checkbox" name="..." value="AF" /><label for="...">Afghanistan</label>
I would like each option displayed on it's own line in the browser, instead of all in a row. How can I inject html around or between the options? Or is there a CSS method to accomplish this?
Thanks.
From The Symfony Docs
Form theming
How to customize form rendering
Default form div layout
What you basically need to do is to overload checkbox_widget block.
{% form_theme form _self %}
{% block checkbox_widget %}
{% spaceless %}
<input type="checkbox" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />
{% endspaceless %}
{% endblock checkbox_widget %}
Of course you can place your widgets in its own line with CSS (but it's not a Symfony2 question).
A lazier way I found to do this was to iterate through the form/choice array.
At its simplest, rendering a form you might do:
{{ form_widget(form) }}
For a little more granularity, you might do:
{{ form_row(form.itemA) }}
{{ form_row(form.itemB) }}
{{ form_row(form.itemC) }}
But if "itemA" is a multi-choice, you're stuck with the entire list getting rendered on the same line. If you're looking for just a little more granularity before you step up to theming, you can do this:
{% for t in form.itemA %}
{{ form_row(t) }}
{% endfor %}
That'll render each checkbox on its own line, or give you an opportunity to do whatever you want between each item.
As Kuba has said in his answer this sounds partly like a CSS question. Semantically speaking injecting something like a <br /> tag doesn't have much meaning but you can do that if you wish by following the documents in Kuba's answer.
If you wish to write some CSS to get those elements to display line by line you can use this against symfony's default output:
input, label {
float: left;
}
input {
clear: left;
}
Of course this will actually cause all input and label tags to float left which might not be suitable to you so you can a) wrap your checkboxes in another div and use a css sub-selector like .checkboxes input, .checkboxes label or b) apply a custom css class to your widgets using:
{{ form_widget(form.name, { 'attr': {'class': 'foo'} }) }}
and the CSS would be the same but instead of input you'd have .foo.

Resources