Flow-JavaScript-API für WordPress-Formulare

Flow stellt seine Browser-Laufzeitoberfläche unter dem globalen WP-Suite-Objekt bereit:

  • globalThis.WpSuite.plugins.flow
  • globalThis.WpSuite.plugins.flow.features

Bereitschaftshelfer

Wie andere WP-Suite-Plugins unterstützt Flow Bereitschaftshelfer für die Laufzeit, darunter:

  • onReady(cb)
  • availability()

Sie können außerdem auf der Seite ausgegebene Bereitschafts- und Fehlerereignisse überwachen:

  • wpsuite:flow:ready
  • wpsuite:flow:error

Beispiel:

window.addEventListener("wpsuite:flow:ready", () => {
const flow = globalThis.WpSuite?.plugins?.flow;
console.log("Flow is ready", flow?.status);
});

window.addEventListener("wpsuite:flow:error", (event) => {
console.error("Flow failed to initialize", event.detail);
});

Store-Zugriff

Flow stellt einen verzögert erstellten Store bereit über:

  • WpSuite.plugins.flow.features.store

Das ist für erweiterte Integrationen hilfreich, die auf den Laufzeitstatus oder die Konfiguration von Flow zugreifen müssen.

Flow stellt unter WpSuite.plugins.flow.modals außerdem einen Modal-Controller im Light DOM bereit.

Verfügbare Methoden:

  • register(modalElement, options?)
  • unregister(modalOrId)
  • open(modalId, options?)
  • close(modalId, returnValue?)
  • toggle(modalId, options?)
  • closeAll(returnValue?)
  • isOpen(modalId)
  • get(modalId)
  • registerAction(actionName, handler)
  • unregisterAction(actionName)

Unterstützte Lebenszyklusereignisse:

  • wps-flow-modal:before-open
  • wps-flow-modal:open
  • wps-flow-modal:before-close
  • wps-flow-modal:close
  • wps-flow-modal:ok
  • wps-flow-modal:cancel
  • wps-flow-modal:dismiss
  • wps-flow-modal:error

Über registerAction(actionName, handler) registrierte Aktionshandler können asynchron sein. Die Modal-Laufzeit wartet auf das zurückgegebene Promise, hält das Modal währenddessen geöffnet, versetzt es in einen Beschäftigt-Zustand, deaktiviert die üblichen Modal-Aktionsauslöser und markiert das aktuell laufende Auslöserelement mit data-wps-flow-pending="true" und aria-busy="true". Diese Ausstehend-Markierung ist bewusst allgemein gehalten und funktioniert sowohl mit Core-Button-Blöcken als auch mit eigenem Schaltflächen-Markup.

Gibt ein asynchroner Handler false zurück, wird das automatische Schließen übersprungen und das Modal bleibt geöffnet. Bei verwerfenden Schließpfaden wie der integrierten Schließen-Schaltfläche, Klicks auf den Hintergrund, Escape oder programmgesteuerten Schließaufrufen gibt die Laufzeit zusätzlich wps-flow-modal:dismiss aus.

Beispiel: Öffnen Sie ein Flow-Modal über eine benachbarte Gutenberg-Schaltfläche, schließe es über eine weitere Gutenberg-Schaltfläche im Modal und überwache das Schließereignis:

  1. Setzen Sie im Inspector des Flow-Modal-Blocks modalId auf newsletter-preferences.
  2. Fügen Sie neben dem Modal einen Core-Button-Block hinzu und setzen Sie dessen Advanced -> Additional CSS class(es) auf wps-flow-modal-open--newsletter-preferences.
  3. Fügen Sie im Modal-Inhalt einen weiteren Core-Button-Block hinzu und setzen Sie dessen Advanced -> Additional CSS class(es) auf wps-flow-modal-close.
  4. Überwache wps-flow-modal:close auf document.

WordPress wendet diese eigenen Klassen auf den gerenderten .wp-block-button-Wrapper an. Die Laufzeit führt den Auslöser daher vom angeklickten inneren Link oder der Schaltfläche auf diesen Wrapper zurück.

<!-- Neighboring core/button block -->
<div class="wp-block-button wps-flow-modal-open--newsletter-preferences">
<a class="wp-block-button__link wp-element-button">
Open preferences
</a>
</div>

<!-- Inside the Flow Modal block -->

<div class="wp-block-button wps-flow-modal-close">
<a class="wp-block-button__link wp-element-button">
Close popup
</a>
</div>

<script>
document.addEventListener("wps-flow-modal:close", (event) => {
const detail = event.detail ?? {};

if (detail.modalId !== "newsletter-preferences") {
return;
}

console.log("Flow modal closed", {
modalId: detail.modalId,
returnValue: detail.returnValue,
});

// Example: reset host-page UI or fire analytics here.
});
</script>

Für einen Core-Button-Block ist der Weg über CSS-Klassen meist die einfachste Integration, weil die Laufzeit Klicks auf .wps-flow-modal-open--{modalId} und .wps-flow-modal-close bereits delegiert. Eine .wps-flow-modal-close-Schaltfläche schließt das nächstgelegene Flow-Modal und gibt wps-flow-modal:close mit detail.returnValue === "close" aus.

Modalabhängige Galerie-Öffner

wps-flow-modal:open enthält das triggerElement, das den Dialog geöffnet hat. WpSuite.plugins.flow.modals.open(modalId, { triggerElement }) akzeptiert dieselbe Eingabe für programmgesteuertes Öffnen. Der Flow-Galerie-Block verwendet dieses Öffnerelement, um folgende optionale Hinweise aufzulösen:

  • wps-flow-gallery-target--{galleryId} oder data-wps-flow-gallery-target="{galleryId}"
  • wps-flow-gallery-index--N oder data-wps-flow-gallery-index="N"

Damit kann ein benachbarter Core-Bild- oder Core-Button-Block ein Modal öffnen und direkt ein bestimmtes Galeriebild anzeigen. Enthält das Modal nur eine Flow-Galerie, kann der Zielhinweis entfallen; der Index allein genügt.

<div class="wp-block-image wps-flow-modal-open--product-lightbox wps-flow-gallery-target--product-gallery wps-flow-gallery-index--2">
<figure class="wp-block-image size-large">
<img src="/images/product-side.jpg" alt="Product side view" />
</figure>
</div>
const triggerElement = document.querySelector(".hero-product-image");

globalThis.WpSuite.plugins.flow.modals.open("product-lightbox", {
triggerElement,
});

Formularbezogene Feldstandardwerte

Flow Core stellt auf WpSuite.plugins.flow außerdem Hilfsmethoden für formularbezogene Feldstandardwerte bereit:

  • setFormFieldDefaultValue(formId, fieldName, value)
  • setFormFieldDefaultValues(formId, values)
  • clearFormFieldDefaultValues(formId)
  • getFormFieldDefaultValue(formId, fieldName)
  • getFormFieldDefaultValues(formId)

Jeder Helfer gibt ein Promise zurück, da Flow vor dem Lesen oder Schreiben von Werten auf seinen internen Store wartet.

Beispiel:

await globalThis.WpSuite.plugins.flow.setFormFieldDefaultValues("newsletter-footer", {
email: "user@example.com",
utm_source: "spring-campaign",
});

Wenn Sie lieber direkt mit dem Store arbeiten, verwenden Sie dieselben Aktionen über features.store und wp.data.dispatch(...):

const store = await globalThis.WpSuite.plugins.flow.features.store;
const actions = globalThis.wp.data.dispatch(store);

actions.setFormFieldDefaultValue("newsletter-footer", "email", "user@example.com");

Diese APIs schreiben formularbezogene Standardwerte in den gemeinsamen Flow-Store. Gerenderte Flow-Formulare lösen diese Werte anhand der formId auf und wenden sie an.

Zeichenketteninterpolation zur Laufzeit

Einige Zeichenketteneinstellungen der Flow-Laufzeit unterstützen Token-Interpolation. Flow ersetzt dabei {{...}}-Platzhalter vor der Verwendung der Zeichenkette durch Werte aus dem aktuellen Seitenkontext.

Das ist für Einstellungen wie einen formularbezogenen endpointPath oder den apiEndpoint eines API-gestützten Optionsfelds hilfreich, wenn die endgültige URL von der aktuellen Seite, der Abfragezeichenkette, globalen Werten der Hostseite oder aktuellen Formularwerten abhängt.

API-gestützte Optionsfelder können ihren anfänglichen Auswahlstatus außerdem aus jedem Antwortelement ableiten. Verwenden Sie apiSelectedPath, um ein Kennzeichen oder Statusfeld pro Element zu lesen, und optional apiSelectedValue, wenn ein Element nur bei einem bestimmten Wert wie SUBSCRIBED als ausgewählt gelten soll. Dies ist besonders für checkbox-group hilfreich und gilt auch für die Felder select, radio und tags.

Bei benutzerdefinierten Formularübermittlungen kann die Endpunkt-URL mit einer endpointMethod von GET, POST, PUT oder PATCH kombiniert werden. Ist keine Methode konfiguriert, verwendet Flow POST. Bei GET sendet Flow serialisierte Feldwerte als URL-Abfrageparameter statt als JSON-Anfrageinhalt. Über endpointHeaders, das in Blockattributen als JSON-Objektzeichenkette gespeichert wird, können Sie zusätzliche browserseitige Anfrage-Header anhängen. Flow führt sie mit dem vorhandenen reCAPTCHA-Anfrage-Header zusammen. Headerwerte unterstützen dieselben Laufzeit-Interpolationstokens wie endpointPath, werden jedoch als einfache Zeichenketten statt als URL-codierte Pfadsegmente aufgelöst.

Werden Laufzeittokens in endpointPath oder im apiEndpoint eines API-gestützten Felds verwendet, URL-codiert Flow dynamische Feld- und Abfragezeichenkettenwerte, bevor es sie in die endgültige URL einfügt.

Unterstützte Tokenfamilien:

  • {{email}}, {{fullName}}, {{message}} usw. für aktuelle Formularfeldwerte nach Feldname
  • {{query.foo}} — Abfragezeichenkettenwerte aus window.location.search
  • {{location.href}}, {{location.origin}}, {{location.pathname}}, {{location.search}}, {{location.hash}}, etc.
  • {{wp.postId}}, {{wp.postSlug}}, {{wp.postType}}, {{wp.postTitle}}, {{wp.postUrl}}
  • {{wpsuite.apiBaseUrl}}, {{wpsuite.siteSettings.siteId}} usw. als Kurzform für das globale Objekt WpSuite.*
  • {{global.MyApp.config.formsBaseUrl}} für jeden anderen über globalThis erreichbaren primitiven Wert
  • {{field.email}}, {{field.fullName}} usw. als ausdrücklicher Alias für aktuelle Formularfeldwerte

Beispiele:

{{location.origin}}/contact
https://api.example.com/forms?source={{location.pathname}}
{{wpsuite.apiBaseUrl}}/contact
{{global.MyApp.forms.submitUrl}}
{{wpsuite.contactApiBaseUrl}}/{{email}}

Wichtige Einschränkungen:

  • Interpolation führt kein beliebiges JavaScript aus. Sie liest nur Werte aus bekannten Laufzeitkontexten oder Eigenschaftspfaden auf globalThis.
  • Funktionsaufrufe, Ausdrücke und Bedingungen wie foo ? bar : baz werden nicht unterstützt.
  • Bei global.* und wpsuite.* muss der Wert bereits als primitiver Wert (string, number oder boolean) auf der Seite vorhanden sein, wenn Flow die Einstellung auflöst.
  • Tokens für aktuelle Formularfeldwerte sind nur in Laufzeitoberflächen verfügbar, die bereits Zugriff auf den Formularstatus haben, etwa gerenderte Formularfelder und API-gestützte Optionslader.

Funktionsentscheidung

In paketierten Integrationen stellt Flow über das Flow-Core-Modul außerdem Hilfsfunktionen wie waitForFlowReady(), getStore(), decideCapability() und resolveBackend() bereit. Diese Helfer sind nützlich, wenn Sie auf die Initialisierung warten oder entscheiden müssen, ob die aktuelle Website backendgestützte Funktionen verwenden kann.

Formularereignisse zur Laufzeit

Gerenderte Flow-Formulare geben für wichtige Laufzeitaktionen aufsteigende CustomEvent-Ereignisse aus. Sie können sie am Hostelement des Formulars oder auf document-Ebene überwachen, da die Ereignisse aufsteigen und die Shadow-Grenze überschreiten.

document.addEventListener("smartcloud-flow:submit-success", (event) => {
console.log("Flow submit success", event.detail);
});

document.addEventListener("smartcloud-flow:wizard-step-change", (event) => {
console.log("Wizard moved", event.detail);
});

Aktuelle Ereignisse:

  • smartcloud-flow:draft-saved
  • smartcloud-flow:draft-loaded
  • smartcloud-flow:draft-deleted
  • smartcloud-flow:ai-suggestion-accepted
  • smartcloud-flow:ai-suggestions-rejected
  • smartcloud-flow:submit-after-ai-accepted
  • smartcloud-flow:submit-success
  • smartcloud-flow:success-state-shown
  • smartcloud-flow:wizard-step-change
  • smartcloud-flow:return-to-form
  • smartcloud-flow:options-request-error
  • smartcloud-flow:error

Jedes spezifische Ereignis gibt zusätzlich ein allgemeines smartcloud-flow:state-change-Ereignis aus, dessen Feld detail.event den ursprünglichen Ereignisnamen enthält.

Häufige detail-Felder:

  • formId
  • action
  • submissionId
  • status
  • suggestionId
  • Assistentenmetadaten wie wizardPath, stepIndex, stepTitle und totalVisibleSteps

Bei Ladefehlern API-gestützter Felder kann detail außerdem fieldName, fieldType, requestMethod, errorType, message, status und responseText enthalten.

Beispiel: einen Fehler bei API-gestützten Optionen im JavaScript der Hostseite behandeln:

<div id="preferences-api-error" hidden></div>

<script>
const errorBox = document.getElementById("preferences-api-error");

document.addEventListener("smartcloud-flow:options-request-error", (event) => {
const detail = event.detail ?? {};

if (detail.formId && detail.formId !== "preferences-form") {
return;
}

const message =
typeof detail.message === "string" && detail.message.trim()
? detail.message.trim()
: "Unable to load options right now.";

if (errorBox) {
errorBox.textContent = message;
errorBox.hidden = false;
}

console.warn("Flow options request error", {
formId: detail.formId,
fieldName: detail.fieldName,
status: detail.status,
errorType: detail.errorType,
responseText: detail.responseText,
});
});

document.addEventListener("smartcloud-flow:submit-success", () => {
if (errorBox) {
errorBox.hidden = true;
errorBox.textContent = "";
}
});
</script>

Verwenden Sie detail.message für die Benutzeroberfläche. Behandle detail.responseText als Diagnose- und Debugdaten und zeige ihn Endbenutzern nicht direkt an.

Diese Ereignisebene ist der empfohlene Integrationspunkt, wenn eine äußere Anwendung Analysen, Conversion-Tracking, eigene Weiterleitungen oder Reaktionen der Hostseiten-Oberfläche benötigt.