2

I want to add an event listener or something similar that changes the display of the character class in CSS from none to grid when a key is typed in the searchbar. I've tried several ways but am not having much luck and am not quite sure how to work it in. I would also like to make the elements clickable. Any help would really be appreciated. Code

HTML

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <link rel="stylesheet" href="app.css" />
  </head>
  <body>
    <div class="container">
      <h1>&#x2728;Harry Potter Characters &#x2728;</h1>
      <div id="searchWrapper">
        <input
          type="text"
          name="searchBar"
          id="searchBar"
          placeholder="search for a character"
        />
      </div>
      <ul id="charactersList"></ul>
    </div>
    <script src="app.js"></script>
  </body>
</html>

CSS

body {
  font-family: sans-serif;
  background-color: #111d4a;
}

* {
  box-sizing: border-box;
}
h1 {
  color: #eee;
  margin-bottom: 30px;
}
.container {
  padding: 40px;
  margin: 0 auto;
  max-width: 1000px;
  text-align: center;
}

#charactersList {
  padding-inline-start: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  grid-gap: 20px;
}

.character {
  list-style-type: none;
  background-color: #eaeaea;
  border-radius: 3px;
  padding: 10px 20px;
  display: none;
  grid-template-columns: 3fr 1fr;
  grid-template-areas:
    "name"
    "house";
  text-align: left;
}

.hide {
  display: none;
}

.character > h2 {
  grid-area: name;
  margin-bottom: 0px;
}

.character > p {
  grid-area: house;
  margin: 0;
}

#searchBar {
  width: 100%;
  height: 32px;
  border-radius: 3px;
  border: 1px solid #eaeaea;
  padding: 5px 10px;
  font-size: 12px;
}

#searchWrapper {
  position: relative;
}

#searchWrapper::after {
  content: "🔍";
  position: absolute;
  top: 7px;
  right: 15px;
}

JS

const charactersList = document.getElementById("charactersList");
const searchBar = document.getElementById("searchBar");
let hpCharacters = [];

searchBar.addEventListener("keyup", (e) => {
  const searchString = e.target.value.toLowerCase();

  const filteredCharacters = hpCharacters.filter((character) => {
    return character.name.toLowerCase().includes(searchString);
  });
  displayCharacters(filteredCharacters);
});

const loadCharacters = async () => {
  try {
    const res = await fetch("https://hp-api.herokuapp.com/api/characters");
    hpCharacters = await res.json();
    displayCharacters(hpCharacters);
  } catch (err) {
    console.error(err);
  }
};

const displayCharacters = (characters) => {
  const htmlString = characters
    .map((character) => {
      return `
            <li class="character">
                <h2>${character.name}</h2>
                <p>House: ${character.house}</p>
            </li>
        `;
    })
    .join("");
  charactersList.innerHTML = htmlString;
};

loadCharacters();

1
  • Basically, when you press a key you want to make a <li class="character"> to be active (visible). The best way to do that is to work at the high level of that concept, rather than twiddling with low-level attributes like the display value. So as @Wally answers, add (or toggle) a class so the element would become <li class="character active"> and have a CSS rule that says .character.active { display: grid; } Bonus advantage: if you were to redesign and used a flow layout, not grid, your code would not have to change, just your CSS (which has to change anyway in a redesign)
    – Stephen P
    Commented Jun 23, 2020 at 22:57

1 Answer 1

0

So

So I want to add an event listener or something similar that changes the display of the display of the "character" class in css from "none" to "grid" when a key is typed in the searchbar.

You could do this by applying an eventlistener i.e the keypress event listener - and on that functions callback just use the element.classlist.toggle or element.classlist.add to add another class to the element which has the display of grid.

another method would also to be use the event listener for the keypress of your choice, but in the call back, edit the style of the element in question - so

addEventListener('keypress', function (e) {
    if (e.key === 'Enter') {
      element.style.display="grid";

    // to make the element clickable - just add another event listener to it - 
    }
});

For any key being pressed the event listener is keydown -

https://developer.mozilla.org/en-US/docs/Web/API/Document/keydown_event

addEventListener('keydown', function (e) {
        
          element.style.display="grid"; 
    
    });

Hope that helps - W

10
  • Thanks! In the second option how do you make it work on any key instead of just enter? Commented Jun 23, 2020 at 22:58
  • as in on any key that is pressed regardless of what key it is? then that would be keypress - I've updated my answer
    – Wally
    Commented Jun 23, 2020 at 23:02
  • Yeah, as soon as a key any is pressed, there's a function that starts mapping through the data and populates a list in the html. Right now that list class character is set to display none, and I want it change to ``` grid`` when any key is first entered into the searchbar. I'm sure the answer is in the code you provided but I haven't got it working yet. Commented Jun 23, 2020 at 23:08
  • put this into chrome dev tools - or any dev tools for an example :::: document.addEventListener('keypress', ()=>{ console.log('code will run') })
    – Wally
    Commented Jun 23, 2020 at 23:12
  • 1
    div.classList.toggle("grid"); <<< you'd need a class called grid in your css btw
    – Wally
    Commented Jun 24, 2020 at 12:25

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.