Listes de choix gérées en AJAX

Vides au départ (trop de données sinon), mais impossible à (re-)remplir

Le problème exposé dans ce sujet a été résolu.

Plop tout le monde !

J'ai un petit problème à vous soumettre.

Pour le projet sur lequel je travaille actuellement, j'ai le cas de listes d'entités qui vont grossir à vitesse $V$, et du coup, je ne peux pas me permettre de fournir l'entier des listes à chaque fois. J'ai découvert jQuery.select2 qui me semble me permettre de gérer la recherche parmi les entrées disponibles en base de données et fait en sorte que le formulaire envoie bien la valeur.

Mais.

Le truc qui fonctionnait jusqu'à Symfony 3.0 ne fonctionne plus maintenant que je suis avec la version 3.1, à savoir qu'apparemment il y a validation de la valeur pour savoir si elle est dans l'ensemble donné lors de la construction du formulaire. Conséquence : j'arrive à créer un objet quand il y a un de ces champs, mais il m'est ensuite impossible de changer la valeur de ce même champ : j'ai l'avertissement comme quoi la valeur n'est pas valide. Ce n'est pas dû à des contraintes de validation (j'en avais bien sur ce champ, mais les enlever et purger le cache ne change rien).

Au niveau serveur, j'ai mis en place les événements de formulaire PRE_SET_DATA et PRE_SUBMIT, voici un exemple pour la version qui fonctionne à l'insertion et pas à l'édition :

 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
<?php
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        // …
        ->add('client')
        ->addEventListener(
            FormEvents::PRE_SET_DATA,
            array($this, 'onPreSetData')
        )->addEventListener(
            FormEvents::PRE_SUBMIT,
            array($this, 'onPreSubmit')
        )
    ;
}

public function onPreSetData(FormEvent $event)
{
    $project = $event->getData();
    $form = $event->getForm();

    if ($entity = $project->getClient()) {
        $form->add('client', null, array(
            'required'     => true,
            'choices'      => [$entity],
        ));
    }
}

public function onPreSubmit(FormEvent $event)
{
    $form = $event->getForm();
    $project = $form->getData();

    if ($entity = $project->getClient()) {
        $form->add('client', null, array(
            'required'     => true,
            'choices'      => [$entity],
        ));
    }
}

Extrait de la classe de formulaire pour un objet Project, avec le champ client qui est en oneToMany vers une table avec potentiellement trop d'entrées

Maintenant, histoire de ne pas faire simple, j'ai aussi ce système de chargement, mais pour des listes liées, donc j'ai une première liste vide qui utilise jQuery.select2, et quand j'ai choisi l'option, cela me permet de filtrer sur ce que je vais avoir dans la seconde liste.

Tout content (et n'ayant pas encore tenté l'édition), je suis passé à mon formulaire avec les listes interdépendantes, que j'ai mis en place comme suit :

 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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<?php
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
      // …
        ->add('project', null, array(
            'class'        => Project::class,
            'choices'      => [],
        ))
        ->add('task', null, array(
            'choice_label' => 'title',
            'choices'      => [],
        ))->addEventListener(
            FormEvents::PRE_SET_DATA,
            array($this, 'onPreSetData')
        )->addEventListener(
            FormEvents::PRE_SUBMIT,
            array($this, 'onPreSubmit')
        )
    ;
}

public function onPreSetData(FormEvent $event)
{
    $time = $event->getData();
    $form = $event->getForm();

    if ($project = $time->getProject()) {
        $form->add('project', null, array(
            'required'     => true,
            'choices'      => [$project],
        ));
    }
    if ($task = $time->getTask()) {
        $form->add('task', null, array(
            'required'     => true,
            'choices'      => [$task],
            'choice_label' => 'title'
        ));
    }
}

public function onPreSubmit(FormEvent $event)
{
    $form = $event->getForm();
    $time = $form->getData();

    if ($project = $time->getProject()) {
        $form->add('project', null, array(
            'required'     => true,
            'choices'      => [$project],
        ));
    }
    if ($task = $time->getTask()) {
        $form->add('task', null, array(
            'required'     => true,
            'choices'      => [$task],
            'choice_label' => 'title'
        ));
    }
}

La version adaptée aux listes chaînées

Alors j'imagine volontiers que je pourrais redéfinir le formulaire dans PRE_SUBMIT pour ne plus restreindre les choix, mais je voulais savoir si c'était évitable ?

Merci d'avance  :)

Edit

En fait, redéfinir le champ sans restriction sur les choix ne fonctionne pas vraiment non-plus : le formulaire n'est pas considéré comme valide (il se réaffiche après soumission), il n'y a cependant aucune erreur, et l'information est bien enregistrée. J'ai vérifié dans le formulaire contrôleur, je suis bien censé être redirigé vers la page de détails quand la modification a fonctionné…

+0 -0

Salut,

Je suis étonné que cela fonctionnât chez toi avec la version 3.0. Je suis sur la 2.8, et j'ai le même comportement que toi. J'ai dû redéfinir via un événement de formulaire mon champ qui doit se mettre à jour avec les valeurs disponibles. C'était ça où désactiver une partie de la validation, et je n'étais pas très chaud. A mon avis, il n'y a pas vraiment d'autres solutions, d'autant que les événements de formulaire sont faits pour ça.

+1 -0

Bon, je ne sais pas trop ce qu'il s'est passé, mais là, je viens de refaire des tests, et ça fonctionne… Le problème, c'est que je ne sais même pas si c'est dû au passage à 3.1.2  :honte:

Edit

Qu'on soit clair : c'est la solution que je souhaitais éviter qui ne semblait pas fonctionner hier et joue aujourd'hui.  :euh:

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte