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

Accessing the value in the key value pair of localStorage.recentSearches.

Hi Everyone, I'm trying to update my local storage when a user clicks the remove button. Currently, my app.js file only updates local storage on a page refresh, but doesn't delete the reccentSearches portion when you click on the remove button from a li section. Can anyone help me? I don't know how to access the value in the localStorage.recentSearches key value pair.

2 Answers

//Adding the eventListener to the dom, now you can put your script anywhere on the page and it will load.

document.addEventListener('DOMContentLoaded', () => { 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');

const clearButton = document.getElementById('clearStorage');

filterLabel.textContent = "Hide those who haven't responded";
filterCheckBox.type = 'checkbox';
div.appendChild(filterLabel);
div.appendChild(filterCheckBox);
mainDiv.insertBefore(div, ul);

// Filtering your checkbox
filterCheckBox.addEventListener('change', (e) => {
  const isChecked = e.target.checked;
  const lis = ul.children;
  if (isChecked) {
    for (let i = 0; i < lis.length; i++) {
      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++) {
      let li = lis[i];
      li.style.display = "";
    }
  }
});

//Create LI elements with name, buttons, and checkbox
const createLI = text => {

  function createElement(elementName, property, value) {
    const element = document.createElement(elementName);
    element[property] = value;
    return element;
  }

  function appendToLI(elementName, property, value) {
    const element = createElement(elementName, property, value);
    li.appendChild(element);
    return element;
  }

  const li = document.createElement('li');
  appendToLI('span', 'textContent', text);
  // Refactoring below
  // const span = document.createElement('span');
  // span.textContent = text;
  // li.appendChild(span);
  appendToLI('label', 'textContent', 'Confirmed')
    .appendChild(createElement('input', 'type', 'checkbox'));
  appendToLI('button', 'textContent', 'edit');
  appendToLI('button', 'textContent', 'remove');
  ul.append(li);
}

//================ Local Storage ================== //

function supportsLocalStorage() {
  try {
    return 'localStorage' in window && window['localStorage'] !== null
  } catch(e) {
    return false;
  }
}

function getRecentSearches() {
  let searches = localStorage.getItem('recentSearches');
  if (searches) {
    return JSON.parse(searches);
  }
  return [];
}

function saveSearchString(str) {
  let searches = getRecentSearches();
  if (!str || searches.indexOf(str) > -1) {
    return false;
  }
  searches.push(str);
  localStorage.setItem('recentSearches', JSON.stringify(searches));
  return true;
}

function removeSearches() {
  localStorage.removeItem('recentSearches')
}

// NEED HELP HERE //not sure how to access the values from localStorage.recentSearches so I can remove the one that mataches with the textContent of my span. function removeSearchItem(recentSearches, span) { let text = span.textContent; for (let i = 0; i < recentSearches.length; i++) { if (text === recentSearches[i]) { localStorage.removeItem(text); } } }

function clearList(listElement) {
  listElement.innerHTML = '';
}

if(supportsLocalStorage) {
  let recentSearches = getRecentSearches();
  recentSearches.forEach(function(searchString){
    createLI(searchString);
  });

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

  //e holds the event object. It's a reference to the object that dispatched the event
  //'change' is a change of state when the checkbox is clicked or unclicked
  ul.addEventListener('change', (e) => {
    const checkbox = event.target;
    //checked will be true if checked or false if not checked
    const checked = checkbox.checked;
    const listItem = checkbox.parentNode.parentNode;

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

  ul.addEventListener('click', (e) => {
    // since click events can be triggered through all the children of ul, we need to filter just for a button click on ul
    if (e.target.tagName === "BUTTON") {
      const button = e.target;
      const li = button.parentNode;
      const ul = li.parentNode;
      const action = button.textContent;
      const span = li.firstElementChild;

      const nameActions = {
        remove : () => {
          ul.removeChild(li);
          removeSearchItem(recentSearches, span);
        },
        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";
        },
        save: () => {
          const input = li.firstElementChild;
          const span = document.createElement("span");
          span.textContent = input.value;
          li.insertBefore(span, input);
          li.removeChild(input);
          button.textContent = "edit";
        }
      }
      //select and run action in button's name
      nameActions[action]();
      // actions will either be remove, edit or save, so when we click on a button, it will either remove, edit or save.
      //name of the buttons match the name of the properties, so it works out.
      // dont need the if/else statement, nameActions[action]() replaces the if/else statement
      // if (action === "remove") {
      //   nameActions.remove();
      // } else if (action === "edit") {
      //   nameActions.edit();
      // } else if (action === "save") {
      //   nameActions.save();
      // }
    }
  });

  clearButton.addEventListener('click', function(event){
    removeSearches();
    clearList(ul);
    console.log('local storage has been cleared.');
  })
}

});

<!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>
  <h2>Invitees</h2>
  <ul id="invitedList"></ul>
</div>

<button class="button" type="button" id="clearStorage">Clear Storage</button>

</div> <script type='text/javascript' src='app.js'></script> </body> </html>