Symfony2表单:根据表单值设置默认选项

时间:2016-06-01 10:16:30

标签: php forms symfony

我正在使用Symfony2框架(特别是Symfony 2.7)。我的问题与表格构建有关。

我有一个名为 place 的实体,它可以与我项目的许多其他实体相关联。因此,我创建了一个自定义表单类型,可以在我的应用程序的许多部分中重用。

class PlacesType extends AbstractType
{

    private $security_context;

    public function __construct(SecurityContext $security_context)
    {
        $this->security_context = $security_context;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $user = $this->security_context->getToken()->getUser();

        parent::configureOptions($resolver);

        $resolver->setDefaults(array(
            'class' => 'AppBundle\Entity\Places',
            'query_builder' => function (EntityRepository $repository) use ($user)
            {
                return $repository->queryPlacesForUser($user);
            },
        ));

    }

    public function getParent()
    {
        return 'entity' ;
    }

    public function getName()
    {
        return 'places';
    }
}

事实上,地方可以被软删除(我在类中设置了一个已删除的标志)。因此,新实体只能与活动场所相关联,而旧实体可以与现在删除的场所保持关联。

出于这个原因,我希望 queryPlacesForUser 函数仅返回活动位置,除非该位置已经与父表单数据相关联。<登记/> 像这样:

    public function configureOptions(OptionsResolver $resolver)
    {
        // ...

        $currdata = $this->getForm()->getData(); // pseudo-code, this does not work

        $resolver->setDefaults(array(
            'class' => 'AppBundle\Entity\Places',
            'query_builder' => function (EntityRepository $repository) use ($user)
            {
                return $repository->queryPlacesForUser($user, $currdata);
            },
        ));

    }

不幸的是,我不知道如何从选项解析器获取当前数据。可以在表单的 buildForm 函数中检索当前数据,但是无法在其中设置表单选项。

有没有办法可以使用表单传递数据设置表单默认选项?

2 个答案:

答案 0 :(得分:2)

您无法访问configureOptions中的表单数据。我认为,只有你想要预先/重新配置扩展类型的附加约束,唯一的选择是将所需的配置提取到使用此自定义表单类型的位置。 E.g:

<强>用法

<?php

/**
 * @inheritdoc
 */
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $this->builder->add('place', PlacesType::class, [
        'only_active' => false // <- this is the *external* configuration
    ]);
}

PlacesType

<?php

/**
 * @inheritdoc
 */
public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'class' => 'AppBundle\Entity\Places',
        'only_active' => true, // <- this is the *default* configuration

        // note the extra closure, this gives you access to the *resolved* options.
        'query_builder' => function (Options $options) { 
            return function (EntityRepository $repository) use ($options) {
                return $repository->queryPlacesForUser(
                    $this->security_context->getToken()->getUser(),
                    $options['only_active']
                );
            };
        },
    ));
}

答案 1 :(得分:0)

您可以像这样使用事件监听器:

    $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
                    $data = $event->getData();
                    $form = $event->getForm();
    //check your data here and add the fields you want accordingly

$field = $builder->get('fieldToModify');         // get the field
$options = $field->getOptions();            // get the options
$type = $field->getType()->getName();       // get the name of the type
$options['label'] = "Login Name";           // change the label
$builder->add('fieldToModify', $type, $options); // replace the field
        }