Suche…
So erweitern Sie ChoiceType, EntityType und DocumentType, um die Auswahlmöglichkeiten mit AJAX zu laden.
In Symfony arbeitet der eingebaute ChoiceType (und EntityType oder DocumentType, der ihn erweitert) grundsätzlich mit einer konstanten Auswahlliste.
Wenn Sie möchten, dass ajax-Anrufe verwendet werden, müssen Sie diese ändern, um alle zusätzlichen Auswahlmöglichkeiten zu akzeptieren.
Wie fange ich mit einer leeren Auswahlliste an?
Wenn Sie Ihr Formular erstellen, setzen Sie einfach die
choices
auf ein leeresarray()
: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())); } }
Sie erhalten also eine leere Auswahleingabe ohne Auswahlmöglichkeiten. Diese Lösung funktioniert für ChoiceType und alle seine Kinder (EntityType, DocumentType, ...).
So akzeptieren Sie die eingereichten neuen Optionen :
Um die neuen Optionen zu akzeptieren, müssen Sie sie in der Formularfeldauswahlliste verfügbar machen. Sie können Ihr Formularfeld in Abhängigkeit von den übermittelten Daten mit dem Ereignis FormEvent :: PRE_SUBMIT ändern.
Dieses Beispiel zeigt, wie es mit einem einfachen ChoiceType gemacht wird:
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)); } ); } }
Ihre eingereichten Auswahlmöglichkeiten sind jetzt zulässig, und die eingebaute Validierung von Symfony ChoiceType lehnt sie nicht mehr ab.
Wenn Sie dasselbe mit einem ChoiceType-Kind (EntityType, DocumentType, ...) machen möchten, müssen Sie den entityManager oder den documentManager einfügen und die Datenübertragung durchführen, wenn Sie die neuen Optionen auffüllen.
Füllen Sie ein Auswahlfeld abhängig vom Wert eines anderen auf.
In diesem Beispiel wird gezeigt, wie die zulässigen Auswahlmöglichkeiten für ein Unterkategorie-Auswahlfeld in Abhängigkeit vom Wert des Kategorieauswahlfelds geändert werden. Dazu müssen Sie die Auswahl der Unterkategorie für die Client- und die Serverseite dynamisch festlegen.
1. Machen Sie das Formular auf Client-Seite für Anzeige- / Benutzerinteraktionen dynamisch
Beispiel für ein clientseitiges dynamisches Formular (mit 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);
});
});
Natürlich können Sie die Wahl von einem AJAX-Anruf erhalten. Das ist nicht der Zweck dieses Beispiels.
2. Machen Sie das Formular auf der Serverseite für die Initialisierung / Validierung dynamisch
Beispiel eines serverseitigen dynamischen Formulars:
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);
}
}