【问题标题】:Symfony form validation errors are displayed twiceSymfony 表单验证错误显示两次
【发布时间】:2015-08-25 15:00:31
【问题描述】:

我需要一个简单的用户注册表格。表单验证按预期工作,除了来自回调约束的验证错误由于某种原因显示两次。

我在错误消息中插入了一个随机数,以查看回调是否被调用了一次或两次。 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()])
        ]);

    }

用于呈现表单的树枝模板是:

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

【问题讨论】:

    标签: php forms validation symfony


    【解决方案1】:

    您正在显示表单错误和表单小部件两次!

    你有

    <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() 函数,只显示错误和小部件而不是标签。
    • 然后把form_label()拿走,不要就不要渲染了。但是这样做比操作所提供的功能要容易得多。基本上它只是多一行代码。
    • 按照你的建议做是可行的,但它会涉及将表单的每个字段写入两次。这是我试图避免使用表单自定义的原因。
    • 顺便说一下,小部件只显示一次。
    • form_rest(form) 很棒的提示
    【解决方案2】:

    事实证明,{% form_theme form _self %} 功能只有在您的模板扩展了另一个模板时才能使用。

    所以我将 form_row 块放在另一个文件中并使用 {% form_theme form "otherfile.htmltwig"%} 效果很好。

    【讨论】:

    • 其实扩展 'base.html.twig' 也可以,而且更优雅
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多