Symfony表单验证错误显示两次

3
我需要一个简单的用户注册表单。表单验证可以正常工作,但是由回调约束产生的验证错误会因某种原因显示两次。
我在错误消息中插入了一个随机数字,以查看回调是否被调用一次或两次。这2个错误消息显示相同的随机数,因此回调很可能只被调用一次。
非常感谢任何帮助!
额外问题:“所有来自回调函数的错误都在表单的同一位置显示(如预期)。是否(轻松)可以指定应在哪个字段上显示验证错误?”
表单类型类的外观如下:
class RegisterType extends AbstractType{

static private $em;
static private $translator;

public function __construct( EntityManager $em , TranslatorInterface $translator){
    RegisterType::$em = $em;
    RegisterType::$translator = $translator;
}

public function buildForm(FormBuilderInterface $builder , array $options){
    $builder
    ->add('email','email',[
            'attr'=>['placeholder'=>RegisterType::$translator->trans('your.email')],
            'label'=>false ,
            'constraints'=>[new NotBlank() , new Assert\Email()]])
            ->add('password','password',[
                    'attr'=>['placeholder'=>RegisterType::$translator->trans('your.password')],
                    'label'=>false ,
                    'constraints'=>[new NotBlank()]])
                    ->add('confirmPassword','password',[
                            'attr'=>['placeholder'=>RegisterType::$translator->trans('confirm.password')],
                            'label'=>false ,
                            'constraints'=>[new NotBlank()]]);
}

public function getName(){
    return 'register';
}

public function configureOptions( OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
            'constraints' =>array( new Assert\Callback( array('AppBundle\Forms\Type\RegisterType','validateForm' )  )),
    ));
}

static public function validateForm(array $data, ExecutionContextInterface $context){
    if($data['email']){
        $user = RegisterType::$em->getRepository('AppBundle:User')->findByEmail($data['email']);
        if($user){
            $context->buildViolation('email.is.used'.rand())->addViolation();
        }
    }

    if($data['password'] && $data['confirmPassword']){
        if($data['password'] != $data['confirmPassword']){
            $context->buildViolation('password.confirm.failed')->addViolation();
        }
    }
}

表单在控制器中的调用方式如下:
        public function registerFormAction(Request $request){

        $form = $this->createForm('register');
        $form->handleRequest($request);

        if($form->isValid()){
            //TODO
        }

        return new JsonResponse(['success'=>false,
                                 'message'=>$this->renderView('AppBundle:Security:register.html.twig' , ['form'=>$form->createView()])
        ]);

    }

用于呈现表单的Twig模板为:

{% form_theme form _self %}
{%- block form_row -%}
    <div class = "form-group">
        {{- form_errors(form) -}}
        {{- form_widget(form) -}}
    </div>
{%- endblock form_row -%}
{{ form(form) }}
2个回答

6

您的表单错误和表单小部件重复显示了两次!

您有

<div class = "form-group">
    {{- form_errors(form) -}}  //displays all form errors
    {{- form_widget(form) -}}  //displays all form widgets (not the labels!)
</div>

并且

{{ form(form) }}  //displays the whole form

在你的代码中。

为什么不直接自己渲染表单,这样你还可以设置表单错误的显示位置。

{{ form_start(form) }}
    <div class="form-group">
        {{ form_errors(form.username) }}  //errors for the "username" field of your form
        {{ form_label(form.username) }}   //labels for the "username" field of your form
        {{ form_widget(form.username) }}  //formfields for the "username" field of your form
    </div>
{{ form_end(form) }}

此外,还有一个名为 form_rest(form) 的 Twig 函数,它将显示尚未手动渲染的所有表单字段!

嗯,我的意图是使用form_row块覆盖form_row()函数,以仅显示错误和小部件而不是标签。 - Ward Beullens
然后去掉 form_label(),如果你不想渲染它,就不要渲染。但是这样做比操作提供的函数更容易。基本上每个函数只需要再加一行代码。 - KhorneHoly
按照您建议的做法是可行的,但这将涉及到对表单的每个字段进行两次编写。这正是我试图避免使用表单定制的原因。 - Ward Beullens
顺便提一下,小部件只会显示一次。 - Ward Beullens
1
form_rest(form) 是一个很好的技巧。 - lookbadgers

1
原来,{% form_theme form _self %} 功能仅能在你的模板继承另一个模板时使用。

enter image description here

所以我将form_row块放在另一个文件中,并使用{% form_theme form "otherfile.htmltwig"%},这个方法运行良好。


实际上,扩展“base.html.twig”同样有效且更加优雅。 - Ward Beullens

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