简体   繁体   中英

Pre-filling a field of a Symfony form of type EntityType

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM