/** * VITEC – click-to-edit for the "Current value" column of the product text * import (Edit Product view). * EXT:vitec/Resources/Public/Javascript/product-inline-edit.js * * Delegated click handler on [data-vitec-inline-edit] cells (backend CSP * forbids inline handlers). Clicking a cell fetches the FULL raw field value * (the cell itself only shows a truncated preview), swaps in a textarea with * Save/Cancel, and writes through the vitec_product_field_save AJAX route, * which uses the same whitelist and DataHandler path as the form apply. * RTE fields are edited as raw HTML on purpose - no inline WYSIWYG * (decision 2026-08-28). */ import AjaxRequest from "@typo3/core/ajax/ajax-request.js"; import Notification from "@typo3/backend/notification.js"; const SELECTOR = "[data-vitec-inline-edit]"; function previewOf(cell) { return cell.querySelector("[data-vitec-preview]"); } function closeEditor(cell) { const editor = cell.querySelector("[data-vitec-editor]"); if (editor) { editor.remove(); } const preview = previewOf(cell); if (preview) { preview.hidden = false; } delete cell.dataset.vitecEditing; } async function openEditor(cell) { if (cell.dataset.vitecEditing === "1") { return; } cell.dataset.vitecEditing = "1"; const getUrl = TYPO3.settings.ajaxUrls["vitec_product_field_get"]; const saveUrl = TYPO3.settings.ajaxUrls["vitec_product_field_save"]; if (!getUrl || !saveUrl) { Notification.error("Inline edit", "AJAX routes are not registered."); delete cell.dataset.vitecEditing; return; } let value = ""; try { const response = await new AjaxRequest(getUrl) .withQueryArguments({ uid: cell.dataset.uid, field: cell.dataset.field }) .get(); const data = await response.resolve(); if (!data.success) { Notification.error("Inline edit", data.message || "Could not load the field value."); delete cell.dataset.vitecEditing; return; } value = data.value; } catch (e) { Notification.error("Inline edit", "Loading the field value failed."); delete cell.dataset.vitecEditing; return; } const preview = previewOf(cell); if (preview) { preview.hidden = true; } const wrap = document.createElement("div"); wrap.setAttribute("data-vitec-editor", "1"); const textarea = document.createElement("textarea"); textarea.className = "form-control"; textarea.rows = Math.min(14, Math.max(3, Math.ceil(value.length / 80))); textarea.style.fontFamily = "monospace"; textarea.style.fontSize = "11px"; textarea.value = value; wrap.appendChild(textarea); const bar = document.createElement("div"); bar.style.marginTop = ".25rem"; // type="button" is essential: the cells live inside the big mapping