具有额外选项

时间:2016-11-14 16:07:21

标签: symfony symfony-forms

希望有人帮助我,我无法解决这个问题。

我正在使用Symfony 3.1.6。

我有两个实体,地区和城市,关系是一对多。我有一个带有选择框的表单,用于加载区域,并且在选择的区域中显示该区域的城市。这很有效。

我已经通过finishView()向Cities组合框添加了一个选项,以便为用户提供机会,如果未列出他的城市,则选择此选项,并且显示的输入提供添加的可能性新城市。此选项值为0.

但是当提交表单时,会显示一个错误,显示“此值无效”。我认为这是因为没有任何地区的任何城市id = 0,该选项的价值。然后我需要的是禁用/消除/什么这样的验证,但我不知道如何做到这一点。

我试过了:

$builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {
        $event->stopPropagation();
    }, 900);

但没有奏效......

显然我可以使用ChoiceType而不是EntityType,消除实体之间的关系或其他不那么优雅的方法来解决这个问题。但我很确定有一种方法,这就是Symfony。

编辑1:添加LocationType

<?php
namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Doctrine\ORM\EntityRepository;
use Symfony\Component\Form\Extension\Core\Type\CountryType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\ChoiceList\View\ChoiceView;

class LocationType extends AbstractType
{

public function buildForm(FormBuilderInterface $builder, array $options)
{

    $region_options = array(
        'class' => 'AppBundle:Region',
        'choice_label' => 'name',
        'label' => 'Region',
        'translation_domain' => 'messages',
        'required' => true,
        'mapped' => false,
    );

    $city_options = array(
        'class' => 'AppBundle:City',
        'choice_label' => 'name',
        'label' => 'City',
        'translation_domain' => 'messages',
        'required' => true,
        'mapped' => false,
    );

    $alt_city_options = array(
        'required' => false,
        'mapped' => true,
        'label' => 'Alternative city',
        'translation_domain' => 'messages',
        'attr' => array(
            'placeholder' => 'Enter your city name',
        ),
    );

    $builder->addEventListener(
        FormEvents::PRE_SET_DATA,
        function (FormEvent $event) use ($region_options, $city_options, $alt_city_options) {
            $form = $event->getForm();
            $data = $event->getForm()->getParent()->getData();

            $country = '332';

            $region_options['query_builder'] = function (EntityRepository $er) use ($country) {
                    return $er->createQueryBuilder('r')
                        ->where('r.country = :country')
                        ->setParameter('country', $country)
                        ->orderBy('r.name', 'ASC');
                };

                if (!empty($data->getRegion())) {
                    $region_options['data'] = $data->getRegion()->getId();
                }
                $form->add('region', EntityType::class, $region_options);
            }

            if ( !empty($data->getRegion()) ) {
                $region = $data->getRegion();
                $city_options['query_builder'] = function (EntityRepository $er) use ($country, $region) {
                    return $er->createQueryBuilder('c')
                        ->where('c.country = :country')
                        ->andWhere('c.region = :region')
                        ->setParameter('country', $country)
                        ->setParameter('region', $region)
                        ->orderBy('c.name', 'ASC');
                };

                if (!empty($data->getCity())) {
                    $region_options['data'] = $data->getCity()->getId();
                }
                $form->add('city', EntityType::class, $city_options);
            }
            $form->add('alt_city', TextType::class, $alt_city_options);
        }
    );

    $builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {
        $event->stopPropagation();
    }, 900);
}

public function finishView(FormView $view, FormInterface $form, array $options)
{
    $new_choice = new ChoiceView(array(), '0', 'not_in_the_list');
    $view->children['city']->vars['choices'][] = $new_choice;
}

}

希望这有帮助。

1 个答案:

答案 0 :(得分:0)

您可以粘贴我们的EntityType字段定义吗?

它可以帮助解决问题。

要设置EntityType字段,您必须指定以下选项:

  • class
  • choice_label(除非您的实体中有__toString()函数)