수색…
ChoiceType, EntityType 및 DocumentType을 확장하여 AJAX로 선택 항목을로드하는 방법
내장 된 ChoiceType (그리고 그것을 확장 한 EntityType 또는 DocumentType) 인 Symfony에서 기초적인 선택 목록으로 작업합니다.
아약스 호출로 작동하게하려면 추가 된 선택 항목을 수락하도록 변경해야합니다.
비어있는 선택 목록으로 시작하는 방법?
양식을 작성할 때
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를 삽입하고 새 선택 항목을 채울 때 데이터 변환을 수행해야합니다.
다른 값에 따라 선택 필드를 채 웁니다.
다음은 category select 필드의 값에 따라 subCategory select 필드에서 허용되는 선택 항목을 변경하는 방법을 보여주는 예제입니다. 이를 위해서는 클라이언트와 서버 측면 모두에서 하위 카테고리 선택을 동적으로 만들어야합니다.
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);
}
}