JavaScript DOM Scripting By Example Editing and Filtering Names Moving to an Editing State

Hamzah Iqbal
Hamzah Iqbal
Full Stack JavaScript Techdegree Student 9,235 Points

"Undefined" - error

It seems that the code keeps having a sudden error of undefined li:

Uncaught TypeError: Cannot read property 'firstElementChild' of undefined.

Li is created in the previous section as button.parentNode;

var form = document.getElementById("registrar");
const input = form.querySelector("input");
 const ul = document.getElementById("invitedList");


function createLI(text) {
   const li = document.createElement("li");
  li.textContent = text;
  const  label = document.createElement("label");

    const span = document.createElement("span");
  span.textContent = text;
 li.appendChild(span);


  label.textContent = "Confirmed";
  const checkbox = document.createElement("input");
  checkbox.type = "checkbox";
  label.appendChild(checkbox)
  li.appendChild(label);


     const editButton = document.createElement("button");
  editButton.textContent = "Edit";
  li.appendChild(editButton);

    const removeButton = document.createElement("button");
  removeButton.textContent = "Remove";
  li.appendChild(removeButton);
  return li;
}

form.addEventListener("submit", (e) => {
  e.preventDefault();
  const text = input.value;
  input.value = "";
 const li = createLI(text);
  ul.appendChild(li);

});


ul.addEventListener("change", (e) => {
const checkbox = e.target;
  const checked = e.target.checked;
  listItem = checkbox.parentNode.parentNode;

  if (checked) {

    listItem.className = "responded";

  }
  else {
    listItem.className = "";
  }
});



      ul.addEventListener("click", (e) => 
                  {
                    if(e.target.tagName === "BUTTON")      
                          {

                            const button = e.target;
                        if(button.textContent === "Remove")
                          {

                            var li = button.parentNode;
                            var ul = button.parentNode;
                            ul.removeChild(li);
                          }
                      else if(button.textContent === "Edit")
                              {
                              const span =   li.firstElementChild;
                                const input = document.createElement("input");
                                input.type = "text";
                               li.insertBefore(input, span);
                                li.removeChild(span);



                              }
                              }


                    });

1 Answer

Victor Mercier
MOD
Victor Mercier
Treehouse Moderator 13,507 Points
const form = document.getElementById('registrar');
const input = form.querySelector('input');

const mainDiv = document.querySelector('.main');
const ul = document.getElementById('invitedList');

const div = document.createElement('div');
const filterLabel = document.createElement('label');
const filterCheckBox = document.createElement('input');

filterLabel.textContent = "Hide those who haven't responded";
filterCheckBox.type = 'checkbox';
div.appendChild(filterLabel);
div.appendChild(filterCheckBox);
mainDiv.insertBefore(div, ul);
filterCheckBox.addEventListener('change', (e) => {
  const isChecked = e.target.checked;
  const lis = ul.children;
  if(isChecked) {
    for (let i = 0; i < lis.length; i += 1) {
      let li = lis[i];
      if (li.className === 'responded') {
        li.style.display = '';  
      } else {
        li.style.display = 'none';                        
      }
    }
  } else {
    for (let i = 0; i < lis.length; i += 1) {
      let li = lis[i];
      li.style.display = '';
    }                                 
  }
});

function createLI(text) {
  const li = document.createElement('li');
  const span = document.createElement('span');  
  span.textContent = text;
  li.appendChild(span);
  const label = document.createElement('label');
  label.textContent = 'Confirmed';
  const checkbox = document.createElement('input');
  checkbox.type = 'checkbox';
  label.appendChild(checkbox);
  li.appendChild(label);  
  const editButton = document.createElement('button');
  editButton.textContent = 'edit';
  li.appendChild(editButton);
  const removeButton = document.createElement('button');
  removeButton.textContent = 'remove';
  li.appendChild(removeButton);
  return li;
}

form.addEventListener('submit', (e) => {
  e.preventDefault();
  const text = input.value;
  input.value = '';
  const li = createLI(text);
  ul.appendChild(li);
});

ul.addEventListener('change', (e) => {
  const checkbox = event.target;
  const checked = checkbox.checked;
  const listItem = checkbox.parentNode.parentNode;

  if (checked) {
    listItem.className = 'responded';
  } else {
    listItem.className = '';
  }
});

ul.addEventListener('click', (e) => {
  if (e.target.tagName === 'BUTTON') {
    const button = e.target;
    const li = button.parentNode;
    const ul = li.parentNode;
    if (button.textContent === 'remove') {
      ul.removeChild(li);
    } else if (button.textContent === 'edit') { 
      const span = li.firstElementChild;
      const input = document.createElement('input');
      input.type = 'text';
      input.value = span.textContent;
      li.insertBefore(input, span);
      li.removeChild(span);
      button.textContent = 'save';
    } else if (button.textContent === 'save') { 
      const input = li.firstElementChild;
      const span = document.createElement('span');
      span.textContent = input.value;
      li.insertBefore(span, input);
      li.removeChild(input);
      button.textContent = 'edit';
    }
  }
});  

Please mark as best answer if it solved your issue!

Hamzah Iqbal
Hamzah Iqbal
Full Stack JavaScript Techdegree Student 9,235 Points

I can't seem to see any explanation. Merely just a change of the code. Please add the change also.