8000 Fixing a very subtle validation issue with the CollectionType. I've d… · knpuniversity/symfony@ab02c47 · GitHub
[go: up one dir, main page]

Skip to content

Commit ab02c47

Browse files
committed
Fixing a very subtle validation issue with the CollectionType. I've doc'ed it quite a bit - it fixes (in our project) symfony/symfony#7468. Thanks to Jürgen Modic for the tip on this!
1 parent 2db22bc commit ab02c47

File tree

2 files changed

+74
-1
lines changed

2 files changed

+74
-1
lines changed

_tuts/steps.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1250,6 +1250,11 @@
12501250
"name": "Validation: Setting errorPath",
12511251
"description": null
12521252
},
1253+
{
1254+
"id": "validation-fixing-collection-index-issue",
1255+
"name": "Validation: Fixing collection index issue",
1256+
"description": null
1257+
},
12531258
{
12541259
"id": "form-customizing-prototype",
12551260
"name": "Form: Customizing prototype",
@@ -1301,5 +1306,5 @@
13011306
"description": null
13021307
}
13031308
],
1304-
"sha": "7d28227a16674de081ff2133036a39d19d02ebfe"
1309+
"sha": "2db22bc14b7fac9c26d6769285c0344e39c68168"
13051310
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
diff --git a/src/AppBundle/Form/GenusFormType.php b/src/AppBundle/Form/GenusFormType.php
2+
index b27928a..cdeb7b7 100644
3+
--- a/src/AppBundle/Form/GenusFormType.php
4+
+++ b/src/AppBundle/Form/GenusFormType.php
5+
@@ -12,6 +12,8 @@ use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
6+
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
7+
use Symfony\Component\Form\Extension\Core\Type\DateType;
8+
use Symfony\Component\Form\FormBuilderInterface;
9+
+use Symfony\Component\Form\FormEvent;
10+
+use Symfony\Component\Form\FormEvents;
11+
use Symfony\Component\Form\FormInterface;
12+
use Symfony\Component\Form\FormView;
13+
use Symfony\Component\OptionsResolver\OptionsResolver;
14+
@@ -51,6 +53,8 @@ class GenusFormType extends AbstractType
15+
'by_reference' => false,
16+
])
17+
;
18+
+
19+
+ $builder->addEventListener(FormEvents::PRE_SUBMIT, array($this, 'onPreSubmit'));
20+
}
21+
22+
public function configureOptions(OptionsResolver $resolver)
23+
@@ -59,4 +63,45 @@ class GenusFormType extends AbstractType
24+
'data_class' => 'AppBundle\Entity\Genus'
25+
]);
26+
}
27+
+
28+
+ /**
29+
+ * This fixes a validation issue with the Collection. Suppose
30+
+ * the following situation:
31+
+ *
32+
+ * A) Edit a Genus
33+
+ * B) Add 2 new scientists - don't submit & leave all fields blank
34+
+ * C) Delete the FIRST scientist
35+
+ * D) Submit the form
36+
+ *
37+
+ * The one new scientist has a validation error, because
38+
+ * the yearsStudied field was left blank. But, this error
39+
+ * shows at the *top* of the form, not attached to the form.
40+
+ * The reason is that, on submit, addGenusScientist() is
41+
+ * called, and the new scientist is added to the next available
42+
+ * index (so, if the Genus previously had 2 scientists, the
43+
+ * new GenusScientist is added to the "2" index). However,
44+
+ * in the HTML before the form was submitted, the index used
45+
+ * in the name attribute of the fields for the new scientist
46+
+ * was *3*: 0 & 1 were used for the existing scientists and 2 was
47+
+ * used for the first genus scientist form that you added
48+
+ * (and then later deleted). This mis-match confuses the validator,
49+
+ * which thinks there is an error on genusScientists[2].yearsStudied,
50+
+ * and fails to map that to the genusScientists[3].yearsStudied
51+
+ * field.
52+
+ *
53+
+ * Phew! It's a big pain :). Below, we fix it! On submit,
54+
+ * we simply re-index the submitted data before it's bound
55+
+ * to the form. The submitted genusScientists data, which
56+
+ * previously had index 0, 1 and 3, will now have indexes
57+
+ * 0, 1 and 2. And these indexes will match the indexes
58+
+ * that they have on the Genus.genusScientists property.
59+
+ *
60+
+ * @param FormEvent $event
61+
+ */
62+
+ public function onPreSubmit(FormEvent $event)
63+
+ {
64+
+ $data = $event->getData();
65+
+ $data['genusScientists'] = array_values($data['genusScientists']);
66+
+ $event->setData($data);
67+
+ }
68+
}

0 commit comments

Comments
 (0)
0