document.addEventListener("DOMContentLoaded", () => { /* make all forms semi-smart */ const forms = document.querySelectorAll("form[data-smart]"); for (const form of forms) { const script = form.querySelector("script"); form.onsubmit = async (event) => { event.preventDefault(); const form_data = new FormData(form); const body = {}; for (const [key, value] of form_data.entries()) { const elements = key.split("."); let current = body; for (const element of elements.slice(0, elements.length - 1)) { current[element] = current[element] ?? {}; current = current[element]; } current[elements.slice(elements.length - 1).shift()] = value; } const url = form.action; const method = form.dataset.method ?? "POST"; console.dir({ method, form, }); try { // TODO: send session header const options = { method, headers: { Accept: "application/json", }, }; if (["POST", "PUT", "PATCH"].includes(method)) { options.headers["Content-Type"] = "application/json"; options.body = JSON.stringify(body); } const response = await fetch(url, options); if (!response.ok) { const error_body = await response.json(); const error = error_body?.error; if (form.on_error) { return form.on_error(error); } alert(error.message ?? "Unknown error!"); return; } const response_body = await response.json(); if (form.on_response) { return form.on_response(response_body); } } catch (error) { console.dir({ error, }); if (form.onerror) { return form.onerror(error); } alert(error); } }; } });