Mehrseitiges Formular per Ajax entwickeln

Aus UX-Gründen ist es sinnvoll, die Formular-Verarbeitung per AJAX umzusetzen. So bleibt der User nach dem Absenden des Formulars nicht nur auf der entsprechenden Seite, auch der unschöne Page-Reload entfällt.

In diesem Beispiel erstellen wir ein interaktives mehrseitiges Formular, das bei der Übermittlung zunächst die erforderlichen Felder überprüft. Danach sorgt das Formular dafür, dass sowohl der Webseitenbetreiber als auch der Benutzer eine E-Mail mit den eingereichten Daten erhalten.

Formular mit ACF erzeugen und als Block registrieren

In ACF haben wir zunächst die gewünschten Felder definiert. Für jede Seite des Formulars haben wir eine eigene Gruppe oder ein Repeater-Feld erstellt. Du kannst diese Felder auch ganz einfach in ACF importieren – wir haben sie bereits für dich in unserem GitHub-Repository vorbereitet. So kannst du direkt loslegen und dein Formular nach deinen Vorstellungen gestalten

Neue Homepage | Webdesign | Schwyz | Zug | Luzern | Altdorf | ulrich.digital
Jede Formularseite wird als Gruppe bzw. Repeater in ACF hinterlegt.
Digitaler Auftritt für Kultur und Wirtschaft | Webdesign | Schwyz | Zug | Luzern | Altdorf | ulrich.digital
Jede Gruppe wird mit der Klasse block_container versehen, um sie als separate Abschnitte des Formulars darzustellen.

Um das Formular im Backend bequem als Block einzufügen, muss die Feldgruppe nun als Block registriert werden. Dazu haben wir in unserem Theme unter blocks den Ordner multisite_ajax_form erstellt. In diesen Ordner legen wir folgende Dateien ab:

  • block.json
  • multisite_ajax_form.php
  • multisite_ajax_form.js
  • multisite_ajax_form_ajax.js
  • multisite_ajax_form.css

Die Registration deines Blocks erfolgt in der functions.php-Datei deines WordPress-Themas. Du verwendest den Hook acf/init, um die Funktion uldi_load_blocks() aufzurufen. Diese Funktion wiederum nutzt die Funktion register_block_type(), um deinen Block zu registrieren.

function uldi_load_blocks() {
    register_block_type(dirname(__FILE__) . '/blocks/multisite_ajax_form');
}
add_action('acf/init', 'uldi_load_blocks');

Eigenschaften des Blocks festlegen

In der Datei block.json legen wir nun die Metadaten unseres Blocks ab:

{
    "_comment": "Place your comments here.",
    "name": "multisite-ajax-form",
    "title": "Multisite-AJAX-Form",
    "description": "Place your description here.",
    "style": [
        "file:./multisite_ajax_form.css"
    ],
    "category": "formatting",
    "icon": "clipboard",
    "keywords": [],
    "acf": {
        "mode": "edit",
        "renderTemplate": "multisite_ajax_form.php"
    },
    "align": "full"
}

Dieses Beispiel verwendet nur eine Handvoll der verfügbaren Einstellungen. Die block.json Dokumentation von WordPress findest du hier, diejenige von ACF hier.

Formular-Block-Ausgabe

In der Datei multisite_ajax_form.php erzeugen wir Ausgabe des Formulars mithilfe der ACF-Funktion acf_form(). Stelle sicher, dass du die entsprechende ACF-Feldgruppe, die wir zuvor definiert haben, in der Option 'field_groups' angibst. Die verfügbaren Optionen für diese Funktion sind in der ACF-Funktion ausführlich beschrieben. Nach dem Formular geben wir zusätzlich zwei Nachrichten aus, die je nach erfolgreichem oder fehlgeschlagenem Versenden des Formulars erscheinen.

<?php 
acf_form([
    'field_groups' => ['group_63e6803ee1c1f'],
    'form_attributes' => array("class" => "multisite_ajax_form"),
    'id' => 'new-facility-request',
    'post_id'  => 'new_post',
    'submit_value' => "Anfragen"
]);
?>

<div class="msg_container">
    <div class="msg_success">Ihre Anfrage wurde erfolgreich gesendet.</div>
    <div class="msg_failed">Bitte füllen Sie alle erforderlichen Felder aus.</div>
</div>

Benutzer-Eingaben verarbeiten

Die Datei multisite_ajax_form.js verschiebt bestimmte Elemente im DOM, setzt Platzhaltertexte und verarbeitet vor allem die Benutzereingaben, wie zum Beispiel die Navigation zwischen den Formularseiten. Darüber hinaus erstellt sie für die letzte Formularseite ein Element mit der Klasse .summary, das eine Zusammenfassung der gemachten Eingaben enthält. Beim Absenden des Formulars wird dieses Element ausgelesen und per E-Mail versandt.

Formularseiten-Navigation

<form> Das <form>-Tag erhält das Data-Attribut form-step, welches den aktuellen Schritt repräsentiert. Bei jedem Klick auf den Vorwärts-Button wird dieses Attribut um 1 erhöht, und beim Klick auf den Zurück-Button verringert. Zusätzlich erhält dieses Tag die Klasse .is_first_step auf der ersten Formularseite und .is_last_step auf der letzten.

.form_container Alle Elemente mit dieser Klasse erhalten das Data-Attribute data-container-step. Diese Attribute werden mit fortlaufenden Nummern befüllt.

prev_next_step() Diese Funktion hat drei Zustände: "init", "prev" und "next". Im Zustand "init" wird das Formular auf die erste Seite zurückgesetzt, indem das Data-Attribut form-step des <form>-Tags auf 1 gesetzt wird. Im Zustand prev bzw. next wird der aktuelle Zähler an das Data-Attribut form-step des <form>-Tags übergeben. Wenn der Wert des Data-Attributs data-container-step eines Formular-Containers dem Wert des Data-Attributs form-step des Formulars entspricht, erhält der jeweilige Container die Klasse .current_container.

Summary

Um sicherzustellen, dass auf der letzten Formularseite eine Zusammenfassung der getätigten Eingaben angezeigt wird, werden alle Eingabefelder ausgelesen. Je nach Art des Feldes – Text, Number usw. – müssen die Werte unterschiedlich ausgelesen werden.

Es gibt auch einen Bereich mit einem Repeater-Feld, bei dem wir die Ausgabe für jede Zeile in einem eigenen Element haben wollten. Mit der Funktion repeater_check() wird das Attribut data-id für jede Zeile ausgelesen. Alle Repeater-Elemente im HTML-Element mit der Klasse .summary erhalten dann diesen Wert im Attribut data-repeater-row. Anschliessend werden alle Geschwister-Elemente, die denselben Wert für «data-repeater-row» haben, in ein Container-Element eingefügt.

Hier findest du die Datei multisite_ajax_form.

Ajax-Call

Sobald der Benutzer den Submit-Button klickt, wird der Inhalt aus dem Element mit der Klasse ".summary" der Variablen $my_content übergeben. Wenn der Benutzer die Bedingungen akzeptiert hat, wird der AJAX-Call ausgeführt und bei Erfolg das Element mit der Klasse ".msg_success" eingeblendet, Formular und Navigation ausgeblendet.

jQuery(document).ready(function ($) {

    $("form[id*='multipage-ajax-form-']").submit(function (e) {

        e.preventDefault();
      
        $this = $(this);
        // grab content
        $my_content = $(this).find(".summary").html();

        // Message-Container after form
        var my_msg_container = $(this).next(".msg_container");

        //  Bedingungen checked?
        if ($(this).find('.acf-field[data-name="bedingungen"] .acf-input label').hasClass('selected')) {
            $(my_msg_container).find(".msg_failed").css("display", "none");

            
            $.ajax({
                cache: false,
                type: 'POST',
                url: multisite_ajax_form.ajaxurl,
                data: {
                    action: 'multisite_ajax_form_ajax',
                    security: multisite_ajax_form.ajaxnonce,
                    content: $my_content
                },
                datatype: "html",

                success: function (data, textStatus, XMLHttpRequest) {

                    // Success Nachricht einblenden, nach 5 Sekunden wieder ausblenden
                    $(my_msg_container).find(".msg_success").fadeIn("slow").delay(5000).fadeOut("slow");

                    // close accordion 
                    $this.find(".acf-field-accordion.-open").removeClass("-open");
                    $this.find(".acf-accordion-content").css("display", "none");

                    // hide form navigation
                    $this.find(".form_prev_next_container").css("display", "none");
                },
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    console.log(errorThrown);
                }
            });
        }else{
            // show failed container
            $(my_msg_container).find(".msg_failed").fadeIn("slow").delay(5000).fadeOut("slow");
           
        }
    });
});

Aufruf der Ajax-Funktion für den Mail-Versand

In der functions.php-Datei rufen wir die Ajax-Funktion auf. Da es sich um ein Formular handelt, laden wir den ACF-Form-Head, der für die korrekte Darstellung des Formulars erforderlich ist. Anschliessend werden die beiden JavaScript-Dateien geladen. Schliesslich wird die Ajax-Funktion aufgerufen, die die Versendung der E-Mails ermöglicht.

/* =============================================================== *\
   add ACF Form Head
\* =============================================================== */
function uldi_add_acf_form_head(){
	if(!is_admin()){
		// wird bei allen Seiten geladen, keine andere Lösung möglich
		acf_form_head();
	}
}
add_action('init', 'uldi_add_acf_form_head', 10, 1);

/* =============================================================== *\
   add Frontend JavaScripts
\* =============================================================== */
function ud_enqueue_frontend_scripts(){
    // Multisite-Ajax-Form 
    wp_enqueue_script('block_multisite_ajax_form',  get_stylesheet_directory_uri() . "/blocks/multisite_ajax_form/multisite_ajax_form.js", array('jquery'), filemtime(get_template_directory() . "/blocks/multisite_ajax_form/multisite_ajax_form.js"), true);
    wp_enqueue_script('block_multisite_ajax_form_ajax',  get_stylesheet_directory_uri() . "/blocks/multisite_ajax_form/multisite_ajax_form_ajax.js", array('jquery'), filemtime(get_template_directory() . "/blocks/multisite_ajax_form/multisite_ajax_form_ajax.js"), true);
    wp_localize_script('block_multisite_ajax_form_ajax', 'multisite_ajax_form',array('ajaxurl'=> admin_url('admin-ajax.php'),'ajaxnonce'=> wp_create_nonce('multisite_ajax_form_validation')));
}
add_action('wp_enqueue_scripts', 'ud_enqueue_frontend_scripts');

/* =============================================================== *\ 
   Multisite AJAX Form > AJAX Action
\* =============================================================== */
add_action('wp_ajax_multisite_ajax_form_ajax', 'multisite_ajax_form_ajax_callback');
add_action('wp_ajax_nopriv_multisite_ajax_form_ajax', 'multisite_ajax_form_ajax_callback');
function multisite_ajax_form_ajax_callback() {

    // see in this file: wp_localize_script('block_multisite_ajax_form_ajax', 'multisite_ajax_form',array('ajaxurl'=> admin_url('admin-ajax.php'),'ajaxnonce'=> wp_create_nonce('multisite_ajax_form_validation')));
    check_ajax_referer('multisite_ajax_form_validation', 'security');

    $my_content = $_POST['content'];
    
    $to = 'support@ulrich.digital';
    $subject = 'Anlage-Anfrage';
    $body = $my_content;
    $headers = array('Content-Type: text/html; charset=UTF-8');
    
    wp_mail($to, $subject, $body, $headers);
    wp_die();
}

So, nun hast du es geschafft! Mit Hilfe von ACF und AJAX werden nun die Formulare auf deiner Webseite effizient und benutzerfreundlich verarbeitet, ohne dass es zu lästigen Seitenaktualisierungen kommt. Das Ergebnis ist ein reibungsloses und interaktives Formularerlebnis für deine Benutzer. Du kannst die benötigten Dateien für die Umsetzung hier finden und verwenden. Viel Erfolg bei der Implementierung!

1 Star2 Stars3 Stars4 Stars5 Stars (0)

Wir brauchen dein Feedback, um uns zu verbessern. Ob du uns jetzt für geniale Webgurus hältst oder für das Gegenteil, lass es uns wissen!

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