@@ -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,18 +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. This example uses `jQuery `_ and
285- assumes you have it included somewhere on your page (e.g. using Symfony's
286- :doc: `Webpack Encore </frontend >`).
287-
288- Add a ``<script> `` tag somewhere on your page to include the required
289- 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:
290294
291295.. code-block :: javascript
292296
293297 document
294298 .querySelectorAll (' .add_item_link' )
295- .forEach (btn => btn .addEventListener (" click" , addFormToCollection));
299+ .forEach (btn => {
300+ btn .addEventListener (" click" , addFormToCollection)
301+ });
296302
297303 The ``addFormToCollection() `` function's job will be to use the ``data-prototype ``
298304attribute to dynamically add a new form when this link is clicked. The ``data-prototype ``
@@ -531,14 +537,15 @@ First, add a "delete this tag" link to each tag form:
531537
532538.. code-block :: javascript
533539
534- const tags = document .querySelectorAll (' ul.tags li' )
535- tags .forEach ((tag ) => {
536- addTagFormDeleteLink (tag)
537- })
540+ document
541+ .querySelectorAll (' ul.tags li' )
542+ .forEach ((tag ) => {
543+ addTagFormDeleteLink (tag)
544+ })
538545
539546 // ... the rest of the block from above
540547
541- function addFormToCollection () {
548+ const addFormToCollection = ( e ) => {
542549 // ...
543550
544551 // add a delete link to the new form
@@ -549,17 +556,16 @@ The ``addTagFormDeleteLink()`` function will look something like this:
549556
550557.. code-block :: javascript
551558
552- const addTagFormDeleteLink = (tagFormLi ) => {
553- const removeFormButton = document .createElement (' button' )
554- removeFormButton .classList
555- removeFormButton .innerText = ' Delete this tag'
559+ const addTagFormDeleteLink = (item ) => {
560+ const removeFormButton = document .createElement (' button' );
561+ removeFormButton .innerText = ' Delete this tag' ;
556562
557- tagFormLi .append (removeFormButton);
563+ item .append (removeFormButton);
558564
559565 removeFormButton .addEventListener (' click' , (e ) => {
560- e .preventDefault ()
566+ e .preventDefault ();
561567 // remove the li for the tag form
562- tagFormLi .remove ();
568+ item .remove ();
563569 });
564570 }
565571
@@ -651,10 +657,9 @@ the relationship between the removed ``Tag`` and ``Task`` object.
651657 The Symfony community has created some JavaScript packages that provide the
652658 functionality needed to add, edit and delete elements of the collection.
653659 Check out the `@a2lix/symfony-collection `_ package for modern browsers and
654- the `symfony-collection `_ package based on jQuery for the rest of browsers.
660+ the `symfony-collection `_ package based on ` jQuery `_ for the rest of browsers.
655661
656662.. _`Owning Side and Inverse Side` : https://www.doctrine-project.org/projects/doctrine-orm/en/current/reference/unitofwork-associations.html
657- .. _`jQuery` : http://jquery.com/
658663.. _`JSFiddle` : https://jsfiddle.net/ey8ozh6n/
659664.. _`@a2lix/symfony-collection` : https://github.com/a2lix/symfony-collection
660665.. _`symfony-collection` : https://github.com/ninsuo/symfony-collection
0 commit comments