JavaScript DOM Scripting By Example Editing and Filtering Names Filter Invitees Who Have Not Responded

Siddharth Pandey
Siddharth Pandey
4,069 Points

Why does this code not work?

I feel like I have done everything right. However, this is definitely something missing, can someone explain why the checkbox for "Show Selected items" is not working and on the console whenever I press it, the console says "Uncaught TypeError: Cannot read property 'className' of undefined at HTMLDivElement.filter (script.js:21)" I do not understand what is wrong. Can someone please explain to me what is wrong and how to fix it.

Here is my code:

const form = document.querySelector('#registrar');
const input = form.querySelector('input');
const ul = document.querySelector('#invitedList');

const main = document.querySelector('.main');
const div = document.createElement('div');
const label = document.createElement('label');
const filter = document.createElement('input');

main.insertBefore(div, ul);
div.appendChild(label);
div.appendChild(filter);
filter.type = 'checkbox';
label.textContent = 'Show Selected Items';

div.addEventListener('click', function filter(e) {
 const unchecked = ul.children;
 if(e.target.tagName === 'INPUT') {
  for(let i = 0; i < ul.children.length; i += 1) {
    let li = ul[i];
   if (li.className === 'responded') {
    li.style.display = '';      
  } else {
    li.style.display = 'none';
  }
  }
 }
});
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', function submit(name) {
  name.preventDefault();
  const text = input.value;
  input.value = '';
  const li = createLI(text);
  ul.appendChild(li);
});

ul.addEventListener('change', function styling(e) {
  const checkbox = e.target;
  const checked = e.target.checked;
  const listItem = checkbox.parentNode.parentNode;
  if (checked) {
    listItem.className = 'responded';
  } else {
    listItem.className = '';
  }
});

ul.addEventListener('click', function remove(e) {
const listItem = e.target.parentNode;
const ul = listItem.parentNode;
const button = e.target;
const li = button.parentNode;
 if (button.tagName == 'BUTTON') {
     if (button.textContent === 'Remove') {
      ul.removeChild(listItem);
   } 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';
   }
 }
});

Thanks For Helping! Sid

1 Answer

KRIS NIKOLAISEN
PRO
KRIS NIKOLAISEN
Pro Student 49,926 Points

li is list item. So in your for loop in div.addEventListener perhaps you meant:

let li = ul.children[i];
Siddharth Pandey
Siddharth Pandey
4,069 Points

I changed that but and some other things but I still get the syntax error "Cannot read property 'className' of undefined[.]" Can you please explain what is not working?

Here is the revised code:

const form = document.querySelector('#registrar');
const input = form.querySelector('input');
const ul = document.querySelector('#invitedList');

const main = document.querySelector('.main');
const div = document.createElement('div');
const label = document.createElement('label');
const filter = document.createElement('input');

main.insertBefore(div, ul);
div.appendChild(label);
div.appendChild(filter);
filter.type = 'checkbox';
label.textContent = 'Show Selected Items';

div.addEventListener('change', function filter(e) {
 const unchecked = ul.children;
 if(e.target.tagName === 'INPUT') {
  for(let i = 0; i < ul.children.length; i += 1) {
    let li = ul[i];
    console.log(ul.children);
   if (li.className =='responded') {
    li.style.display = '';      
  } else {
    li.style.display = 'none';
  }
  }
 }
});
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', function submit(name) {
  name.preventDefault();
  const text = input.value;
  input.value = '';
  const li = createLI(text);
  ul.appendChild(li);
});

ul.addEventListener('change', function styling(e) {
  const checkbox = e.target;
  const checked = e.target.checked;
  const listItem = checkbox.parentNode.parentNode;
  if (checked) {
    listItem.className = 'responded';
  } else {
    listItem.className = '';
  }
});

ul.addEventListener('click', function remove(e) {
const listItem = e.target.parentNode;
const ul = listItem.parentNode;
const button = e.target;
const li = button.parentNode;
 if (button.tagName == 'BUTTON') {
     if (button.textContent === 'Remove') {
      ul.removeChild(listItem);
   } 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';
   }
 }
});