Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

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

Bryn Newell
seal-mask
.a{fill-rule:evenodd;}techdegree
Bryn Newell
Full Stack JavaScript Techdegree Student 4,066 Points

Unclicking hide button, does not make the names reappear

It seems my code works perfectly well for the most part. When you click the filter button, it works as it should and the names that have not responded hide. But when you unclick the filter button, nothing changes. The names that have not responded do not reappear. Help?

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

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

//adding a checkbox to filter the list
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);

//Showing or hiding the list based on if the checkbox is checked
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 = " ";
    }
  }
});
Mike Hatch
Mike Hatch
14,940 Points

Hi Bryn. You haven't provided your .html file. You can either provide that below and separated by JavaScript code, or you can also click on the Snapshot icon in your Workspace area then share the link here. Also, to prevent orange colored JS code put "JavaScript" after the backticks.

3 Answers

Mike Hatch
Mike Hatch
14,940 Points

Bryn,

It's in your second for loop under filterCheckBox.

    for (let i = 0; i < lis.length; i += 1) {
      let li = lis[i];
      li.style.display = " "; 
    }
  }
});

It will work if you close your quotes. I think this is related to the fact that an empty string is a falsey value. Since Guest name "Lisa" hasn't responded it is falsey. But why is your code passing in the loop above it without putting a space in between I'd like to know.

Also, I noticed you put else and else if on new lines. I don't think this will break your code, but it is something to be mindful of. I personally feel like it's better to change up the quotes. You're using double quotes across the board. I use single quotes for most everything except for external strings that the user will see. It's also less typing to do.

Bryn Newell
seal-mask
.a{fill-rule:evenodd;}techdegree
Bryn Newell
Full Stack JavaScript Techdegree Student 4,066 Points

It's a little wordy as I'm using comments as a kind of note taking in my own text editor. So here's my full javascript.

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

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

//adding a checkbox to filter the list
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);

//Showing or hiding the list based on if the checkbox is checked
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) {
  //create a new list item in the invited List ul
  const li = document.createElement("li");
  /* making the content of the input html format and assigning
  that content to the new li */
  const span = document.createElement("span");
  span.textContent = text;
  li.appendChild(span);
  //Giving text to the textbox we're about to create
  const label = document.createElement("label");
  label.textContent = "Confirmed";
  //creating the checkbox
  const checkbox = document.createElement("input");
  checkbox.type = "checkbox";
  //appending the label/text to the checkbox
  label.appendChild(checkbox);
  //appending the checkbox to the li
  li.appendChild(label);

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

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

form.addEventListener ("submit", (e) => {
  // The default of submit is to refresh the page, stops it from refreshing
  e.preventDefault();
  const text = input.value;
  //clear out the input field so it's blank after entry
  input.value = " ";
  //Using the function
  const li = createLI(text);
  //appending the li to the ul
  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) => {
  //only runs if the thing clicked is a button
  if (e.target.tagName === "BUTTON") {
    const button = e.target;
    const li = button.parentNode;
    const ul = li.parentNode;
    //checking for edit button or remove button
    if (button.textContent === "remove") {
        ul.removeChild(li);
  } else if (button.textContent === "edit") {
      /*selecting the name originally entered that needs to be edited,
      which we turned into a span */
      const span = li.firstElementChild;
      // replacing the text (span element) with an input field
      const input = document.createElement("input");
      input.type = "text";
      //leaving the name in the input field to edit
      input.value = span.textContent;
      li.insertBefore(input, span);
      li.removeChild(span);
      //changing the edit button to a save button
      button.textContent = "save";
    }
    else if (button.textContent === "save") {
      //the first child is now the input field
        const input = li.firstElementChild;
        // saving the value of the input into a span text and appending it
        const span = document.createElement("span");
        span.textContent = input.value;
        li.insertBefore(span, input);
        li.removeChild(input);
        //changing the save button to an edit button
        button.textContent = "edit";
      }
  }
});

and my full HTML

<!DOCTYPE html>
<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>RSVP App</title>
  <link href="https://fonts.googleapis.com/css?family=Courgette" rel="stylesheet">
  <link href="https://fonts.googleapis.com/css?family=Lato:400,700" rel="stylesheet">
  <link href="css/style.css" rel="stylesheet">
</head>
<body>
  <div class="wrapper">
    <header>
      <h1>RSVP</h1>
      <p>A Treehouse App</p>
      <form id="registrar">
        <input type="text" name="name" placeholder="Invite Someone">
        <button type="submit" name="submit" value="submit">Submit</button>
      </form>
    </header>

    <div class="main">
      <h2>Invitees</h2>
      <ul id="invitedList"></ul>
    </div>
  </div>
  <script type = "text/javascript" src="app.js"> </script>
</body>
</html>
Bryn Newell
seal-mask
.a{fill-rule:evenodd;}techdegree
Bryn Newell
Full Stack JavaScript Techdegree Student 4,066 Points

How weird! It seems like it should be closed with the double quotes, but when I changed it to single quotes it did finally work. Thank you for this. I guess it's just personal preference of mine to also stick with double quotes but I'll keep this in mind for the future. Thank you!!

Mike Hatch
Mike Hatch
14,940 Points

You're welcome. I'll conclude that I believe closed quotes is an empty string that results to false and open quotes is an inline string that results to truthy.