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