Symfony2 表单:从监听器启用/禁用字段

Rol*_*our 2 forms events symfony

我需要根据给定字段的值禁用/重新启用表单字段。为了实现它,我在 onPreSubmit 事件上使用了一个侦听器。然后,如果应禁用某个字段,则会将其再次添加到表单中,例如

$form->add('name', 'text', array("disabled" => "disabled");
Run Code Online (Sandbox Code Playgroud)

这在某种意义上非常有效:如果一个字段被启用但应该被禁用,那么结果是可以的。在另一种意义上,如果某个字段被禁用,则不会发送该字段。在侦听器中,该字段已启用,但在最终结果中,初始值不再存在。

我假设,因为该字段被禁用,它没有被发送,所以 Symfony 认为它有一个空值。从 preSubmit 或 Submit 事件的侦听器中,如果我这样做:

$event->getData()
Run Code Online (Sandbox Code Playgroud)

然后所有在表单中但不在 POST 数据中的字段都设置为空。有没有办法简单地激活字段,保持初始值?或者不考虑缺失字段的价值?

Mar*_*nte 5

迟到总比不到好:)

今天我遇到了同样的问题,总而言之,您无法使用侦听器更改字段的选项,因为 options 属性是私有的,并且只有 getOption 和 getOptions,但是您可以删除并添加该字段的克隆

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $this->buildUserForm($builder, $options);

    $builder->addEventListener(
        FormEvents::PRE_SET_DATA,
        function (FormEvent $event) {
            $form = $event->getForm();
            $user = $event->getData();
            if($user->getBirthday()){ 
                $this->disableField($form->get('birthday'));
            }
        }
    );
}

private function disableField($field){
    $parent = $field->getParent();
    $options = $field->getConfig()->getOptions();
    $name = $field->getName();
    $type = $field->getConfig()->getType()->getName();
    $parent->remove($name);
    $parent->add($name, $type, array_merge($options,['disabled' => true]));
}
Run Code Online (Sandbox Code Playgroud)


con*_*con 5

除了Marino Di Celemente的回答之外,这是 disableFieldSymfony 3.2的稍微调整的方法

use Symfony\Component\Form\FormInterface;
private function disableField(FormInterface $field)
{
    $parent  = $field->getParent();
    $options = $field->getConfig()->getOptions();
    $name    = $field->getName();
    $type    = get_class($field->getConfig()->getType()->getInnerType());
    $parent->remove($name);
    $parent->add($name, $type, array_merge($options, ['disabled' => true]));
}
Run Code Online (Sandbox Code Playgroud)