Symfony2:如何根据数据为绑定PRE_SET_DATA中的字段添加表单约束

时间:2012-11-28 19:48:11

标签: forms validation symfony

我在Symfony 2中有一个表单,基本上有两个字段:

public function buildForm(FormBuilderInterface $builder, array $options) {

    $builder->add('contactType', 'select', array(  'choices' => $contactTypes ))
            ->add('value', 'text');
}

然后我添加了一个侦听FormEvents :: PRE_SET_DATA事件的EventSubscriber。我真正想做的是根据contactType的值改变验证方式(数字值从1到4,代表电子邮件,移动,固定电话和传真)。

我遵循了本教程http://symfony.com/doc/current/cookbook/form/dynamic_form_generation.html

但我无法弄清楚,如何在值字段中添加约束。

任何人都可以帮助我吗?非常感谢。

2 个答案:

答案 0 :(得分:8)

不是在事件订阅者中动态添加验证约束(不确定这是否可能),您可以将组设置为字段的验证约束和determine validation groups based on submitted data

答案 1 :(得分:0)

从控制器创建表单的功能:

<?php 

// ...

class DefaultController extends Controller
{
    /**
     * 
     * @param \Clicproxy\DeltadocCabBundle\Entity\Mark $mark
     * @param \Clicproxy\DeltadocCabBundle\Entity\Tag $tag
     * @return Form
     */
    private function createTagForm(Mark $mark, Tag $tag)
    {
        $form = $this->createForm(new TagType(), $tag, array(
            'action' => $this->generateUrl('tag_new', array('slug' => $this->slugify($mark->getName()))),
            'method' => 'POST',
        ));

        foreach ($mark->getFields() as $field)
        {
            $form->add($this->slugify($field->getName()), $field->getFormType(), $field->getOptions());
        }

        $form->add('submit', 'submit', array('label' => 'crud.default.save'));

        return $form;
    }

// ...

实体中的代码(类型,约束,......):

<?php

// ...

/**
 * Field
 *
 * @ORM\Table()
 * @ORM\Entity
 * @UniqueEntity({"name", "mark"})
 */
class Field
{

   // ...

    /**
     * 
     * @return array
     */
    public function getOptions()
    {
        $options = array('label' => $this->getName(), 'mapped' => FALSE);

        $options['required'] = $this->getType() != 'checkbox';

        if ('date' == $this->getType())
        {
            $options['attr']['class'] = 'datepicker'; // 'input-group date datepicker';
            $options['attr']['data-date-format'] = 'dd/mm/yyyy';
            $options['attr']['data-date-autoclose'] = true;
        }

        if ('choice' == $this->getType())
        {
            $choices = array();
            foreach ($this->getChoices() as $choice)
            {
                $choices[$choice->getValue()] = $choice->getName();
            }
            asort($choices);
            $options['choices'] = $choices;
        }

        $options['constraints'] = $this->getValidationConstraint();

        return $options;
    }

    public function getValidationConstraint ()
    {
        $validation_constraint = array();
        if ('number' == $this->getType()) {
            if (0 < $this->getMaximum()) {
                $validation_constraint[] = new LessThanOrEqual (array(
                    'message' => 'entity.field.number.lessthanorequal', // {{ compared_value }}
                    'value' => $this->getMaximum()
                ));
            }
            if (0 < $this->getMinimum()) {
                $validation_constraint[] = new GreaterThanOrEqual(array(
                    'message' => 'entity.field.number.greaterthanorequal', // {{ compared_value }}
                    'value' => $this->getMinimum()
                ));
            }
        } elseif ('text' == $this->getType ()) {
            if (0 < $this->getMaximum()) {
                $validation_constraint[] = new Length(array(
                    'min' => $this->getMinimum() > 0 ? $this->getMinimum() : 0,
                    'max' => $this->getMaximum() > 0 ? $this->getMaximum() : 0,
                    'minMessage' => 'entity.field.text.minMessage', // {{ limit }}
                    'maxMessage' => 'entity.field.text.maxMessage',
                    'exactMessage' => 'entity.field.text.exactMessage',
                ));
            }
        } elseif ('date' == $this->getType()) {

        }

        return $validation_constraint;
    }

// ...

所有这些代码实际上都有用。

有了这个,您就可以使用约束来动态生成表单。