@@ -238,19 +238,26 @@ it will receive an *unknown* number of tags. Otherwise, you'll see a
238
238
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
- dynamically create any new "tag" forms with JavaScript. Now add the following
242
- ``data-index `` (containing the current "form row" number for the following JavaScript)
243
- and `` data-prototype `` attribute to the existing `` <ul> `` in your template:
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
243
+ template:
244
244
245
245
.. code-block :: html+twig
246
246
247
- <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>
248
252
249
253
On the rendered page, the result will look something like this:
250
254
251
255
.. code-block :: html
252
256
253
- <ul class =" tags" data-index =" 0" 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> ; " >
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 >
254
261
255
262
Now add a button to dynamically add a new tag:
256
263
@@ -282,16 +289,16 @@ Now add a button to dynamically add a new tag:
282
289
and you need to adjust the following JavaScript accordingly.
283
290
284
291
Now add some JavaScript to read this attribute and dynamically add new tag forms
285
- when the user clicks the "Add a tag" link.
286
-
287
- Add a ``<script> `` tag somewhere on your page to include the required
288
- 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:
289
294
290
295
.. code-block :: javascript
291
296
292
297
document
293
298
.querySelectorAll (' .add_item_link' )
294
- .forEach (btn => btn .addEventListener (" click" , addFormToCollection));
299
+ .forEach (btn => {
300
+ btn .addEventListener (" click" , addFormToCollection)
301
+ });
295
302
296
303
The ``addFormToCollection() `` function's job will be to use the ``data-prototype ``
297
304
attribute to dynamically add a new form when this link is clicked. The ``data-prototype ``
@@ -304,17 +311,17 @@ you'll replace with a unique, incrementing number (e.g. ``task[tags][3][name]``)
304
311
const addFormToCollection = (e ) => {
305
312
const collectionHolder = document .querySelector (' .' + e .currentTarget .dataset .collectionHolderClass );
306
313
307
- const element = document .createElement (' li' );
314
+ const item = document .createElement (' li' );
308
315
309
- element .innerHTML = collectionHolder
316
+ item .innerHTML = collectionHolder
310
317
.dataset
311
318
.prototype
312
319
.replace (
313
320
/ __name__/ g ,
314
321
collectionHolder .dataset .index
315
322
);
316
323
317
- collectionHolder .appendChild (element );
324
+ collectionHolder .appendChild (item );
318
325
319
326
collectionHolder .dataset .index ++ ;
320
327
};
@@ -530,34 +537,35 @@ First, add a "delete this tag" link to each tag form:
530
537
531
538
.. code-block :: javascript
532
539
533
- const tags = document .querySelectorAll (' ul.tags li' )
534
- tags .forEach ((tag ) => {
535
- addTagFormDeleteLink (tag)
536
- })
540
+ document
541
+ .querySelectorAll (' ul.tags li' )
542
+ .forEach ((tag ) => {
543
+ addTagFormDeleteLink (tag)
544
+ })
537
545
538
546
// ... the rest of the block from above
539
547
540
- function addFormToCollection () {
548
+ const addFormToCollection = ( e ) => {
541
549
// ...
542
550
543
551
// add a delete link to the new form
544
- addTagFormDeleteLink (element );
552
+ addTagFormDeleteLink (item );
545
553
}
546
554
547
555
The ``addTagFormDeleteLink() `` function will look something like this:
548
556
549
557
.. code-block :: javascript
550
558
551
- const addTagFormDeleteLink = (element ) => {
559
+ const addTagFormDeleteLink = (item ) => {
552
560
const removeFormButton = document .createElement (' button' );
553
561
removeFormButton .innerText = ' Delete this tag' ;
554
562
555
- element .append (removeFormButton);
563
+ item .append (removeFormButton);
556
564
557
565
removeFormButton .addEventListener (' click' , (e ) => {
558
566
e .preventDefault ();
559
567
// remove the li for the tag form
560
- element .remove ();
568
+ item .remove ();
561
569
});
562
570
}
563
571
0 commit comments