Single validation error message displays at top of form instead of next to
each field
I'm building a form in Symfony 2 whose fields will vary depending on how
the corresponding entity is configured.
Briefly, each entity has a set of "detail" fields that can hold different
types and configurations of data.
For example, a Project entity might have the following configuration:
url renders as a text input and validates as a URL with max length of 300
chars.
description renders as a textarea with no validation constraints.
logo renders as a file input and validates as an image file with max
dimensions of 500x500.
And so on. The part that makes this interesting is that all of this is
configured via database tables so that an administrator could change the
configuration of these models via a UI.
The (relevant part of the) database structure looks something like this:
project stores the Project records.
project_detail stores the value of each detail field for each Project.
detail_type defines the type and configuration for each detail field.
detail_type_assignment defines which detail types are available for each
entity and the order in which the fields should display on forms.
Everything is working great so far except for rendering error messages in
forms.
When any of these detail fields generates a validation error, only one
error message is displayed, and it is displayed at the top of the form:
Notice in the above screenshot:
The only error message that renders is 'This URL must have the twitter.com
domain'.
The error message renders at the top of the form rather than next to the
"Twitter URL" field.
No other error messages are rendered.
Here's what the ProjectType looks like:
class ProjectType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
/* To add detail fields, we need access to the Project
object, which
* isn't available to buildForm(). To work around this, we
* will add the remaining fields in the form.pre_set_data
* phase.
*/
->addEventSubscriber(new DetailFormSubscriber());
}
...
}
And the DetailFormSubscriber:
class DetailFormSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return array(
FormEvents::PRE_SET_DATA => 'preSetData'
);
}
public function preSetData(FormEvent $event)
{
/* For brevity, assume $event->getData() is a valid Project here. */
foreach($event->getData()->getDetails() as $slug => $detail)
{
$event->getForm()->add(
$slug
, $detail->getFormFieldType()
, $detail->getFormFieldOptions(array(
'constraints' =>
$detail->getValidationConstraints()
))
);
}
}
}
What am I missing and/or doing wrong?
No comments:
Post a Comment