0

I've got a form that is mapped to an entity ('data_class' => ...). I've got validators set up (via annotations) on the entity's properties.

The entity has a property (nameTranslations) of doctrine's type array. I created a custom field type composed of multiple fields that is assigned to this field in the form. Each of the subform's fields (of type text) has validators setup (NotBlank) via validation_constraint option.

I tried various validation annotations on the nameTranslations property, including Valid(). I tried settings error_bubbling on almost anything. The subform (field nameTranslations) doesn't get validated at all.

The subform:

class TranslatableTextType extends AbstractType
{
    private $langs;

    /**
    * {@inheritDoc}
    */
    public function __construct($multilang)
    {
        $this->langs = $multilang->getLangs();
    }

    /**
    * {@inheritDoc}
    */
    public function buildForm(FormBuilder $builder, array $options)
    {
        foreach($this->langs as $locale => $lang)
        {
            $builder->add($locale, 'text', array(
                'label' => sprintf("%s [%s]", $options['label'], $lang),
                'error_bubbling' => true,
            ));
        }
    }

    /**
    * {@inheritDoc}
    */
    public function getDefaultOptions(array $options)
    {
        $constraints = [
            'fields' => [],
            'allowExtraFields' => true,
            'allowMissingFields' => true,
        ];

        foreach($this->langs as $locale => $lang)
        {
            $constraints['fields'][$locale] = new NotBlank();
        }

        $collectionConstraint = new Collection($constraints);

        return [
            'validation_constraint' => $collectionConstraint,
            'label' => '',
            'error_bubbling' => true
        ];
    }

    /**
    * {@inheritDoc}
    */
    public function getParent(array $options)
    {
        return 'form';
    }

    /**
    * {@inheritDoc}
    */
    public function getName()
    {
        return 'translatable_text';
    }
}

In the main form:

$builder->add('nameTranslations', 'translatable_text', [
            'label' => 'Name'
        ]);

In the entity:

/**
 * @var array
 *
 * @Assert\Valid
 * @ORM\Column(type="array")
 */
protected $nameTranslations;
pinkeen
  • 690
  • 3
  • 10
  • 21

1 Answers1

0

I think you should use collection type for that instead of custom one or your custom type should have collection type defined as parent.

You can use All validator like:

/**
 * @Assert\All({
 *     @Assert\NotBlank
 * })
 * @ORM\Column(type="array")
 */
 protected $nameTranslations;

it will check if each of array value is not blank.

l3l0
  • 3,363
  • 20
  • 19
  • It is not well suited for a collection, there is a (for the most part of time) fixed number of fields. Besides I've got exactly the same problem with another field - which couldn't be converted to collection even if I wanted to. I do not understand why symfony doesn't validate the subform when it's every field has a validator and the field that this subform is attached to also has validator (`ORM\Validate`). Even if your solution worked (can't test it right now, back at home) it would validate the subform as a whole - it would be nicer if every field was treated separately (UX). – pinkeen Jan 11 '13 at 19:48
  • http://symfony.com/doc/master/reference/forms/types/form.html#cascade-validation that why it is not validate subforms by default... and I do not understand why fixed number of fields not suite for collection type... collection type should be use when you want have many subforms (types)... BTW even if you not use collection you can validate that by All constraint – l3l0 Jan 11 '13 at 19:57
  • From `cascade_validation`: _Instead of using this option, you can also use the Valid constraint in your model to force validation on a child object stored on a property._ Already tried the `Valid` contraint. As far as the collection dispute is concerned - I can't use collection for the other field with the same problem. Collection isn't suitable for many fields and it feels more like workaround rather than solution. – pinkeen Jan 11 '13 at 20:20