Formularvalidierung in Symfony vom Ajax-Aufruf

Lesezeit: 7 Minuten

Benutzer-Avatar
Joseph

Ich muss Daten aus einem Formular mit Symfony über einen Ajax-Aufruf speichern, um den Browser nicht zu aktualisieren. Außerdem brauche ich Sie im Falle von Fehlern in den Feldern, um sie irgendwie als Antwort auf diesen Aufruf von Ajax zu bekommen und meine Formularfehler anzuzeigen, alles ohne die Seite zu aktualisieren.

Ich habe ein Formular mit Symfony-Asset, um Felder zu validieren und alles perfekt zu machen, wenn ein Ajax-Aufruf ausgeführt wird, die Daten gespeichert oder die Seite mit Fehlern aktualisiert werden, aber ich brauche dasselbe, ohne die Seite zu aktualisieren.

Dann habe ich einen Teil des Codes eingefügt, den ich verwende:

Regler:

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-Aufruf:(Ich verstehe nicht, wie ich mit dem Fehlerteil umgehen soll)

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

Ich habe gesehen, dass einige eine JsonResponse vom Controller zurückgeben und Ajax verwenden, aber ich beginne mit Ajax und weiß nicht, wie ich es verwenden soll. Dann gebe ich den Code ein, den ich meine:

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

Wenn Sie mir helfen könnten, mehr zu verstehen, wie Ajax verwendet wird, um dieses Problem zu lösen, bin ich Ihnen unendlich dankbar, denn für viele Handbücher, die ich gesehen habe, verstehe ich es immer noch nicht gut.

Vielen Dank im Voraus.

Ich kann Ihnen eine benutzerdefinierte Lösung mitteilen, die ich in einem alten Projekt verwende, um Fehler in Formularen zu verwalten, die per Ajax-Aufruf übermittelt wurden.

In der Controller-Aktion:

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

Und der js-Code sieht so aus: Auf der Client-Seite:

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

Ich hoffe das hilft

  • Hallo @Matteo, Nochmals vielen Dank für den Code, es hat perfekt funktioniert, Fehler im Ajax-Aufruf zu bekommen, aber ich habe ein Problem mit meinem Formular. Ich habe ein anderes eingebettetes Codeformular und es hat die Felder mit Fehlern dieses eingebetteten Formulars nicht zurückgegeben . Wissen Sie, wie ich es zum Schlüsseldatum des Arrays hinzufügen könnte, das beim Aufruf zurückgegeben wird? Ich zeige die beiden Felder des Formulars Estudent die eine andere eingebettete Form hat Responsible (Eltern) auf diese Weise: ->add('responsiblee1', new PadresType(),array('label' => 'Mother')) ->add('responsible2', new PadresType(),array('label' => 'Father'))

    – Joseph

    4. Dezember 2015 um 1:03 Uhr


  • Ich habe gelesen, dass einige hinzugefügt werden müssen cascade_validation=true für die Validierung des eingebetteten Formulars erfolgt, wüsste aber nicht, wo es hingehört. Könnte es das sein, was ich brauche, um es zu validieren?

    – Joseph

    4. Dezember 2015 um 10:10 Uhr


  • Hallo @Matteo, kannst du mir helfen? Ich kann mein Problem nicht lösen, indem ich das eingebettete Formular validiere

    – Joseph

    6. Dezember 2015 um 15:41 Uhr

  • Hallo @Joseph, ich weiß nicht, ob sich meine Lösung an Ihre Bedürfnisse anpassen kann. Versuchen Sie, in der nachzuforschen getErrorMessages wie es mit der Unterformularsituation umgeht und wie es auf das js-Fehlermanagement angewendet wird. Entschuldigung, aber ich habe das nicht in meinem Projekt benötigt ….

    – Matteo

    6. Dezember 2015 um 16:43 Uhr

  • @Matteo, danke, es funktioniert gut. Ich möchte Fehler in einer separaten Ansicht abrufen errors.html.twig und in der JsonResponse zurückgeben. Ich kann das tun, um die Ansicht mit jquery anzuzeigen, kann aber nicht verstehen, wie man diese Javascript-Schleife ändert for (var key in data.data) { $(form.find('[name*="'+key+'"]')[0]).before('<ul class="errors"><li>'+data.data[key]+'</li></ul>'); } zum Twig-Code. Ich habe das versucht, aber es funktioniert nicht {% for error in data %} {{ error }} {% endfor %}

    – Haus

    12. April 2016 um 12:23 Uhr

Es gibt tatsächlich eine viel einfachere Möglichkeit, Formularvalidierungsfehler beim Senden eines Formulars über Ajax zu rendern. Bei beiden obigen Antworten müssen Sie die Fehlermeldungen manuell an die richtigen Felder usw. anhängen.

Da die Frage alt ist, verallgemeinere ich etwas aus Ihrem speziellen Fall für diejenigen, die mit einem ähnlichen Problem hierher kommen:

Im Controller können Sie das gerenderte Formular einfach zurückgeben, wenn es nicht validiert wird:

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

Dann können Sie in Ihrem Ajax-Aufruf den zurückgegebenen HTML-Code (einschließlich aller Validierungsfehlermeldungen) wieder in Ihr Formular einfügen. Unten ersetze ich nur den Inhalt des Formulars, sodass alle an das Formular selbst angehängten Handler intakt bleiben.

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

  • netter Trick, aber wie fügen Sie diese data.success in den Controller ein?

    – Junger Herr

    12. Juni 2021 um 12:47 Uhr

  • Sie können dem JSON-Array, das Sie in Ihrem Controller zurückgeben, ein „Erfolgs“-Element hinzufügen, aber das spielt keine Rolle. Sie können auch “Ergebnis” wie in der oberen Antwort verwenden. Es dient nur dazu festzustellen, ob Sie Validierungsfehler anzeigen müssen.

    – SimonW

    13. Juni 2021 um 17:05 Uhr

Mit Symfony 3 und dem Error Validator können Sie Ihre Ajax-Anfrage wie folgt parsen:

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

Und 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 {

                }
            }
        });
    });

  • Sie validieren das Formular hier zweimal, handleRequest validiert das Formular bereits, wenn es gesendet wird. Sie können verwenden $form->getErrors()

    – Riki137

    7. Februar 2019 um 10:52 Uhr

1017860cookie-checkFormularvalidierung in Symfony vom Ajax-Aufruf

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy