(Symfony 4 表单类型)如何根据表单上的 <select> 值制作一个完整的子表单 required/not?
(Symfony 4 form types) How do you make an entire subform required/not required based on a <select> value on the form?
这是我的表单类型 class。所以我说的 < select>
字段是 'numSubscriptionTiers':
class UserProfileType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('numSubscriptionTiers', ChoiceType::class, [
'choices' => [
'1' => 1,
'2' => 2,
'3' => 3
]
])
->add('subscriptionTier1', UserSubscriptionTierType::class, [
'required' => false,
'entry_type' => UserSubscriptionTierType::class
])
->add('subscriptionTier2', UserSubscriptionTierType::class, [
'required' => false,
'entry_type' => UserSubscriptionTierType::class
])
->add('subscriptionTier3', UserSubscriptionTierType::class, [
'required' => false,
'entry_type' => UserSubscriptionTierType::class
])
如果用户 selects 1,则只需要 subscriptionTier1 子表单,如果用户 selects 2,则只需要 subscriptionTier1 和 subscriptionTier2 子表单,依此类推。 .
我知道有 PRE_SET_DATA、POST_SUBMIT 等表单事件...但是您可以从表单类型 [=27] 中添加类似于 JavaScript 事件的内容吗=]?像 numSubscriptionTiers select 的某种 onChange 事件,并将相应的子表单的 required 属性设置为 true/false?
我已经去了这里:https://symfony.com/doc/current/form/dynamic_form_modification.html#how-to-dynamically-generate-forms-based-on-user-data 它只给出了一个如何动态填充选择列表的示例,而不是在指定选项后添加更改事件。
使用 PRE_SUBMIT
事件 modify the form dynamically 设置表单元素的后端验证。
例如,如果 numSubscriptionTiers
的发送值是 2
,则删除子项 subscriptionTier1
和 subscriptionTier2
并再次添加它们,但这次使用额外的 NotBlank
约束:
// add imports
public function buildForm(FormBuilderInterface $builder, array $options)
{
// skipped for brevity
$builder->addEventListener(FormEvents::PRE_SUBMIT, [$this, 'conditional']);
}
public function conditional(FormEvent $event)
{
$form = $event->getForm();
$data = $event->getData();
// make sure tierCount is between 1-3
$tierCount = min(3, max(1, (int) $data['numSubscriptionTiers'] ?? 0));
for ($i = 1; $i <= $tierCount; $i++) {
$childName = sprintf('subscriptionTier%d', $i);
$form
->remove($childName)
->add($childName, UserSubscriptionTierType::class, [
'required' => false,
'entry_type' => UserSubscriptionTierType::class,
'constraints' => new NotBlank(),
]);
}
}
恐怕必须使用 JavaScript 动态添加 HTML5 required
属性,因为 PHP 不会在客户端处理它。好吧,您可以修改动态重新添加的字段 subscriptionTier1
的 required
属性,但是想想如果用户将 numSubscriptionTiers
更改为 2
会发生什么。由于 subscriptionTier1
元素上的 required
属性,因此无法提交表单。因此只有 JavaScript 是解决方案。
这是我的表单类型 class。所以我说的 < select>
字段是 'numSubscriptionTiers':
class UserProfileType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('numSubscriptionTiers', ChoiceType::class, [
'choices' => [
'1' => 1,
'2' => 2,
'3' => 3
]
])
->add('subscriptionTier1', UserSubscriptionTierType::class, [
'required' => false,
'entry_type' => UserSubscriptionTierType::class
])
->add('subscriptionTier2', UserSubscriptionTierType::class, [
'required' => false,
'entry_type' => UserSubscriptionTierType::class
])
->add('subscriptionTier3', UserSubscriptionTierType::class, [
'required' => false,
'entry_type' => UserSubscriptionTierType::class
])
如果用户 selects 1,则只需要 subscriptionTier1 子表单,如果用户 selects 2,则只需要 subscriptionTier1 和 subscriptionTier2 子表单,依此类推。 .
我知道有 PRE_SET_DATA、POST_SUBMIT 等表单事件...但是您可以从表单类型 [=27] 中添加类似于 JavaScript 事件的内容吗=]?像 numSubscriptionTiers select 的某种 onChange 事件,并将相应的子表单的 required 属性设置为 true/false?
我已经去了这里:https://symfony.com/doc/current/form/dynamic_form_modification.html#how-to-dynamically-generate-forms-based-on-user-data 它只给出了一个如何动态填充选择列表的示例,而不是在指定选项后添加更改事件。
使用 PRE_SUBMIT
事件 modify the form dynamically 设置表单元素的后端验证。
例如,如果 numSubscriptionTiers
的发送值是 2
,则删除子项 subscriptionTier1
和 subscriptionTier2
并再次添加它们,但这次使用额外的 NotBlank
约束:
// add imports
public function buildForm(FormBuilderInterface $builder, array $options)
{
// skipped for brevity
$builder->addEventListener(FormEvents::PRE_SUBMIT, [$this, 'conditional']);
}
public function conditional(FormEvent $event)
{
$form = $event->getForm();
$data = $event->getData();
// make sure tierCount is between 1-3
$tierCount = min(3, max(1, (int) $data['numSubscriptionTiers'] ?? 0));
for ($i = 1; $i <= $tierCount; $i++) {
$childName = sprintf('subscriptionTier%d', $i);
$form
->remove($childName)
->add($childName, UserSubscriptionTierType::class, [
'required' => false,
'entry_type' => UserSubscriptionTierType::class,
'constraints' => new NotBlank(),
]);
}
}
恐怕必须使用 JavaScript 动态添加 HTML5 required
属性,因为 PHP 不会在客户端处理它。好吧,您可以修改动态重新添加的字段 subscriptionTier1
的 required
属性,但是想想如果用户将 numSubscriptionTiers
更改为 2
会发生什么。由于 subscriptionTier1
元素上的 required
属性,因此无法提交表单。因此只有 JavaScript 是解决方案。