I'm working on a Symfony project and I'm currently encountering a problem with a form that I want to pre-fill from a collection of objects.
The form field in question is of type EntityType::class. I would like to pre-select elements of this field from a collection that contains objects of the same type(Classe).
One of the solutions I found is to add a 'data' => $defaultClass property in the buildForm, which would contain the data to be inserted, and to pass this object in the parameters($options) on the formBuilder. Unfortunately, the two objects of type Classe do not appear in the field once the form is generated even though the $options variable contains the objects.
Thanks in advance for your help. Here are the codes concerned :
SearchCourseData
<?php
namespace App\Data;
use App\Entity\Classe;
use App\Entity\Teacher;
use App\Entity\Location;
class SearchCourseData
{
/**
* @var integer
*/
public $page = 1;
/**
* @var Classe[]
*/
public $classe = [];
// Missing lines
/**
* @var String
*/
public $status;
}
Code SearchCourseForm
class SearchCourseForm extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$defaultClass = new Classe();
if (!empty($options['data']->classe)) {
$defaultClass = $options["data"]->classe;
}
$builder
->add('classe', EntityType::class, [
'class' => Classe::class,
'label' => false,
'required' => false,
'expanded' => false,
'multiple' => true,
'query_builder' => function (ClasseRepository $qb) {
return $qb->createQueryBuilder('a')->orderBy('a.title', 'ASC');
},
'choice_label' => function (Classe $atelier) {
return($atelier->getTitle());
},
'attr' => [
'placeholder' => 'Atelier',
'class' => 'select-classes'
],
'data' => $defaultClass,
])
>add('status', ChoiceType::class, [
'required' => true,
'choices' => [
'Disponible' => "Disponible",
'Brouillon' => "Brouillon",
'Archivé' => "Archivé"
],
'label' => false,
])
;
}
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults([
'data_class' => SearchCourseData::class,
'method' => 'GET',
'csrf_protection' => false
]);
}
public function getBlockPrefix() {
return '';
}
}
Code CourseController
/**
* @Route("/course")
*/
class CourseController extends AbstractController {
/**
* @Route("/",name="course")
*/
public function courseList(CourseRepository $courseRepository, Request $request) {
$data = new SearchCourseData();
$defaultClassB = $this->getDoctrine()->getRepository(Classe::class)->find(49);
$defaultClassA = $this->getDoctrine()->getRepository(Classe::class)->find(1);
$defaultClass[] = new ArrayCollection();
$defaultClass[0] = $defaultClassA;
$defaultClass[1] = $defaultClassB;
$data->classe = $defaultClass;
$form = $this->createForm(SearchCourseForm::class, $data);
}
}
@V-light is right you are setting a collection in an index of an array - then overwrite it...
$defaultClass[] = new ArrayCollection();
// === $defaultClass[0] = new ArrayCollection();
the correct and easiest way would be:
/**
* @Route("/course")
*/
class CourseController extends AbstractController {
/**
* @Route("/",name="course")
*/
public function courseList(CourseRepository $courseRepository, Request $request) {
$data = new SearchCourseData();
$data->classe = $this->getDoctrine()->getRepository(Classe::class)->findById([49, 1]);
$form = $this->createForm(SearchCourseForm::class, $data);
}
}
EDIT - the corrected form: 'data' of classe gets set by the ModelTransformer automaticly.
class SearchCourseForm extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('classe', EntityType::class, [
'class' => Classe::class,
'label' => false,
'required' => false,
'expanded' => false,
'multiple' => true,
'query_builder' => function (ClasseRepository $qb) {
return $qb->createQueryBuilder('a')->orderBy('a.title', 'ASC');
},
'choice_label' => function (Classe $atelier) {
return($atelier->getTitle());
},
'attr' => [
'placeholder' => 'Atelier',
'class' => 'select-classes'
],
])
>add('status', ChoiceType::class, [
'required' => true,
'choices' => [
'Disponible' => "Disponible",
'Brouillon' => "Brouillon",
'Archivé' => "Archivé"
],
'label' => false,
])
;
}
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults([
'data_class' => SearchCourseData::class,
'method' => 'GET',
'csrf_protection' => false
]);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.