在 Symfony 2/3 中有条件地启用表单类型

问题描述

我有 2 个表单类型,显示 2 个选择

thisFileisNew.pdf

然后在树枝模板中

    $builder
        ->add('control1',EntityType::class,[
            'label' => 'Country','class' => Country::class,])
        ->add('control2',[
            'label' => 'State','class' => State::class,])

如何仅在控件 1 中选择特定选项时启用控件 2?谢谢。

解决方法

Dynamic Generation for Submitted Forms

您想要自定义特定于用户提交的数据的表单。例如,假设您有一份体育聚会的注册表。某些事件将允许您指定您在场上的首选位置。例如,这将是一个选择字段。但是,可能的选择取决于每项运动。您需要正确的选项才能通过验证。

以下示例创建一个包含两个字段 countrystate 的表单。 state 字段取决于 country 字段,如果未选择任何国家/地区,则将保持禁用状态且没有可用选项。

表单类型

namespace AppBundle\Form;

use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;
use Doctrine\ORM\EntityManagerInterface;
use AppBundle\Entity\Country;
use AppBundle\Entity\State;

class CountryStateType extends AbstractType
{
  private $entityManager;
  private $countryRepository;
  private $stateRepository;

  public function __construct(EntityManagerInterface $entityManager)
  {
    $this->entityManager     = $entityManager;
    $this->countryRepository = $entityManager->getRepository(Country::class);
    $this->stateRepository   = $entityManager->getRepository(State::class);
  }
  public function buildForm(FormBuilderInterface $builder,array $options)
  {
    $builder->add('country',EntityType::class,[
      'class' => Country::class,'placeholder' => 'Select','choice_label' => 'name','label' => 'Country'
    ]);

    $formModifier = function (FormInterface $form,$countryId = null) {
      $country  = null === $countryId ? null : $this->countryRepository->find($countryId);
      $states   = null === $country ? [] : $this->stateRepository->findAll();
      $disabled = null === $country ? true : false;

      $form->add('state',[
        'class' => State::class,'label' => 'State','choices' => $states,'disabled' => $disabled
      ]);
    };

    $builder->addEventListener(
      FormEvents::PRE_SET_DATA,function (FormEvent $event) use ($formModifier) {
        $data = $event->getData();
        $data = null === $data ? [] : $data;
        $countryId = array_key_exists('country',$data) ? $data['country'] : null;

        $formModifier($event->getForm(),$countryId);
      }
    );

    $builder->get('country')
      ->addEventListener(FormEvents::POST_SUBMIT,function (FormEvent $event) use ($formModifier) {
        $country = $event->getForm()->getData();
        $countryId = null === $country ? null : $country->getId();

        $formModifier($event->getForm()->getParent(),$countryId);
      }
    );
  }
}

模板

{{ form_start(form) }}         
  {{ form_widget(form.country) }}
  {{ form_widget(form.state) }}
  <button type="submit">Submit</button>
{{ form_end(form) }}

<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
  var $country = $('#{{ form.country.vars.id }}');
  $country.change(function () {
    var $form = $(this).closest('form');
    var data = {};
    data[$country.attr('name')] = $country.val();

    $.ajax({
      url: $form.attr('action'),type: $form.attr('method'),data: data,success: function (html) {
        $('#{{ form.state.vars.id }}').replaceWith(
          $(html).find('#{{ form.state.vars.id }}')
        );
      }
    });
  });
</script>

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...