2015-09-04 2 views
3

Я работаю над формой в Symfony (2.6). Пользователь может выбрать бесплатный продукт, который будет отправлен пользователю. Пользователь должен заполнить некоторые личные данные и его адрес (обязательный). Если он хочет указать другой адрес доставки, он проверяет флажок, который не привязан к объекту, и завершает адрес доставки. Теперь я хочу отправить форму и только подтвердить поля адреса доставки, если пользователь установил этот флажок. Как это может быть сделано?Подтверждение условной формы Symfony

Адреса Поля и поля адреса доставки используют тот же класс формы, который сопоставлен с одним и тем же объектом. Я использую 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')); 
    } 
} 

Наконец 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() 
     ) 
    ); 
} 

Заранее спасибо за помощь!

+0

возможного дубликату [проверка условного поля, которое зависит от другого поля] (http://stackoverflow.com/questions/20471812/conditional-field-validation-that-depends-on-another- поле) –

ответ

0

В документах Symfony также содержится много материала о динамических формах и группах проверки сущности/формы, которые должны указывать на вас в правильном направлении; например:

Этот случай использования, кажется, придумать много на SO. Я предлагаю сделать быстрый поиск, чтобы узнать, можете ли вы найти подобный вопрос.

Надеется, что это помогает :)

+0

Я прочитал обе главы, и я попытался реализовать решение, используя eventListener для моего флажка и используя группы проверки. Возможно, я сделал что-то не так, но валидатор продолжал использовать проверку для основного типа адреса. Я использую классический php 'checkbox checked' -solution. Спасибо за вашу помощь! –

7

Это может быть относительно легко достигаются с помощью групп.

Прежде всего, добавьте группы в поля, которые вы хотите проверить только в определенных случаях (ваш адрес доставки).

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 установлен.

Надеется, что это помогает

Смежные вопросы