Bonjour,
Je viens ici cherche de l'aide car je ne parviens pas à trouver la solution par moi même. Je cherche à faire une multiple imbrication de formulaire. Je m'explique, je code pour un projet, un système de création d'exercices.
Un exercice doit avoir plusieurs questions (QCM). Un QCM a aussi plusieurs réponses.
J'ai réussi à imbriquer mon formulaire de question dans celui de l'exercice.
Un peu de code saura surement mieux faire comprendre les choses
J'ai une entité Exercice :
Comme on peut le voir, j'ai une collection de questions. Mon entité Question est comme ceci :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 class Exercice { /** * @var integer * * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ private $id; /** * @var string * * @ORM\Column(name="titre", type="string", length=255) */ private $titre; /** * @ORM\OneToMany(targetEntity="Question", mappedBy="exercice") */ protected $questions; public function __construct() { $this->questions = new ArrayCollection(); } }
et mon entité ItemQCM :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 class Question { /** * @var integer * * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ protected $id; /** * @var string * * @ORM\Column(name="libelle", type="text") */ protected $libelle; /** * @var integer * * @ORM\Column(name="numQuestion", type="integer") */ protected $numQuestion; /** * @ORM\OneToMany(targetEntity="ItemQCM", mappedBy="question") */ protected $itemsQCM; /** * @ORM\ManyToOne(targetEntity="Exercice", inversedBy="questions") * @ORM\JoinColumn(nullable=false) */ protected $exercice; public function __construct() { $this->itemsQCM = new ArrayCollection(); } }
Je n'ai pas copié tous les getter/setter afin de ne pas trop surcharger..
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 class ItemQCM { /** * @var integer * * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ private $id; /** * @var string * * @ORM\Column(name="libelle", type="text") */ private $libelle; /** * @var boolean * * @ORM\Column(name="isJuste", type="boolean") */ private $isJuste; /** * @ORM\ManyToOne(targetEntity="Question", inversedBy="itemsQCM") * @ORM\JoinColumn(nullable=false) */ private $question; }
J'ai ensuite trois classes de formulaires :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 class ExerciceType extends AbstractType { /** * @param FormBuilderInterface $builder * @param array $options */ public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('titre') ->add('questions', 'collection', array( 'type' => new QuestionType(), 'allow_add' => true, 'by_reference' => false,)) ; } /** * @param OptionsResolverInterface $resolver */ public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setDefaults(array( 'data_class' => 'Bili\ExerciceBundle\Entity\Exercice', )); } /** * @return string */ public function getName() { return 'exercice'; } }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 class QuestionType extends AbstractType { /** * @param FormBuilderInterface $builder * @param array $options */ public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('libelle', 'textarea', array('label' => "Libelle", 'attr' => array('rows' => '10','cols' => '100'))) ->add('itemsQCM', 'collection', array('type' => new ItemQCMType(), 'allow_add' => true, 'by_reference' => false, )) ; } /** * @param OptionsResolverInterface $resolver */ public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setDefaults(array( 'data_class' => 'Bili\ExerciceBundle\Entity\Question', )); } /** * @return string */ public function getName() { return 'question'; } }Pour finir, mon fichier twig new.html.twig est de cette forme :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 class ItemQCMType extends AbstractType { /** * @param FormBuilderInterface $builder * @param array $options */ public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('libelle') ->add('isJuste') ; } /** * @param OptionsResolverInterface $resolver */ public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setDefaults(array( 'data_class' => 'Bili\ExerciceBundle\Entity\ItemQCM' )); } /** * @return string */ public function getName() { return 'itemqcm'; } }
mon erreur est de la forme :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 <form action="{{ path('exercice_create') }}" method="post" {{ form_enctype(form) }}> <table id="exercice_form"> <tbody> <tr> <th>{{ form_label(form.titre) }}</th> <td> {{ form_errors(form.titre) }} {{ form_widget(form.titre) }} </td> </tr> </tbody> </table> <ul class="questions" data-prototype="{{ form_widget(form.questions.vars.prototype)|e }}"> <ul class="itemsQCM" data-prototype="{{ form_widget(form.questions.vars.itemsQCM.prototype)|e }}"> </ul> </ul> {{ form_rest(form) }} </form>
Donc ma question est : comment faire pour imbriquer un formulaire dans un formulaire lui même imbriqué dans un autre ?Key "itemsQCM" for array with keys "value, attr, form, id, name, full_name, disabled, label, multipart, block_prefixes, unique_block_prefix, translation_domain, cache_key, read_only, errors, valid, data, required, max_length, pattern, size, label_attr, compound, method, action, submitted, sonata_admin_enabled, sonata_admin, allow_add, allow_delete, prototype" does not exist in SidesEntrainementBundle:Entrainement:new.html.twig at line 102
Et ma deuxième question, comment fait-on pour modifier l'aspect d'un formulaire imbriqué ?
Je me suis inspiré de ce site : http://symfony.com/fr/doc/current/co...llections.html
Très bien fait mais il n'explique pas comment imbriquer plusieurs collections
Merci d'avance pour votre aide
Antoine
Partager