2017-12-14 12 views
2

Symfony 3.3을 사용하고 있습니다. URL에있는 매개 변수를 기반으로 일부 필드를 동적으로 표시해야하는 양식이 있습니다.symfony 3.3의 url 매개 변수를 기반으로 양식 필드를 동적으로 설정합니다.

사용자는 처음에는 제목 필드 만있는 양식이 표시됩니다. 그 후에 그는 주제를 선택하고 양식의 일부 필드는 숨겨 지거나 표시됩니다. 일부 필드는 널 입력 가능하므로 완료 할 필요가 없습니다.

나는 이렇게 보입니다 Form을 만들었습니다.

내가 아는 한, 그것은 느껴지고 엉망진창처럼 보입니다. 저는 심포니를 처음 접했고이 시나리오에 관한 문서는 존재하지 않거나 찾을 수없는 것 같습니다.

public function contactAction(Request $request, Mailer $mailer) { 

    $contact = new Contact(); 
    $form = $this->createForm(ContactType::class, $contact, ['allow_extra_fields' => true]); 
    $form->handleRequest($request); 

    if ($form->isSubmitted() && $form->isValid()) { 
     $mailer->sendContactMail($form); 

     $em = $this->getDoctrine()->getManager(); 
     $em->persist($contact); 
     $em->flush(); 
    } 

    return $this->render('WIVCoreBundle:Core:contact.html.twig', array(
     'form' => $form->createView(), 
     'routes' => [ 
      'blank' => $this->generateUrl('wiv_core_contact', ['subject' => ContactType::CONTACT_CHOICE_BLANK]), 
      'register' => $this->generateUrl('wiv_core_contact', ['subject' => ContactType::CONTACT_CHOICE_REGISTER]), 
      'company' => $this->generateUrl('wiv_core_contact', ['subject' => ContactType::CONTACT_CHOICE_COMPANY]), 
      'contact' => $this->generateUrl('wiv_core_contact', ['subject' => ContactType::CONTACT_CHOICE_CONTACT]), 
     ], 
     'default_route' => $this->generateUrl('wiv_core_contact'), 
    )); 
} 

내 질문 : 컨트롤러에서

const CONTACT_CHOICE_BLANK = 'blank'; 
const CONTACT_CHOICE_REGISTER = 'register'; 
const CONTACT_CHOICE_COMPANY = 'company'; 
const CONTACT_CHOICE_CONTACT = 'contact'; 

.... 

/** 
* @return string 
*/ 
private function getChoice() { 
    if($this->requestStack->getCurrentRequest()->query->has('subject')) { 
     $subject = $this->requestStack->getCurrentRequest()->query->get('subject'); 
     switch($subject){ 
      case self::CONTACT_CHOICE_REGISTER: 
       $default_choice = 'contact.form.select.option.' . self::CONTACT_CHOICE_REGISTER; 
       break; 
      case self::CONTACT_CHOICE_COMPANY: 
       $default_choice = 'contact.form.select.option.' . self::CONTACT_CHOICE_COMPANY; 
       break; 
      case self::CONTACT_CHOICE_CONTACT: 
       $default_choice = 'contact.form.select.option.' . self::CONTACT_CHOICE_CONTACT; 
       break; 

      case self::CONTACT_CHOICE_BLANK: 
      default: 
       $default_choice = 'contact.form.select.option.' . self::CONTACT_CHOICE_BLANK; 
       break; 
     } 
     return $default_choice; 
    } 

    return self::CONTACT_CHOICE_BLANK; 
} 

/** 
* {@inheritdoc} 
*/ 
public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $default_choice = $this->getChoice(); 

    $this->session->set('show_message', false); 
    $this->session->set('show_email', false); 
    $this->session->set('show_company', false); 
    $this->session->set('show_email_pro', false); 
    $this->session->set('show_company_spouse', false); 

    $builder 
     ->add('subject', ChoiceType::class, array(
      'choices' => array(
       'contact.form.select.option.' . self::CONTACT_CHOICE_BLANK => self::CONTACT_CHOICE_BLANK, 
       'contact.form.select.option.' . self::CONTACT_CHOICE_REGISTER => self::CONTACT_CHOICE_REGISTER, 
       'contact.form.select.option.' . self::CONTACT_CHOICE_COMPANY => self::CONTACT_CHOICE_COMPANY, 
       'contact.form.select.option.' . self::CONTACT_CHOICE_CONTACT => self::CONTACT_CHOICE_CONTACT, 
      ), 
      'label' => 'contact.form.select.subject', 
      'required' => true, 
      'data' => $default_choice, 
     )) 

     ->add('firstName', TextType::class, array('label' => 'contact.form.input.firstname')) 
     ->add('familyName', TextType::class, array('label' => 'contact.form.input.familyname')) 
     ->add('phoneNumber', TextType::class, array('label' => 'contact.form.input.phone')) 
     ->add('contactReason', ChoiceType::class, array(
       'choices' => array(
        'contact.form.select.option.advertising' => 'contact.form.select.option.advertising', 
        'contact.form.select.option.internet' => 'contact.form.select.option.internet', 
        'contact.form.select.option.member' => 'contact.form.select.option.member', 
        'contact.form.select.option.word' => 'contact.form.select.option.word', 
        'contact.form.select.option.other' => 'contact.form.select.option.other'), 
       'label' => 'contact.form.select.reason' 
      )) 
     ->add('send', SubmitType::class, array('label' => 'contact.form.textarea.send')); 


    $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($default_choice) { 
     $form = $event->getForm(); 

     if($default_choice == 'contact.form.select.option.information_request') { 
      $form->add('email', TextType::class, array(
       'label' => 'contact.form.input.email', 
      )); 
      $this->session->set('show_email', true); 
     } 

     if($default_choice == 'contact.form.select.option.business_membership_application') { 
      $form->add('emailPro', TextType::class, array(
       'label' => 'contact.form.input.emailPro', 
      )); 
      $form->add('company', TextType::class, array(
       'label' => 'contact.form.input.company', 
      )); 
      $this->session->set('show_email_pro', true); 
      $this->session->set('show_company', true); 
     } 

     if($default_choice == 'contact.form.select.option.registration_request') { 
      $form->add('companySpouse', TextType::class, array(
       'label' => 'contact.form.input.companyspouse', 
      )); 
      $this->session->set('show_company_spouse', true); 
     } 

     if($default_choice == 'contact.form.select.option.registration_request' || $default_choice == 'contact.form.select.option.information_request') { 
      $form->add('message', TextareaType::class, array(
       'label' => 'contact.form.textarea.message', 
      )); 
      $this->session->set('show_message', true); 
     } 
    }); 
} 

,이 양식을 처리하는 기능과 같이 보이는 /이 필드를 숨기 보여줄 수있는 더 좋은 방법이 있나요? 아마도 완전한 혼란처럼 느껴지지 않는 무언가일까요?

나는 손을 잡을 필요가 없으며, 일부는 올바른 방향으로 가리키고 있습니다. 아마도 필자가 놓친 문서의 일부분 일 것입니다.

+0

'contact' 엔티티에는 string 형의'subject'라는 필드가 있습니까? – zizoujab

+0

네, 맞습니다. 그렇습니다. – Andrew

답변

0

내가 얻는 경우에 확실하지 않다 귀하의 질문, 내가 대답을 제공하고 내가 틀렸을 경우 의견을 주시기 바랍니다.

public function contactAction(Request $request, Mailer $mailer) { 

    $contact = new Contact(); 
    $contact->setSubject($request->query->get('subject'); 
    ..... 
} 

이미 제목 필드를 폼에 contact 엔티티를 통과 한 후 PRE_SET_DATA 경우에 당신이 확인 :

왜 컨트롤러 내에 contact 기업에 대한 주제를 설정하지 마십시오 contact 기업의 subject 분야 :

$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($default_choice) { 
    $form = $event->getForm(); 
    $contact = $event->getData(); 
    if ($contact && $contact->getSubject() == 'value1') { 
     $form->add(...) 
    // do your magic here 
    })); 
    } 

출처 : http://symfony.com/doc/2.8/form/dynamic_form_modification.html