Symfony2形式:启用/禁用侦听器的字段

时间:2015-04-24 14:47:29

标签: forms symfony events

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

$form->add('name', 'text', array("disabled" => "disabled");

这项工作在某种意义上很棒:如果某个字段已启用但应禁用,那么结果就可以了。 在另一种意义上,如果禁用某个字段,则不会发送此字段。在监听器中,该字段是启用的,但在最终结果中,初始值不再存在。

我认为,由于该字段已被禁用,因此未发送,因此Symfony认为它具有空值。来自preSubmit或Submit事件的监听器,如果我这样做:

$event->getData()

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

3 个答案:

答案 0 :(得分:4)

比以后更好:)

今天我遇到了同样的问题,总而言之,你不能使用监听器来改变字段的选项,因为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]));
}

答案 1 :(得分:3)

Marino Di Celemente的答案外,这是Symfony 3.2的略微调整的disableField方法

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]));
}

答案 2 :(得分:0)

您的问题看起来类似于Symfony's documentation on dynamic form modification中的示例。在您的情况下,值的“给定字段”取决于“名称”字段的禁用/重新启用,它等同于Symfony文档的“体育”字段以及您的“名称”字段(更具体地讲,“已禁用”选项)等效于Symfony文档的“位置”字段(更具体地说是“选择”选项)。

上面,我提供了Symfony 2.8文档的链接,因为它是您在问题中提到的版本,但是现在不再维护。如果您需要最新信息,请参阅more recent doc