Skip to content

Commit 532c25d

Browse files
committed
finishing docs
1 parent f261c7a commit 532c25d

File tree

1 file changed

+71
-7
lines changed

1 file changed

+71
-7
lines changed

src/LiveComponent/src/Resources/doc/index.rst

Lines changed: 71 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1073,10 +1073,10 @@ section above) is to add:
10731073
Using Actions to Change your Form: CollectionType
10741074
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10751075

1076-
Have you ever used Symfony's `CollectionType`_? If you want to be able
1077-
to dynamically add or remove embedded forms, you need to write some
1078-
JavaScript. Well, that's true, unless you render your form inside a
1079-
live component.
1076+
Symfony's `CollectionType`_ can be used to embed a collection of
1077+
embedded forms including allowing the user to dynamically add or remove
1078+
them. Live components can accomplish make this all possible while
1079+
writing zero JavaScript.
10801080

10811081
For example, imagine a "Blog Post" form with an embedded "Comment" forms
10821082
via the ``CollectionType``::
@@ -1100,6 +1100,7 @@ via the ``CollectionType``::
11001100
'entry_type' => CommentFormType::class,
11011101
'allow_add' => true,
11021102
'allow_delete' => true,
1103+
'by_reference' => false,
11031104
])
11041105
;
11051106
}
@@ -1144,14 +1145,76 @@ Now, create a Twig component to render the form::
11441145
// "formValues" represents the current data in the form
11451146
// this modifies the form to add an extra comment
11461147
// the result: another embedded comment form!
1148+
// change "comments" to the name of the field that uses CollectionType
11471149
$this->formValues['comments'][] = [];
11481150
}
1151+
1152+
#[LiveAction]
1153+
public function removeComment(#[LiveArg] int $index)
1154+
{
1155+
unset($this->formValues['comments'][$index]);
1156+
}
11491157
}
11501158

1151-
Finally, render the form in the component's template like normal, but
1152-
with a live action that points to ``addComment()``:
1159+
The template for this component has two jobs: (1) render the form
1160+
like normal and (2) include links that trigger the ``addComment()``
1161+
and ``removeComment()`` actions:
1162+
1163+
.. code-block:: twig
1164+
1165+
<div{{ attributes }}>
1166+
{{ form_start(this.form) }}
1167+
{{ form_row(this.form.title) }}
1168+
1169+
<h3>Comments:</h3>
1170+
{% for key, commentForm in this.form.comments %}
1171+
<button
1172+
data-action="live#action"
1173+
data-action-name="removeComment(index={{ key }})"
1174+
type="button"
1175+
>X</button>
1176+
1177+
{{ form_widget(commentForm) }}
1178+
{% endfor %}
1179+
</div>
1180+
1181+
{# avoid an extra label for this field #}
1182+
{% do this.form.comments.setRendered %}
1183+
1184+
<button
1185+
data-action="live#action"
1186+
data-action-name="addComment"
1187+
type="button"
1188+
>+ Add Comment</button>
1189+
1190+
<button type="submit" >Save</button>
1191+
{{ form_end(this.form) }}
1192+
</div>
1193+
1194+
Done! Behind the scenes, it works like this:
1195+
1196+
A) When the user clicks "+ Add Comment", an Ajax request is sent that
1197+
triggers the ``addComment()`` action.
1198+
1199+
B) ``addComment()`` modifies ``formValues``, which you can think of as
1200+
the raw "POST" data of your form.
1201+
1202+
C) Still during the Ajax request, the ``formValues`` are "submitted"
1203+
into your form. The new key inside of ``$this->formValues['comments']``
1204+
tells the ``CollectionType`` that you want a new, embedded form.
1205+
1206+
D) The form is rendered - now with another embedded form! - and the
1207+
Ajax call returns with the form (with the new embedded form).
1208+
1209+
When the user clicks ``removeComment()``, a similar process happens.
1210+
1211+
.. note::
11531212

1154-
TODO
1213+
When working with Doctrine entities, add ``orphanRemoval: true``
1214+
and ``cascade={"persist"}`` to your ``OneToMany`` relationship.
1215+
In this example, these options would be added to the ``OneToMany``
1216+
attribute above the ``Post.comments`` property. These help new
1217+
items save and deletes any items whose embedded forms are removed.
11551218

11561219
Modifying Embedded Properties with the "exposed" Option
11571220
-------------------------------------------------------
@@ -1636,3 +1699,4 @@ bound to Symfony's BC policy for the moment.
16361699
.. _`dependent form fields`: https://symfony.com/doc/current/form/dynamic_form_modification.html#dynamic-generation-for-submitted-forms
16371700
.. _`Symfony UX configured in your app`: https://symfony.com/doc/current/frontend/ux.html
16381701
.. _`Component attributes`: https://symfony.com/bundles/ux-twig-component/current/index.html#component-attributes
1702+
.. _`CollectionType`: https://symfony.com/doc/current/form/form_collections.html

0 commit comments

Comments
 (0)