我有一个包含三个对象的表单:
$builder
->add('customer', new CustomerType())
->add('shippingAddress', new AddressType())
->add('billingAddress', new AddressType())
->add('sameAsShipping', 'checkbox', ['mapped' => false])
;
每个嵌入的表单都有自己的验证约束,它们可以工作。在我的主窗体中,我有cascade_validation => true
,以便应用所有嵌入的表单验证约束。这也有效。
如果billingAddress
复选框已启用,我在sameAsShipping
表单上“禁用”验证时遇到问题。我无法在AddressType表单中进行条件验证,因为始终需要对shippingAddress表单强制执行。
答案 0 :(得分:0)
我通过使用验证组解决了同样的问题。
首先,这很重要:使用validation_groups
中的AddressType
选项设置每个字段的每个约束的验证组类型:
<?php
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Form\FormBuilderInterface;
class AddressType extends \Symfony\Component\Form\AbstractType
{
function buildForm(FormBuilderInterface $builder, array $options)
{
$groups = $options['validation_groups'];
$builder->add('firstName', 'text', ['constraints' => new Assert\NotBlank(['groups' => $groups])]);
$builder->add('lastName', 'text', ['constraints' => new Assert\NotBlank(['groups' => $groups])]);
}
}
然后,在父表单中将不同的验证组传递给两个字段:
<?php
$formBuilder = $this->get('form.factory')
->createNamedBuilder('checkout', 'form', null, [
'cascade_validation' => true,
])
->add('billingAddress', 'address', [
'validation_groups' => 'billingAddress'
])
->add('shippingAddress', 'address', [
'validation_groups' => 'shippingAddress'
]);
然后,通过查看复选框的值来确定您的验证组。
if ($request->request->get('sameAsShipping')) {
$checkoutValidationGroups = ['Default', 'billingAddress'];
} else {
$checkoutValidationGroups = ['Default', 'billingAddress', 'shippingAddress'];
}
然后,您可以使用验证组机制仅验证billingAddress
或shippingAddress
或两者。
我选择使用按钮:
$formBuilder->add('submitButton', 'submit', ['validation_groups' => $checkoutValidationGroups]);
答案 1 :(得分:0)
创建表单模型(我几乎在每个表单中使用它,但此处的代码未经过测试):
/**
* @Assert\GroupSequenceProvider()
*/
class YourForm implements GroupSequenceProviderInterface {
/**
* @Assert\Valid()
*/
private $customer;
/**
* @Assert\Valid()
*/
private $shippingAddress;
/**
* @Assert\Valid(groups={'BillingAddressRequired'})
*/
private $billingAddress;
private $billingSameAsShipping;
public function getGroupSequence() {
$groups = ['YourForm'];
if(!$this->billingSameAsShipping) {
$groups[] = 'BillingAddressRequired';
}
return $groups;
}
}
尝试使用有意义的名称。 sameAsShipping
很难理解。阅读getGroupSequence
中的if条件:如果不是发货(地址)与发货(地址)相同,则需要结算地址。
在我看来,这一切都是明确的代码。