Updated: Form Serialization mit Ajax
An alle, die zuerst meinen alten Beitrag zur „Form Serialization mit Ajax“ gelesen haben: Es geht doch auch viel einfacher!!!
Verbesserungen
Anstatt das übersendbare Objekt per JavaScript manuell zusammenzusetzen, kann auch die Klasse FormData() verwendet werden. Seit HTML5 ist dieses ein browserweit verfügbares JavaScript Objekt, das für genau einen WZeck entwickelt wurde: Elemente aus einem Formular per XmlHttpRequest zu verschicken. Unsere Implementierung ändert sich wie folgt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
var form = $('form'); var target = form.attr('action'); var submits = form.find('[type=submit]'); var 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 // simple as that! 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 } }); }); |
Diese Umstellung hat außerdem zur Folge, dass wir im zweiten Controller nicht mehr manuell „submitten“ müssen, sondern stattdessen – wie gewohnt – die Methode handleRequest() verwenden können:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
/** * 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 send 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()) { // do whatever is needed // 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 manuell eingeben.
Kurzum: Diese Methode sollte definitiv gegenüber der anderen Variante verwendet werden!