Skip to content

Commit fd7609f

Browse files
committed
bug #2403 [LiveComponent] fix required select not initialized (dsoriano)
This PR was squashed before being merged into the 2.x branch. Discussion ---------- [LiveComponent] fix required select not initialized | Q | A | ------------- | --- | Bug fix? | yes | New feature? | no | Issues | Fix #1332 | License | MIT Initialize required select(ChoiceType or EntityType) with the first entry. Not applied to multiple or expanded. Commits ------- 9d1dada [LiveComponent] fix required select not initialized
2 parents 8b6090f + 9d1dada commit fd7609f

File tree

6 files changed

+91
-2
lines changed

6 files changed

+91
-2
lines changed

src/LiveComponent/src/ComponentWithFormTrait.php

+19-2
Original file line numberDiff line numberDiff line change
@@ -258,9 +258,26 @@ private function extractFormValues(FormView $formView): array
258258
if (\array_key_exists('checked', $child->vars)) {
259259
// special handling for check boxes
260260
$values[$name] = $child->vars['checked'] ? $child->vars['value'] : null;
261-
} else {
262-
$values[$name] = $child->vars['value'];
261+
continue;
262+
}
263+
264+
if (\array_key_exists('choices', $child->vars)
265+
&& $child->vars['required']
266+
&& !$child->vars['disabled']
267+
&& !$child->vars['value']
268+
&& !$child->vars['placeholder']
269+
&& !$child->vars['multiple']
270+
&& !$child->vars['expanded']
271+
&& $child->vars['choices']
272+
) {
273+
if (null !== $firstKey = array_key_first($child->vars['choices'])) {
274+
$values[$name] = $child->vars['choices'][$firstKey]->value ?? null;
275+
}
276+
277+
continue;
263278
}
279+
280+
$values[$name] = $child->vars['value'];
264281
}
265282

266283
return $values;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\UX\LiveComponent\Tests\Fixtures\Factory;
13+
14+
use Symfony\UX\LiveComponent\Tests\Fixtures\Entity\CategoryFixtureEntity;
15+
use Zenstruck\Foundry\Persistence\PersistentProxyObjectFactory;
16+
17+
final class CategoryFixtureEntityFactory extends PersistentProxyObjectFactory
18+
{
19+
protected function defaults(): array|callable
20+
{
21+
return [
22+
'name' => self::faker()->name(),
23+
];
24+
}
25+
26+
public static function class(): string
27+
{
28+
return CategoryFixtureEntity::class;
29+
}
30+
}

src/LiveComponent/tests/Fixtures/Form/FormWithManyDifferentFieldsType.php

+20
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\UX\LiveComponent\Tests\Fixtures\Form;
1313

14+
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
1415
use Symfony\Component\Form\AbstractType;
1516
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
1617
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
@@ -22,6 +23,7 @@
2223
use Symfony\Component\Form\FormBuilderInterface;
2324
use Symfony\Component\OptionsResolver\OptionsResolver;
2425
use Symfony\Component\Validator\Constraints\Length;
26+
use Symfony\UX\LiveComponent\Tests\Fixtures\Entity\CategoryFixtureEntity;
2527

2628
/**
2729
* @author Jakub Caban <[email protected]>
@@ -41,6 +43,20 @@ public function buildForm(FormBuilderInterface $builder, array $options)
4143
'foo' => 1,
4244
'bar' => 2,
4345
],
46+
'required' => false,
47+
])
48+
->add('choice_required_with_placeholder', ChoiceType::class, [
49+
'choices' => [
50+
'bar' => 2,
51+
'foo' => 1,
52+
],
53+
'placeholder' => 'foo',
54+
])
55+
->add('choice_required_without_placeholder', ChoiceType::class, [
56+
'choices' => [
57+
'bar' => 2,
58+
'foo' => 1,
59+
],
4460
])
4561
->add('choice_expanded', ChoiceType::class, [
4662
'choices' => [
@@ -64,6 +80,10 @@ public function buildForm(FormBuilderInterface $builder, array $options)
6480
],
6581
'multiple' => true,
6682
])
83+
->add('entity', EntityType::class, [
84+
'class' => CategoryFixtureEntity::class,
85+
'choice_label' => 'name',
86+
])
6787
->add('checkbox', CheckboxType::class)
6888
->add('checkbox_checked', CheckboxType::class)
6989
->add('file', FileType::class)

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

+8
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Component\DomCrawler\Crawler;
1616
use Symfony\Component\Form\FormFactoryInterface;
1717
use Symfony\UX\LiveComponent\Tests\Fixtures\Component\FormWithCollectionTypeComponent;
18+
use Symfony\UX\LiveComponent\Tests\Fixtures\Factory\CategoryFixtureEntityFactory;
1819
use Symfony\UX\LiveComponent\Tests\Fixtures\Form\BlogPostFormType;
1920
use Symfony\UX\LiveComponent\Tests\LiveComponentTestHelper;
2021
use Zenstruck\Browser\Test\HasBrowser;
@@ -157,6 +158,9 @@ public function testFormRemembersValidationFromInitialForm(): void
157158

158159
public function testHandleCheckboxChanges(): void
159160
{
161+
$category = CategoryFixtureEntityFactory::createMany(5);
162+
$id = $category[0]->getId();
163+
160164
$mounted = $this->mountComponent(
161165
'form_with_many_different_fields_type',
162166
[
@@ -174,9 +178,12 @@ public function testHandleCheckboxChanges(): void
174178
'textarea' => '',
175179
'range' => '',
176180
'choice' => '',
181+
'choice_required_with_placeholder' => '',
182+
'choice_required_without_placeholder' => '2',
177183
'choice_expanded' => '',
178184
'choice_multiple' => ['2'],
179185
'select_multiple' => ['2'],
186+
'entity' => (string) $id,
180187
'checkbox' => null,
181188
'checkbox_checked' => '1',
182189
'file' => '',
@@ -296,6 +303,7 @@ public function testLiveCollectionTypeAddButtonsByDefault(): void
296303

297304
public function testResetForm(): void
298305
{
306+
CategoryFixtureEntityFactory::createMany(5);
299307
$mounted = $this->mountComponent('form_with_many_different_fields_type');
300308

301309
$dehydratedProps = $this->dehydrateComponent($mounted)->getProps();

src/LiveComponent/tests/Functional/Test/InteractsWithLiveComponentsTest.php

+4
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,16 @@
1717
use Symfony\Component\Security\Http\Attribute\IsGranted;
1818
use Symfony\UX\LiveComponent\Test\InteractsWithLiveComponents;
1919
use Symfony\UX\LiveComponent\Tests\Fixtures\Component\Component2;
20+
use Symfony\UX\LiveComponent\Tests\Fixtures\Factory\CategoryFixtureEntityFactory;
21+
use Zenstruck\Foundry\Test\ResetDatabase;
2022

2123
/**
2224
* @author Kevin Bond <[email protected]>
2325
*/
2426
final class InteractsWithLiveComponentsTest extends KernelTestCase
2527
{
2628
use InteractsWithLiveComponents;
29+
use ResetDatabase;
2730

2831
public function testCanRenderInitialData(): void
2932
{
@@ -172,6 +175,7 @@ public function testActingAs(): void
172175

173176
public function testCanSubmitForm(): void
174177
{
178+
CategoryFixtureEntityFactory::createMany(5);
175179
$testComponent = $this->createLiveComponent('form_with_many_different_fields_type');
176180

177181
$response = $testComponent->submitForm(['form' => ['text' => 'foobar']])->response();

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

+10
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,21 @@
1313

1414
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
1515
use Symfony\UX\LiveComponent\Tests\Fixtures\Component\FormComponentWithManyDifferentFieldsType;
16+
use Symfony\UX\LiveComponent\Tests\Fixtures\Factory\CategoryFixtureEntityFactory;
17+
use Zenstruck\Foundry\Test\ResetDatabase;
1618

1719
/**
1820
* @author Jakub Caban <[email protected]>
1921
*/
2022
class ComponentWithFormTest extends KernelTestCase
2123
{
24+
use ResetDatabase;
25+
2226
public function testFormValues(): void
2327
{
28+
$category = CategoryFixtureEntityFactory::createMany(5);
29+
$id = $category[0]->getId();
30+
2431
$formFactory = self::getContainer()->get('form.factory');
2532
$component = new FormComponentWithManyDifferentFieldsType($formFactory);
2633
$component->initialData = [
@@ -36,9 +43,12 @@ public function testFormValues(): void
3643
'textarea' => '',
3744
'range' => '',
3845
'choice' => '',
46+
'choice_required_with_placeholder' => '',
47+
'choice_required_without_placeholder' => '2',
3948
'choice_expanded' => '',
4049
'choice_multiple' => ['2'],
4150
'select_multiple' => ['2'],
51+
'entity' => (string) $id,
4252
'checkbox' => null,
4353
'checkbox_checked' => '1',
4454
'file' => '',

0 commit comments

Comments
 (0)