javascript 来自ajax调用的symfony中的表单验证

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34066421/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 17:12:06  来源:igfitidea点击:

Form Validation in symfony from ajax call

javascriptphpjqueryajaxsymfony

提问by Joseph

I need to store data from a form with symfony through an ajax call me not to update the browser. Also I need you in case of errors in the fields can somehow get them in response to that call Ajax and to show my form errors, all without refreshing the page.

我需要通过 ajax 调用 symfony 来存储表单中的数据,不要更新浏览器。另外,我需要你,以防字段中的错误可以以某种方式让它们响应那个调用 Ajax 并显示我的表单错误,所有这些都不需要刷新页面。

I have a form with symfony asset to validate fields, and make everything perfect if ajax call is performed, stores the data or updates the page showing errors, but I need that same without refreshing the page.

我有一个带有 symfony 资产的表单来验证字段,并在执行 ajax 调用、存储数据或更新显示错误的页面时使一切变得完美,但我需要相同的内容而不刷新页面。

Then I put some of the code I'm using:

然后我放了一些我正在使用的代码:

Controller:

控制器:

public function createAction(Request $request)
{
    $entity = new Student();
    $form = $this->createCreateForm($entity);
    $form->handleRequest($request);

    if ($form->isValid()) {
        $em = $this->getDoctrine()->getManager();
        $em->persist($entity);
        $em->flush();

        return $this->redirect($this->generateUrl('student_show', array('id' => $entity->getId())));
    }

    return $this->render('BackendBundle:Student:new.html.twig', array(
        'entity' => $entity,
        'form'   => $form->createView(),
    ));
}

ajax call:(I do not understand how to handle the error part)

ajax调用:(我不明白如何处理错误部分)

$('.form_student').submit(function(event) {
   event.preventDefault();

  $.ajax({
    type: 'POST',
    url: Routing.generate('student_create'),
    data: $(this).serialize(),

    success: function(data) {

      //clean form
      cleanForm($(this));

      //show success message
      $('#result').html("<div id='message'></div>");
      $('#message').html("<h2> student created</h2>").hide();
      $('#message').fadeIn('slow').delay(5000).fadeOut('slow');
      event.stopPropagation();   
    },
    error: function (xhr, desc, err) 
      {
        alert("error");
      }
    })
  return false;
});

I've seen some return a JsonResponse from the controller and use Ajax, but I'm starting with Ajax and I do not know how to use it. Then I put the code I mean:

我见过一些从控制器返回 JsonResponse 并使用 Ajax,但我从 Ajax 开始,我不知道如何使用它。然后我把我的意思的代码:

 if ( $request->isXmlHttpRequest() ) {

    if ($form->isValid()) {
     //...
     return new JsonResponse(array('message' => 'Success!'), 200);
    }

    $response = new JsonResponse(array(
    'message' => 'Error',
    'form' => $this->renderView('BackendBundle:student:new.html.twig',
            array(
        'entity' => $entity,
        'form' => $form->createView(),
    ))), 400);

  return $response;
}

If you could help me understand more how to use Ajax to solve this problem, I eternally grateful, because for many manuals I've seen I still do not understand it well.

如果你能帮助我更多地了解如何使用Ajax来解决这个问题,我永远感激,因为我看了很多手册我还是不太明白。

Thank you very much in advance.

非常感谢您提前。

回答by Matteo

I can share with you a custom solution i use in an old project for manage error on form submitted via ajax call.

我可以与您分享我在旧项目中使用的自定义解决方案,用于管理通过 ajax 调用提交的表单上的错误。

In the controller action:

在控制器动作中:

 ....
 if ( $request->isXmlHttpRequest() ) {

        if (!$form->isValid()) {
                return array(
            'result' => 0,
            'message' => 'Invalid form',
            'data' => $this->getErrorMessages($form)
        );

            // Do some stuff
           return array(
            'result' => 1,
            'message' => 'ok',
            'data' => ''
         }

}
    // Generate an array contains a key -> value with the errors where the key is the name of the form field
    protected function getErrorMessages(\Symfony\Component\Form\Form $form) 
    {
        $errors = array();

        foreach ($form->getErrors() as $key => $error) {
            $errors[] = $error->getMessage();
        }

        foreach ($form->all() as $child) {
            if (!$child->isValid()) {
                $errors[$child->getName()] = $this->getErrorMessages($child);
            }
        }

        return $errors;
    }

And the js code is something like: In the client side:

而js代码是这样的:在客户端:

        $.ajax({
            url: ...,
            data: ....,
            type: "POST",
            success: function(data) {
                if(data.result == 0) {
                    for (var key in data.data) {
                        $(form.find('[name*="'+key+'"]')[0]).before('<ul class="errors"><li>'+data.data[key]+'</li></ul>');
                    }
                } else {
                // Submit OK
                }
            }
        });

hope this help

希望这有帮助

回答by SimonW

There is actually a much easier way to render form validation errors when submitting a form via ajax. Both the answers above require you to manually attach the error messages to the right fields, etc.

通过ajax提交表单时,实际上有一种更简单的方法来呈现表单验证错误。上面的两个答案都要求您手动将错误消息附加到正确的字段等。

Since the question is old, I will generalize a bit from your specific case for those who come here with a similar problem:

由于这个问题很老,我将从您的具体案例中为那些遇到类似问题的人概括一下:

In the controller, you can just return the rendered form if it does not validate:

在控制器中,如果未验证,您可以只返回呈现的表单:

public function createAction(Request $request)
{
    $form = $this->createForm(StudentType::class);
    $form->handleRequest($request);

    if ($form->isSubmitted() && !$form->isValid()) {
        return $this->render('new.html.twig', [
            'form' => $form->createView(),
        ]);
    }
    // ...
}

Then in your ajax call, you can take the html that gets returned (including any validation error messages) and plug it back into your form. Below I replace just the contents of the form, so any handlers attached to the form itself stay intact.

然后在您的 ajax 调用中,您可以获取返回的 html(包括任何验证错误消息)并将其插入到您的表单中。下面我只替换表单的内容,因此附加到表单本身的任何处理程序都保持完整。

$.ajax({
    url: ...,
    data: ....,
    type: "POST",
    success: function(data) {
        if(!data.success) { // undefined here, set to true in controller the form is valid
            var innerHTML = $(data).find('#appbundle_student').html();
            $('#appbundle_student').html(innerHTML);
        } else {
            // Submit OK
        }
    }
});

回答by Vince Verhoeven

With symfony 3 and the error validator you can parse your Ajax request like this:

使用 symfony 3 和错误验证器,您可以像这样解析您的 Ajax 请求:

 /**
     * Create new student (ajax call)
     * @Method("POST")
     * @Route("/student/create", name"student_create")
     * @param Request $request
     * @return JsonResponse
     */
    public function createAction(Request $request)
    {

        $student = new Student();
        $form = $this->createForm(CreateStudentType::class, $student);
        $form->handleRequest($request);
        $errors = array();

        if ($form->isSubmitted()) {
            $validator = $this->get('validator');
            $errorsValidator = $validator->validate($student);

            foreach ($errorsValidator as $error) {
                array_push($errors, $error->getMessage());
            }


            if (count($errors) == 0) {
                $em = $this->getDoctrine()->getManager();
                $em->persist($student);
                $em->flush();

                return new JsonResponse(array(
                    'code' => 200,
                    'message' => 'student toegevoegd',
                    'errors' => array('errors' => array(''))),
                    200);
            }

        }

        return new JsonResponse(array(
            'code' => 400,
            'message' => 'error',
            'errors' => array('errors' => $errors)),
            400);
    }

And jquery ajax

和 jquery ajax

$("#createForm").submit(function(e) {

        e.preventDefault();
        var formSerialize = $(this).serialize();

        var url = location.origin + '/web/app_dev.php/student/create';
        $.ajax({
            type: "POST",
            url: url,
            data: formSerialize,
            success: function (result) {
                console.log(result);
                if (result.code === 200) {
                    // refresh current url to see student
                } else {

                }
            }
        });
    });