サーチ…


ChoiceType、EntityType、DocumentTypeを拡張してAJAXで選択肢を読み込む方法

Symfonyでは、組み込みChoiceType(およびそれを拡張するEntityTypeまたはDocumentType)は、基本的に定数選択リストで動作します。

あなたがajax呼び出しを使用できるようにしたい場合は、それらを変更して余分な選択肢を受け入れる必要があります。

  • 空の選択リストから始めるには?

    フォームをビルドするときは、 choicesオプションを空の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()));
         }
     }
    

    したがって、選択せずに空の選択入力を取得します。このソリューションは、ChoiceTypeとそのすべての子(EntityType、DocumentType、...)に対して機能します。

  • 提出された新しい選択肢を受け入れる方法

    新しい選択肢を受け入れるには、フォームフィールドの選択肢で利用できるようにする必要があります。 FormEvent :: PRE_SUBMITイベントで、送信されたデータに応じてフォームフィールドを変更することができます。

    この例では、基本的な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));
                 }
             );
         }
     }
    

    あなたの提出された選択肢は現在許可されています.Symfony ChoiceTypeのビルトイン検証でもそれを拒否することはありません。

    ChoiceTypeの子(EntityType、DocumentType、...)を使用して同じことをする場合は、entityManagerまたはdocumentManagerを挿入し、新しい選択肢を設定するときにデータ変換を実行する必要があります。

別の値に応じて選択フィールドに値を設定します。

これは、カテゴリ選択フィールドの値に応じて、サブカテゴリ選択フィールドで許可される選択肢を変更する方法を示す例です。これを行うには、サブカテゴリ選択をクライアント側とサーバー側の両方に対して動的にする必要があります。

1.表示/ユーザー操作のために、クライアント側でフォームを動的にする

クライアントサイドの動的フォームの例(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);
        });
    });

もちろん、あなたはAJAX呼び出しから選択肢を得ることができます。これはこの例の目的ではありません。

2.初期化/検証のためにサーバー側でフォームを動的にする

サーバー側の動的フォームの例:

    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
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow