使用 Sonata 字段类型在 Controller 中创建表单

Posted

技术标签:

【中文标题】使用 Sonata 字段类型在 Controller 中创建表单【英文标题】:Create form in Controller using Sonata field type 【发布时间】:2016-05-15 20:44:59 【问题描述】:

在 Symfony admin 中,我有一个表单,其中第二个字段类型取决于所选的 ChoiceField 值。第二个字段可以是 Symfony Url 字段类型或奏鸣曲提供的 sonata_type_model_list 字段类型。

我已向 My Bundle Controller 创建了一个 ajax 请求以返回包含所需字段的表单。

> /src/MyBundle/Controller/MyController.php

namespace MyBundle\Controller

use Sonata\AdminBundle\Controller\CRUDController;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
use Sonata\AdminBundle\Form\FormMapper;

class MyController extends CRUDController

    public function getFieldAction()
  
    //getting the value of choice field
    $type = $this->get('request')->get('type'); 

    //sonata.admin.reference is a service name of ReferenceBundle admin class
        $fieldDescription = $this->admin->getModelManager()
         ->getNewFieldDescriptionInstance($this->admin->getClass(), 'reference');
        $fieldDescription->setAssociationAdmin($this->container->get('sonata.admin.reference'));
        $fieldDescription->setAdmin($this->admin);
        $fieldDescription->setAssociationMapping(array(
            'fieldName' => 'reference',
            'type' => ClassMetadataInfo::ONE_TO_MANY,
        ));
    
    // Getting form mapper in controller:
    $contractor = $this->container->get('sonata.admin.builder.orm_form');
    $mapper = new FormMapper($contractor, $this->admin->getFormBuilder(), $this->admin);

    $form_mapper = $mapper->add('reference', 'sonata_type_model_list', array(
            'translation_domain' => 'ReferenceBundle',
            'sonata_field_description' => $fieldDescription,
            'class' => $this->container->get('sonata.admin.reference')->getClass(),
            'model_manager' => $this->container->get('sonata.admin.reference')->getModelManager(),
            'label' => 'Reference',
            'required' => false,
        ));


    //@ToDo build $form from $form_mapper


    return $this->render('MyBundle:Form:field.view.html.twig', array(
        'form' => $form->createView(),
    ));
  

我在Sonata\AdminBundle\Form\FormMapper 类中找不到任何方法来构建表单(create() 方法似乎可以,但它只适用于常见的 Symfony 字段类型,而不适用于通常在Block 或 Admin 类)。

是否可以在Controller中使用Sonata\AdminBundle\Form\FormMapper来构建表单? 或者有没有其他方法可以在 Controller 中使用 Sonata 表单字段类型构建表单?

【问题讨论】:

为什么不使用您的 Admin Class 制作表单?就是为了这个 【参考方案1】:

您不应使用控制器,而应使用 Sonata Admin Service。

Sonata 为您提供了“sonata_type_choice_field_mask”类型,它允许您根据“sonata_type_choice_field_mask”输入的值动态更改表单上显示的字段。

Here is the doc 在这里您可以找到有关奏鸣曲类型和选择字段掩码的所有信息。

protected function configureFormFields(FormMapper $formMapper)

    $formMapper
        ->add('reference', 'sonata_type_choice_field_mask', array(
            'choices' => array(
                //The list of available 'Reference' here
                'choice1',
                'choice2'
            ),
            'map' => array(
                //What you want to display depending of the selected option
                'choice1' => array(
                    // List of the fields displayed if choice 1 is selected
                    'field1', 'field3'
                ),
                'choice2' => array(
                    // List of the fields displayed if choice 2 is selected
                    'field2', 'field3'
                )
            ),
            'placeholder' => 'Choose an option',
            'required' => false
        ))
        ->add('field1', 'sonata_type_model_list', array(/* Options goes here */))
        ->add('field2', 'url', array(/* Options goes here */))
        ->add('field3')
    ;

【讨论】:

【参考方案2】:

您似乎可以访问直接处理使用Sonata\AdminBundle\Admin\AbstractAdmin::getForm 构建表单的管理员。

$form = $this->admin->getForm();

【讨论】:

以上是关于使用 Sonata 字段类型在 Controller 中创建表单的主要内容,如果未能解决你的问题,请参考以下文章

使用更多表单字段扩展奏鸣曲用户包,获取无法加载类型“Application\Sonata\UserBundle\Form\RegistrationType”

Symfony Sonata Admin - 在 listView 中添加字段类型 url 不起作用

如何在 Sonata Admin 中正确配置“sonata_type_collection”字段

Sonata Admin 的 sonata_type_model 字段的自定义选项列表

如何使用 Sonata 和 Knp 可翻译行为克隆翻译的字段

sonata_type_collection 字段仅适用于现有的父对象