2016-09-05 10 views
0

here을 논의했다.양식 가입자와 "이 양식은 별도의 필드를 포함 할 수 없습니다"오류가 나는 심포니 2.3, 그래서 분명히, 나는 'allow_extra_fields'옵션을 사용할 수 없습니다 사용하고

/** 
* Class RegistrationStep1DeclarationType 
* @package Evo\DeclarationBundle\Form\Type 
*/ 
class RegistrationStep1DeclarationType extends AbstractType 
{ 
    /** 
    * @var EntityManagerInterface 
    */ 
    private $em; 

    /** 
    * @var EventSubscriberInterface 
    */ 
    private $addBirthCountyFieldSubscriber; 

    /** 
    * RegistrationStep1DeclarationType constructor. 
    * @param EntityManagerInterface $em 
    * @param EventSubscriberInterface $addBirthCountyFieldSubscriber 
    */ 
    public function __construct(EntityManagerInterface $em, EventSubscriberInterface $addBirthCountyFieldSubscriber) 
    { 
     $this->em = $em; 
     $this->addBirthCountyFieldSubscriber = $addBirthCountyFieldSubscriber; 
    } 

    /** 
    * @param FormBuilderInterface $builder 
    * @param array $options 
    */ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->add('birthLastname', null, [ 
       'label' => 'Nom de naissance', 
       'attr' => [ 
        'required' => true, 
       ], 
      ]) 
      ->add('nationality', 'entity', [ 
       'label' => 'Nationalité', 
       'class' => 'Evo\GeoBundle\Entity\Country', 
       'property' => 'nationalityFr', 
       'attr' => [ 
        'required' => true, 
        'class' => 'selectpicker', 
       ], 
       'preferred_choices' => $this->fillPreferredNationalities(), 
      ]) 
      ->add('birthCountry', 'entity', [ 
       'label' => 'Pays de naissance', 
       'class' => 'Evo\GeoBundle\Entity\Country', 
       'property' => 'nameFr', 
       'empty_value' => '', 
       'empty_data' => null, 
       'attr' => [ 
        'required' => true, 
        'class' => 'trigger-form-modification selectpicker', 
       ], 
       'preferred_choices' => $this->fillPreferredBirthCountries(), 
      ]) 
      ->add('birthCity', null, [ 
       'label' => 'Ville de naissance', 
       'attr' => [ 
        'required' => true, 
       ], 
      ]) 
     ; 

     $builder->get("birthCountry")->addEventSubscriber($this->addBirthCountyFieldSubscriber); 
    } 

    /** 
    * @return array 
    */ 
    private function fillPreferredNationalities() 
    { 
     $nationalities = $this->em->getRepository("EvoGeoBundle:Country")->findBy(["isDefault" => true]); 

     return $nationalities; 
    } 

    /** 
    * @return array|\Evo\GeoBundle\Entity\Country[] 
    */ 
    private function fillPreferredBirthCountries() 
    { 
     $countries = $this->em->getRepository("EvoGeoBundle:Country")->findBy(["isDefault" => true]); 

     return $countries; 
    } 

    /** 
    * @param OptionsResolverInterface $resolver 
    */ 
    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults(array(
      'required' => false, 
      'data_class' => 'Evo\DeclarationBundle\Entity\Declaration', 
      'validation_groups' => false, 
     )); 
    } 

    /** 
    * @return string 
    */ 
    public function getName() 
    { 
     return 'evo_declaration_bundle_registration_step1_declaration_type'; 
    } 
} 

:

/** 
* Class RegistrationStep1UserType 
* @package Evo\DeclarationBundle\Form\Type 
*/ 
class RegistrationStep1UserType extends AbstractType 
{ 
    /** 
    * @param FormBuilderInterface $builder 
    * @param array $options 
    */ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->add('customer', new RegistrationStep1CustomerType(), [ 
       'label' => false, 
       'data_class' => 'Evo\UserBundle\Entity\Customer', 
       'cascade_validation' => true, 
      ]) 
      ->add('declaration', 'evo_declaration_bundle_registration_step1_declaration_type', [ 
       'label' => false, 
       'cascade_validation' => true, 
      ]) 
     ; 
    } 

    /** 
    * @param OptionsResolverInterface $resolver 
    */ 
    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => 'Evo\UserBundle\Entity\User', 
      'validation_groups' => false, 
     )); 
    } 

    /** 
    * @return string 
    */ 
    public function getName() 
    { 
     return 'evo_declaration_bundle_registration_step1_user_type'; 
    } 
} 

이 양식 유형은 서비스로 등록, RegistrationStep1DeclarationType ("선언"필드에) 포함 된 폼 유형을 포함

나는 주요 양식 유형, RegistrationStep1UserType이 이 embedded Form Type은 "birthCountry"필드에 Subscriber (EntityManager의 주입이 필요하기 때문에 서비스로도 등록 됨)를 추가합니다.

목표는 birthCountry 선택 목록의 값에 따라 추가 필드 ("birthCounty"라고 함)를 동적으로 추가하거나 제거하는 것입니다. 여기서 2 개의 필드는 "birthCountry"및 "birthCounty"와 다릅니다. 설명 된 바와 같이 (이하 "birthCountry"선택 목록이 변경되면 그 요청을 처리하고 다시보기를 렌더링 제어기에 AJAX 요청을 트리거 뷰

/** 
* Class AddBirthCountyFieldSubscriber 
* @package Evo\CalculatorBundle\Form\EventListener 
*/ 
class AddBirthCountyFieldSubscriber implements EventSubscriberInterface 
{ 
    /** 
    * @var EntityManagerInterface 
    */ 
    private $em; 

    /** 
    * AddBirthCountyFieldSubscriber constructor. 
    * @param EntityManagerInterface $em 
    */ 
    public function __construct(EntityManagerInterface $em) 
    { 
     $this->em = $em; 
    } 

    /** 
    * @return array 
    */ 
    public static function getSubscribedEvents() 
    { 
     return array(
      FormEvents::POST_SET_DATA => 'postSetData', 
      FormEvents::POST_SUBMIT => 'postSubmit', 
     ); 
    } 

    /** 
    * @param FormEvent $event 
    */ 
    public function postSetData(FormEvent $event) 
    { 
     $birthCountry = $event->getData(); 
     $form = $event->getForm()->getParent(); 

     $this->removeConditionalFields($form); 

     if ($birthCountry instanceof Country && true === $birthCountry->getIsDefault()) { 
      $this->addBirthCountyField($form); 
     } 
    } 

    /** 
    * @param FormEvent $event 
    */ 
    public function postSubmit(FormEvent $event) 
    { 
     $birthCountry = $event->getData(); 
     $form = $event->getForm()->getParent(); 

     if (!empty($birthCountry)) { 
      $country = $this->em->getRepository("EvoGeoBundle:Country")->find($birthCountry); 

      $this->removeConditionalFields($form); 

      if ($country instanceof Country && true === $country->getIsDefault()) { 
       $this->addBirthCountyField($form); 
      } 
     } 
    } 

    /** 
    * @param FormInterface $form 
    */ 
    private function addBirthCountyField(FormInterface $form) 
    { 
     $form 
      ->add('birthCounty', 'evo_geo_bundle_autocomplete_county_type', [ 
       'label' => 'Département de naissance', 
       'attr' => [ 
        'required' => true, 
       ], 
      ]) 
     ; 
    } 

    /** 
    * @param FormInterface $form 
    */ 
    private function removeConditionalFields(FormInterface $form) 
    { 
     $form->remove('birthCounty'); 
    } 
} 

: 여기서

는 가입자)이 documentation about dynamic form submission에 :

$form = $this->createForm(new RegistrationStep1UserType(), $user); 

if ($request->isXmlHttpRequest()) { 
    $form->handleRequest($request); 
} elseif ("POST" == $request->getMethod()) { 
    [...] 
} 

문제는 다음

나는 birthCountry 선택 목록 및 SELEC에 변경하면 타 국가 형태가 제대로 해당 필드없이 렌더링은 "birthCounty"필드를 숨길 생각하지만, 오류 메시지가 표시됩니다 :

Ce formulaire ne doit pas contenir des champs supplémentaires. 

또는

this form should not contain extra fields (in english) 

내가 노력

다양한 솔루션 :

  • RegistrationStep1UserType 및 RegistrationStep1DeclarationType에 'validation_groups'옵션을 추가하십시오.
  • AddSir을 AddSir에 추가하십시오. 심지어 birthCounty 필드 'mapped' => false, 추가 preSetData 및 postSubmit 방법
  • 논리 복제 thCountyFieldSubscriber 오류를 트리거한다. 매우 놀라운

난 그냥 \ 심포니 \ 심포니 \ SRC \ 심포니 \ 구성 요소 \ 양식 \ 확장 \ 검사기는 \ FormValidator \ 제약은, 내가 볼 수 $form->handleRequest($request);

후 그러나 공급 업체에 덤프 경우에도 $form->getExtraData() 비어 추가 필드 여기

array(1) { 
    ["birthCounty"]=> 
    string(0) "" 
} 

:

// Mark the form with an error if it contains extra fields 
    if (count($form->getExtraData()) > 0) { 
     echo '<pre>'; 
     \Doctrine\Common\Util\Debug::dump($form->getExtraData()); 
     echo '</pre>'; 
     die(); 

     $this->context->addViolation(
      $config->getOption('extra_fields_message'), 
      array('{{ extra_fields }}' => implode('", "', array_keys($form->getExtraData()))), 
      $form->getExtraData() 
     ); 
    } 

내가 뭔가를 놓친 건가 동적 추가 필드를 형성합니까?

답변

0

나는 모든 질문을 분석하지는 않았지만 논리를 뒤집을 수 있다고 생각합니다. 항상 조건을 만족하지 않을 때 필드를 추가하고 제거하십시오.

당신이 postSubmit에서 작업을 수행 할 필요가 없습니다 그 방법 (문제가 어디 즉)

+0

이 아마 일하는 것이,하지만 정말 해결 방법처럼 보인다. – VaN

+0

@VaN 정말 해결 방법이 확실하지 않습니다. – DonCallisto