Symfony 6 为窗体中未映射的 ChoiceType 字段设置默认值

Symfony 6 set default value for unmapped ChoiceType field in form

提问人:K. Weber 提问时间:10/25/2023 更新时间:10/25/2023 访问量:43

问:

我有这个场景:

从 Cookie 中读取值,并将其作为 FormType 传递:$option

$indexOrder = $request->cookies->get('clientfile-order') ?? 'date-last';
$advancedSearchform = $this->createForm(ClientFileSearchType::class, null, ['index_order' => $indexOrder]);

在表单中,我有以下代码:

$builder
        ->add('queryOrder', ChoiceType::class, ['label'     => "Order by",
                                                'mapped'   => false, 
                                                'expanded' => false,
                                                'multiple' => false,
                                                'required' => true,
                                                //'empty_data' => $options['index_order'],
                                                'data'     => $options['index_order'],
                                                'choices'  => [ 'Fecha de última actuación'              => 'action-last',
                                                                'Fecha apertura (más recientes primero)' => 'date-last',
                                                                'Fecha apertura (más antiguos primero)'  => 'date-first',
                                                                'Nº fichero (más recientes primero)'  => 'clientfile-last',
                                                                'Nº fichero (más antiguos primero)'   => 'clientfile-first'
                                                                ]
                                                ]);

public function configureOptions(OptionsResolver $resolver): void
{
    $resolver->setDefaults([
        'index_order'   => null, //'date-last',
        'data_class'    => null,
    ]);
}

如果我在读取 cookie 后调试$indexOrder值,则在将选项传递给 createForm 之前该值是正确的。我尝试了这两个属性,并且它们的行为相同。dataempty_data

但是默认值不会加载,它总是显示上次调用中使用的最后一个值,并且只有当我使用 Ctrl + F5 重新加载页面时,才会出现正确的值。

我可以通过 Javascript 设置值,但如果可能的话,我更喜欢在服务器上设置它,有没有办法做到这一点?什么是失败?

形式 默认值 symfony6 (英语)

评论

0赞 Hornth 10/25/2023
$options['index_order'] 值是否与选择值兼容?它应该是其中之一
0赞 K. Weber 10/25/2023
是的,这是价值观之一'action-last' | 'date-last' | 'date-first' | 'clientfile-last' | 'clientfile-first'

答:

0赞 pok_net 10/25/2023 #1

这可能是你在$options中传递index_order的方式。

您可能应该尝试在表单类型中调试 indexOrder。

您还可以添加一个模型以更好地控制表单变量。

下面是一个工作示例,使用 symfony 文档中的主表单,并添加了下拉框:

TaskModel.php

namespace App\Model;
use DateTimeInterface;

class TaskModel
{
    protected string $name;

    protected ?DateTimeInterface $dueDate;

    protected string $indexOrder;

    public function getName(): string
    {
        return $this->name;
    }

    public function setName(string $name): void
    {
        $this->name = $name;
    }

    public function getDueDate(): ?DateTimeInterface
    {
        return $this->dueDate;
    }

    public function setDueDate(?DateTimeInterface $dueDate): void
    {
        $this->dueDate = $dueDate;
    }

    public function getIndexOrder(): string
    {
        return $this->indexOrder;
    }

    public function setIndexOrder(string $indexOrder): void
    {
        $this->indexOrder = $indexOrder;
    }
}

pageController.php

    #[Route('/page3', name: 'page3')]
    public function page3(Request $request): Response
    {
        $indexOrder = $request->cookies->get('clientfile-order') ?? 'date-last';
        $task = new TaskModel();
        $task->setName('Write a blog post');
        $task->setDueDate(new DateTimeImmutable('tomorrow'));
        $task->setIndexOrder($indexOrder);
        $form = $this->createForm(TaskType::class, $task);
        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            $task2 = $form->getData();
        }
        return $this->render('page/page3.html.twig', [
            'form' => $form,
        ]);
    }

TaskType.php


class TaskType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        //dd($options);
        $data1 = $options['data']->getIndexOrder();

        $builder
            ->add('name', TextType::class)
            ->add('dueDate', DateType::class)
            ->add('queryOrder', ChoiceType::class, ['label'     => "Order by",
                'mapped'   => false,
                'expanded' => false,
                'multiple' => false,
                'required' => true,
                //'empty_data' => $options['index_order'],
                'data'     => $data1,
                'choices'  => [ 'Fecha de última actuación'     => 'action-last',
                    'Fecha apertura (más recientes primero)'    => 'date-last',
                    'Fecha apertura (más antiguos primero)'     => 'date-first',
                    'Nº fichero (más recientes primero)'        => 'clientfile-last',
                    'Nº fichero (más antiguos primero)'         => 'clientfile-first'
                ]
            ])

            ->add('save', SubmitType::class)
        ;
    }

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

最后,在 Twig 模板中,如果需要,只需添加或任何其他自定义。{{ form(form) }}