1

我有一个用例,我需要在 Symfony 5 中构建的动态表单上使用一些默认条件逻辑。

让我试着用一个简单的表格来解释我的用例是什么以及我的问题。例如,我有一个包含两个字段的表单产品:

  1. 部分(选择类型 => 左、右)
  2. 长度(数字类型)

更改时,所有字段 (:input) 都通过 Ajax 请求提交。我有两种控制器方法,一种用于访问页面(正在构建表单),另一种用于通过 ajax 请求呈现表单(处理条件逻辑)。

对于条件逻辑部分,需要完成以下操作

  • 剩下部分时,默认长度需要为 50
  • 当部分正确时,默认长度需要为 100
  • 用户可以更改默认数据

根据左或右设置长度的默认数据不是问题。选择 left 时,默认长度变为 50。当将值更改为 55(每次更改都提交表单)时,它再次变为 50。这种行为是合乎逻辑的,但是如何覆盖默认数据呢?

上述情况也可以描述为给用户默认数据并选择更改它

表格类型

<?php
// ... namespace, use statments

class ProductType extends AbstractType
{
    /**
     * {@inheritDoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder->add('part', ChoiceType::class, array(
            'choices' => array(
                'Left' => 'left',
                'Right' => 'right',
            )
        ));

        $builder->add('length', NumberType::class);

        $builder->addEventListener(FormEvents::POST_SET_DATA, function(FormEvent $event) use ($options)
        {
            $form = $event->getForm();
            if(null === $product = $event->getData()) {
                return;
            }

            switch($product->getPart()) {
                case 'left': $defaultLength = 50; break;
                case 'right': $defaultLength = 100; break;
                default: $defaultLength = 0;
            }

            $form->get('length')->setData($defaultLength);
        });
    }

    /**
     * {@inheritDoc}
     */
    public function getName(): string
    {
        return 'product';
    }

    /**
     * {@inheritDoc}
     */
    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults(array(
            'data_class' => Product::class,
            'translation_domain' => 'forms',
        ));
    }
}

控制器

// src/Controller/ProductController.php

// ... namespace, use statments
namespace App\Controller;

class ProductController extends AbstractController
{
    public function productAction(Request $request): Response
    {
        $product = new Product();

        $form = $this->createForm(ProductType::class, $product);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $product = $form->getData();

            dd($product);
        }

        return $this->render('product_view.html.twig', array(
            'form' => $form->createView()
        ));
    }

    public function productConfigureAjaxAction(Request $request): Response
    {
        $product = new Product();
        $part = $request->request->get('product')['part'] ?? null;

        $product->setPart($part);

        $form = $this->createForm(ProductType::class, $product);
        $form->handleRequest($request);

        // product_form.html.twig is an separated file and included in product_view.html.twig
        // by making the form separated is could been used for an ajax response
        return $this->render('product_form.html.twig', array(
            'form' => $form->createView()
        ));
    }
}
4

0 回答 0