5

我在 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

但我不知道如何向值字段添加约束。

谁能帮我?提前非常感谢。

4

2 回答 2

9

您可以将组设置为字段的验证约束并根据提交的数据确定验证组,而不是在事件订阅者中动态添加验证约束(不确定这是否可能)。

于 2013-02-02T18:23:19.720 回答
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;
    }

// ...

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

有了这个,你就有了一个解决方案来动态生成一个带有约束的表单。

于 2014-04-16T12:43:41.017 回答