如何将 EntityType 字段设置为只读/禁用,以便该值无法编辑但仍与表单一起发送?

问题描述 投票:0回答:1

在 Symfony 6 中,当我渲染

EntityType
(HTML 选择字段)设置
readonly
attr 时,该字段实际上被修改了。

如果我设置

disabled
,那么我会收到错误,因为此字段是必需的。

如何避免该字段被修改却渲染?

class ClientFileType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('clientFileType', EntityType::class, ['label' => 'Tipo',
                                                        'required' => true,
                                                        'class' => TypeOfClientFile::class,
                                                        'query_builder' => function (EntityRepository $er) {
                                                            return $er->createQueryBuilder('T')
                                                                ->orderBy('T.name', 'ASC');
                                                        }])
    (...)
}

这是twig模板代码,仅在修改时字段为

readonly
,但在新实体上可编辑:

{{ form_row(form.clientFileType, {'attr': {'readonly': (client_file.id != null) }}) }}
symfony symfony-forms
1个回答
0
投票

您不能同时使用

disabled
required
。如果你仔细想想,你会发现这没有意义:使用
required
你是在告诉“这个值需要填写并发送”,使用
disabled
你是在说“忽略并且不发送该值”。该字段的值”。

为此,您必须实现稍微复杂的逻辑。

如果要禁用值字段,那么也许您不再需要将其显示为

select
。您不需要这些选项(客户端无法选择新选项),那么为什么要查询它们并渲染它们呢?

在这种情况下,只需在不同情况下添加不同的字段类型即可。如果字段为

disabled
,则显示不同的 UI 元素,并发送适当的数据。

一个粗略的示例(您必须对其进行改进,使其适合您的用例,实际上尚未在我的项目中运行它,但这个想法是有效的):

class ClientFileType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        if ($options['client_file']) {
            $builder->add('clientFileType', HiddenType::class, [
                 'value' => $options['client_file'],
            ]);

            $builder->add('clientFileTypeDisplay', TextType::class, [
              'label' => 'Tipo',
              'value' => $options['client_file_name'],
              'disabled' => true,
            ]);
        } else {
            $builder
                ->add('clientFileType', EntityType::class, ['label' => 'Tipo',
                    'required' => true,
                    'class' => TypeOfClientFile::class,
                    'query_builder' => function (EntityRepository $er) {
                        return $er->createQueryBuilder('T')
                            ->orderBy('T.name', 'ASC');
                    }]);
        }
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'client_file' => 'int',
            'client_file_name' => '',
        ]);

        $resolver->addAllowedTypes('client_file', 'integer');
        $resolver->addAllowedTypes('client_file_name', 'string');
    }
}

然后在控制器中创建表单时,您将根据需要设置选项:

$form = $this->createForm(ClientFileType::class, options: [
   'client_file' => $client_file_id, // or 0 if not applicable,
    'client_flie_name' => $client_file_name // the actual name, so you don't have to make a query in the form
]);

渲染时:

{{ form_row(form.clientFileType) }}

{% if client_file.id %}
{{ form_row(form.clientFileTypeDisplay) }}
{% endif %}
© www.soinside.com 2019 - 2024. All rights reserved.