2017-08-08 103 views
1

我正在使用事件偵聽器來動態修改表單。我想添加另一個事件監聽器到第二個字段。我想這個代碼,但沒有奏效:將事件偵聽器添加到Symfony3中的動態添加字段

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 

     $builder 
     ->add('Marque', EntityType::class, array(
      'class'  => 'EK\PlateformeBundle\Entity\Marque', 
      'placeholder' => '-- Choississez une marque --', 
      //'mapped' => false 
     )) 
     ->add('Modele', EntityType::class, array(
      'class'  => 'EK\PlateformeBundle\Entity\Modele', 
      'placeholder' => '-- Choississez un modèle --', 
      //'mapped' => false 
     )) 
     ->add('nom', EntityType::class, array(
      'class'  => 'EK\PlateformeBundle\Entity\Type', 
      'placeholder' => '-- Choississez une type --', 
      //'mapped' => false 
     )) 
    ; 

    $formModifierM = function (FormInterface $form, Marque $marque = null) { 

     $modeles = null === $marque ? array() : $marque->getAvailableModeles(); // only in a bidirectional relationship 
     $placeholder = empty($modeles) ? '-- Choississez un modèle --' : ''; 
     $form->add('Modele', EntityType::class, array(
      'class' => 'EK\PlateformeBundle\Entity\Modele', 
      'placeholder' => $placeholder, 
      'choices' => $modeles, 
     )) 
      ->add('Rechercher', SubmitType::class) ; 

    }; 

    $formModifierModele = function (FormInterface $form, Modele $modele = null) { 

     $types = null === $modele ? array() : $modele->getAvailableTypes(); // only in a bidirectional relationship 
     $placeholder = empty($types) ? '-- Choississez un type --' : ''; 
     $form->add('nom', EntityType::class, array(
      'class' => 'EK\PlateformeBundle\Entity\Type', 
      'placeholder' => $placeholder, 
      'choices' => $types, 
     )) 
      ->add('Rechercher', SubmitType::class) ; 

    }; 


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

    $builder->get('Marque')->addEventListener(
     FormEvents::POST_SUBMIT, 
     function(FormEvent $event) use ($formModifierM) { 

      $form = $event->getForm()->getParent(); 
      $marque = $event->getForm()->getData(); 
      // since we've added the listener to the child, we'll have to pass on 
      // the parent to the callback functions! 
      $formModifierM($form, $marque); 
     } 

    ); 


    $builder->get('Modele')->addEventListener(// this code did'nt work 
     FormEvents::POST_SUBMIT, 
     function(FormEvent $event) use ($formModifierModele) { 

      $form = $event->getForm()->getParent(); 
      $modele = $event->getForm()->getData(); 
      $formModifierModele($form, $modele); 
     } 
    ); 

} 

我沒有找到這個problem.Any一個可以幫我請任何解決方案。 我發現了同樣的問題,但它並沒有爲我工作 How to add an Event Listener to a dynamically added field using Symfony Forms

回答

0

我解決了我的問題。這是我的工作代碼: POST_SUBMIT必須PRE_SUBMIT

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 

     /** @var \Doctrine\ORM\EntityManager $em */ 
     $em = $options['entity_manager']; 

     $builder 
     ->add('Marque', EntityType::class, array(
      'class'  => 'EK\PlateformeBundle\Entity\Marque', 
      'placeholder' => '-- Choississez une marque --', 
      'required' => false, 
      //'mapped' => false 
     )) 
     ->add('Modele', EntityType::class, array(
      'class'  => 'EK\PlateformeBundle\Entity\Modele', 
      'placeholder' => '-- Choississez un modèle --', 
      'required' => false, 
      //'mapped' => false 
     )) 
     ->add('nom', EntityType::class, array(
      'class'  => 'EK\PlateformeBundle\Entity\Type', 
      'placeholder' => '-- Choississez une type --', 
      'required' => false, 
      //'mapped' => false 
     )) 
    ; 

    $formModifierM = function (FormInterface $form, Marque $marque = null) { 

     $modeles = null === $marque ? array() : $marque->getAvailableModeles(); // only in a bidirectional relationship 
     $placeholder = empty($modeles) ? '-- Choississez un modèle --' : ''; 
     $form->add('Modele', EntityType::class, array(
      'class' => 'EK\PlateformeBundle\Entity\Modele', 
      'placeholder' => $placeholder, 
      'required' => false, 
      'choices' => $modeles, 
     )) 
      ->add('Rechercher', SubmitType::class) ; 

    }; 

    $formModifierModele = function (FormInterface $form, Modele $modele = null) { 

     $types = null === $modele ? array() : $modele->getAvailableTypes(); // only in a bidirectional relationship 
     $placeholder = empty($types) ? '-- Choississez un type --' : ''; 
     $form->add('nom', EntityType::class, array(
      'class' => 'EK\PlateformeBundle\Entity\Type', 
      'placeholder' => $placeholder, 
      'required' => false, 
      'choices' => $types, 
     )) 
      ->add('Rechercher', SubmitType::class) ; 

    }; 


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

    $builder->addEventListener(
     FormEvents::PRE_SUBMIT, 
     function(FormEvent $event) use ($formModifierM ,$formModifierModele , $em) { 
      $form = $event->getForm(); 
      $data = $event->getData(); 
      if (!isset($data['Modele']) || empty($data['Modele'])) 
      { 

      $marque_id = $data['Marque']; 
      $marque = $em->getRepository("EK\PlateformeBundle\Entity\Marque")->find($marque_id); 
      $formModifierM($form, $marque); 
      } 
      else 
      { 
       $modele_id = $data['Modele'];  
       $modele = $em->getRepository("EK\PlateformeBundle\Entity\Modele")->find($modele_id); 
       $formModifierModele($form, $modele); 
      } 

     } 

    ); 



} 
1

我認爲這是更好地利用鏈改性劑和使用NamedFormBuilder如下面的例子中添加它們來代替。 這是因爲在PRE_SUBMIT事件中,您正在訪問請求數據,這會在某些可能情況下破壞您的代碼。

$volumeModifier = function(FormInterface $form, ?Vendor $vendor, ?int $year, ?int $volume): void { 

     if (null === $volume) { 
      return; 
     } 

     $form->add("model", EntityType::class, [ 
      "class"   => Model::class, 
      "required"  => false, 
      "query_builder" => function(ModelRepository $er) use ($vendor, $year, $volume) { 

      // return builded qb; 
      }, 
     ]); 
    }; 

    $yearModifier = function(FormInterface $form, ?Vendor $vendor, ?int $year) use ($volumeModifier): void { 

     if (null === $year) { 
      return; 
     } 

     $volumes = [];//build volumes choices 

     $builder = 
      $form->getConfig()->getFormFactory()->createNamedBuilder("volume", ChoiceType::class, null, [ 
       "auto_initialize" => false, 
       "required"  => false, 
       "choices"   => $volumes, 
      ]); 

     $builder->addEventListener(
      FormEvents::POST_SUBMIT, 
      function(FormEvent $event) use ($vendor, $year, $volumeModifier) { 
       /** @var int $volume */ 
       $volume = $event->getForm()->getData(); 
       $volumeModifier($event->getForm()->getParent(), $vendor, $year, $volume); 
      }); 

     $form->add($builder->getForm()); 
    }; 
$vendorModifier = function(FormInterface $form, ?Vendor $vendor) use ($yearModifier): void { 

     if (null === $vendor) { 
      return; 
     } 

     $years = [];// build years choices 

     $builder = 
      $form->getConfig()->getFormFactory()->createNamedBuilder("year", ChoiceType::class, null, [ 
       "auto_initialize" => false, 
       "required"  => false, 
       "choices"   => $years, 
      ]); 

     $builder->addEventListener(
      FormEvents::POST_SUBMIT, 
      function(FormEvent $event) use ($vendor, $yearModifier) { 
       /** @var int $year */ 
       $year = $event->getForm()->getData(); 
       $yearModifier($event->getForm()->getParent(), $vendor, $year); 
      }); 

     $form->add($builder->getForm()); 
    }; 

    $builder->get("vendor")->addEventListener(
     FormEvents::POST_SUBMIT, 
     function(FormEvent $event) use ($vendorModifier) { 
      /** @var Vendor $vendor */ 
      $vendor = $event->getForm()->getData(); 
      $vendorModifier($event->getForm()->getParent(), $vendor); 
     }); 
相關問題