【问题标题】:Form Validation in symfony from ajax call来自ajax调用的symfony中的表单验证
【发布时间】:2016-03-08 02:12:35
【问题描述】:

我需要通过 ajax 存储来自 symfony 表单的数据,调用我不要更新浏览器。此外,如果字段中出现错误,我需要您以某种方式让它们响应该调用 Ajax 并显示我的表单错误,所有这些都无需刷新页面。

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

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

控制器:

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调用:(我不明白如何处理错误部分)

$('.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;
});

我看到一些从控制器返回 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;
}

如果您能帮助我更多地了解如何使用 Ajax 来解决这个问题,我将永远感激不尽,因为对于我看过的许多手册我仍然不太了解。

非常感谢您。

【问题讨论】:

    标签: javascript php jquery ajax symfony


    【解决方案1】:

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

    在控制器动作中:

     ....
     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;
        }
    

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

    希望有帮助

    【讨论】:

    • 嗨@Matteo,再次非常感谢你的代码,它在ajax调用中完美地出错了,但是我的表单有问题我有另一个嵌入式代码表单,但它没有返回嵌入表单的错误字段。您知道如何将它添加到调用中返回的数组的关键日期吗?我以这种方式显示Estudent 表单的两个字段,其中有另一个嵌入表单Responsible(父母):@987654325 @
    • 我已经阅读了一些需要添加cascade_validation=true 来验证嵌入表单的内容,但不知道该放在哪里。难道是我需要验证它?
    • 嗨@Matteo,你能帮我吗?我无法解决我的问题验证嵌入的表单
    • 嗨@Joseph,我不知道我的解决方案是否能适应您的需要。尝试在getErrorMessages 中调查它如何处理子表单情况以及如何将其应用于 js 错误管理。抱歉,我的项目中不需要这个....
    • @Matteo,谢谢你,它运作良好。我想在单独的视图 errors.html.twig 中获取错误并在 JsonResponse 中返回它。我可以用 jquery 显示视图,但不明白如何将这个 javascript 循环 for (var key in data.data) { $(form.find('[name*="'+key+'"]')[0]).before('&lt;ul class="errors"&gt;&lt;li&gt;'+data.data[key]+'&lt;/li&gt;&lt;/ul&gt;'); } 更改为树枝代码。我试过这个但不起作用{% for error in data %} {{ error }} {% endfor %}
    【解决方案2】:

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

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

    在控制器中,如果它没有验证,你可以只返回渲染的表单:

    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(),
            ]);
        }
        // ...
    }
    

    然后在您的 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
            }
        }
    });
    

    【讨论】:

    • 不错的技巧,但是如何在控制器中添加这个 data.success 呢?
    • 您可以将“成功”项添加到您在控制器中返回的 JSON 数组中,但这并不重要。您也可以像在最佳答案中一样使用“结果”。只是确定是否需要显示验证错误。
    【解决方案3】:

    使用 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);
        }
    

    还有 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 {
    
                    }
                }
            });
        });
    

    【讨论】:

    • 您在这里验证了两次表单,handleRequest 已经验证了表单是否已提交。你可以使用$form-&gt;getErrors()
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-15
    • 2021-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-11
    相关资源
    最近更新 更多