Hi.
I've been able to create a code with the help of GROK and ChatGPT, that I inserted into components JS tab, after I created some custom user fields in the signup menu.
I have managed to get the functionality of the dependent dropdown menu to work, but, but submiting the form is not possible.
The code is currently available for review at foorum.maarahvas.ee/signup
Here's the JS code that is currently in use there:
// dependent-dropdown.jsimport { apiInitializer } from "discourse/lib/api";export default apiInitializer("0.8", api => { if (window.__DEPENDENT_DROPDOWN_INITIALIZED) { console.debug("Dependent dropdown script already initialized, skipping."); return; } window.__DEPENDENT_DROPDOWN_INITIALIZED = true; const landParishMap = { "Virumaa": ["Ebavere (Väike-Maarja)", "Haljala", "Jõvi (Jõhvi)", "Katkuküla (Simuna)", "Lüganuse", "Mahu (Viru-Nigula)", "Rakvere", "Rõhu (Viru-Jaagupi)", "Torvastvere (Kadrina)", "Tärevere (Iisaku)", "Vaivara"], "Järvamaa": ["Ambla", "Keika (Järva-Jaani)", "Koeru", "Kullamäe (Järva-Madise)", "Nõstvere (Anna)", "Paide", "Türi", "Ämbra (Peetri)"], "Harjumaa": ["Hageri", "Juuru", "Jõelähtme", "Keila", "Kose", "Kuusalu", "Külaselja (Risti)", "Nissi", "Padise (Harju-Madise)", "Rapla", "Sahataguse (Harju-Jaani)", "Vaskjala (Jüri)"], "Läänemaa": ["Emaste (Emmaste)", "Hanila", "Karuse", "Kirbla", "Kullamaa", "Käina", "Lihula", "Märjamaa", "Noarootsi", "Pöhelepe (Pühalepa)", "Pööna (Lääne-Nigula)", "Reigi", "Rõdali (Ridala)", "Soontaga (Mihkli)", "Umra (Martna)", "Varbla", "Vigala", "Vormsi"], "Saaremaa": ["Anseküla", "Jämaja", "Kaarma", "Karja", "Kihelkonna", "Kärla", "Muhu", "Mustjala", "Para (Jaani)", "Pöide", "Püha", "Ruhnu", "Valjala"], "Pärnumaa": ["Aliste (Halliste)", "Audru", "Häädemeeste", "Karksi", "Kõrve (Pärnu-Jaagupi)", "Pärnu", "Ruhja", "Saarde", "Salatsi", "Soontaga (Mihkli)", "Tori", "Tõstamaa", "Vändra"], "Wiljandimaa": ["Helme", "Kolga (Kolga-Jaani)", "Kõpu", "Paistu", "Pilistvere", "Põltsamaa", "Tarvastu", "Valula (Suure-Jaani)", "Viljandi"], "Tartumaa": ["Kambja", "Kodavere", "Kursi", "Kõrenduse (Maarja-Magdaleena)", "Laiuse", "Nõo", "Otepää", "Palamuse", "Puhja", "Rannu", "Rõngu", "Sangaste", "Tartu (Tartu-Maarja)", "Tõrma (Torma)", "Võnnu", "Äksi"], "Võrumaa": ["Hargla", "Kanepi", "Karula", "Luke", "Põlva", "Rõugu (Rõuge)", "Räpinä (Räpina)", "Urvaste", "Vahtseliina (Vastseliina)", "Valga"], "Setomaa": ["Setomaa"] }; const LAND_FIELD_NAME = "user_fields[6]"; const PARISH_FIELD_NAME = "user_fields[8]"; function findSignupForm() { return ( document.querySelector(".user-signup-form") || document.querySelector("form[action*='signup']") || document.querySelector("form[id*='new-account']") || document.querySelector("form:has(.user-field)") ); } function resetSelectKitState(header, body, fieldName) { header.classList.remove("is-expanded", "is-invalid", "is-disabled"); header.classList.add("is-valid"); header.setAttribute("tabindex", "0"); header.setAttribute("aria-expanded", "false"); body.style.display = ""; body.classList.remove("is-expanded"); console.debug(`Resetting SelectKit state for ${fieldName}:`, { headerClasses: header.className, bodyDisplay: body.style.display, ariaExpanded: header.getAttribute("aria-expanded") }); setTimeout(() => { body.style.display = ""; header.classList.remove("is-expanded"); header.focus(); }, 100); } function initializeDropdowns() { try { if (!window.location.pathname.includes("/signup")) { console.debug("Not on sign-up page, skipping initialization"); return; } const signupForm = findSignupForm(); if (!signupForm) { console.error("Sign-up form not found"); return; } const landField = Array.from(signupForm.querySelectorAll(".user-field")).find(field => field.querySelector("label")?.textContent.trim() === "Maa" ); const parishField = Array.from(signupForm.querySelectorAll(".user-field")).find(field => field.querySelector("label")?.textContent.trim() === "Kodukihelkond" ); const landHeader = landField?.querySelector(".select-kit-header"); const parishHeader = parishField?.querySelector(".select-kit-header"); const landBody = landField?.querySelector(".select-kit-body"); const parishBody = parishField?.querySelector(".select-kit-body"); console.debug("Form and field details:", { signupForm: !!signupForm, landField: !!landField, parishField: !!parishField, landHeader: !!landHeader, parishHeader: !!parishHeader, landBody: !!landBody, parishBody: !!parishBody }); if (!landField || !parishField || !landHeader || !parishHeader || !landBody || !parishBody) { console.error("Required elements not found"); return; } const landLabel = landField.querySelector("label"); const parishLabel = parishField.querySelector("label"); if (landLabel) landLabel.setAttribute("for", "user_fields_6"); if (parishLabel) parishLabel.setAttribute("for", "user_fields_8"); function getOrCreateInputField(fieldContainer, fieldName, inputId) { let inputField = signupForm.querySelector(`input[name='${fieldName}']`); if (!inputField) { console.warn(`No input field found for ${fieldName}, creating one`); inputField = document.createElement("input"); inputField.type = "hidden"; inputField.name = fieldName; inputField.id = inputId; inputField.value = ""; inputField.setAttribute("required", "required"); inputField.setAttribute("data-select-kit", "true"); const controls = fieldContainer.querySelector(".controls"); if (controls) { controls.appendChild(inputField); } else { fieldContainer.appendChild(inputField); } } console.debug(`Input field details for ${fieldName}:`, { name: inputField.name, value: inputField.value, id: inputField.id, parent: inputField.parentElement?.className || inputField.parentElement?.tagName }); return inputField; } const landInput = getOrCreateInputField(landField, LAND_FIELD_NAME, "user_fields_6"); const parishInput = getOrCreateInputField(parishField, PARISH_FIELD_NAME, "user_fields_8"); const usernameInput = signupForm.querySelector("input[name='username']"); const emailInput = signupForm.querySelector("input[name='email']"); if (usernameInput) usernameInput.setAttribute("autocomplete", "username"); if (emailInput) emailInput.setAttribute("autocomplete", "email"); function updateParishOptions(selectedLand) { if (!parishBody) { console.error("Parish SelectKit body not found"); return; } parishBody.innerHTML = ""; const defaultOption = document.createElement("div"); defaultOption.className = "select-kit-row is-none"; defaultOption.setAttribute("data-value", ""); defaultOption.setAttribute("data-name", "Vali kihelkond"); defaultOption.innerHTML = 'Vali kihelkond'; parishBody.appendChild(defaultOption); if (selectedLand && landParishMap[selectedLand]) { landParishMap[selectedLand].forEach(parish => { const option = document.createElement("div"); option.className = "select-kit-row"; option.setAttribute("data-value", parish); option.setAttribute("data-name", parish); option.innerHTML = `${parish}`; parishBody.appendChild(option); }); parishHeader.setAttribute("data-value", ""); parishHeader.setAttribute("data-name", "Vali kihelkond"); const selectedName = parishHeader.querySelector(".select-kit-selected-name"); if (selectedName) { selectedName.innerHTML = 'Vali kihelkond'; } parishHeader.setAttribute("aria-label", "Vali kihelkond"); parishHeader.classList.remove("is-disabled", "is-invalid"); parishHeader.classList.add("is-valid"); parishHeader.setAttribute("tabindex", "0"); parishInput.value = ""; parishInput.classList.remove("invalid"); parishInput.dispatchEvent(new Event("change", { bubbles: true })); parishInput.dispatchEvent(new Event("input", { bubbles: true })); parishInput.dispatchEvent(new Event("blur", { bubbles: true })); } else { parishHeader.classList.add("is-disabled"); parishHeader.setAttribute("tabindex", "-1"); parishInput.value = ""; parishInput.dispatchEvent(new Event("change", { bubbles: true })); } resetSelectKitState(parishHeader, parishBody, "Kodukihelkond"); } parishBody.addEventListener("click", (event) => { const row = event.target.closest(".select-kit-row:not(.is-none)"); if (!row) return; const value = row.getAttribute("data-value"); const name = row.getAttribute("data-name"); parishHeader.setAttribute("data-value", value); parishHeader.setAttribute("data-name", name); const selectedName = parishHeader.querySelector(".select-kit-selected-name"); if (selectedName) { selectedName.innerHTML = `${name}`; } parishHeader.setAttribute("aria-label", `Valitud: ${name}`); parishHeader.classList.remove("is-invalid"); parishHeader.classList.add("is-valid"); parishHeader.closest(".select-kit")?.classList.remove("is-invalid"); parishInput.value = value; parishInput.classList.remove("invalid"); parishInput.dispatchEvent(new Event("change", { bubbles: true })); parishInput.dispatchEvent(new Event("input", { bubbles: true })); parishInput.dispatchEvent(new Event("blur", { bubbles: true })); const customEvent = new CustomEvent("select-kit:change", { bubbles: true, detail: { value } }); parishInput.dispatchEvent(customEvent); signupForm.dispatchEvent(new Event("change", { bubbles: true })); console.debug("Parish input updated:", { value, valid: parishInput.checkValidity(), formValid: signupForm.checkValidity(), parishHeaderClasses: parishHeader.className, parishBodyDisplay: parishBody.style.display }); resetSelectKitState(parishHeader, parishBody, "Kodukihelkond"); }); const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (mutation.attributeName === "data-value") { const selectedLand = landHeader.getAttribute("data-value"); landInput.value = selectedLand || ""; landInput.classList.remove("invalid"); landInput.dispatchEvent(new Event("change", { bubbles: true })); landInput.dispatchEvent(new Event("input", { bubbles: true })); landInput.dispatchEvent(new Event("blur", { bubbles: true })); console.debug("Land input updated:", { value: selectedLand, valid: landInput.checkValidity(), formValid: signupForm.checkValidity() }); updateParishOptions(selectedLand); } }); }); observer.observe(landHeader, { attributes: true, attributeFilter: ["data-value"] }); const initialLand = landHeader.getAttribute("data-value"); landInput.value = initialLand || ""; updateParishOptions(initialLand); const formObserver = new MutationObserver(() => { if (!signupForm.querySelector(`input[name='${LAND_FIELD_NAME}']`)) { console.warn("Land input missing, recreating"); getOrCreateInputField(landField, LAND_FIELD_NAME, "user_fields_6"); } if (!signupForm.querySelector(`input[name='${PARISH_FIELD_NAME}']`)) { console.warn("Parish input missing, recreating"); getOrCreateInputField(parishField, PARISH_FIELD_NAME, "user_fields_8"); } }); formObserver.observe(signupForm, { childList: true, subtree: true }); signupForm.addEventListener("submit", () => { console.debug("Form submission attempted:", { landValue: landInput.value, landValid: landInput.checkValidity(), parishValue: parishInput.value, parishValid: parishInput.checkValidity(), formValid: signupForm.checkValidity(), formErrors: Array.from(signupForm.querySelectorAll(".invalid")).map(el => el.name || el.id) }); }); signupForm.addEventListener("ajax:error", (event) => { console.debug("Form submission error:", event.detail); }); console.log("Dependent dropdowns initialized successfully."); } catch (error) { console.error("Error initializing dependent dropdowns:", error); } } const formObserver = new MutationObserver((mutations, obs) => { const signupForm = findSignupForm(); if (signupForm && signupForm.querySelector(".user-field")) { initializeDropdowns(); obs.disconnect(); } }); formObserver.observe(document.body, { childList: true, subtree: true }); setTimeout(initializeDropdowns, 5000);});
Does anyone have any clue what is wrong there and how can this be fixed? Thanks
Discuss this on our forum.