Szukaj…


Jak rozszerzyć ChoiceType, EntityType i DocumentType, aby załadować opcje za pomocą AJAX.

W Symfony wbudowany ChoiceType (i EntityType lub DocumentType go rozszerzający) zasadniczo działa ze stałą listą wyboru.

Jeśli chcesz, aby działało z wywołaniami ajax, musisz je zmienić, aby akceptować wszelkie sumowane dodatkowe opcje.

  • Jak zacząć od pustej listy wyboru?

    Podczas budowania formularza po prostu ustaw opcję choices na pustą 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()));
         }
     }
    

    Otrzymasz pusty wybór wejściowy, bez wyborów. To rozwiązanie działa dla ChoiceType i wszystkich jego dzieci (EntityType, DocumentType, ...).

  • Jak zaakceptować przesłane nowe opcje :

    Aby zaakceptować nowe wybory, musisz je udostępnić w liście wyboru pola formularza. Możesz zmienić pole formularza w zależności od przesłanych danych za pomocą zdarzenia FormEvent :: PRE_SUBMIT.

    Ten przykład pokazuje, jak to zrobić za pomocą podstawowego ChoiceType:

     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));
                 }
             );
         }
     }
    

    Twoje przesłane opcje są teraz dozwolone, a wbudowane sprawdzanie poprawności Symfony ChoiceType nie będzie już ich odrzucać.

    Jeśli chcesz zrobić to samo z dzieckiem potomnym ChoiceType (EntityType, DocumentType, ...), musisz wstrzyknąć encję Managera lub managera dokumentu i wykonać transformację danych podczas zapełniania nowych opcji.

Wypełnij pole wyboru w zależności od innej wartości.

Jest to przykład pokazujący, jak zmienić dozwolone wybory w polu wyboru podkategorii w zależności od wartości pola wyboru kategorii. Aby to zrobić, musisz dokonać dynamicznych wyborów podkategorii zarówno po stronie klienta, jak i serwera.

1. Uczyń formularz dynamicznym po stronie klienta w celu wyświetlania / interakcji użytkownika

Przykład dynamicznej formy po stronie klienta (przy użyciu 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);
        });
    });

Oczywiście możesz wybierać z połączenia AJAX. To nie jest celem tego przykładu.

2. Uczyń formularz dynamicznym po stronie serwera w celu inicjalizacji / weryfikacji

Przykład dynamicznej formy po stronie serwera:

    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
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow