Bonsoir à tous,

Je rencontre actuellement un problème avec mon application basée sur Symfony 2, et plus précisément avec les formulaires.

En effet, dans le but de permettre à tous les usagers d'exploiter de la meilleure des manières l'application, les différentes fonctionnalités sont prévues pour fonctionner avec et sans javascript. Je réalise donc l'envoi de certains formulaires par voie normale (synchrone) et par voie asynchrone avec Ajax.

Il s'avère cependant que je rencontre un comportement étrange lors de la soumission d'un certain formulaire via Ajax. En effet, il s'agit d'une bête classe contenant deux boutons submit, "Cancel" et "Confirm", afin de valider ou d'annuler une décision. Le code de la classe est le suivant :

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
 
<?php
 
namespace My\Bundle\Form\Type;
 
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
 
class ConfirmationType extends AbstractType
{
 
    public function __construct(){
 
    }
 
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
 
        $builder->add("confirm", 'submit');
        $builder->add("cancel", "submit");
 
    }
 
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => null,
            'csrf_protection' => true
        ));
    }
 
    public function getName()
    {
        return 'confirmation';
    }
 
}
Ce formulaire est utilisé dans le template comme suit :

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
 
<form id="forum_inbox_delete_form" class="form-horizontal" action="{{ path('com_delete_folder', {"id":currentFolder.getIdFolder})}}" method="post" {{ form_enctype(deleteform) }}>
            <div class="panel panel-primary">
                <div class="panel-heading">Are you really sure ?</div>
                <div class="panel-body">
                    <div class="alert alert-danger" role="alert"><strong>Be careful !</strong> Do you really want to delete this folder ?</div>
                    <div class="form-group">
                        {{ form_widget(deleteform._token) }}
                        <div class="col-sm-6">
                            {{ form_widget(deleteform.confirm, {'attr': {'class': 'form-control'}}) }}
                        </div>
                        <div class="col-sm-6">
                            {{ form_widget(deleteform.cancel, {'attr': {'class': 'form-control'}}) }}
                        </div>
                    </div>
                </div>
            </div>
        </form>
et le code javascript associé :

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
 
$("#forum_inbox_delete_form").submit(function(){
 
                var data = $(this).serializeArray();
 
                console.log(data);
 
                $.ajax({
                    url: $(this).attr("action"),
                    method: "post",
                    data: data,
                    dataType: "json"
                }).done(function(data){
                    console.log(data);
                    if (data.text) {
                        alert(data.text);
                    }
 
                    if (data.code == "200") {
                        location.reload();
                    }
                });
                return false;
            });
Le controller a le comportement suivant :

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
 
    public function deleteAction($id, Request $request) {
 
        //something
 
        $form = $this->createForm(new ConfirmationType(), array(), array('method' => "post"));
        $form->handleRequest($request);
 
        if ($request->isMethod("post")) {
            if ($form->isValid()) {
                $components = $form->all();
 
                if ($form->get("confirm")->isClicked()) {
                    exit(var_dump($_POST));
                    //TODO
                }
                else if ($form->get("cancel")->isClicked()) {
                    exit('canceled');
                }
 
            }
 
        }
 
        //TODO
    }
Le problème rencontré est que le comportement du script n'est pas le même selon que je procède à un submit via Ajax que par voie classique. Par la voie classique, le contrôleur détecte bien que j'ai cliqué sur le bouton confirm via la ligne suivante :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
 
if ($form->get("confirm")->isClicked()) {
En revanche, via l'envoi Ajax, seul le token crsf est sérialisé, autrement dit le contrôleur ne reçoit pas l'information d'un des deux boutons cliqué. Je souhaitais donc savoir si vous aviez déjà remarqué un comportement similaire, ou si non, si vous auriez des pistes pour mener à la résolution de ce "bug". Je tiens à préciser que les identifiants des boutons dans le template final sont bien uniques et qu'il n'y a pas de duplicata.

Merci d'avance pour votre aide et votre temps

Bien cordialement

Cr3a

-------------

EDIT : Désolé de mon incultitude, il s'avère que serialize() ne transmet tout simplement pas les boutons. Issu de la doc :

Only "successful controls" are serialized to the string. No submit button value is serialized since the form was not submitted using a button

En espérant que ceux qui rencontrent ce problème trouveront assez vite la réponse

Cordialement