Sky
Sky

Reputation: 1

Getting problems in selecting options in a Dropdown

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

Answers (1)

Jordan
Jordan

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

Related Questions