Ricerca…


Come estendere ChoiceType, EntityType e DocumentType per caricare le scelte con AJAX.

In Symfony, il ChoiceType incorporato (e EntityType o DocumentType che lo estendono), funzionano in modo basico con una lista di scelta costante.

Se vuoi farlo funzionare con le chiamate ajax, devi cambiarle per accettare qualsiasi altra scelta addizionale.

  • Come iniziare con una lista di scelta vuota?

    Quando crei il tuo modulo, imposta l'opzione choices su un array() vuoto array() :

     namespace AppBundle\Form;
    
     use Symfony\Component\Form\AbstractType;
    
     use Symfony\Component\Form\FormBuilderInterface;
    
     use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
    
     class FooType extends AbstractType
     {
         public function buildForm(FormBuilderInterface $builder, array $options)
         {
             $builder
                 ->add('tag', ChoiceType::class, array('choices'=>array()));
         }
     }
    

    Quindi otterrai un input di selezione vuoto, senza scelte. Questa soluzione funziona per ChoiceType e tutti i suoi figli (EntityType, DocumentType, ...).

  • Come accettare le nuove scelte presentate :

    Per accettare le nuove scelte, devi renderle disponibili nel menu di scelta del modulo. È possibile modificare il campo modulo in base ai dati inviati con l'evento FormEvent :: PRE_SUBMIT.

    Questo esempio mostra come farlo con un ChoiceType di base:

     namespace AppBundle\Form;
    
     use Symfony\Component\Form\AbstractType;
    
     use Symfony\Component\Form\FormBuilderInterface;
    
     use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
    
     class FooType extends AbstractType
     {
         public function buildForm(FormBuilderInterface $builder, array $options)
         {
             $builder
                 ->add('tag', ChoiceType::class, array('choices'=>array()))
             ;
             
             $builder->addEventListener(
                 FormEvents::PRE_SUBMIT,
                 function(FormEvent $event){
                     // Get the parent form
                     $form = $event->getForm();
                     
                     // Get the data for the choice field
                     $data = $event->getData()['tag'];
                     
                     // Collect the new choices
                     $choices = array();
                     
                     if(is_array($data)){
                         foreach($data as $choice){
                             $choices[$choice] = $choice;
                         }
                     }
                     else{
                         $choices[$data] = $data;
                     }
                     
                     // Add the field again, with the new choices :
                     $form->add('tag', ChoiceType::class, array('choices'=>$choices));
                 }
             );
         }
     }
    

    Le tue scelte inviate sono ora scelte consentite e la convalida incorporata di Symfony ChoiceType non le rifiuterà più.

    Se vuoi fare lo stesso con un bambino ChoiceType (EntityType, DocumentType, ...), devi iniettare l'entityManager o il documentManager e fare il datatransformation quando compili le nuove scelte.

Compilare un campo di selezione in base al valore di un altro.

Questo è un esempio per mostrare come modificare le scelte consentite su un campo di selezione della sottocategoria in base al valore del campo di selezione della categoria. Per fare ciò devi rendere dinamiche le tue scelte di sottocategoria sia per lato client che server.

1. Rendi dinamico il modulo sul lato client per le interazioni display / utente

Esempio di modulo dinamico lato client (utilizzando Javascript / JQuery):

    $('#category').change(function(){
        switch($(this).val()){
            case '1': // If category == '1'
                var choice = {
                    'choice1_1':'1_1',
                    'choice1_2':'1_2',
                    'choice1_3':'1_3',
                };
            break;
            case '2': // If category == '2'
                var choice = {
                    'choice2_1':'2_1',
                    'choice2_2':'2_2',
                    'choice2_3':'2_3',
                };
            break;
            case '3': // If category == '3'
                var choice = {
                    'choice3_1':'3_1',
                    'choice3_2':'3_2',
                    'choice3_3':'3_3',
                };        
            break;
        }
        
        var $subCategorySelect = $('#subCategory');
        
        $subCategorySelect.empty();
        $.each(choice, function(key, value) {
            $subCategorySelect.append($('<option></option>')).attr('value',value).text(key);
        });
    });

Naturalmente potresti ottenere le scelte da una chiamata AJAX. Questo non è lo scopo di questo esempio.

2. Rendere dinamico il modulo sul lato server per l'inizializzazione / convalida

Esempio di modulo dinamico lato server:

    namespace AppBundle\Form;

    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;

    use Symfony\Component\Form\Extension\Core\Type\ChoiceType;

    use Symfony\Component\Form\FormEvent;
    use Symfony\Component\Form\FormEvents;

    class MyBaseFormType extends AbstractType
    {
        /**
         * @param FormBuilderInterface $builder
         * @param array $options
         */
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                ->add('category',ChoiceType::class,array('choices'=>array(
                        'choice1'=>'1',
                        'choice2'=>'2',
                        'choice3'=>'3',
                    )))
            ;
            
            $addSubCategoryListener = function(FormEvent $event){
                $form = $event->getForm();
                $data = $event->getData();
                
                switch($data['category']){
                    case '1': // If category == '1'
                        $choices = array(
                            'choice1_1'=>'1_1',
                            'choice1_2'=>'1_2',
                            'choice1_3'=>'1_3',
                        );
                    break;
                    case '2': // If category == '2'
                        $choices = array(
                            'choice2_1'=>'2_1',
                            'choice2_2'=>'2_2',
                            'choice2_3'=>'2_3',
                        );                        
                    break;
                    case '3': // If category == '3'
                        $choices = array(
                            'choice3_1'=>'3_1',
                            'choice3_2'=>'3_2',
                            'choice3_3'=>'3_3',
                        );                        
                    break;
                }
                
                $form->add('subCategory',ChoiceType::class,array('choices'=>$choices));
            };
            
            // This listener will adapt the form with the data passed to the form during construction :
            $builder->addEventListener(FormEvents::PRE_SET_DATA, $addSubCategoryListener);
            
            // This listener will adapt the form with the submitted data :
            $builder->addEventListener(FormEvents::PRE_SUBMIT, $addSubCategoryListener);
        }
    }


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow