Symfony条件表单验证

5
我正在使用Symfony(2.6)中的表单。用户可以选择一个免费的产品,该产品将被运送给用户。用户必须填写一些个人细节和地址(必填)。如果他想指定另一个交付地址,则勾选一个未映射到实体的复选框,并完成交付地址。现在,我想提交表单,并且仅在用户勾选此复选框时验证交付地址字段。如何实现?
地址字段和交付地址字段使用相同的表单类映射到同一个实体。我使用YAML文件来进行约束。
(部分)validation.yml:
AppBundle\Entity\Address:
    properties:
        street:
          - NotBlank: { message: "Please fill in your first name." }
          - Length:
              min: 3
              max: 256
              minMessage: "Please fill in your street name."
              maxMessage: "Please fill in your street name."
        number:
          - NotBlank: { message: "Please fill in your house number." }
          - Length:
              min: 1
              max: 10
              minMessage: "Please fill in your house number."
              maxMessage: "Please fill in your house number."
        postCode:
          - NotBlank: { message: "Please fill in your postal code." }
          - Length:
              min: 2
              max: 10
              minMessage: "Please fill in your postal code."
              maxMessage: "Please fill in your postal code."
        city:
          - NotBlank: { message: "Please fill in your city." }
          - Length:
              min: 2
              max: 256
              minMessage: "Please fill in your city."
              maxMessage: "Please fill in your city."
          - Type:
              type: alpha
              message: "Please fill in your city."
        country:
          - NotBlank: { message: "Please select your country." }
          - Country: ~

AppBundle\Entity\Product:
    properties:
      product:
        - NotBlank: { message: "Please select your product." }
        - Type:
            type: integer
            message: "Please select your product."
      contact:
          - Type:
              type: AppBundle\Entity\Contact
          - Valid: ~
      deliveryAddress:
          - Type:
              type: AppBundle\Entity\Address
          - Valid: ~

产品表单类:

    <?php

class ProductFormType extends AbstractType
{

    /**
     *
     * @param OptionsResolverInterface $resolver
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\Product'
        ));
    }

    /**
     * Returns the name of this type.
     *
     * @return string The name of this type
     */
    public function getName()
    {
        return 'product';
    }


    /**
     *
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('contact', new ContactFormType()); //CONTACTFORMTYPE also has an AddressFormType for the Address Fields

        $builder->add('differentDeliveryAddress', 'checkbox', array( //delivery address is only specific for this Form
            'label'     => 'Different Shipping Address',
            'required'  => false,
            'mapped'    => false
        ));
        $builder->add('deliveryAddress', new AddressFormType());

        //specific

        $builder->add('product', 'choice', array(
            'choices' => array('a'=>'product x','b' => 'product y'),
            'required' => true,
            'invalid_message' => 'This field is required',
            'label' => 'Your Free Product',
        ));

        $builder->add('submit', 'button', array('label' => 'Submit'));
    }
}

最后是My Controller中的getProductFormAction函数

   public function getProductFormAction(Request $request)
{

    $product = new Product();
    $form    = $this->get('form.factory')->create(new ProductFormType($product);

    $form->handleRequest($request);

    if($form->isValid()){
        return new Response('Success'); //just to test
    }

    return $this->render(
        'productForm.html.twig',
        array(
            'pageTitle'   => 'Test',
            'form'        => $form->createView()
        )
    );
}

可能是依赖于另一个字段的条件字段验证的重复问题。 - A.L
2个回答

10

通过使用分组,可以相对容易地实现此目标。

首先,将分组添加到仅在特定场合(例如您的送货地址)验证字段上。

street:
      - NotBlank: 
          message: "Please fill in your first name."
          groups: [delivery]
      - Length:
          min: 3
          max: 256
          minMessage: "Please fill in your street name."
          maxMessage: "Please fill in your street name."
          groups: [delivery]
现在这些验证已经被分组了,除非明确告知需要验证,否则它们不会被验证。
因此,现在我们让表单决定何时验证这个分组。
public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'validation_groups' => function (FormInterface $form) {
            $data = $form->getData();

            if ($data->differentDeliveryAddress()) {
                return array('Default', 'delivery');
            }

            return array('Default');
        },
    ));
}

在这里,表单将始终验证“默认”组(所有未设置任何组的验证),并且当设置了differentDeliveryAddress时,还将验证“送货”组。

希望这可以帮助。


0

我已经阅读了两章内容,尝试使用事件监听器和验证组来实现复选框的解决方案。也许我做错了什么,但是验证器一直使用主地址类型的验证。我将使用经典的php“是否勾选复选框”的解决方案。感谢你的帮助! - N.P.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接