@@ -239,23 +239,31 @@ it will receive an *unknown* number of tags. Otherwise, you'll see a
239
239
The ``allow_add `` option also makes a ``prototype `` variable available to you.
240
240
This "prototype" is a little "template" that contains all the HTML needed to
241
241
dynamically 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:
243
244
244
245
.. code-block :: html+twig
245
246
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>
247
252
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 :
249
254
250
- .. code-block :: html+twig
255
+ .. code-block :: html
251
256
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 >
253
261
254
- On the rendered page, the result will look something like this :
262
+ Now add a button to dynamically add a new tag :
255
263
256
- .. code-block :: html
264
+ .. code-block :: html+twig
257
265
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 >
259
267
260
268
.. seealso ::
261
269
@@ -265,7 +273,7 @@ On the rendered page, the result will look something like this:
265
273
.. tip ::
266
274
267
275
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.
269
277
This means that you can call ``form_widget() ``, ``form_row() `` or ``form_label() ``
270
278
on it. You could even choose to render only one of its fields (e.g. the
271
279
``name `` field):
@@ -281,16 +289,16 @@ On the rendered page, the result will look something like this:
281
289
and you need to adjust the following JavaScript accordingly.
282
290
283
291
Now 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:
288
294
289
295
.. code-block :: javascript
290
296
291
297
document
292
298
.querySelectorAll (' .add_item_link' )
293
- .forEach (btn => btn .addEventListener (" click" , addFormToCollection));
299
+ .forEach (btn => {
300
+ btn .addEventListener (" click" , addFormToCollection)
301
+ });
294
302
295
303
The ``addFormToCollection() `` function's job will be to use the ``data-prototype ``
296
304
attribute 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:
529
537
530
538
.. code-block :: javascript
531
539
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
+ })
536
545
537
546
// ... the rest of the block from above
538
547
539
- function addFormToCollection () {
548
+ const addFormToCollection = ( e ) => {
540
549
// ...
541
550
542
551
// add a delete link to the new form
@@ -547,17 +556,16 @@ The ``addTagFormDeleteLink()`` function will look something like this:
547
556
548
557
.. code-block :: javascript
549
558
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' ;
554
562
555
- tagFormLi .append (removeFormButton);
563
+ item .append (removeFormButton);
556
564
557
565
removeFormButton .addEventListener (' click' , (e ) => {
558
- e .preventDefault ()
566
+ e .preventDefault ();
559
567
// remove the li for the tag form
560
- tagFormLi .remove ();
568
+ item .remove ();
561
569
});
562
570
}
563
571
@@ -652,7 +660,6 @@ the relationship between the removed ``Tag`` and ``Task`` object.
652
660
the `symfony-collection `_ package based on `jQuery `_ for the rest of browsers.
653
661
654
662
.. _`Owning Side and Inverse Side` : https://www.doctrine-project.org/projects/doctrine-orm/en/current/reference/unitofwork-associations.html
655
- .. _`jQuery` : http://jquery.com/
656
663
.. _`JSFiddle` : https://jsfiddle.net/ey8ozh6n/
657
664
.. _`@a2lix/symfony-collection` : https://github.com/a2lix/symfony-collection
658
665
.. _`symfony-collection` : https://github.com/ninsuo/symfony-collection
0 commit comments