Form Validation in symfony from ajax call Form Validation in symfony from ajax call symfony symfony

Form Validation in symfony from ajax call


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

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:

        $.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


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.

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


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

 /**     * 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

$("#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 {                }            }        });    });