@@ -1070,52 +1070,89 @@ section above) is to add:
1070
1070
+ data-action="change->live#update"
1071
1071
>
1072
1072
1073
- Resetting the Form in an Action
1074
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1073
+ Using Actions to Change your Form: CollectionType
1074
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1075
1075
1076
- .. versionadded :: 2.1
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.
1077
1080
1078
- The ``refreshForm() `` method was added in LiveComponent 2.1.
1081
+ For example, imagine a "Blog Post" form with an embedded "Comment" forms
1082
+ via the ``CollectionType ``::
1079
1083
1080
- Imagine you have a live action that, instead of saving, changes the underlying
1081
- data of your form - e.g. by setting a property to some value. To handle this,
1082
- be sure to (1) call ``$this->submitForm() `` to handle the incoming frontend data
1083
- and (2) call ``$this->refreshForm() `` after finishing::
1084
+ namespace App\Form;
1084
1085
1085
- #[AsLiveComponent('author_with_book_form')]
1086
- class AuthorWithBookCollectionTypeComponent extends AbstractController
1087
- {
1088
- use ComponentWithFormTrait ;
1089
- use DefaultActionTrait ;
1086
+ use Symfony\Component\Form\AbstractType;
1087
+ use Symfony\Component\Form\Extension\Core\Type\CollectionType;
1088
+ use Symfony\Component\Form\FormBuilderInterface;
1089
+ use Symfony\Component\OptionsResolver\OptionsResolver ;
1090
+ use App\Entity\BlogPost ;
1090
1091
1091
- public Author $author;
1092
+ class BlogPostFormType extends AbstractType
1093
+ {
1094
+ public function buildForm(FormBuilderInterface $builder, array $options)
1095
+ {
1096
+ $builder
1097
+ ->add('title', TextType::class)
1098
+ // ...
1099
+ ->add('comments', CollectionType::class, [
1100
+ 'entry_type' => CommentFormType::class,
1101
+ 'allow_add' => true,
1102
+ 'allow_delete' => true,
1103
+ ])
1104
+ ;
1105
+ }
1092
1106
1093
- public function __construct( )
1107
+ public function configureOptions(OptionsResolver $resolver )
1094
1108
{
1095
- $this->author = new Author( );
1109
+ $resolver->setDefaults(['data_class' => BlogPost::class] );
1096
1110
}
1111
+ }
1112
+
1113
+ Now, create a Twig component to render the form::
1114
+
1115
+ namespace App\Twig;
1116
+
1117
+ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
1118
+ use Symfony\Component\Form\FormInterface;
1119
+ use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
1120
+ use Symfony\UX\LiveComponent\Attribute\LiveAction;
1121
+ use Symfony\UX\LiveComponent\ComponentWithFormTrait;
1122
+ use Symfony\UX\LiveComponent\DefaultActionTrait;
1123
+ use App\Entity\BlogPost;
1124
+ use App\Entity\Comment;
1125
+ use App\Form\BlogPostFormType;
1126
+
1127
+ #[AsLiveComponent('blog_post_collection_type')]
1128
+ class BlogPostCollectionTypeComponent extends AbstractController
1129
+ {
1130
+ use ComponentWithFormTrait;
1131
+ use DefaultActionTrait;
1132
+
1133
+ #[LiveProp]
1134
+ public BlogPost $post;
1097
1135
1098
1136
protected function instantiateForm(): FormInterface
1099
1137
{
1100
- return $this->createForm(AuthorType ::class, $this->author );
1138
+ return $this->createForm(BlogPostFormType ::class, $this->post );
1101
1139
}
1102
1140
1103
1141
#[LiveAction]
1104
- public function addBook ()
1142
+ public function addComment ()
1105
1143
{
1106
- // submit the values, but no further validation
1107
- $this->submitForm(false, false);
1108
-
1109
- // Add a Book to the Author
1110
- // If AuthorType has a CollectionType "books" field, this will
1111
- // cause a new, embedded form to render
1112
- $this->author->addBook(new Book());
1113
-
1114
- // for the form to rebuild with the new data
1115
- $this->refreshForm();
1144
+ // "formValues" represents the current data in the form
1145
+ // this modifies the form to add an extra comment
1146
+ // the result: another embedded comment form!
1147
+ $this->formValues['comments'][] = [];
1116
1148
}
1117
1149
}
1118
1150
1151
+ Finally, render the form in the component's template like normal, but
1152
+ with a live action that points to ``addComment() ``:
1153
+
1154
+ TODO
1155
+
1119
1156
Modifying Embedded Properties with the "exposed" Option
1120
1157
-------------------------------------------------------
1121
1158
0 commit comments