Set widget container attributes dynamically - symfony

I'm busy with templating my forms inside Symfony 2.0.
It is possible to add attributes to a formfield like this:
$form->add('name', 'text', array('attr' => array('class' => 'my_class')));
But how can I dynamically add attributes to the formfield widget? If i look to the form_div_layout.html.twig content, their is a
{{ block('widget_container_attributes') }}
which can load attributes, but I have no idea where I can add attributes to my FormBuilder in the Controller. Could anyone help me?
Thx!

You should do that in twig layer:
{{ form_row(form.name, {attr: {class: 'my_class'}}) }}

Related

Symfony 4 - Organize layout of fields

Using Symfony 4, I wonder if there a simple way to organize the layout of how display my fields.
For now, I template everything in my views (to have 2 columns for example) :
<div class="row">
<div class="col-md-6">
{{ form_row(form.name) }}
</div>
<div class="col-md-6">
{{ form_row(form.company) }}
</div>
</div>
{{ form_rest(form) }}
But, I don't want to do this, I just want to render whole form in my view, and manage the template in my FormBuilder. I would like to write something like :
$builder
->add('<div class="row"><div class="col-md-6">', HtmlType::class)
->add('name', TextType::class, [
'label' => 'Nom'
])
->add('</div><div class="col-md-6">', HtmlType::class)
->add('company', TextType::class, [
'label' => 'Société cliente'
])
->add('</div></div>', HtmlType::class);
I looked at the documentation, but it's pretty poor, it shows how to inerhit from existing fields.
Is there a way to create this HtmlType to just handle simple Html tags ? or a better way ?
You should be able to do something like that :
$builder->add('your_field', YourFieldClass::class, [
'attr' => ['class' => 'your css class'],
]);
The best solution would be to create a custom form theme. Reference to the documentation is here. I haven't done this myself for creating custom grid but I guess you can create some custom type options using the OptionResolver that will tell your template how to organize your fields and then based on that you can organize your custom form theme however you want.

Unable to set custom data in show action field in symfony sonata admin

I have a show page and I want to add a custom value.
I have tried doing what I did in other actions which is to add an array to the
third parameter with the data key like so:
protected function configureShowFields(ShowMapper $showMapper)
{
$showMapper
->add('name')
->add('dateEnd')
->add('example', null,
array('data' => 'example value')
)
;
}
In the configureListFields action, this works. I have injected custom values with the data attribute.
But still I am not able to access key example in the show.html.twig file.
It gives me this error
Variable "example" does not exist.
What should I do to access this custom variable in the twig file ?
Try
{{ elements.elements.example.options.data }}
in your twig template
I used this solution. In the configureShowFields() method of an Admin class:
$showMapper
->with('Tab Name')
->add(
'any_name',
null,
[
'template' => 'Admin/Custom/any_name_show_template.html.twig',
'customData' => $this->someRepository->getSomeEntityBy($field),
'anotherCustomData' => $this->someService->getSomeDataBy($value),
]
)
;
In the custom template, you can access custom data by field_description.options.<customFieldName>, so for provided example data accessors would be {{ field_description.options.customData }} and {{ field_description.options.anotherCustomData }}
For the shorter field name in the Twig template, you can do like this:
{% set customData = field_description.options.customData %}
and access the custom data like {{ customData }}
Hope this helps and saves time.

Symfony - pass custom data from Form Builder to form theme

I would like to set a special div surrounding a bunch of my fields. For that I want to add something to the form builder that I could detect in my form_theme, and set the div when it's there.
I tried to add
->add('field', new myCustomType(), array('inherit_data' => true, "label" => false, "required" => false, 'attr' => array("test" => "aaa")))
to the form builder, setting an custom attr, it's actually rendered in the html as an attribute... But I'm unable to detect it in the form theme.
{{ block('widget_container_attributes') }}
Only gives the widget attributes, and
{{ block('row_container_attributes') }}
doesn't work. I actually have a hard time finding any source online about what variables are available in the blocks of the form theme and how to use them (it was already difficult to know how to call blocks).
I looked for some more information on the official site, here mostly but without any success...
Thanks ahead for any help !
If you put it in your form builder, then you might as well permanently set in your template. If there is some logic required to set the data, then that belongs in your controller anyway, so just put it there to start with.
Controller:
public function someAction()
{
// ....
return $this->render('some_twig_template.twig.html', array(
'attr' => array("test" => "aaa")
);
}
Then in your twig template
{{ dump(attr) }}
{{ dump(attr.test) }}
EDIT:
To render in your template every time, you can set a class on the rendered field directly:
{{ form_label(form.field, 'My label', { 'label_attr': {'class': 'js-hidden-row'} }) }}
{{ form_widget(form.field, { 'attr': {'class': 'js-hidden-row'} }) }}
Then in my javascript you can hide with some simple jQuery:
<script>
jQuery(document).ready(function() {
$('.js-hidden-row').hide();
});
</script>

How to set attr id and class in form widget

How can I set attr id and class in twig, something like :
{{ form_widget(form.description,{'attr':{'id':"editor-one",'class':"editor-wrapper"}}) }}
If I understand your question correctly, wou want to add a class to a form. You can do so by passing the class as an attribute option to createFormBuilder.
$this->createFormBuilder($entity, array('attr' => array('class' => 'classname')));
I imagine you can do the same with ID, although I have not tried that myself.
You must move 'id' outside of 'attr', like this:
{{ form_widget(form.description,{'id':"editor-one", 'attr':{'class':"editor-wrapper"}}) }}

Grouped checkboxes in Symfony / twig

I have 2 entities: Projects and Categories. I have a ManyToMany relation between these two.
The Categories has ManytoOne relation with the entity "industry"
At this moment, there is no direct relation between Projects and industry and I would like to keep this like so, for further search functionality. So in the category table, the list includes categories from all industries.
When I build the form to edit the project (using the form widget), I have a list of checkboxes representing all the categories listed in my category table.
I would like to group the category choices by industry. How can this be done on the form layout only? How can I extract the industry value from the twig widget form data and group the checkboxes by the industry entity?
Thanks Leevi,
I could not find how to implement the suggestion above using both industry and category related entities... I finally found this way of going around the issue, tell me if there is a simpler way, but this works perfect now.
This is my form in the controller
$form = $this->createFormBuilder($project)
->add('categories', 'entity', array(
'class' => 'ACMEProjectBundle:Category',
'property' => 'name',
'expanded' => true,
'multiple' => true,
->getForm();
I also pass to the rendered form the array of industries which has each a list of related categories
$industries = $this->getDoctrine()->getManager()->getRepository('ACMEProjectBundle:Industry')->findall();
In the form.html.twig template
{{ form_errors(form) }}
<form method="post" {{ form_enctype(form) }}>
{% for industry in industries %}
<h4>{{industry.name}}</h4>
<ul class="unstyled">
{% for category in industry.categories %}
{% set key = category.id %}
<li>{{ form_widget(form.categories[key]) }}{{category.name}}</li>
{% endfor %}
</ul>
{% endfor %}
{{form_rest(form)}}
Which gives me the wanted results.
Hopefully this will be enough direction without giving you exact code examples :).
You'll have to setup your form with an expanded, multiple, entity field like so:
<?php
// src/Acme/ProjectBundle/Controller/DefaultController.php
namespace Acme\ProjectBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Acme\ProjectBundle\Entity\Project;
use Symfony\Component\HttpFoundation\Request;
class DefaultController extends Controller
{
public function newAction(Request $request)
{
// create a project and give it some dummy data for this example
$project = new Project();
$form = $this->createFormBuilder($project)
->add('categories', 'entity', array(
'expanded' => true,
'multiple' => true,
'group_by' => 'industry.title'
))
->add('save', 'submit')
->getForm();
return $this->render('AcmeProjectBundle:Default:new.html.twig', array(
'form' => $form->createView(),
));
}
}
The group_by parameter groups the options based on the property path:
See: http://symfony.com/doc/current/reference/forms/types/entity.html#group-by
Now group_by renders a select tag but you should be able to override that with a custom twig theme or manually in the template.
Given the form above you can access the choices in {{ form.categories.vars.choices }} and iterate over them manually.
See: {% block choice_widget_collapsed %} in form_div_layout.html.twig to see how the select box is rendered.
Here's some more information of form theming: http://symfony.com/doc/current/cookbook/form/form_customization.html

Resources