I need to custom sort entity type field, but without query_builder
option. I need to sort it based on some information not available at database-level (hence, not using the query_builder
).
Is there a way I can sort the elements of the <select>
widget?
EDIT: I have a parent
self-association in my section
table, which contains also a title
property:
+--------------+-----------+--------+
| section_id | parent_id | title |
+--------------+-----------+--------+
| 1 | NULL | Parent |
+--------------+-----------+--------+
| 2 | 1| Child |
+--------------+-----------+--------+
| 3 | 2| Nephew |
+--------------+-----------+--------+
I'd like to show a select box where items are sorted by a concatenation of its title and ancerstor's titles, i.e:
Parent
Parent/Child
Parent/Child/nephew
Not easy to accomplish with a single SQL select, so I need a way to get the options and simple sort by this "path".
You can default sort a relationship in the entity by doing this:
/**
* @ManyToMany(targetEntity="Group")
* @OrderBy({"name" = "ASC"})
**/
private $groups;
More info: Ordering To-Many Associations
If I understand the OP correctly, the sorting is merely for displaying the select options in order for the user's benefit.
Add a function to your form type like this:
public function finishView(FormView $view, FormInterface $form, array $options)
{
usort($view->children['select']->children, function(FormView $a, FormView $b) {
return strcasecmp($a->vars['value']->getFullTitle(), $b->vars['value']->getFullTitle());
});
}
This example assumes a getFullTitle()
function exists on your entity which can generated the value to use for sorting comparisons. select
would be the fieldName of the relationship the select box will be based on.
5 Years later...
Trying my own solution again in Symfony 4, this doesn't seem to work.
This is the solution that did work:
public function finishView(FormView $view, FormInterface $form, array $options)
{
usort($view->children['select']->vars['choices'], function(ChoiceView $a, ChoiceView $b) {
return strcasecmp($a->label, $b->label);
});
}
I would suggest to add a "path" field on your section. And as soon as you call $parent->addChild($child)
I would set the $child->path
to $parent->path . $child->path
. This is the only way if you want to filter within sql.
You could also consider using the Tree extension that uses nested sets in order to improve performance on this kind of operations: https://github.com/l3pp4rd/DoctrineExtensions/blob/master/doc/tree.md
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With