3

I am trying to order an entity form field witch is translated.

I am using the symfony translation tool, so i can't order values with a SQL statement. Is there a way to sort values after there are loaded and translated ?

Maybe using a form event ?

$builder
    ->add('country', 'entity', 
            array(
                'class' => 'MyBundle:Country',
                'translation_domain' => 'countries',
                'property' => 'name',
                'empty_value' => '---',
            )
        )
Seb33300
  • 7,464
  • 2
  • 40
  • 57

3 Answers3

9

I found the solution to sort my field values in my Form Type.

We have to use the finishView() method which is called when the form view is created :

<?php

namespace My\Namespace\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\FormInterface;
use Symfony\Bundle\FrameworkBundle\Translation\Translator;

class MyFormType extends AbstractType
{
    protected $translator;

    public function __construct(Translator $translator)
    {
        $this->translator = $translator;
    }

    public function finishView(FormView $view, FormInterface $form, array $options)
    {
        // Order translated countries
        $collator = new \Collator($this->translator->getLocale());
        usort(
            $view->children['country']->vars['choices'], 
            function ($a, $b) use ($collator) {
                return $collator->compare(
                    $this->translator->trans($a->label, array(), 'countries'), 
                    $this->translator->trans($b->label, array(), 'countries')
                );
            }
        );
    }

    // ...

    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('country', 'entity', 
                    array(
                        'class' => 'MyBundle:Country',
                        'translation_domain' => 'countries',
                        'property' => 'name',
                        'empty_value' => '---',
                    )
                )
        ;
    }

}

OLD ANSWER

I found a solution for my problem, I can sort them in my controller after creating the view :

$fview = $form->createView();
usort(
    $fview->children['country']->vars['choices'], 
    function($a, $b) use ($translator){
        return strcoll($translator->trans($a->label, array(), 'countries'), $translator->trans($b->label, array(), 'countries'));
    }
);

Maybe I can do that in a better way ? Originally I wished to do directly in my form builder instead of adding extra code in controllers where I use this form.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Seb33300
  • 7,464
  • 2
  • 40
  • 57
0

I think it's impossible. You need to use PHP sorting, but if you use Symfony Form Type, I would advise to sort it with JavaScript after page is loaded.

Victor Bocharsky
  • 11,930
  • 13
  • 58
  • 91
0

If your countries are in an array, just use the sort() function, with the SORT_STRING flag. You will do some gymnastic to have it in my opinion. Check this doc : http://php.net/manual/fr/function.sort.php

Hornth
  • 323
  • 5
  • 13