首页 > 解决方案 > Symfony 动态添加表单输入并转换为 JSON

问题描述

所以这有点难以解释。问题是,我有这个实体

class TypeParking
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=55)
     */
    private $libelle;

    /**
     * @ORM\Column(type="time", nullable=true)
     */
    private $tempsmax;

    /**
     * @ORM\Column(type="date", nullable=true)
     */
    private $jourdebut;

    /**
     * @ORM\Column(type="date", nullable=true)
     */
    private $jourfin;

    /**
     * @ORM\Column(type="json_array", nullable=true)
     */
    private $heurstravail;

    /**
     * @ORM\Column(type="json_array", nullable=true)
     */
    private $exception;

这是我的控制器:


    /**
     * @Route("/new", name="type_parking_new", methods={"GET","POST"})
     */
    public function new(Request $request): Response
    {
        $typeParking = new TypeParking();
        $form = $this->createForm(TypeParkingType::class, $typeParking);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $entityManager = $this->getDoctrine()->getManager();
            $entityManager->persist($typeParking);
            $entityManager->flush();

            return $this->redirectToRoute('type_parking_index');
        }

        return $this->render('type_parking/new.html.twig', [
            'type_parking' => $typeParking,
            'form' => $form->createView(),
        ]);
    }

<?php

namespace App\Form;

use App\Entity\TypeParking;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class TypeParkingType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('libelle')
            ->add('tempsmax')
            ->add('jourdebut')
            ->add('jourfin')
            ->add('heurstravail')
            ->add('exception')
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => TypeParking::class,
        ]);
    }
}

看到那个异常字段了吗?它的类型是数据库中的 JSON。它必须包含名称、开始日期、结束日期以及开始时间和结束时间。像这样https://imgur.com/a/2qrz5yy 每当我按下加号按钮时,我都可以添加另一个异常字段(JQuery)。当我提交表单时,整个异常字段会被解析为 JSON 并与表单的其余部分一起保存到数据库中。我的数据库:https ://imgur.com/a/UonYT3W

我一直试图让这个工作好几天了,但我什么也做不了。

标签: jsonsymfony

解决方案


您的表单类型非常简约。为您的异常字段显式添加(子)字段。

<?php

namespace App\Form;

use App\Entity\TypeParking;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
// don't forget to add the types here!
use Symfony\Component\Form\Extension\Core\Type\TextType;

class TypeParkingType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('libelle')
            ->add('tempsmax')
            ->add('jourdebut')
            ->add('jourfin')
            ->add('heurstravail')
            ->add('exception_name', TextType::class, ['property_path' => 'exception[name]')
            // add other fields of exception, look at 
            // https://symfony.com/doc/current/reference/forms/types.html
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => TypeParking::class,
        ]);
    }
}

我希望这有帮助 ...

但是,表单组件(属性访问器)将尝试获取异常,因此我们必须通过将以下内容添加到 TypeParking 实体类来提供帮助:

public function getException() {
    return array_merge([
        'name' => '', 
        // other sub-fields "empty" values
    ], $this->exception ?? [] // prevent array_merge from failing if exception is empty
    );
}

推荐阅读