@@ -239,23 +239,31 @@ it will receive an *unknown* number of tags. Otherwise, you'll see a
239239The ``allow_add `` option also makes a ``prototype `` variable available to you.
240240This "prototype" is a little "template" that contains all the HTML needed to
241241dynamically create any new "tag" forms with JavaScript. To render the prototype, add
242- the following ``data-prototype `` attribute to the existing ``<ul> `` in your template:
242+ the following ``data-prototype `` attribute to the existing ``<ul> `` in your
243+ template:
243244
244245.. code-block :: html+twig
245246
246- <ul class="tags" data-index="{{ form.tags|length > 0 ? form.tags|last.vars.name + 1 : 0 }}" data-prototype="{{ form_widget(form.tags.vars.prototype)|e('html_attr') }}"></ul>
247+ {# the data-index attribute is required for the JavaScript code below #}
248+ <ul class="tags"
249+ data-index="{{ form.tags|length > 0 ? form.tags|last.vars.name + 1 : 0 }}"
250+ data-prototype="{{ form_widget(form.tags.vars.prototype)|e('html_attr') }}"
251+ ></ul>
247252
248- Now add a button just next to the `` <ul> `` to dynamically add a new tag :
253+ On the rendered page, the result will look something like this :
249254
250- .. code-block :: html+twig
255+ .. code-block :: html
251256
252- <button type="button" class="add_item_link" data-collection-holder-class="tags">Add a tag</button>
257+ <ul class =" tags"
258+ data-index =" 0"
259+ data-prototype =" < ; div> ;< ; label class=" ; required" ;> ; __name__< ; /label> ;< ; div id=" ; task_tags___name__" ;> ;< ; div> ;< ; label for=" ; task_tags___name___name" ; class=" ; required" ;> ; Name< ; /label> ;< ; input type=" ; text" ; id=" ; task_tags___name___name" ; name=" ; task[tags][__name__][name]" ; required=" ; required" ; maxlength=" ; 255" ; /> ;< ; /div> ;< ; /div> ;< ; /div> ; "
260+ ></ul >
253261
254- On the rendered page, the result will look something like this :
262+ Now add a button to dynamically add a new tag :
255263
256- .. code-block :: html
264+ .. code-block :: html+twig
257265
258- <ul class = " tags " data-index = " 0 " data-prototype = " & lt ; div & gt ;& lt ; label class=& quot ; required & quot ;& gt ; __name__ & lt ; /label & gt ;& lt ; div id= & quot ; task_tags___name__ & quot ;& gt ;& lt ; div & gt ;& lt ; label for= & quot ; task_tags___name___name & quot ; class= & quot ; required & quot ;& gt ; Name & lt ; /label & gt ;& lt ; input type= & quot ; text & quot ; id= & quot ; task_tags___name___name & quot ; name= & quot ; task[ tags][__name__][name] & quot ; required= & quot ; required & quot ; maxlength= & quot ; 255 & quot ; / & gt ;& lt ; /div & gt ;& lt ; /div & gt ;& lt ; /div & gt ; " >
266+ <button type="button" class="add_item_link " data-collection-holder- class=" tags">Add a tag</button >
259267
260268.. seealso ::
261269
@@ -265,7 +273,7 @@ On the rendered page, the result will look something like this:
265273.. tip ::
266274
267275 The ``form.tags.vars.prototype `` is a form element that looks and feels just
268- like the individual ``form_widget(tag) `` elements inside your ``for `` loop.
276+ like the individual ``form_widget(tag.* ) `` elements inside your ``for `` loop.
269277 This means that you can call ``form_widget() ``, ``form_row() `` or ``form_label() ``
270278 on it. You could even choose to render only one of its fields (e.g. the
271279 ``name `` field):
@@ -281,16 +289,16 @@ On the rendered page, the result will look something like this:
281289 and you need to adjust the following JavaScript accordingly.
282290
283291Now add some JavaScript to read this attribute and dynamically add new tag forms
284- when the user clicks the "Add a tag" link.
285-
286- Add a ``<script> `` tag somewhere on your page to include the required
287- functionality with JavaScript:
292+ when the user clicks the "Add a tag" link. Add a ``<script> `` tag somewhere
293+ on your page to include the required functionality with JavaScript:
288294
289295.. code-block :: javascript
290296
291297 document
292298 .querySelectorAll (' .add_item_link' )
293- .forEach (btn => btn .addEventListener (" click" , addFormToCollection));
299+ .forEach (btn => {
300+ btn .addEventListener (" click" , addFormToCollection)
301+ });
294302
295303 The ``addFormToCollection() `` function's job will be to use the ``data-prototype ``
296304attribute to dynamically add a new form when this link is clicked. The ``data-prototype ``
@@ -529,14 +537,15 @@ First, add a "delete this tag" link to each tag form:
529537
530538.. code-block :: javascript
531539
532- const tags = document .querySelectorAll (' ul.tags li' )
533- tags .forEach ((tag ) => {
534- addTagFormDeleteLink (tag)
535- })
540+ document
541+ .querySelectorAll (' ul.tags li' )
542+ .forEach ((tag ) => {
543+ addTagFormDeleteLink (tag)
544+ })
536545
537546 // ... the rest of the block from above
538547
539- function addFormToCollection () {
548+ const addFormToCollection = ( e ) => {
540549 // ...
541550
542551 // add a delete link to the new form
@@ -547,17 +556,16 @@ The ``addTagFormDeleteLink()`` function will look something like this:
547556
548557.. code-block :: javascript
549558
550- const addTagFormDeleteLink = (tagFormLi ) => {
551- const removeFormButton = document .createElement (' button' )
552- removeFormButton .classList
553- removeFormButton .innerText = ' Delete this tag'
559+ const addTagFormDeleteLink = (item ) => {
560+ const removeFormButton = document .createElement (' button' );
561+ removeFormButton .innerText = ' Delete this tag' ;
554562
555- tagFormLi .append (removeFormButton);
563+ item .append (removeFormButton);
556564
557565 removeFormButton .addEventListener (' click' , (e ) => {
558- e .preventDefault ()
566+ e .preventDefault ();
559567 // remove the li for the tag form
560- tagFormLi .remove ();
568+ item .remove ();
561569 });
562570 }
563571
@@ -652,7 +660,6 @@ the relationship between the removed ``Tag`` and ``Task`` object.
652660 the `symfony-collection `_ package based on `jQuery `_ for the rest of browsers.
653661
654662.. _`Owning Side and Inverse Side` : https://www.doctrine-project.org/projects/doctrine-orm/en/current/reference/unitofwork-associations.html
655- .. _`jQuery` : http://jquery.com/
656663.. _`JSFiddle` : https://jsfiddle.net/ey8ozh6n/
657664.. _`@a2lix/symfony-collection` : https://github.com/a2lix/symfony-collection
658665.. _`symfony-collection` : https://github.com/ninsuo/symfony-collection
0 commit comments