2012-06-19 18 views
8

एक सिम्फनी 2 वेबसाइट में मैं देश (क्षेत्र> शहर जैसी निर्भरता के साथ 2 (या 3) ड्रॉपडाउन सूचियों के साथ एक फॉर्म बनाने की कोशिश कर रहा हूं। और वह शहर तत्व का एक क्षेत्र है जिसे मैं फॉर्म के साथ संपादित कर रहा हूं। विचार चयन के आधार पर सूचियों को भरना है। http://aulatic.16mb.com/wordpress/2011/08/symfony2-dynamic-forms-an-event-driven-approach/ (जो वेब-ऑन-द वेब पर आधारित है .com/पी = 5?)सिम्फनी 2 फॉर्म इवेंट्स - ड्रॉप डाउन सूचियां

मुद्दा रहा है: यह सब काम करता है लेकिन

मैं प्रपत्र घटनाओं यहाँ के साथ ट्यूटोरियल का पालन किया है जब मैं तत्व को संपादित करने के लिए फॉर्म का उपयोग करता हूं, तो शहर को सही ढंग से चुना जाता है (डीबी से) लेकिन देश और क्षेत्र ड्रॉपडाउन सूचियों को पहले से भर दिया जाता है और 'एक मान का चयन करें' पर छोड़ दिया जाता है। मुझे नहीं पता कि यह ट्यूटोरियल के साथ काम करना चाहिए या नहीं।

प्रश्न: मैं इन सूचियों को कैसे चुन सकता हूं? मैं एक POST_SET_DATA ईवेंट जोड़ने की कोशिश कर रहा हूं लेकिन मुझे फॉर्म फ़ील्ड में मान का चयन करने का कोई तरीका नहीं मिल रहा है।

यहां फॉर्म वर्ग है: http://pastebin.com/PpWkHxC3 (ध्यान दें कि शहर के बजाय यह है: फ़ील्ड> विषय और विषय एक पाठ का एक क्षेत्र है जिसे फॉर्म संपादित करता है)।

उत्तर

10

मुझे लगभग यह था। किसी और कभी भी इस यहाँ की जरूरत है क्या इस समाधान काम पूरी तरह से बनाने के लिए किसी मौजूदा आइटम को संपादित करते समय जोड़ा जा करने की जरूरत है है:

class ItemDetailForm extends AbstractType 
{ 
    ... 
     $builder->addEventListener(FormEvents::POST_SET_DATA, function (DataEvent $event) use ($refreshTopic) { 
      $data = $event->getData(); 
      $form = $event->getForm(); 
      if (null === $data) { 
       return; 
      } 

      $form->get('region')->setData($data->getCity()->getRegion()); 
     }); 
} 

संपादित करें: सिम्फोनी 2.1 के बाद से, बच्चों रूप से जुड़ जाते हैं इससे पहले कि POST_SET_DATA घटना कहा जाता है , अपवाद बढ़ाने के लिए सभी प्राप्त ('क्षेत्र') का कारण बनता है।

 /** @var FormFactory $factory */ 
     $form->add($factory->createNamed('region', 'entity', null, array(
      'class'=>'AcmeBundle:Region', 
      'property_path'=>false, 
      'empty_value'=>'Choose a value', 
      'required'=>true, 
      'label'=>'Region' 
     ))); 

ध्यान दें कि आप बंद घटना से निपटने में 'उपयोग' के लिए $ कारखाना जोड़ने की जरूरत:

समाधान buildForm() में POST_SET_DATA में और नहीं इस क्षेत्र को बनाने के लिए है
$builder->addEventListener(FormEvents::POST_SET_DATA, function (DataEvent $event) use ($refreshTopic, $factory) { 

यहाँ पूरे प्रपत्र वर्ग है:

<?php 
namespace AAA\CoreBundle\Form; 

use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\Form\FormFactory; 
use Symfony\Component\Form\FormEvents; 
use Symfony\Component\Form\FormEvent; 
use Symfony\Component\Form\Form; 
use Symfony\Component\OptionsResolver\OptionsResolverInterface; 
use Doctrine\ORM\EntityRepository; 
use AAA\CoreBundle\Entity\ClassYear; 
use AAA\CoreBundle\Entity\Field; 
use AAA\CoreBundle\Entity\Lesson; 
use AAA\CoreBundle\Form\LessonContentForm; 

class LessonDetailForm extends AbstractType 
{ 
    public $country; 
    function __construct($country=null) { 
     // Get country for classyear dropdown list 
     $this->country = $country; 
    } 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $factory = $builder->getFormFactory(); 

     $builder->add('name', null, array('label'=>'Titre de la leçon')); 
     $builder->add('description', 'textarea', array('label'=>'Description (définition conceptuelle) Qu\'est-ce que c\'est ? Et à quoi ça sert ? (importance, utilité)')); 
     $builder->add('text', 'textarea', array('label'=>'Leçon', 'required'=>false)); // Can't set 'required' on textareas used by TinyMCE 
     $builder->add('reperes', 'textarea', array('label'=>'Repères (détectionel) - Quels sont les éléments qui me permettent de repérer que je dois penser à ce concept ?', 'required'=>false)); 
     $builder->add('other_topic', null, array(
      'required' => false, 
      'mapped'  => false 
     )); 

     $refreshField = function ($form, $classyear) use ($factory) { 
      /** @var FormFactory $factory */ 
      /** @var Form $form */ 
      $form->add($factory->createNamed('field','entity',null, array(
       'class'   => 'AAA\CoreBundle\Entity\Field', 
       'mapped'  => false, 
       'label'   => 'Matière', 
       'empty_value' => 'Sélectionne une valeur', 
       'empty_data' => null, 
       'required'  => false, 
       'query_builder' => function (EntityRepository $repository) use ($classyear) { 
        $qb = $repository->createQueryBuilder('field') 
         ->innerJoin('field.classyear', 'classyear'); 

        if($classyear instanceof ClassYear) { 
         $qb = $qb->where('field.classyear = :classyear') 
          ->setParameter('classyear', $classyear); 
        } elseif(is_numeric($classyear)) { 
         $qb = $qb->where('classyear.id = :classyear_id') 
          ->setParameter('classyear_id', $classyear); 
        } else { 
         $qb = $qb->where('0 = 1'); 
        } 

        return $qb; 
       } 
      ))); 
     }; 
     $refreshTopic = function ($form, $field) use ($factory) { 
      /** @var FormFactory $factory */ 
      /** @var Form $form */ 
      $form->add($factory->createNamed('topic','entity',null, array(
       'class'   => 'AAA\CoreBundle\Entity\Topic', 
       'property'  => 'name', 
       'label'   => 'Sujet', 
       'empty_value' => 'Sélectionne une valeur', 
       'empty_data' => null, 
       'required'  => false, 
       'query_builder' => function (EntityRepository $repository) use ($field) { 
        $qb = $repository->createQueryBuilder('topic') 
         ->innerJoin('topic.field', 'field'); 

        if($field instanceof Field) { 
         $qb = $qb->where('topic.field = :field') 
          ->setParameter('field', $field); 
        } elseif(is_numeric($field)) { 
         $qb = $qb->where('field.id = :field_id') 
          ->setParameter('field_id', $field); 
        } else { 
         $qb = $qb->where('0 = 1'); 
        } 

        return $qb; 
       } 
      ))); 
     }; 

     // Populate ddl to show form 
     $country = $this->country; 
     $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($refreshTopic, $refreshField, $factory, $country) { 
      /** @var Lesson $data */ 
      $data = $event->getData(); 
      $form = $event->getForm(); 

      // Test if null because this event is called 2 times, only the second time with the actual Lesson object (which has null values in the creation case) 
      if($data != null) 
       // In case of creation 
       if($data->getId()==null) { 
        // Creates empty fields 
        $refreshTopic($form, null); 
        $refreshField($form, null); 
       } 
       // In case of edition 
       else { 
        if ($data->getTopic() != null) { 
         $refreshTopic($form, $data->getTopic()->getField()); 
         if ($data->getTopic()->getField() != null) { 
          $refreshField($form, $data->getTopic()->getField()->getClassYear()); 
         } 
        } 
        else { 
         $refreshField($form, null); 
         $refreshTopic($form, null); 
        } 
       } 

      /** @var FormFactory $factory */ 
      $form->add($factory->createNamed('classyear', 'entity', null, array(
       'class'   => 'AAACoreBundle:ClassYear', 
       'property'  => 'name'.$country, 
       'mapped'  => false, 
       'label'   => 'Année', 
       'empty_value' => 'Sélectionne une valeur', 
       'empty_data' => null, 
       'required'  => false, 
       'query_builder' => function (EntityRepository $repository) { 
        return $repository->createQueryBuilder('classyear') 
         ->orderBy('classyear.sort'); 
       } 
      ))); 
     }); 
     // Populate ddl when form was posted 
     $builder->addEventListener(FormEvents::PRE_BIND, function (FormEvent $event) use ($refreshTopic, $refreshField) { 
      $form = $event->getForm(); 
      $data = $event->getData(); 

      if(array_key_exists('classyear', $data)) { 
       $refreshField($form, $data['classyear']); 
      } 
      if(array_key_exists('field', $data)) { 
       $refreshTopic($form, $data['field']); 
      } 
     }); 

     // Select value in ddl when editing 
     $builder->addEventListener(FormEvents::POST_SET_DATA, function (FormEvent $event) use ($refreshTopic) { 
      /** @var Lesson $data */ 
      $data = $event->getData(); 
      $form = $event->getForm(); 
      if (null === $data || null === $data->getId()) { 
       return; 
      } 

      if ($data->getTopic() != null) { 
       $form->get('field')->setData($data->getTopic()->getField()); 
       if ($data->getTopic()->getField() != null) { 
        $form->get('classyear')->setData($data->getTopic()->getField()->getClassYear()); 
       } 
      } 
     }); 
    } 
    public function getName() 
    { 
     return 'LessonDetailForm'; 
    } 
    /** @param OptionsResolverInterface $resolver */ 
    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => 'AAA\CoreBundle\Entity\Lesson' 
     )); 
    } 
} 

?> 
+0

मैं तुम्हें थॉमस करने के लिए एक सवाल है, मैं अपने सिस्टम में एक ऐसी ही लटकती निर्भरता है। मेरा मामला यह है कि मैं फॉर्म बनाता हूं और मैं इसे अन्य मानों (वास्तव में अनुरोध) से जोड़ता हूं, मैं 'क्षेत्र' डेटा कैसे सेट कर सकता हूं और जब मैं फॉर्म बनाता हूं तो दोनों काम करना जारी रखता हूं और मैं इसे बाध्य नहीं कर रहा हूं और जब मैं बांधता हूं अनुरोध के साथ डेटा? – eagleoneraptor

+0

क्षमा करें, मैं वास्तव में उस प्रश्न को समझ नहीं पाया। :) (दिमाग कि फॉर्म में बाध्यकारी 2.1 में सुधार किया गया है, इसलिए आप बस बाइंड() और bindRequest() को कॉल नहीं करते हैं। – Thomas

+0

हैलो थॉमस। मैं जो किया वह करने के लिए मैं नरक की तरह संघर्ष कर रहा हूं। दुर्भाग्यवश फॉर्म के साथ ट्यूटोरियल घटनाएं अब और नहीं हैं। लिंक मर चुका है। क्या आप बेटे की तरह हो सकते हैं और अपना जवाब संपादित कर सकते हैं ताकि मेरे जैसे आगे बढ़ सकें। यह वाकई बहुत अच्छा होगा :) अग्रिम धन्यवाद। चीयर्स। मार्क – Marc

संबंधित मुद्दे