@@ -1220,6 +1220,91 @@ When the user clicks ``removeComment()``, a similar process happens.
12201220 attribute above the ``Post.comments `` property. These help new
12211221 items save and deletes any items whose embedded forms are removed.
12221222
1223+ Using LiveCollectionType
1224+ ~~~~~~~~~~~~~~~~~~~~~~~~
1225+
1226+ .. versionadded :: 2.3
1227+
1228+ The ``LiveCollectionType `` was added in LiveComponent 2.3.
1229+
1230+
1231+ Symfony's `LiveCollectionType `_ can be used to embed a collection of
1232+ embedded forms including allowing the user to dynamically add or remove
1233+ them. Live components can accomplish make this all possible while
1234+ writing zero JavaScript.
1235+
1236+ For example, imagine a "Blog Post" form with an embedded "Comment" forms
1237+ via the ``LiveCollectionType ``::
1238+
1239+ namespace App\Form;
1240+
1241+ use Symfony\Component\Form\AbstractType;
1242+ use Symfony\Component\Form\FormBuilderInterface;
1243+ use Symfony\Component\OptionsResolver\OptionsResolver;
1244+ use Symfony\UX\LiveComponent\Form\Type\LiveCollectionType;
1245+ use App\Entity\BlogPost;
1246+
1247+ class BlogPostFormType extends AbstractType
1248+ {
1249+ public function buildForm(FormBuilderInterface $builder, array $options)
1250+ {
1251+ $builder
1252+ ->add('title', TextType::class)
1253+ // ...
1254+ ->add('comments', LiveCollectionType::class, [
1255+ 'entry_type' => CommentFormType::class,
1256+ 'allow_add' => true,
1257+ 'allow_delete' => true,
1258+ 'by_reference' => false,
1259+ ])
1260+ ;
1261+ }
1262+
1263+ public function configureOptions(OptionsResolver $resolver)
1264+ {
1265+ $resolver->setDefaults(['data_class' => BlogPost::class]);
1266+ }
1267+ }
1268+
1269+ Now, create a Twig component to render the form::
1270+
1271+ namespace App\Twig;
1272+
1273+ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
1274+ use Symfony\Component\Form\FormInterface;
1275+ use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
1276+ use Symfony\UX\LiveComponent\Attribute\LiveAction;
1277+ use Symfony\UX\LiveComponent\ComponentWithFormTrait;
1278+ use Symfony\UX\LiveComponent\DefaultActionTrait;
1279+ use App\Entity\BlogPost;
1280+ use App\Entity\Comment;
1281+ use App\Form\BlogPostFormType;
1282+
1283+ #[AsLiveComponent('blog_post_collection_type')]
1284+ class BlogPostCollectionTypeComponent extends AbstractController
1285+ {
1286+ use LiveCollectionTrait;
1287+ use DefaultActionTrait;
1288+
1289+ #[LiveProp]
1290+ public BlogPost $post;
1291+
1292+ protected function instantiateForm(): FormInterface
1293+ {
1294+ return $this->createForm(BlogPostFormType::class, $this->post);
1295+ }
1296+ }
1297+
1298+ The template for this component has two jobs: (1) render the form
1299+ like normal and (2) include links that trigger the ``addComment() ``
1300+ and ``removeComment() `` actions:
1301+
1302+ .. code-block :: twig
1303+
1304+ <div {{ attributes }} data-action="change->live#update">
1305+ {{ form(form) }}
1306+ </div>
1307+
12231308 Modifying Embedded Properties with the "exposed" Option
12241309-------------------------------------------------------
12251310
0 commit comments