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

时间:2015-12-03 12:43:33

标签: javascript php jquery ajax symfony

我需要使用symfony通过ajax存储来自表单的数据,而不是更新浏览器。此外,我需要你,如果字段中的错误可以以某种方式让他们响应该调用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来解决这个问题,我会永远感激,因为对于很多手册,我看到我仍然不太了解它。

非常感谢你。

3 个答案:

答案 0 :(得分:19)

我可以与您分享我在旧项目中使用的自定义解决方案,用于通过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
                }
            }
        });

希望这个帮助

答案 1 :(得分:3)

实际上,通过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
        }
    }
});

答案 2 :(得分:2)

使用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 {

                }
            }
        });
    });