Pi Wi
Pi Wi

Reputation: 1085

Maintain posted order in symfony2 choice input field (with choice list)

I'm using the Symfony2 framework in my project and use the Form component to create forms. I'm using the choice input field type to enable users to multi select options and I'm using a plugin to enable users to order these options. Unfortunately the order of these options isn't maintained when posting the form to the controller. The request has the correct order by the Form component uses the order of the choices option.

How can I maintain the posted order using the Form component and choice input field type?

For the record, I did search on Google, Stackoverflow and at Github and I only found an issue about keeping the order of the preferred_choices (https://github.com/symfony/symfony/issues/5136). This issue does speak about a sort option but I can't find this option in the Symfony2 documentation.

Upvotes: 2

Views: 780

Answers (1)

Oleg Babakov
Oleg Babakov

Reputation: 76

I tried to solve same problem : it was needed to select several organizations and sort them in list.

And after $form->getData() my order from request was changed.

I made form event handlers and found that data have right order on FormEvents::PRE_SUBMIT event and I saved it in $this->preSubmitData.

After that, on FormEvents::SUBMIT event I overwrite data with wrong order (in real, it depends on order from choices option) from $this->preSubmitData. (You can remove array_merge from method)

class PriorityOrganizationSettingsType extends AbstractType {
    private $preSubmitData;

    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     * @throws \Exception
     */
    public function buildForm(FormBuilderInterface $builder, array $options)

        $builder
            ->add('organizations', 'choice', array(
                'multiple' => 'true',
                'required'    => false,
                'choices' => $this->getPriorityOperatorChoices(),
                'attr' => [
                    'class' => 'multiselect-sortable',
                    'style' => 'height: 350px; width:100%;'
                ]
            ))
        ;

        $builder->addEventListener(FormEvents::SUBMIT, array($this, 'submitEvent'));
        $builder->addEventListener(FormEvents::PRE_SUBMIT, array($this, 'preSubmitEvent'));
    }

    public function preSubmitEvent(FormEvent $event) {
        $this->preSubmitData = $event->getData();
    }

    public function submitEvent(FormEvent $event) {
        $event->setData(array_merge(
            $event->getData(),
            $this->preSubmitData
        ));
    }

}

Upvotes: 1

Related Questions