Bonjour,

J'ai un soucis concernant les formulaires imbriqués. Je me suis basé sur un exemple trouvé ici pour développer mon formulaire.
Si quelqu'un a quelque chose de mieux, je suis preneur!

En fait, j'ai un bug dans la gestion de mes éléments.
Par exemple, lorsque j'ajoute 5 éléments et que je fais exprès de faire une erreur de saisie et que je valide, j'ai bien le message d'erreur. Je supprime le 4ème élément et j'en insère un autre et je valide toujours avec une erreur. L'ancien 5ème élément, qui est devenu le 4ème suite à la suppression, a disparu...
En débugant, j'ai compris le problème, mais je ne sais pas le corriger.
En fait, quand je calcul l'index, je me base sur le nombre d'élément dans le formulaire, mais l'ancien 5ème élément portait le numéro 5 et porte toujours le numéro 5 après suppression du 4ème. Sauf que le nouvel élément que je créé porte aussi le numéro 5, donc il y a conflit.
Savez vous comment régler le problème?

Voici mon code :

Dans le formulaire :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
 
->add('hausses', 'collection', array(
    'type' => new HausseType($builder->getData()),
    'allow_add' => true,
    'allow_delete' => true,
    'label' => false,
    'prototype' => true,
    'prototype_name' => 'hausse__name__',
    'options' => array(
        // options on the rendered HausseTypes
    ),
Dans la vue :

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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
 
{# src/KG/BeekeepingManagementBundle/Resources/views/Visite/add.html.twig #}
 
{% extends "KGBeekeepingManagementBundle::layout.html.twig" %}
 
{% block stylesheets %}
    {{ parent() }}
    {% stylesheets filter='cssrewrite' 'css/bootstrap_switch/bootstrap-switch.css' %}
        <link rel="stylesheet" href="{{ asset_url }}" type="text/css">
    {% endstylesheets %} 
    {{ form_stylesheet(form) }}
{% endblock %}
 
{% block javascripts %}
    {{ parent() }}
    {% javascripts 'js/bootstrap_switch/bootstrap-switch.js'
                    '@KGBeekeepingManagementBundle/Resources/public/js/visite/add.js'%}
        <script src="{{ asset_url }}" type="text/javascript"></script> 
    {% endjavascripts %}
    {{ form_javascript(form) }}
{% endblock %}
 
{% block title %}{{ parent() }} - Créer une visite{% endblock %}
 
{% form_theme form "KGBeekeepingManagementBundle::form_layout.html.twig" %}
 
{% macro widget_prototype(widget, remove_text) %}
    {% if widget.vars.prototype is defined %}
        {% set form = widget.vars.prototype %}
        {% set name = widget.vars.prototype.vars.name %}
    {% else %}
        {% set form = widget %}
        {% set name = widget.vars.full_name %}
    {% endif %}
 
    <div data-content="{{ name }}">
        <a class="btn-remove" data-related="{{ name }}">{{ remove_text }}</a>
        <li class="list-group-item">
            {{ form_errors(form) }} 
            <div class="form-group">
                {{ form_label(form, "Cadres plein :", {'label_attr': {'class': 'col-sm-5 col-md-4 control-label'}}) }}
                <div class="col-sm-5 col-md-5">
                    {{ form_widget(form) }}
                </div>
            </div>
        </li>         
    </div>
{% endmacro %}
 
{% block ruchers %}{{ colonie.ruche.emplacement.rucher.nom }}{% endblock %}
 
{% block panel_title %}
    <div class="row">
        <div class="col-xs-12">
            <h4>Création d'une visite</h4>
        </div>
    </div>
{% endblock %}
 
{% block form_error %}
    {{ form_errors(form.date) }}   
    {{ form_errors(form.activite) }}
    {{ form_errors(form.pollen) }}   
    {{ form_errors(form.reine) }}
    {{ form_errors(form.celroyales) }}   
    {{ form_errors(form.etat) }}
    {{ form_errors(form.agressivite) }}
    {{ form_errors(form.nourrissement) }}
    {{ form_errors(form.traitement) }}
    {{ form_errors(form.observations) }}
    {{ form_errors(form.nbnourriture) }}
    {{ form_errors(form.nbcouvain) }}
    {{ form_errors(form) }}   
{% endblock %}
 
{% block panel_body %}           
    {{ form_start(form, {'attr': {'class': 'form-horizontal'}}) }}
 
        <fieldset>
            <legend>Généralités :</legend>         
            <div class="form-group">
                {{ form_label(form.date, "Date :", {'label_attr': {'class': 'col-sm-5 col-md-4 control-label'}}) }}
                <div class="col-sm-5 col-md-5">
                    {{ form_widget(form.date, {'attr': {'class': 'form-control'}}) }}
                </div>
            </div>   
 
            <div class="form-group">
                {{ form_label(form.activite, "Activité :", {'label_attr': {'class': 'col-sm-5 col-md-4 control-label'}}) }}
                <div class="col-sm-5 col-md-5">
                    {{ form_widget(form.activite, {'attr': {'class': 'form-control'}}) }}
                </div>
            </div>
 
            <div class="form-group">
                <label class="col-sm-5 col-md-4 control-label" for="checkboxes">Stockage de pollen :</label>
                <div class="col-sm-5 col-md-5">
                  {{ form_widget(form.pollen, {'attr': {'class': 'form-control', 'data-on-text': "Oui", 'data-off-text': 'Non'}}) }}
                </div>
            </div>  
 
            <div class="form-group">
                <label class="col-sm-5 col-md-4 control-label" for="checkboxes">Reine vue :</label>
                <div class="col-sm-5 col-md-5">
                  {{ form_widget(form.reine, {'attr': {'class': 'form-control', 'data-on-text': "Oui", 'data-off-text': 'Non'}}) }}
                </div>
            </div>                         
 
            <div class="form-group">
                <label class="col-sm-5 col-md-4 control-label" for="checkboxes">Cellules royales :</label>
                <div class="col-sm-5 col-md-5">
                  {{ form_widget(form.celroyales, {'attr': {'class': 'form-control', 'data-on-text': "Oui", 'data-off-text': 'Non'}}) }}
                </div>
            </div>
 
            <div class="form-group">
                {{ form_label(form.etat, "Etat :", {'label_attr': {'class': 'col-sm-5 col-md-4 control-label'}}) }}
                <div class="col-sm-5 col-md-5">
                    {{ form_widget(form.etat, {'attr': {'class': 'form-control'}}) }}
                </div>
            </div>                     
 
            <div class="form-group">
                {{ form_label(form.agressivite, "Agressivité :", {'label_attr': {'class': 'col-sm-5 col-md-4 control-label'}}) }}
                <div class="col-sm-5 col-md-5">
                    {{ form_widget(form.agressivite, {'attr': {'class': 'form-control'}}) }}
                </div>
            </div>                         
 
            <div class="form-group">
                {{ form_label(form.nourrissement, "Nourrissement :", {'label_attr': {'class': 'col-sm-5 col-md-4 control-label'}}) }}
                <div class="col-sm-5 col-md-5">
                    {{ form_widget(form.nourrissement, {'attr': {'class': 'form-control'}}) }}
                </div>
            </div>     
 
            <div class="form-group">
                {{ form_label(form.traitement, "Traitement :", {'label_attr': {'class': 'col-sm-5 col-md-4 control-label'}}) }}
                <div class="col-sm-5 col-md-5">
                    {{ form_widget(form.traitement, {'attr': {'class': 'form-control'}}) }}
                </div>
            </div>     
 
            <div class="form-group">
                {{ form_label(form.observations, "Observations :", {'label_attr': {'class': 'col-sm-5 col-md-4 control-label'}}) }}
                <div class="col-sm-5 col-md-5">
                    {{ form_widget(form.observations, {'attr': {'class': 'form-control'}}) }}
                </div>
            </div>                           
        </fieldset>   
 
        <fieldset>
 
            <legend>Corps :</legend>
                <div class="form-group">
                    {{ form_label(form.nbnourriture, "Cadres de nourriture :", {'label_attr': {'class': 'col-sm-5 col-md-4 control-label'}}) }}
                    <div class="col-sm-5 col-md-5">
                        {{ form_widget(form.nbnourriture, {'attr': {'class': 'form-control'}}) }}
                    </div>
                </div>
 
                <div class="form-group">
                    {{ form_label(form.nbcouvain, "Cadres de couvain :", {'label_attr': {'class': 'col-sm-5 col-md-4 control-label'}}) }}
                    <div class="col-sm-5 col-md-5">
                        {{ form_widget(form.nbcouvain, {'attr': {'class': 'form-control'}}) }}
                    </div>
                </div>
        </fieldset>      
 
        <fieldset>
            <legend>Hausses :</legend>
 
            <div class="row">
                <div class="col-md-offset-3 col-sm-offset-3 col-md-6 col-sm-6">
                    <ul class="list-group">               
                        <div id="post_hausses" data-prototype="{{ _self.widget_prototype(form.hausses, 'Supprimer hausse')|escape }}">
                            {% for widget in form.hausses.children %}
                                {{ _self.widget_prototype(widget, 'Supprimer hausse') }}
                            {% endfor %}
                        </div>
                    </ul>
                </div>
            </div>
 
            <a class="btn-add btn-default" data-target="post_hausses">Ajouter hausse</a>
        </fieldset>                   
 
    {{ form_rest(form) }}
 
    <div class="form-group">
        <div class="col-md-12">
            <button type="submit" class="btn btn-primary pull-right">
                <i class="glyphicon glyphicon-floppy-disk"></i>
                Sauvegarder
            </button>
        </div>       
    </div>
 
    {{ form_end(form) }}    
{% endblock %}
Dans le javascript :

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
 
$("[name='kg_beekeepingmanagementbundle_visite[reine]']").bootstrapSwitch();
$("[name='kg_beekeepingmanagementbundle_visite[celroyales]']").bootstrapSwitch();
$("[name='kg_beekeepingmanagementbundle_visite[pollen]']").bootstrapSwitch();
 
jQuery(function($) {
    $(document).on('click', '.btn-add[data-target]', function(event) {
        var collectionHolder = $('#' + $(this).attr('data-target'));
        if (!collectionHolder.attr('data-counter')) {
            collectionHolder.attr('data-counter', collectionHolder.children().length);
        }
 
        var prototype = collectionHolder.attr('data-prototype');
        var form = prototype.replace(/__name__/g, collectionHolder.attr('data-counter'));
        collectionHolder.attr('data-counter', Number(collectionHolder.attr('data-counter')) + 1);
        collectionHolder.append(form);
        event && event.preventDefault();
    });
 
    $(document).on('click', '.btn-remove[data-related]', function(event) {
        var name = $(this).attr('data-related');
        $('*[data-content="'+name+'"]').remove();
        event && event.preventDefault();
    });
});
Merci pour votre aide!