/** * VITEC – Structured Data generator button (FormEngine fieldWizard). * EXT:vitec/Resources/Public/Javascript/structured-data-generator.js * * Self-initializing: on load it installs a single delegated click handler for * any button matching [data-vitec-sd-generate]. This avoids relying on the * JavaScriptModuleInstruction ->instance() payload (which is unreliable for * fieldWizards) and also works for fields added to the DOM later. * * On click it calls the backend AJAX endpoint for the product uid and writes * the returned JSON-LD string into the associated `structureddata` textarea. * The textarea is resolved by its form name (data-field-name) with a fallback * to the surrounding FormEngine field-item container. */ import DocumentService from "@typo3/core/document-service.js"; import AjaxRequest from "@typo3/core/ajax/ajax-request.js"; import Notification from "@typo3/backend/notification.js"; const SELECTOR = "[data-vitec-sd-generate]"; function findField(button) { const name = button.dataset.fieldName; if (name) { const byName = document.querySelector('[name="' + name + '"]'); if (byName !== null) { return byName; } } const item = button.closest(".t3js-formengine-field-item"); if (item !== null) { return item.querySelector("textarea, input[type=text], input:not([type])"); } return null; } async function generate(button) { const field = findField(button); if (!field) { Notification.error("Fehler", "Das Structured-Data-Feld wurde nicht gefunden."); return; } const ajaxUrl = TYPO3.settings.ajaxUrls["vitec_structureddata_generate"]; if (!ajaxUrl) { Notification.error("Fehler", "AJAX-Route nicht registriert."); return; } button.disabled = true; try { const response = await new AjaxRequest(ajaxUrl) .withQueryArguments({ uid: button.dataset.uid }) .get(); const data = await response.resolve(); if (data.success) { field.value = data.jsonLd; field.dispatchEvent(new Event("change", { bubbles: true })); Notification.success( "Structured Data", "JSON-LD wurde generiert und in das Feld geschrieben." ); } else { Notification.warning("Hinweis", data.message || "Generierung nicht möglich."); } } catch (error) { Notification.error("Fehler", "Die Generierung ist fehlgeschlagen."); } finally { button.disabled = false; } } function init() { // Guard against binding more than once (the module instruction may be // emitted per field instance, but the module itself is a singleton). if (document.body.dataset.vitecSdBound === "1") { return; } document.body.dataset.vitecSdBound = "1"; document.addEventListener("click", (event) => { const button = event.target.closest(SELECTOR); if (button === null) { return; } event.preventDefault(); generate(button); }); } DocumentService.ready().then(init);