2013-03-19 60 views
2

這些是我在SF2上的第一步。我想在包含其他實體的實體上設置多步表單。Symfony2將多步形式合併爲一個結果

我有一個表單類型(縮短)

class ApplicationFormType extends AbstractType 
{ 
    protected $_step = 1; 

    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     if ($this->_step == 1) { 
      $builder 
       ->add('patient', new Type\PersonType()) 
       ->add('insurance', 'entity', array(
        'class' => 'Acme\MainBundle\Entity\Insurance', 
       )); 
     } elseif ($this->_step == 2) { 
      $nurse = new Type\PersonType(); 
      $nurse->requireBareData(); 
      $builder 
       ->add('nurse', $nurse) 
       ->add('nurse_type', 'entity', array(
        'class' => 'Acme\MainBundle\Entity\NurseType', 
        'expanded' => true, 
        'multiple' => false, 
       )) 
       ->add('nursing_support', 'checkbox', array(
        'required' => false, 
       )); 
     } 
    } 

    public function setStep($step) 
    { 
     $this->_step = $step; 
    } 

我的控制器看起來像

public function assistAction() { 
    $request = $this->getRequest(); 

    $step = $this->getSession()->get('assist_step', 1); 
    if ($request->getMethod() != 'POST') { 
     $step = 1; 
     $this->getSession()->set('assist_data', NULL); 
    } 
    $this->getSession()->set('assist_step', $step); 
    $application = new Application(); 
    $type = new ApplicationFormType(); 
    $type->setStep($step); 

    $form = $this->createForm($type, $application, array(
     'validation_groups' => array($step == 1 ? 'FormStepOne' : 'FormStepTwo'), 
    )); 
    if ($request->getMethod() == 'POST') { 
     $form->bindRequest($request); 
     if ($form->isValid()) { 
      if ($step == 1) { 

       $data = $form->getData(); 
       $this->getSession()->set('assist_data', serialize($data)); 
       $this->getSession()->set('assist_step', ++$step); 
       $type = new ApplicationFormType(); 
       $type->setStep($step); 
       $form = $this->createForm($type, $application, array(
        'validation_groups' => array('FormStepTwo'), 
       )); 

      } else { 

       $step_1 = unserialize($this->getSession()->get('assist_data', '')); 
       $data = $form->getData(); 
=>    $data->setPatient($step_1->getPatient()); 
=>    $data->setInsurance($step_1->getInsurance()); 
       $this->getSession()->set('assist_data', NULL); 
       $this->getSession()->set('assist_step', 1); 

      } 
     } 
    } 

    return $this->render('Acme:Default:onlineassist.html.twig', array(
     'form' => $form->createView(), 
     'step' => $step, 
    )); 
} 

我的問題是,如果我不得不「複製」第一種形式一步的性能seperately,像:

$data->setPatient($step_1->getPatient()); 
$data->setInsurance($step_1->getInsurance()); 

或I可以合併從會話中的序列化的數據和從第二形式數據STE P + 還是有一個完全不同的方法?

+0

多步表單的最終目的是什麼?您希望在整個過程中保留提交的數據(如果有效),並且一旦客戶檢查數據,然後將其注入數據庫中,對嗎? – 2013-03-20 05:50:30

+0

@ThomasPotaire:不完全。客戶端不檢查數據。正如你所看到的(在FormType中)第二步提供了另一個實體字段由用戶填充。 (並且會有第三步。)當用戶完成所有步驟時(順便說一句:第二個步驟很快就會選擇),包含所有相關實體的Application實體應該被保存到DB中。 – rabudde 2013-03-20 06:17:19

回答

0

好了,發現比seperately設定步前場,像

$pre_step = unserialize($this->getSession()->get('assist_data', '')); 
$data->setPatient($pre_step->getPatient()); 
$data->setInsurance($pre_step->getInsurance()); 
$data->setInsuranceNumber($pre_step->getInsuranceNumber()); 
$data->setInsuranceLevel($pre_step->getInsuranceLevel()); 

,並且沒有其他辦法就是我已經這樣做的遠。

1

實體可以根據stackoverflow上的響應序列化並放入會話中。

如果每個表單都是不同的類型,我建議您將多種類型的類型分開。

這裏是我想象它:

public function submitAction($step = 1) 
{ 
    switch ($step) { 
     case 1: 
      $entity = new EntityOne(); 
      $form = $this->createForm(new EntityOneType(), $entity); 
      $template = "template_one.html.twig"; 
      $redirect = $urlToStepTwo; // which redirects to this controller action with $step = 2 
      break; 
     case 2: 
      $entity = new EntityTwo(); 
      $form = $this->createForm(new EntityTwoType(), $entity); 
      $template = "template_two.html.twig"; 
      $redirect = $urlToStepThree; // which redirects to this controller action with $step = 3 
      break; 
     case 3: 
      $entity = new EntityThird(); 
      $form = $this->createForm(new EntityThreeType(), $entity); 
      $template = "template_three.html.twig"; 
      $redirect = $urlToConfirmPage; // which redirects to another controller action that unserialize all entities and save them in the DB 
      break; 
     default: 
      throw $this->createNotFoundException(); 
      break; 
    } 

    $request = $this->get('request'); 
    $session = $this->get('session'); 

    if ($request->isMethod('post') === true) { 

     $form->bind($request); 

     if ($form->isValid() === true) { 
      $session->set('entity_'. $step, serialize($entity)); 

      return $this->redirect($redirect); 
     } 
    } 

    $params = array(
     'form' => $form->createView(), 
     'entity' => $entity 
    ); 

    return $this->render($template, $params); 
} 
+0

您的解決方案當然適用於單獨的實體。但我在這三個步驟中有兩個使用了一個大實體。 'ApplicationFormType'表示一個'Application'實體。 (順便說一句:你的代碼不符合SF2.2,即'bindRequest'與'bind'和'getMethod()'與'isMethod('post')') – rabudde 2013-03-21 09:56:07

+0

你可以創建兩個表單類型來表示一組數據'應用程序'並將它們融合在一起(謝絕任何棄用的通話)。 – 2013-03-21 14:57:07

+0

這正是我正在做的(看看我的帖子)。這就是我的問題。如何合併這兩個步驟。可以用PHP中的一條語句來完成,還是讓我手動設置第二步中第一步的每個屬性? – rabudde 2013-03-21 18:41:38