Php Symfony3:验证嵌套(可选)表单
我的项目中有三个文档:事件、OrganizerProfile和用户 用户可以有多个OrganizerProfile(就像Facebook上的“页面”)和活动 当用户创建和处理事件时,他可以为事件分配一个“OrganizerProfile”(用户Alberto为“公司a”创建一个称为“事件X”的事件) 为了实现这一点,我创建了以下表单: OrganizerProfileType.phpPhp Symfony3:验证嵌套(可选)表单,php,forms,symfony,symfony-forms,Php,Forms,Symfony,Symfony Forms,我的项目中有三个文档:事件、OrganizerProfile和用户 用户可以有多个OrganizerProfile(就像Facebook上的“页面”)和活动 当用户创建和处理事件时,他可以为事件分配一个“OrganizerProfile”(用户Alberto为“公司a”创建一个称为“事件X”的事件) 为了实现这一点,我创建了以下表单: OrganizerProfileType.php class OrganizerProfileType extends AbstractType{ pub
class OrganizerProfileType extends AbstractType{
public function buildForm(FormBuilderInterface $builder, array $options){
$builder
->add('email', EmailType::class)
->add('name', TextType::class)
->add('description', TextType::class, ['required' => false])
...
class EventType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options)
{
$profileChoices = ... //List of existing profiles
$builder
->add('profile_list', ChoiceType::class, [
'choices' => $profileChoices,
'required' => false,
'mapped' => false,
])
->add('profile', OrganizerProfileType::class, [
'required' => true,
])
->add('title', TextType::class, ['required' => false])
->add('description', TextType::class, ['required' => false])
...
EventType.php
class OrganizerProfileType extends AbstractType{
public function buildForm(FormBuilderInterface $builder, array $options){
$builder
->add('email', EmailType::class)
->add('name', TextType::class)
->add('description', TextType::class, ['required' => false])
...
class EventType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options)
{
$profileChoices = ... //List of existing profiles
$builder
->add('profile_list', ChoiceType::class, [
'choices' => $profileChoices,
'required' => false,
'mapped' => false,
])
->add('profile', OrganizerProfileType::class, [
'required' => true,
])
->add('title', TextType::class, ['required' => false])
->add('description', TextType::class, ['required' => false])
...
在“概要文件列表”字段中,用户可以找到他们现有的OrganizerProfiles。用户可以选择其中一个并将其分配给事件,但如果用户没有选择现有配置文件,则必须在“配置文件”表单中插入信息
我想将配置文件表单设置为“可选”,并且仅当用户不选择现有配置文件时才将其设置为必需
我该怎么做?谢谢您可以通过以下方式实施
因此,您的表单类型应如下所示:
class EventType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options)
{
$profileChoices = [...];
$builder
->add('profile_list', ChoiceType::class, [
'choices' => $profileChoices,
'required' => false,
'mapped' => false,
])
->add('profile', OrganizerProfileType::class, [
'constraints' => [
new Valid()
]
])
->add('title', TextType::class, ['required' => false])
->add('description', TextType::class, ['required' => false]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'validation_groups' => function (FormInterface $form) {
if (null === $form->get('profile_list')->getData()) {
return ['without_profile'];
}
return ['with_profile']; // Or simply 'Default'
},
]);
}
}
更新:也使用其他表单类型中的验证组
然后,您需要使用验证组处理子窗体的验证,例如:
class OrganizerProfileType extends AbstractType{
public function buildForm(FormBuilderInterface $builder, array $options){
$builder
->add('email', EmailType::class, [
'constraints' => [
new NotNull(
[
'groups' => ['without_profile', 'with_profile']
]
)
]])
->add('name', TextType::class, [
'constraints' => [
new NotNull(
[
'groups' => ['without_profile', 'with_profile']
]
)
]])
->add('description', TextType::class, ['required' => false])
希望您能通过以下方式实现此帮助
因此,您的表单类型应如下所示:
class EventType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options)
{
$profileChoices = [...];
$builder
->add('profile_list', ChoiceType::class, [
'choices' => $profileChoices,
'required' => false,
'mapped' => false,
])
->add('profile', OrganizerProfileType::class, [
'constraints' => [
new Valid()
]
])
->add('title', TextType::class, ['required' => false])
->add('description', TextType::class, ['required' => false]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'validation_groups' => function (FormInterface $form) {
if (null === $form->get('profile_list')->getData()) {
return ['without_profile'];
}
return ['with_profile']; // Or simply 'Default'
},
]);
}
}
更新:也使用其他表单类型中的验证组
然后,您需要使用验证组处理子窗体的验证,例如:
class OrganizerProfileType extends AbstractType{
public function buildForm(FormBuilderInterface $builder, array $options){
$builder
->add('email', EmailType::class, [
'constraints' => [
new NotNull(
[
'groups' => ['without_profile', 'with_profile']
]
)
]])
->add('name', TextType::class, [
'constraints' => [
new NotNull(
[
'groups' => ['without_profile', 'with_profile']
]
)
]])
->add('description', TextType::class, ['required' => false])
希望这对您有所帮助您可以谢谢,我明天会尝试您的解决方案!如果成功,我会在SymfonyDay给你一杯啤酒(如果你愿意的话;))如果我把验证组放在“事件”文档中,当我到达“$form->isValid()”方法时,它会正确停止,但他完全跳过OrganizerProfile表单的验证,忽略验证组。我也尝试过“级联验证”,但仍然不起作用。它仅适用于“手动验证”(使用验证服务并使用正确的组验证OrganizerProfile表单)。是否有方法使用标准方法“$form->isValid()”验证所有表单(和子表单)?hi@AlbertoFecchi,您还应该在其他表单类型中使用验证组。检查我的更新。希望今天也能见到你:)好的,我找到了解决办法!我应该在EventType表单中使用“Valid()”约束而不是“NotNull()”(或者直接在事件文档中使用注释:@Assert\Valid)。现在我的代码工作了!如果你更新你的答案,我会把它标记为最佳答案。谢谢你的帮助!再更正一点:Valid约束不接受“groups”参数,新的Valid()就足够了!谢谢,我明天会试试你的解决方案!如果成功,我会在SymfonyDay给你一杯啤酒(如果你愿意的话;))如果我把验证组放在“事件”文档中,当我到达“$form->isValid()”方法时,它会正确停止,但他完全跳过OrganizerProfile表单的验证,忽略验证组。我也尝试过“级联验证”,但仍然不起作用。它仅适用于“手动验证”(使用验证服务并使用正确的组验证OrganizerProfile表单)。是否有方法使用标准方法“$form->isValid()”验证所有表单(和子表单)?hi@AlbertoFecchi,您还应该在其他表单类型中使用验证组。检查我的更新。希望今天也能见到你:)好的,我找到了解决办法!我应该在EventType表单中使用“Valid()”约束而不是“NotNull()”(或者直接在事件文档中使用注释:@Assert\Valid)。现在我的代码工作了!如果你更新你的答案,我会把它标记为最佳答案。谢谢你的帮助!再更正一点:Valid约束不接受“groups”参数,新的Valid()就足够了!