@@ -160,55 +160,64 @@ Using jQuery, a simple example might look like this. If you're rendering
160160your collection fields all at once (e.g. ``form_row(form.emails) ``), then
161161things are even easier because the ``data-prototype `` attribute is rendered
162162automatically for you (with a slight difference - see note below) and all
163- you need is the JavaScript:
163+ you need is this JavaScript code:
164+
165+ .. code-block :: javascript
166+
167+ // add-collection-widget.js
168+ jQuery (document ).ready (function () {
169+ jQuery (' .add-another-collection-widget' ).click (function (e ) {
170+ e .preventDefault ();
171+ var list = jQuery (jQuery (this ).attr (' data-list' ));
172+ // Try to find the counter of the list
173+ var counter = list .data (' widget-counter' ) | list .children ().length ;
174+ // If the counter does not exist, use the length of the list
175+ if (! counter) { counter = list .children ().length ; }
176+
177+ // grab the prototype template
178+ var newWidget = list .attr (' data-prototype' );
179+ // replace the "__name__" used in the id and name of the prototype
180+ // with a number that's unique to your emails
181+ // end name attribute looks like name="contact[emails][2]"
182+ newWidget = newWidget .replace (/ __name__/ g , counter);
183+ // Increase the counter
184+ counter++ ;
185+ // And store it, the length cannot be used if deleting widgets is allowed
186+ list .data (' widget-counter' , counter);
187+
188+ // create a new list element and add it to the list
189+ var newElem = jQuery (list .attr (' data-widget-tags' )).html (newWidget);
190+ newElem .appendTo (list);
191+ });
192+ });
193+
194+ And update the template as follows:
195+
196+ .. code-block :: html+twig
197+
198+ {{ form_start(form) }}
199+ {# ... #}
200+
201+ {# store the prototype on the data-prototype attribute #}
202+ <ul id="email-fields-list"
203+ data-prototype="{{ form_widget(form.emails.vars.prototype)|e }}"
204+ data-widget-tags="{{ '<li></li>'|e }}">
205+ {% for emailField in form.emails %}
206+ <li>
207+ {{ form_errors(emailField) }}
208+ {{ form_widget(emailField) }}
209+ </li>
210+ {% endfor %}
211+ </ul>
164212
165- .. configuration-block ::
213+ <a href="#"
214+ class="add-another-collection-widget"
215+ data-list="#email-field-list>Add another email</a>
166216
167- .. code-block :: html+twig
217+ {# ... #}
218+ {{ form_end(form) }}
168219
169- {{ form_start(form) }}
170- {# ... #}
171-
172- {# store the prototype on the data-prototype attribute #}
173- <ul id="email-fields-list"
174- data-prototype="{{ form_widget(form.emails.vars.prototype)|e }}">
175- {% for emailField in form.emails %}
176- <li>
177- {{ form_errors(emailField) }}
178- {{ form_widget(emailField) }}
179- </li>
180- {% endfor %}
181- </ul>
182-
183- <a href="#" id="add-another-email">Add another email</a>
184-
185- {# ... #}
186- {{ form_end(form) }}
187-
188- <script type="text/javascript">
189- // keep track of how many email fields have been rendered
190- var emailCount = '{{ form.emails|length }}';
191-
192- jQuery(document).ready(function() {
193- jQuery('#add-another-email').click(function(e) {
194- e.preventDefault();
195-
196- var emailList = jQuery('#email-fields-list');
197-
198- // grab the prototype template
199- var newWidget = emailList.attr('data-prototype');
200- // replace the "__name__" used in the id and name of the prototype
201- // with a number that's unique to your emails
202- // end name attribute looks like name="contact[emails][2]"
203- newWidget = newWidget.replace(/__name__/g, emailCount);
204- emailCount++;
205-
206- // create a new list element and add it to the list
207- var newLi = jQuery('<li></li>').html(newWidget);
208- newLi.appendTo(emailList);
209- });
210- })
211- </script>
220+ <script src="add-collection-widget.js"></script>
212221
213222.. tip ::
214223
0 commit comments