【问题标题】:Correct way to use FormEvents to customise fields in SonataAdmin在 SonataAdmin 中使用 FormEvents 自定义字段的正确方法
【发布时间】:2014-10-07 22:16:26
【问题描述】:

我有一个 Sonata Admin 类,其中包含一些表单字段,但我想使用 FormEvents::PRE_SET_DATA 事件根据绑定的数据动态添加另一个表单字段。

但是,我遇到了几个问题:

1) 我能找到在管理员中将表单字段添加到正确的“formGroup”的唯一方法是添加新字段两次(一次通过 formMapper,一次通过表单本身)......这看起来很错了,我无法控制它出现在 formGroup 的哪个位置。

2) 添加的元素似乎不知道它有一个连接的管理员(可能是因为它是使用Form::add() 添加的)。这意味着它与表单中的其他字段的呈现方式不同,因为它触发了form_admin_fields.html.twig 中的{% if sonata_admin is not defined or not sonata_admin_enabled or not sonata_admin.field_description %} 条件

所以,这让我相信我做错了,一定有更好的方法。

所以...

在使用 SonataAdmin 时,使用 FormEvent 将字段添加到表单组(最好是在该组中的首选位置)的正确方法是什么?

这是一些代码,FWIW...

protected function configureFormFields(FormMapper $formMapper)
{
    $admin = $this;
    $formMapper->getFormBuilder()->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($admin, $formMapper) {
        $subject = $event->getData();

        // do something fancy with $subject
        $formOptions = array(/* some cool stuff*/);

        // If I don't add the field with the $formMapper then the new field doesn't appear on the rendered form
        $formMapper
            ->with('MyFormGroup')
                ->add('foo', null, $formOptions)
            ->end()
        ;

        // If I don't add the field with Form::add() then I get a Twig Exception: 
        // Key "foo" for array with keys "..." does not exist in my_form_template.html.twig at line xx
        $event
            ->getForm()
            ->add('foo', null, $formOptions)
        ;
    });

    $formMapper
        ->with('MyFormGroup')
            ->add('fieldOne')
            ->add('fieldTwo')
        ->end()
    ;
}

目的是在MyFormGroup 中的fieldOnefieldTwo 之间添加新的foo 字段。


编辑:这是我在 Cassiano 的回答的帮助下得出的结论

protected function configureFormFields(FormMapper $formMapper)
{
    $builder = $formMapper->getFormBuilder();
    $ff = $builder->getFormFactory();
    $admin = $this;
    $formMapper->getFormBuilder()->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($ff, $admin) {
        $subject = $event->getData();

        // do something fancy with $subject
        $formOptions = array(
            'auto_initialize'       => false,
            'class'                 => 'My\ProjectBundle\Entity\MyEntity',
            /* some cool stuff*/
        );

        $event->getForm()->add($ff->createNamed('foo', 'entity', null, $formOptions));
    });

    $formMapper
        ->with('MyFormGroup')
            ->add('fieldOne')
            ->add('foo')  // adding it here gets the field in the right place, it's then redefined by the event code
            ->add('fieldTwo')
        ->end()
    ;
}

【问题讨论】:

    标签: forms symfony sonata-admin


    【解决方案1】:

    没有时间在这里回答长篇大论,我将粘贴一段代码,我不知道是否完全适合您的情况,在我看来,它是多依赖选择(国家、州、城市、邻居)的一部分。

    use Symfony\Component\Form\FormEvents;
    use Symfony\Component\Form\FormEvent;
    use Doctrine\ORM\EntityRepository;
    
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper->add('myfield');
    
        $builder = $formMapper->getFormBuilder();
        $ff = $builder->getFormFactory();
        $func = function (FormEvent $e) use ($ff) {
            $form = $e->getForm();
            if ($form->has('myfield')) {
                $form->remove('myfield');
            }
            $form->add($ff->createNamed('myfield', 'entity', null, array(
                'class' => '...',
                'attr' => array('class' => 'form-control'),
                'auto_initialize' => false,
                'query_builder' => function (EntityRepository $repository) use ($pais) {
                    $qb = $repository->createQueryBuilder('estado');
                    if ($pais instanceof ...) {
                        $qb = $qb->where('myfield.other = :other')
                                ->setParameter('other', $other);
                    } elseif(is_numeric($other)) {
                        $qb = $qb->where('myfield.other = :other_id')
                                ->setParameter('other_id', $other);
                    }
                    return $qb;
                }
            )));
        };
        $builder->addEventListener(FormEvents::PRE_SET_DATA, $func);
        $builder->addEventListener(FormEvents::PRE_BIND, $func);
    }
    

    【讨论】:

    • 这似乎成功了——谢谢!将更新上述问题,以在这些部分显示用于未来旅行者的代码。
    • 你好@Cassiano,@Caponica,我有问题。添加 $form->add($ff->createName('foto.messages') 时,我得到这个错误:The name "foto.messages" contains illegal characters. Names should start with a letter, digit or underscore and only contain letters, digits, numbers, underscores ("_"), hyphens ("-") and colons (":").
    • Sorry @webyseo 无法仅提供此描述,也许您可​​以在 Stackoverflow 上打开一个新问题,以便我们有更多详细信息来回答您。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多