Symfony2 - 动态表单选择 - 验证删除

时间:2013-08-13 11:06:54

标签: forms validation symfony

我有一个下拉表单元素。最初它开始是空的,但是在用户进行了一些交互之后,它通过javascript填充了值。多数民众赞成。但是,当我提交它时,它总是返回验证错误This value is not valid.

如果我将这些项目添加到表单代码中的选项列表中,它将验证确定,但我正在尝试动态填充它,并且在将项目添加到选项列表之前不会起作用。

我认为问题是因为表单正在验证一个空的项目列表。我根本不希望它根据列表进行验证。我已将验证设置为false。我将chocie类型切换为文本,并始终通过验证。

这只会针对添加到选项列表中的空行或项目进行验证

$builder->add('verified_city', 'choice', array(
  'required' =>  false
));

这里的类似问题没有得到回答 Validating dynamically loaded choices in Symfony 2

假设你不知道所有可用的选择是什么。它可以从外部Web源加载吗?

5 个答案:

答案 0 :(得分:6)

经过很长时间的努力,试图找到它。您基本上需要添加PRE_BIND侦听器。在绑定准备验证的值之前,您可以添加一些额外的选择。

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;


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

  // .. create form code at the top

    $ff = $builder->getFormFactory();

    // function to add 'template' choice field dynamically
    $func = function (FormEvent $e) use ($ff) {
      $data = $e->getData();
      $form = $e->getForm();
      if ($form->has('verified_city')) {
        $form->remove('verified_city');
      }


      // this helps determine what the list of available cities are that we can use
      if ($data instanceof  \Portal\PriceWatchBundle\Entity\PriceWatch) {
        $country = ($data->getVerifiedCountry()) ? $data->getVerifiedCountry() : null;
      }
      else{
        $country = $data['verified_country'];
      }

      // here u can populate choices in a manner u do it in loadChoices use your service in here
      $choices = array('', '','Manchester' => 'Manchester', 'Leeds' => 'Leeds');

      #if (/* some conditions etc */)
      #{
      #  $choices = array('3' => '3', '4' => '4');
      #}
      $form->add($ff->createNamed('verified_city', 'choice', null, compact('choices')));
    };

    // Register the function above as EventListener on PreSet and PreBind

    // This is called when form first init - not needed in this example
    #$builder->addEventListener(FormEvents::PRE_SET_DATA, $func); 

    // called just before validation 
    $builder->addEventListener(FormEvents::PRE_BIND, $func);  

}

答案 1 :(得分:0)

验证由Validator组件处理:http://symfony.com/doc/current/book/validation.html

表单层中的required选项用于控制HTML5 required属性,因此它不会为您更改任何内容,这是正常的。

您应该根据上面链接的文档配置验证层。

答案 2 :(得分:0)

找到了我在此发布的更好的解决方案:Disable backend validation for choice field in Symfony 2 Type

旧答案:

花了几个小时处理这个问题。这个选择 - 类型真的很烦人。我的解决方案与您的解决方案类似,可能会更短。当然它是一个黑客,但你能做什么......

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('place', 'choice'); //don't validate that

    //... more form fields

   //before submit remove the field and set the submitted choice as
   //"static" choices to make "ChoiceToValueTransformer" happy
   $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
        $data = $event->getData();
        $form = $event->getForm();
        if ($form->has('place')) {
            $form->remove('place');
        }

        $form->add('place', 'choice', array(
            'choices' => array($data['place']=>'Whatever'),
        ));
    });
}

答案 3 :(得分:0)

在表单类型类中添加此buildForm方法,以便您可以验证输入字段值,而不是从select字段值中选择;

$builder->addEventListener(
    FormEvents::PRE_SUBMIT,

    function (FormEvent $event) {
        $form = $event->getForm();

        if ($form->has('verified_city')) {
            $form->remove('verified_city');
            $form->add(
                'verified_city', 
                'text', 
                ['required' => false]
            )
        }
    }
);

答案 4 :(得分:-1)

Validations.yml中的更新

请以下列格式更新Validation.yml文件:在每个字段中设置组名称

 
         password:
            - NotBlank: { message: Please enter password ,groups: [Default]}
Update in Form Type /** * @param OptionsResolverInterface $resolver */ public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setDefaults(array( 'data_class' => 'RegistrationBundle\Entity\sf_members', 'validation_groups' => function(FormInterface $form){
$data = $form->getData();
$member_id = $data->getMemberId();

// Block of code; // starts Here :

if( condition == 'edit profile') { return array('edit'); } else { return array('Default'); } },
if( condition == 'edit profile') { return array('edit'); } else { return array('Default'); } },

实体更新