Symfony2 - 动态表单选项 - 验证移除

13

我有一个下拉表单元素。最开始它是空的,但是在用户进行一些操作后,通过JavaScript填充值。这一切都可以正常工作。但是当我提交表单时,它始终返回验证错误此值无效。

如果我将项目添加到表单代码中的选择列表中,它将验证通过,但是我正在尝试动态填充它,并且预先将项目添加到选择列表中不起作用。

我认为问题是因为表单正在针对一个空的项目列表进行验证。我根本不想验证列表。我已将验证要求设置为false。我将选择类型切换为文本,这样总是通过验证。

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

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

这里有一个类似的问题,但未得到答复。
Symfony 2中验证动态加载的选项

假设您不知道所有可用的选择项。它可以从外部网络来源加载吗?

5个回答

7

经过很长时间的试错,我们发现解决方案。你需要添加一个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);  

}

我遇到了同样的问题,我使用DataTransformer来解决它,但没有成功,所以我将使用这种方法。由于数据是通过使用AJAX调用在控制器中构建的,那么我该如何填充$choices数组呢?有什么建议吗? - ReynierPM
感谢您的回答。这种方法的更详细的示例(虽然使用PRE_SUBMIT):http://showmethecode.es/php/symfony/symfony2-4-dependent-forms/ - frumious
来自Symfony文档的一个微妙不同的例子(仅在提交主字段后使用POST_SUBMIT将次要字段添加到表单中):http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html#cookbook-form-events-submitted-data - frumious

0
将以下内容添加到表单类型类中的buildForm方法内,以便您可以验证输入字段值而不是选择字段值:

在你的表单类型类中的buildForm方法内添加以下代码,这样你就可以验证输入字段的值而不是从下拉列表中选择一个值:

$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]
            )
        }
    }
);

0

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

表单层中的required选项用于控制HTML5的required属性,因此它不会对您产生任何影响,这是正常的。

在此处应根据上面链接的文档配置验证层。


我不确定你所说的配置验证层是什么意思? - Robbo_UK
我已经阅读了文档并尝试添加最小值为0,最大值为255的验证,但它不起作用。它仍然只想要来自预设列表的选项。 - Robbo_UK
好的,我想这个链接可能会对你有所帮助:http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html。 - William Durand
3
我希望您能翻译以下内容: 我只想禁用似乎绕了很多弯路并使它变得比必要复杂的验证。 - Robbo_UK

0
发现了更好的解决方法,已发布在这里:Symfony 2 Type中为选择字段禁用后端验证

旧答案:

刚刚花了几个小时解决那个问题。这种选择类型真的很烦人。我的解决方案与你的类似,可能有点短。当然,这只是一个 hack,但你能做什么呢...

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'),
        ));
    });
}

-1

在 Validations.yml 中进行更新

Kindly update the Validation.yml file in the below format : setting the group names in the each field

 
         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();

// 代码块; // 从这里开始:

if (condition == '编辑个人资料') { return array('编辑'); } else { return array('默认'); }
},

实体更新 /** * @var string * * @ORM\Column(name="password", type="text") * @Assert\Regex( * pattern="/(?i)^(?=.[a-zA-Z])(?=.\d).{8,}$/", * match=true, * message="您的密码必须至少包含一个数字和一个字母,且长度不少于8个字符", * groups={"Default","edit"} * ) */
private $password;


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接