Reputation: 1
This is the part I use to dynamicly create a Dropdown.
// Helper: Create Dropdown
const createDropdown = (id, options, selectedOption = [], labelText, isMultiSelect = false) => {
console.log(`Creating dropdown for ${labelText} with ID: ${id}`);
console.log(`Initial selectedOption:`, selectedOption);
console.log(`Options provided:`, options);
console.log(`Multi-select: ${isMultiSelect}`);
const container = document.createElement("div");
container.classList.add("dropdown-container");
// Create the dropdown HTML
container.innerHTML = `
<label for="${id}" class="dropdown-label">${labelText}</label>
<div class="select" id="${id}">
<div class="selected">
${isMultiSelect ?
(selectedOption.length > 0 ? selectedOption.map(option => `<span class="selected-item">${option}</span>`).join('') : "Select options") :
(selectedOption.length > 0 ? `<span class="selected-item">${selectedOption}</span>` : "Select an option")
}
</div>
<div class="options">
${options.map(option => `
<div>
${isMultiSelect ?
`<input type="checkbox" id="${id}-${option}" name="${id}" value="${option}" ${selectedOption.includes(option) ? "checked" : ""}>`
:
`<input type="radio" id="${id}-${option}" name="${id}" value="${option}" ${selectedOption[0] === option ? "checked" : ""}>`
}
<label class="option" for="${id}-${option}" role="option" aria-selected="${selectedOption.includes(option)}">${option}</label>
</div>`).join("")}
</div>
</div>`;
// Debugging log for container creation
console.log('Created dropdown container:', container);
const inputs = container.querySelectorAll('input');
console.log('Attached inputs:', inputs); // Log to ensure inputs are selected
// Handle single-select (radio button change event) with event delegation
container.addEventListener('change', (e) => {
console.log("Inside Event Listener");
// Check if the event target is a radio input
if (!isMultiSelect && e.target.type === 'radio') {
console.log("Single-select change detected:");
console.log("Previously selected option:", selectedOption);
console.log("Currently selected option:", e.target.value);
// Update selectedOption when a radio button is selected
selectedOption = [e.target.value];
// Update the selected text to reflect the new selection
const selectedText = container.querySelector(".selected");
if (selectedText) {
selectedText.innerHTML = `<span class="selected-item">${e.target.value}</span>`;
console.log("Updated selected value (single-select):", selectedOption);
}
// Update the aria-selected attribute for all options
const labels = container.querySelectorAll('.option');
labels.forEach(label => {
label.setAttribute('aria-selected', label.getAttribute('for') === `${id}-${e.target.value}`);
});
}
});
// Add event listeners to all radio buttons
inputs.forEach(input => {
input.addEventListener('change', (e) => {
if (e.target.type === 'radio') {
console.log('Radio button changed:', e.target.value);
}
});
});
return container;
};
Now the weird thing is, That When I first load the page, The Dropdown in CreateEntity works;
// Create Entity
function entityCreateModal(entityType) {
const modal = document.getElementById('entityCreateModal');
const title = document.getElementById('entityCreateModalTitle');
const promptMessageContainer = modal.querySelector('.entity-create-message');
const submitButton = modal.querySelector('.submit-button');
promptMessageContainer.innerHTML = ''; // Clear previous content
// Function to handle entity creation and confirmation
const createEntity = (entityName, entityData) => {
window.openConfirmationModal('create', () => {
saveEntityData(entityName, entityData);
closeModal(modal.querySelector('#modal-close-button'), '#entityCreateModal');
location.reload();
}, entityName);
};
// Call handleFileUpload for Teacher and Student
if (entityType === 'teacher' || entityType === 'student') {
handleFileUpload({}, '#entityCreateModal');
}
// Switch based on entity type
switch (entityType) {
case 'teacher': {
title.textContent = "Create Teacher";
const teacherIdField = createTextField('teacherId', '', 'Teacher ID');
const usernameField = createTextField('username', '', 'Username');
const emailField = createTextField('email', '', 'Email ID');
const genderDropdown = createDropdown('gender', ['Male', 'Female', 'Other'], 'Select Gender', 'Select Gender:');
const curriculumDropdown = createDropdown('curriculum', ['CBSE', 'IPYP', 'IGCSE', 'IBDP'], 'Select Curriculum', 'Select Curriculum:');
const gradeDropdown = createDropdown('grade', ['PRE NURSERY', 'NURSERY', 'LKG', 'UKG', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X', 'XI-SCI', 'XI-COM', 'XI-HUM', 'XII-SCI', 'XII-COM', 'XII-HUM'], 'Select Grade', 'Select Grade:');
promptMessageContainer.innerHTML = '<p>Please enter the details for the new Teacher.</p>';
[teacherIdField, usernameField, emailField, genderDropdown, curriculumDropdown, gradeDropdown].forEach(field => promptMessageContainer.appendChild(field));
createEntity('teacher', {});
break;
}
case 'student': {
title.textContent = "Create Student";
const studentIdField = createTextField('studentId', '', 'Student ID');
const studentNameField = createTextField('studentName', '', 'Student Name');
const curriculumDropdown = createDropdown('curriculum', ['CBSE', 'IPYP', 'IGCSE', 'IBDP'], 'Select Curriculum', 'Select Curriculum:');
const gradeDropdown = createDropdown('grade', ['PRE NURSERY', 'NURSERY', 'LKG', 'UKG', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X', 'XI', 'XII'], 'Select Grade', 'Select Grade:');
const boardingDropdown = createDropdown('boarding', ['Day Boarder', 'Hostelite'], 'Select Boarding', 'Select Boarding:');
const houseDropdown = createDropdown('house', ['Kingfisher (Blue)', 'Ibis (Red)', 'Token (Green)', 'Iora (Yellow)'], 'Select House', 'Select House:');
const genderDropdown = createDropdown('gender', ['Male', 'Female', 'Other'], 'Select Gender', 'Select Gender:');
const emailField = createTextField('email', '', 'Email ID');
const bloodGroupDropdown = createDropdown('bloodGroup', ['A+', 'A-', 'B+', 'B-', 'AB+', 'AB-', 'O+', 'O-'], 'Select Blood Group', 'Select Blood Group:');
promptMessageContainer.innerHTML = '<p>Please enter the appropriate details for the new Student.</p>';
// Append common fields
[studentIdField, studentNameField, curriculumDropdown, gradeDropdown, genderDropdown, houseDropdown, boardingDropdown, bloodGroupDropdown, emailField].forEach(field => promptMessageContainer.appendChild(field));
// Stream dropdown logic
let streamDropdown = null; // Declare the streamDropdown outside
// Log the gradeDropdown element for inspection
console.log("Grade Dropdown Element:", gradeDropdown);
gradeDropdown.addEventListener('change', () => {
const selectedGrade = gradeDropdown.value;
console.log("Inside change event listener");
console.log("Selected Grade:", selectedGrade);
// Check for initial event or empty selection
if (selectedGrade === '' || selectedGrade === undefined) {
console.log('Initial event or empty selection. Ignoring.');
return;
}
console.log('Dropdown changed. Selected value(s):', selectedGrade);
console.log('Grade dropdown change event triggered!');
console.log('Grade dropdown value on change:', selectedGrade);
// Proceed with the rest of your logic
if (selectedGrade === 'XI' || selectedGrade === 'XII') {
console.log('Grade is either XI or XII.');
if (!streamDropdown) {
console.log('Stream dropdown is being created and added to the DOM.');
streamDropdown = createDropdown('stream', ['Science', 'Commerce', 'Humanities'], 'Select Stream', 'Select Stream:');
promptMessageContainer.insertBefore(streamDropdown, boardingDropdown); // Insert Stream just after Grade
} else {
console.log('Stream dropdown already exists in the DOM.');
}
} else {
console.log('Grade is not XI or XII. Removing Stream dropdown if it exists.');
if (streamDropdown) {
console.log('Removing the Stream dropdown from the DOM.');
promptMessageContainer.removeChild(streamDropdown);
streamDropdown = null;
} else {
console.log('No Stream dropdown exists to remove.');
}
}
});
break;
}
case 'ticket': {
title.textContent = "Create Ticket";
const dropdown = createDropdown('affectedSystem', ['Admin Dashboard', 'Student Panel', 'Exams', 'Fees', 'Notices', 'Forget Password', 'Reset Password'],'Select a System', 'Select System:');
promptMessageContainer.innerHTML = '<p>Which system or component are you experiencing issues with?</p>';
promptMessageContainer.appendChild(dropdown);
submitButton.addEventListener('click', (event) => {
event.preventDefault();
const selectedSystem = dropdown.querySelector('.selected')?.textContent;
if (!selectedSystem || selectedSystem === 'Select a System') {
return alert("Please select a valid system.");
}
const [day, month, year] = new Date().toLocaleDateString('en-GB', { timeZone: 'Asia/Kolkata' }).split('/');
const [hour, minute] = new Date().toLocaleTimeString('en-GB', { timeZone: 'Asia/Kolkata', hourCycle: 'h23' }).split(':');
const ticketId = `T${year}${month.padStart(2, '0')}${day.padStart(2, '0')}${hour}${minute}`;
const createdBy = sessionStorage.getItem("TeacherID") || "Unknown";
const createdAt = `${day} ${new Date().toLocaleString('default', { month: 'long' })} ${year} - ${hour}:${minute}`;
const priority = {
'Admin Dashboard': 'High', 'Student Panel': 'High', 'Exams': 'High',
'Fees': 'High', 'Notices': 'High', 'Forget Password': 'Medium',
'Reset Password': 'Medium'
}[selectedSystem] || 'Low';
createEntity('ticket', { ticketId, createdBy, createdAt, affectedSystem: selectedSystem, status: "Open", priority });
});
break;
}
case 'system': {
title.textContent = "Create System";
const priorityDropdown = createDropdown('priority', ['Low', 'Medium', 'High'], 'Select Priority', 'Select Priority:');
const systemIdField = createTextField('systemId', '', 'System ID');
const systemNameField = createTextField('systemName', '', 'System Name');
promptMessageContainer.innerHTML = '<p>Please enter the appropriate details for the new System.</p>';
[systemIdField, systemNameField, priorityDropdown].forEach(field => promptMessageContainer.appendChild(field));
// Move the listener attachment here to ensure it only runs once
const submitHandler = (event) => {
event.preventDefault();
const selectedPriority = priorityDropdown.querySelector('.selected')?.textContent;
if (!selectedPriority || selectedPriority === 'Select Priority') {
return alert("Please select a valid priority.");
}
const systemId = systemIdField.querySelector("input")?.value.trim() || '';
const systemName = systemNameField.querySelector("input")?.value.trim() || '';
if (!systemId || !systemName) {
return alert("Please enter both system ID and system name.");
}
createEntity('system', { systemId, systemName, status: 'Operational', priority: selectedPriority });
};
// Attach the listener after everything is ready
submitButton.removeEventListener('click', submitHandler); // Prevent duplicate listeners
submitButton.addEventListener('click', submitHandler);
break;
}
default:
console.error(`Unsupported entity type: ${entityType}`);
}
// Open modal and prevent background scroll
modal.style.zIndex = '5';
modal.style.display = 'flex';
document.body.style.overflow = 'hidden';
// Close modal
document.getElementById('modal-close-button').addEventListener('click', () => closeModal(modal.querySelector('#modal-close-button'), '#entityCreateModal'));
}
But After I open the Edit Modal, and Try selecting an option there, It bricks both dropdowns (Edit & Create)
// Edit Modal
function openEditModal(entityType, entityData = {}) {
const modal = document.getElementById("editModal");
const form = document.getElementById("editModalForm");
const closeButton = document.getElementById("editModalCloseButton");
const saveButton = document.querySelector(".save-button");
const deleteButton = document.querySelector(".edit-modal-delete-button");
const titles = {
ticket: "Edit Ticket",
teacher: "Edit Teacher",
student: "Edit Student",
system: "Edit System"
};
const fields = {
teacher: [
["Teacher ID", "teacherId"],
["Name", "name"],
["Username", "username"],
["Email", "email"],
["Gender", "gender"],
["Role", "role", ["Administrator", "IT Department", "Admission Department", "Accounts Department", "Discipline Committee", "Grade Coordinator", "Advisor", "Heads of Department", "Exam Department", "Class Teacher", "Subject Teacher"], true] // Multi-select for Role
],
student: [
["Name", "name"],
["Student ID", "studentId"],
["Enrollment Status", "enrollmentStatus", ['Currently Studying', 'Transferred', 'Suspended', 'Graduated']]
],
system: [
["System Name", "systemName"],
["Status", "status", ["Operational", "EP", "Down"]],
["Priority", "priority", ["High", "Medium", "Low"]]
],
ticket: [
["Affected System", "affectedSystem"],
["Status", "status", ["Open", "In Progress", "Closed"]]
]
};
if (!fields[entityType]) {
console.error("Unknown entity type:", entityType);
return;
}
form.innerHTML = ""; // Reset form
// Create form fields for the rest of the data
fields[entityType].forEach(([label, dataField, options, isMultiSelect]) => {
const fieldName = dataField;
const labelText = label.split(' ').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' '); // Title case for labelText
console.log(`Processing field: ${labelText} (dataField: ${dataField}, isMultiSelect: ${isMultiSelect})`);
// Append either dropdown or text field based on options
const isDropdown = options && Array.isArray(options) && options.length;
if (isDropdown) {
// For multi-select, initialize as an array
const selectedValue = entityData[dataField]
? (Array.isArray(entityData[dataField])
? entityData[dataField]
: [entityData[dataField]])
: (isMultiSelect ? [] : "");
console.log(`Creating dropdown for field: ${labelText} with options:`, options);
form.appendChild(
createDropdown(fieldName, options, selectedValue, labelText, isMultiSelect)
);
} else {
form.appendChild(
createTextField(fieldName, entityData[dataField] != null ? entityData[dataField] : "", labelText)
);
}
});
// Set modal title and entity ID
document.getElementById("editModalTitle").textContent = titles[entityType];
document.getElementById("modal-header-entity-ID").textContent = `${titles[entityType].split(" ")[1]} ID: ${entityData[`${entityType}Id`] || "N/A"}`;
modal.style.display = "flex";
modal.setAttribute("aria-hidden", "false");
document.body.style.overflow = "hidden";
closeButton.onclick = closeEditModal;
window.onclick = (e) => e.target === modal && closeEditModal();
saveButton.onclick = () => handleAction("save", entityType, entityData);
deleteButton.onclick = () => handleAction("delete", entityType, entityData);
function closeEditModal() {
modal.style.display = "none";
modal.setAttribute("aria-hidden", "true");
document.body.style.overflow = "auto";
console.log("Modal closed");
}
}
I still can't understand whats wrong. (I'm just learning to sorry if I missed something super obvious)
Upvotes: 0
Views: 29
Reputation: 1501
I second the comment made by Mister Jojo in relation to asking slightly more specific questions, I'd also add that including a minimal reproducible example will help get answers quicker!
Having looked through the code you have provided, I note that you have written:
window.onclick = (e) => e.target === modal && closeEditModal();
This code appears to prevent the onclick
event triggering on your input (checkboxes and radios). Remove this and it should allow you to perform these events.
Upvotes: 1