Skip to content

Commit a44f86c

Browse files
committed
cleanups
1 parent d60ae1a commit a44f86c

File tree

6 files changed

+66
-39
lines changed

6 files changed

+66
-39
lines changed

src/LiveComponent/CHANGELOG.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,12 @@
55
- Added `data-live-ignore` attribute. If included in an element, that element
66
will not be updated on re-render.
77

8-
- `ComponentWithFromTrait`: Added `refreshForm()` to rebuild form based
9-
on chnaged data
10-
118
- `ComponentWithFormTrait`: call `$this->initializeFormValues()` from
129
`mount()` if your component has a custom `mount()`.
1310

1411
- `ComponentWithFormTrait` no longer has a `setForm()` method, just call
1512
`$this->formView = $form` from `mount()` if you have a custom mount.
1613
Hopefully that will not be needed soon.
17-
>>>>>>> 2e4a2fa (Adding refreshForm() to ComponentWithFormTrait)
1814

1915
- The Live Component AJAX endpoints now return HTML in all situations
2016
instead of JSON.

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

Lines changed: 65 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,52 +1070,89 @@ section above) is to add:
10701070
+ data-action="change->live#update"
10711071
>
10721072
1073-
Resetting the Form in an Action
1074-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1073+
Using Actions to Change your Form: CollectionType
1074+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10751075

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.
10771080

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``::
10791083

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;
10841085

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;
10901091

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+
}
10921106

1093-
public function __construct()
1107+
public function configureOptions(OptionsResolver $resolver)
10941108
{
1095-
$this->author = new Author();
1109+
$resolver->setDefaults(['data_class' => BlogPost::class]);
10961110
}
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;
10971135

10981136
protected function instantiateForm(): FormInterface
10991137
{
1100-
return $this->createForm(AuthorType::class, $this->author);
1138+
return $this->createForm(BlogPostFormType::class, $this->post);
11011139
}
11021140

11031141
#[LiveAction]
1104-
public function addBook()
1142+
public function addComment()
11051143
{
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'][] = [];
11161148
}
11171149
}
11181150

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+
11191156
Modifying Embedded Properties with the "exposed" Option
11201157
-------------------------------------------------------
11211158

src/LiveComponent/tests/Fixture/Component/FormWithCollectionTypeComponent.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
use Symfony\UX\LiveComponent\DefaultActionTrait;
2020
use Symfony\UX\LiveComponent\Tests\Fixture\Dto\BlogPost;
2121
use Symfony\UX\LiveComponent\Tests\Fixture\Dto\Comment;
22-
use Symfony\UX\LiveComponent\Tests\Fixture\Entity\Entity1;
2322
use Symfony\UX\LiveComponent\Tests\Fixture\Form\BlogPostFormType;
2423

2524
#[AsLiveComponent('form_with_collection_type')]

src/LiveComponent/tests/Fixture/Entity/Entity1.php

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,4 @@ class Entity1
2424
* @ORM\Column(type="integer")
2525
*/
2626
public $id;
27-
28-
public $name;
29-
30-
public $description;
3127
}

src/LiveComponent/tests/Fixture/Kernel.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ protected function configureContainer(ContainerBuilder $c, LoaderInterface $load
6969
$c->register(Component3::class)->setAutoconfigured(true)->setAutowired(true);
7070
$c->register(Component6::class)->setAutoconfigured(true)->setAutowired(true);
7171
$c->register(ComponentWithAttributes::class)->setAutoconfigured(true)->setAutowired(true);
72-
$c->register(FormThatResetsComponent::class)->setAutoconfigured(true)->setAutowired(true);
7372
$c->register(FormWithCollectionTypeComponent::class)->setAutoconfigured(true)->setAutowired(true);
7473

7574
$c->loadFromExtension('framework', [

src/LiveComponent/tests/Functional/Form/ComponentWithFormTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class ComponentWithFormTest extends KernelTestCase
3131
use HasBrowser;
3232
use ResetDatabase;
3333

34-
public function testRefreshForm(): void
34+
public function testFormValuesRebuildAfterFormChanges(): void
3535
{
3636
/** @var LiveComponentHydrator $hydrator */
3737
$hydrator = self::getContainer()->get('ux.live_component.component_hydrator');

0 commit comments

Comments
 (0)