在 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) }}) }}
您不能同时使用
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 %}