2012-11-10 14 views
19

परिदृश्य: मेरे पास 2 चयनों वाला एक फॉर्म है। जब उपयोगकर्ता पहले चयन से कुछ चुनता है, तो दूसरा चयन नए मानों के साथ पॉप्युलेट हो जाता है। यह हिस्सा ठीक काम करता है।सिम्फनी 2: AJAX और सत्यापन के साथ विकल्प बदलें

लेकिन फ़ॉर्म मान्य नहीं है क्योंकि इसमें कुछ विकल्प हैं जिन्हें प्रारंभिक रूप में अनुमति नहीं है।

प्रपत्र:

<?php 

class MyType extends AbstractType 
{ 
    private $category; 

    public function __construct($category = null) 
    { 
     $this->category = $category; 
    } 

    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder->add('category', 'choice', array(
      'choices' => array(
       'foo' => 'foo', 
       'bar' => 'bar' 
      ) 
     ); 

     $builder->add('template', 'choice', array(
      'choices' => $this->loadChoices() 
     ); 
    } 

    private function loadChoices() 
    { 
     // load them from DB depending on the $this->category 
    } 
} 

प्रारंभ में श्रेणी foo है। तो foo के लिए टेम्पलेट लोड हो जाते हैं और विकल्पों के रूप में सेट होते हैं। लेकिन यदि उपयोगकर्ता bar का चयन करता है, तो बार टेम्पलेट लोड हो जाते हैं। लेकिन फॉर्म में अभी भी foo विकल्प हैं और यह मान्य नहीं है।

इसे हल करने का सबसे अच्छा तरीका क्या है?

एक तरह से मैंने पाया बस नियंत्रक में फार्म का पुन: करने के लिए किया गया था:

<?php 

$form = $this->createForm(new MyType()); 

if ($request->getMethod() === 'POST') { 
    if ($request->request->has($form->getName()) 
     && isset($request->request->get($form->getName())['category'])) { 
      $form = $this->createForm(new MyType($request->request->get($form->getName())['category'])); 
    } 

    // ... 
} 

यह काम करता है, लेकिन मैं इसे परीक्षण नहीं कर सकते क्योंकि यह IllegalArgumentException फेंकता है जब मान सेट और बस डिफ़ॉल्ट मान लिया गया है। क्या इसका कोई बेहतर समाधान है? अग्रिम में धन्यवाद!

+0

आप विकल्प आप को मान्य करने के लिए है के प्रत्येक सेट के लिए मान्यता समूहों सेट करने के लिए करने की कोशिश की है? फिर, आप केवल उस समूह पर सत्यापनकर्ता सेवा को कॉल कर सकते हैं जो आपके लिए प्रासंगिक है। http://symfony.com/doc/2.0/book/forms.html#validation- समूह – Xocoatzin

उत्तर

20

मुझे लगता है कि यू ईवेंट का उपयोग करने के लिए इस का प्रबंधन करने के लिए है, जो और अधिक सही तरीका

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $builder->add('category', 'choice', array(
     'choices' => array(
      'foo' => 'foo', 
      'bar' => 'bar' 
     ) 
    )); 

    $ff = $builder->getFormFactory(); 

    // function to add 'template' choice field dynamically 
    $func = function (FormEvent $e) use ($ff) { 
     $data = $e->getData(); 
     $form = $e->getForm(); 
     if ($form->has('template')) { 
      $form->remove('template'); 
     } 

     $cat = isset($data['category'])?$data['category']:null; 

     // here u can populate ur choices in a manner u do it in loadChoices 
     $choices = array('1' => '1', '2' => '2'); 
     if ($cat == 'bar') { 
      $choices = array('3' => '3', '4' => '4'); 
     } 

     $form->add($ff->createNamed('template', 'choice', null, compact('choices'))); 
    }; 

    // Register the function above as EventListener on PreSet and PreBind 
    $builder->addEventListener(FormEvents::PRE_SET_DATA, $func); 
    $builder->addEventListener(FormEvents::PRE_BIND, $func); 
} 
+0

देर से प्रतिक्रिया के लिए खेद है! मैं आज इसे देख लूंगा। :) – smottt

+0

पूरी तरह से काम करता है, बहुत बहुत धन्यवाद! – smottt

+0

मुझे इसी तरह की समस्या के लिए इस लिंक की अनुशंसा की गई थी कि मैं काम करने की कोशिश कर रहा हूं (जहां मैं 'ऑन चेंज' ट्रिगर के साथ AJAX का उपयोग करना चाहता हूं)। इस तरह से अच्छा लग रहा है, हालांकि मैं सबकुछ बदलने से पहले जांचना चाहता था: क्या यह फ़ॉर्म को सबमिट किए बिना किसी श्रेणी को चुना गया है, तो डेटाबेस लुकअप से 'टेम्पलेट' ड्रॉपडाउन को पॉप्युलेट करने के लिए फॉर्म को रीफ्रेश कर सकता है? – Bendy

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