Reputation: 422
In my Symfony 3.x project, I have 3 entities:
Assumptions:
I would like to render Symfony form for Project entity. I'm using EntityType
field for properties
. However, instead of displaying them in one, long list, I would like to divide them in columns, with Categories as headers.
Regular way of displaying EntityType field:
What I would like to get:
How do I do that? - Without using dirty hacks in entities or views.
Upvotes: 1
Views: 800
Reputation: 422
So the only way I found it working was:
In Repository class (pulling list of all properties with child properties and categories):
$this->getEntityManager()
->createQueryBuilder()
->select('t, category, children')
->join('t.category', 'category')
->leftJoin('t.children', 'children')
->where('t.parent IS NULL')
->orderBy('category.sortOrder', 'ASC')
->addOrderBy('t.sortOrder', 'ASC')
->addOrderBy('t.name', 'ASC');
$entities = $query->getResult();
$options = [];
/** @var Property $entity */
foreach ($entities as $entity) {
$options[$entity->getCategory()->getName()][] = $entity;
}
In Entity class (pulling the list of IDs of selected properties, to preselect checkboxes in the view file):
public function getPropertyIds() {
$properties = $this->getProperties();
$propertyIds = [];
foreach ($properties as $property) {
$propertyIds[] = $property->getId();
}
return $propertyIds;
}
Edition form class, so the data can be validated:
$builder
->add(
'properties',
EntityType::class,
[
'label' => 'Properties',
'class' => Property::class,
'choice_label' => 'name',
'placeholder' => '',
'expanded' => true,
'multiple' => true,
'required' => false,
]
);
And finally, the view file:
{% for categoryName, items in properties %}
<h2>{{ categoryName }}</h2>
<ul>
{% for property in items %}
<li>
<input type="checkbox"
name="{{ form.properties.vars.full_name }}[]"
value="{{ property.id }}"
id="{{ form.properties.vars.id }}_{{ property.id }}">
<label for="{{ form.properties.vars.id }}_{{ property.id }}">
{{ property.name }}
</label>
</li>
{% endfor %}
</ul>
{% endfor %}
{% do form.properties.setRendered %}
(I omitted the "checked" and "children" part in the view)
However this solution is not ideal in my point of view. I would rather to get rid of manually generating <input...>
in the view - I would rather want to use some helper functions.
Anyway, this is some kind of low-level solution to my problem. Hope that helps.
Upvotes: 2