根据ChoiceType上的选择动态加载EntityType字段

时间:2020-07-01 23:14:25

标签: php symfony doctrine

嘿,所以我试图在ChoiceType中选择一个选项后动态加载EntityType数据。如果同时选择了这两个下拉菜单,我想显示表单的其余部分。

有人可以帮我解决这个问题,还是给我链接一个例子?

我的代码:

<?php

namespace App\Form;

use App\Entity\CivilianCriminalRecords;
use App\Entity\FineTypes;
use Doctrine\ORM\EntityRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class CivilianCriminalRecordsType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder->add('fineTypeCategory', ChoiceType::class, [
            'label' => "Categorie type overtreding",
            'choices'  => [
                'Category 0' => 0,
                'Category 1' => 1,
                'Category 2' => 2,
                'Category 3' => 3,
                'Category 4' => 4,
                'Category 5' => 5,
            ],
        ]);

        // Load when fineTypeCategory is selected.
        $builder->add('offenceType', EntityType::class, [
            'class' => FineTypes::class,
            'query_builder' => function (EntityRepository $er) {
                return $er->createQueryBuilder('ft')
                    ->where('ft.category = :categoryId')
                    ->setParameter('categoryId', '0'); // Shouldn't be 0 but the id filled in the fineTypeCategory field.
            },
            'choice_label' => 'label',
        ]);

        // Load when fineTypeCategory AND offenceType is selected
        $builder
            ->add('offence', TextareaType::class, ['label' => 'Omschrijving van de overtreding', 'attr' => ['rows' => '5']])
            ->add('statement', TextareaType::class, ['label' => 'Verklaring van de overtreder', 'attr' => ['rows' => '5']])
            ->add('jailed', CheckboxType::class, ['label' => 'Gevangenisstraf ontvangen?'])
            ->add('save', SubmitType::class, ['label' => 'Overtreding uitschrijven'])
        ;
    }

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

1 个答案:

答案 0 :(得分:0)

尝试这种方法。它没有经过测试,但是您应该看到这个想法。 我不知道您的控制器是什么样子,但是我想是这样的:

public function indexAction(Request $request): Response
{
    //Get your entity
    $records = $this->getDoctrine()->getRepository(CivilianCriminalRecords::class)->find($id);
    $options['show_offence_type'] = !empty($request->request->get('fineTypeCategory'));
    $options['show_more_params'] = !empty($request->request->get('offenceType'));
    $form = $this->createForm(CivilianCriminalRecordsType::class, $records, $options);
    $form->handleRequest($request);
    if(
        $request->request->has('offence') && //means that the third part was visible and filled in
        $form->isSubmitted() && $form->isValid()){
        //process the form
    }
    return $this->render('form.html.twig', [
        'form' => $form->createView(),
        'show_offence_type' => $options['show_offence_type'],
        'show_more_params' => $options['show_more_params']
    ]);
}

然后选择FormType:

public function buildForm(FormBuilderInterface $builder, array $options): void
{
    $builder->add('fineTypeCategory', ChoiceType::class, [
        'label' => "Categorie type overtreding",
        'choices'  => [
            'Category 0' => 0,
            'Category 1' => 1,
            'Category 2' => 2,
            'Category 3' => 3,
            'Category 4' => 4,
            'Category 5' => 5,
        ],
    ]);
    if($options['show_offence_type']){
        // Load when fineTypeCategory is selected.
        $builder->add('offenceType', EntityType::class, [
            'class' => FineTypes::class,
            'query_builder' => function (EntityRepository $er) {
                return $er->createQueryBuilder('ft')
                    ->where('ft.category = :categoryId')
                    ->setParameter('categoryId', '0'); // Shouldn't be 0 but the id filled in the fineTypeCategory field.
            },
            'choice_label' => 'label',
        ]);
    }
    if($options['show_more_params']){
        // Load when fineTypeCategory AND offenceType is selected
        $builder
            ->add('offence', TextareaType::class, ['label' => 'Omschrijving van de overtreding', 'attr' => ['rows' => '5']])
            ->add('statement', TextareaType::class, ['label' => 'Verklaring van de overtreder', 'attr' => ['rows' => '5']])
            ->add('jailed', CheckboxType::class, ['label' => 'Gevangenisstraf ontvangen?']);
    }
    $builder->add('save', SubmitType::class, ['label' => 'Overtreding uitschrijven']);
}

public function configureOptions(OptionsResolver $resolver): void
{
    $resolver->setDefaults([
        'data_class' => CivilianCriminalRecords::class,
        'show_offence_type' => false,
        'show_more_params' => false
    ]);
}

模板应该是这样的(此处仅相关部分):

{% if show_offence_type %}
    {{ form_row(form.offenceType) }}
{% endif %}
{% if show_more_params %}
    {{ form_row(form.offence) }}
    {{ form_row(form.statement) }}
    {{ form_row(form.jailed) }}
{% endif %}

这个想法是仅在提交表格时首先选择并配置和呈现输入字段。之后,显示下一个选择,然后让用户再次发送表单。然后显示其余的表格。最后,填写完表格的所有部分后,即可处理表格。测试愉快!

相关问题