Задать вопрос

Как создать каскадную форму Symfony 2?

Всем доброго дня. Есть задача: сделать форму symfony с тремя полями Страна, Регион, Город.
Эти данные выбираются из выпадающих списков. Соответственно варианты в списках Регион и Город. появляются только после выбора в предыдущем поле.
Со стороны JS - всё понятно и работает, а вот при отправке формы затык, а именно:
Всё реализовано как указано тут: symfony.com.ua/doc/current/form/dynamic_form_modif... радел "Динамическое генерирование для отправленной формы". И с полем "Регион" вопросов не возникает - всё работает, А вот событие POST_SUBMIT уже для региона - не отрабатывает.

Вот код фомы:
<?php

class MyInputType extends AbstractType
{

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        /** @var MyInput $data */
        $data = $builder->getData();
        $builder->add('country', 'entity', [
            'class' => Country::class,
            'choices' => $data->getAvailableCountries(),
            'required' => false,
        ]);

        $this->addRegionPole($builder,$data->getAvailableRegions($data->getCountry()));
        $this->addCityPole($builder,$data->getAvailableCities($data->getCountry(), $data->getRegion()));

        $this->iniPOST_SUBMIT_event($builder);
    }

    private function iniPOST_SUBMIT_event(FormBuilderInterface $builder)
    {
        $context = $this;
        $builder->get('country')->addEventListener(
            FormEvents::POST_SUBMIT,
            function (FormEvent $event) use ($context) {
                /** @var Country $data */
                $data = $event->getForm()->getData();
                $form = $event->getForm()->getParent();
                $context->addRegionPole($form,$form->getData()->getAvailableRegions($data));
            }
        );

        $builder->get('region')->addEventListener(
            FormEvents::POST_SUBMIT,
            function (FormEvent $event) use ($context) {
                /** @var Region $data */
                $region = $event->getForm()->getData();
                $form = $event->getForm()->getParent();
                /** @var Country $country */
                $country = $form->get('country')->getData();

                /** @var MyInput $MyInput */
                $MyInput = $form->getData();

                $context->addCityPole($form,$MyInput->getAvailableCities($country,$region));
            }
        );
    }

    /**
     * @param FormInterface $form
     * @param array $choices
     */
    protected function addRegionPole($form, array $choices)
    {
        $form->add('region', 'entity', [
			'class' => Region::class,
            'choices' => $choices,
            'required' => false,
        ]);
    }

    /**
     * @param FormInterface | FormBuilderInterface $form
     * @param array $choices
     */
    protected function addCityPole($form, array $choices)
    {
        $form->add('city', 'entity', [
            'class' => City::class,
            'choices' => $choices,
            'required' => false,
        ]);
    }

    /**
     * @param OptionsResolverInterface $resolver
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults([
            'data_class' => MyInput::class,
            'csrf_protection' => false,
        ]);
    }

    /**
     * Returns the name of this type.
     *
     * @return string The name of this type
     */
    public function getName()
    {
        return 'MyInputType';
    }
}
  • Вопрос задан
  • 384 просмотра
Подписаться 4 Средний Комментировать
Пригласить эксперта
Ответы на вопрос 1
voronkovich
@voronkovich
Вы динамически переопределяете поле для региона, тем самым "затирая" слушатель события. Т.е. вам нужно еще раз добавить слушатель:

$builder->get('country')->addEventListener(
            FormEvents::POST_SUBMIT,
            function (FormEvent $event) use ($context) {
                /** @var Country $data */
                $data = $event->getForm()->getData();
                $form = $event->getForm()->getParent();

                // !!! Здесь слушатель события для поля 'region' удаляется !!!
                $context->addRegionPole($form,$form->getData()->getAvailableRegions($data));
            }
        );


Возможно, вам лучше вынести код с навешиванием обработчиков в методы addRegionPole и addCityPole:
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы