مرحباً.
تمكنت من إنشاء كود بمساعدة GROK و ChatGPT، وقمت بإدراجه في تبويب JS للمكونات، بعد إنشاء بعض حقول المستخدم المخصصة في قائمة التسجيل.
تمكنت من جعل وظيفة القائمة المنسدلة المعتمدة تعمل، لكن لا يمكن إرسال النموذج.
الكود متاح حالياً للمراجعة على foorum.maarahvas.ee/signup
إليك كود JS المستخدم حالياً هناك:
// dependent-dropdown.js
import { apiInitializer } from "discourse/lib/api";
export default apiInitializer("0.8", api => {
if (window.__DEPENDENT_DROPDOWN_INITIALIZED) {
console.debug("تم تهيئة سكريبت القائمة المنسدلة المعتمدة بالفعل، يتم التجاوز.");
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(`إعادة تهيئة حالة SelectKit للحقل ${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("ليس في صفحة التسجيل، يتم التجاوز عن التهيئة");
return;
}
const signupForm = findSignupForm();
if (!signupForm) {
console.error("لم يتم العثور على نموذج التسجيل");
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("تفاصيل النموذج والحقل:", {
signupForm: !!signupForm,
landField: !!landField,
parishField: !!parishField,
landHeader: !!landHeader,
parishHeader: !!parishHeader,
landBody: !!landBody,
parishBody: !!parishBody
});
if (!landField || !parishField || !landHeader || !parishHeader || !landBody || !parishBody) {
console.error("لم يتم العثور على العناصر المطلوبة");
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(`لم يتم العثور على حقل إدخال لـ ${fieldName}، يتم إنشاء واحد`);
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(`تفاصيل حقل الإدخال لـ ${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("لم يتم العثور على جسم SelectKit للكنيسة");
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 = '<span class="name">Vali kihelkond</span>';
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 = `<span class="name">${parish}</span>`;
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 = '<span class="name">Vali kihelkond</span>';
}
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 = `<span class="name">${name}</span>`;
}
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("تم تحديث إدخال الكنيسة:", {
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("تم تحديث إدخال الأرض:", {
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("حقل إدخال الأرض مفقود، يتم إعادة إنشائه");
getOrCreateInputField(landField, LAND_FIELD_NAME, "user_fields_6");
}
if (!signupForm.querySelector(`input[name='${PARISH_FIELD_NAME}']`)) {
console.warn("حقل إدخال الكنيسة مفقود، يتم إعادة إنشائه");
getOrCreateInputField(parishField, PARISH_FIELD_NAME, "user_fields_8");
}
});
formObserver.observe(signupForm, { childList: true, subtree: true });
signupForm.addEventListener("submit", () => {
console.debug("تمت محاولة إرسال النموذج:", {
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("خطأ في إرسال النموذج:", event.detail);
});
console.log("تم تهيئة القوائم المنسدلة المعتمدة بنجاح.");
} catch (error) {
console.error("خطأ في تهيئة القوائم المنسدلة المعتمدة:", 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);
});
هل لدى أي شخص فكرة عما هو الخطأ هناك وكيف يمكن إصلاح ذلك؟
شكراً لكم