サーチ…
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);
}
}