Symfony2 Sonata 管理员根据所选值动态更改输入数据

Dom*_*s55 1 php forms jquery symfony sonata-admin

对于我的一个对象,我需要创建一些动态表单渲染...但我不知道如何在 Sonata Admin 中执行此操作。例如,当我创建一个对象时,我有一个字段类型。在此字段中,我选择我的对象的类型。现在,当我选择类型时,我想根据类型显示一个字段。例如,如果我选择类型“轮播”,我想显示一个选择实体库中所有对象的字段。如果我选择类型“产品”,我想显示包含所有可供选择的产品的字段...我怎样才能实现这一点?

现在我有这个:

/**
 * @param FormMapper $formMapper
 */
protected function configureFormFields(FormMapper $formMapper)
{
    $formMapper
        ->with('Module', array(
            'class' => 'col-md-6'
        ))
            ->add('position')
            ->add('type', null, array(
                'attr' => array('class' => 'module_type')
            ))
            ->add('items', 'entity', array(
                'class' => 'ApplicationSonataMediaBundle:Gallery'
            ))
        ->end()
    ;
}
Run Code Online (Sandbox Code Playgroud)

我已经覆盖了编辑模板:

{% extends 'SonataAdminBundle:CRUD:edit.html.twig' %}

{% block javascripts %}
    {{ parent() }}
    <script type="text/javascript">
        $(document).ready(function () {
            $(".module_type").change(function() {

            });

        });
    </script>

{% endblock %}
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,画廊现在是硬编码的..

我现在不知道该怎么做...怎么说如果选择的值是这个,则在字段中使用该实体...问题是在 Sonata 中渲染表单的方式非常复杂...我不知道明白它..

也许我应该使用ajax?但是,当我发送一个值并获得响应时,如何在不刷新的情况下添加字段?

任何帮助表示赞赏。

Tof*_*del 5

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

在这个文档中,您可以找到有关奏鸣曲类型和选择字段掩码的所有信息。

protected function configureFormFields(FormMapper $formMapper)
{
    $formMapper
        ->add('type', 'sonata_type_choice_field_mask', array(
            'choices' => array(
                //The list of available 'Type' 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' => true
        ))
        ->add('field1', 'entity', array(/* Options for entity1 goes here */))
        ->add('field2', 'entity', array(/* Options for entity2 goes here */))
        ->add('field3')
    ;
}
Run Code Online (Sandbox Code Playgroud)


小智 5

在不断研究找到一种使用ajax和奏鸣曲与symfony4使用动态下拉菜单的方法之后,我想分享我的解决方案,它实际上是如何为我工作的。

\n\n

就我而言,我有一个区,这个区有不同的城市。我有一家公司,首先选择一个地区,然后根据该地区选择\xc2\xb4s 城市。

\n\n

我做了什么:

\n\n
    \n
  1. 为各地区创建您的实体

  2. \n
  3. 为城市创建您的实体

  4. \n
  5. 进入您的主类(在我的例子中,这是公司实体,并为地区和城市添加两个实体

  6. \n
\n\n
    /**\n     * @ORM\\ManyToOne(targetEntity="App\\Wdm\\MainBundle\\Entity\\Model\\Cities",   inversedBy="id")\n     */\n    private $city;\n\n    /**\n    * @ORM\\ManyToOne(targetEntity="App\\Wdm\\MainBundle\\Entity\\Model\\Districts", inversedBy="id")\n    */\n     private $district;\n\n
Run Code Online (Sandbox Code Playgroud)\n\n
    \n
  1. 更新数据库架构并使用一些示例数据填充城市和地区字段

  2. \n
  3. 进入 configureFormFields 函数中的 AdminClass 并添加以下内容(确保将“choice_label”选项与您的地区或城市实体中的相应字段正确使用。

  4. \n
\n\n
    protected function configureFormFields(FormMapper $formMapper)\n    {         $formMapper\n                  // Some other added fields\n\n             ->add(\'district\', EntityType::class, [\n                 \'choice_label\' => \'name\',\n                 \'class\'       => Districts::class,\n                 \'placeholder\' => \'\',\n             ])\n\n             ->add(\'city\', EntityType::class, [\n                 \'choice_label\' => \'name\',\n                 \'class\'       => Cities::class,\n                 \'placeholder\' => \'\',\n             ])       \n\n             ;\n
Run Code Online (Sandbox Code Playgroud)\n\n
    \n
  1. 这应该已经很好用了。您现在应该能够拥有一个依赖字段。现在让\xc2\xb4s 来看看AJAX 的魔力。

  2. \n
  3. 进入您的 AdminClass(与 configureFields-Class 相同)并添加以下内容

  4. \n
\n\n
 protected function configureRoutes(RouteCollection $collection)\n    {    $collection->add(\'reloadCities\', \'reload-cities\');\n\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n
    \n
  1. 现在您有了可以从 ajax url 访问的路线。现在创建一个新的控制器类,无论您想要在哪里...
  2. \n
\n\n
<?php\n\nnamespace App\\Wdm\\MainBundle\\Controller;\n\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Sonata\\AdminBundle\\Controller\\CRUDController as BaseController;\nuse App\\Wdm\\MainBundle\\Entity\\Model\\Cities;\n\n\nclass CitiesController extends BaseController\n{\n    public function reloadCitiesAction(Request $request)\n    {   $districtid = $request->request->get(\'id\');\n        $cities = $this->getDoctrine()->getRepository(Cities::class)->findBy(array("district" => $districtid));\n        return $this->render("company/cities.html.twig", array("cities" => $cities));\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

...并且不要忘记在 services.yaml 中注册此控制器...

\n\n
  admin.company:\n        class: App\\Wdm\\MainBundle\\Admin\\CompanyAdmin\n        arguments:\n            - ~\n            - App\\Wdm\\MainBundle\\Entity\\Model\\Company\n            - App\\Wdm\\MainBundle\\Controller\\CitiesController (THIS IS THE NEW ROW)\n
Run Code Online (Sandbox Code Playgroud)\n\n

...最后是这个函数中调用的小模板...

\n\n
// THIS IS THE cities.html.twig\n\n{% for city in cities %}\n<option value="{{ city.id }}">{{ city.name }}</option>\n{% endfor %}\n
Run Code Online (Sandbox Code Playgroud)\n\n
    \n
  1. 到目前为止,一切都很好。我们现在得到了从 ajax 调用获取\xc2\xb4s 数据并将其返回到您的奏鸣曲管理编辑表单的逻辑。现在唯一缺少的是sonata admin 编辑模板中所需的jquery 代码。
  2. \n
\n\n

进入您的 AdminClass 并插入以下代码(例如在 configureFormFields 之前)

\n\n
 public function getTemplate($name)\n    {\n        switch ($name) {\n            case \'edit\':\n                return \'company/cities_admin.html.twig\';\n                break;\n            default:\n                return parent::getTemplate($name);\n                break;\n        }\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在我们创建这个 city_admin.html.twig 模板来覆盖默认模板

\n\n
{% extends \'SonataAdminBundle:CRUD:edit.html.twig\' %}\n\n{% block form %}\n    {{ parent() }}\n<script type="text/javascript">\n\n    $(document).ready(function () {\n        $("#ID_OF_YOUR_DISTRICT_SELECT_FIELD").change(function () {\n            $.ajax({\n                url: "{{ admin.generateUrl(\'reloadCities\') }}",\n                data: {\n                    \'id\': $(this).val(),\n                    \'uniquid\': \'{{ admin.uniqid }}\'\n                },\n                method: \'POST\',\n                success: function (html) {\n                    $("#ID_OF_YOUR_CITY_SELECT_FIELD").html(html);\n                },\n                error: function (data) {\n                    // more code\n                }\n            });\n        });\n    });\n</script>\n\n{% endblock %}\n
Run Code Online (Sandbox Code Playgroud)\n\n

那\xc2\xb4就是它。应该像魅力一样发挥作用。

\n