Updated: Form Serialization mit Ajax

Vor einiger Zeit hatte ich bereits einen Beitrag zur Form Serialization mit Ajax geschrieben. Dies war jedoch sehr umständlich im Vergleich zu einer anderen Methode. Es geht nämlich noch viel einfacher! Updated: Form Serialization mit Ajax, die Zweite!

Verbesserungen

Anstatt das Objekt für den Datenaustausch per JavaScript manuell zusammenzusetzen, kann auch die Klasse FormData() verwendet werden. Seit HTML5 ist dieses ein browser-weit verfügbares JavaScript Objekt, das für genau für diesen Zweck entwickelt wurde: Elemente aus einem Formular per XmlHttpRequest zu verschicken.

var form = $('form'),
    target = form.attr('action'),
    submits = form.find('[type=submit]'),
    submitted = null
;

// register, which submit button was used to send the form
// this is important for Symfony!
submits.click(function() {
    submitted = this;
});

// on submit
form.submit(function(e) {
    e.preventDefault();

    // get the form content from form itself
    var callback = new FormData(this);

    // add a submit value for Symfony
    if (null !== submitted) {
        callback.append($(submitted).attr('name'), '');
    }

    // send the data to symfony controller
    $.ajax({
        url: target,
        method: "POST",
        data: callback,
        contentType: false,             // this is new!
        processData: false,             // this is new!
        success: function (data) {
            // do something on success
        },
        error: function (data) {
            // do something on failure
        }
    });
});

Sollte ein Submit-Button im Formular deklariert sein, hat diese Umstellung hat außerdem zur Folge, dass wir im zweiten Controller nicht mehr manuell „submitten“ müssen. Stattdessen wird wie gewohnt die Methode handleRequest() verwendet.

/**
 * Create the form to create a feature
 * @Route("/create-exec/{featureID}", name="feature_create_exec")
 * @param Request $request
 * @return JsonResponse
 */
public function featureCreateExecAction(Request $request)
{
    // was it sent with Ajax?
    if (false === $request->isXmlHttpRequest()) {
        return $this->json([
            'failure' => 'This request was not sent from Ajax!',
        ]);
    }

    // create the form again
    $form = $this->createForm(FeatureForm::class, new FeatureEntity());

    // handle the request as usual
    $form->handleReqeust($request);

    if ($form->isSubmitted() && $form->isValid()) {
        // e.g. save data to DB

        return $this->json([
            'success' => 'The feature was created successfully',
        ]);
    }

    // form is not valid
    return $this->featureListAction([
        'failure' => 'The form data is not valid!',
    ]);
}

Fazit

Diese Form der Implementierung spart nicht nur Quellcode, sie ist zudem robuster! Die erste Form hatte leider keine Übertragung von <input type="file"> Elementen erlaubt. Das FormData() beherrscht diese sehr wohl! Die Verwendung von handleRequest() ist außerdem sicherer, auch wenn wir den geklickten Button eventuell selbst hinzufügen müssen.

Kurzum: Die „Updated Form Serialization mit Ajax“ Methode sollte definitiv gegenüber der anderen Variante verwendet werden!

Kommentar hinterlassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.