/ Gists / Search bar (cloning)
On gists

Search bar (cloning)

JavaScript

search-bar.js Raw #

const userCardTemplate = document.querySelector("[data-user-template]")
const userCardContainer = document.querySelector("[data-user-cards-container]")
const searchInput = document.querySelector("[data-search]")

let users = []

searchInput.addEventListener("input", e => {
  const value = e.target.value.toLowerCase()
  users.forEach(user => {
    const isVisible =
      user.name.toLowerCase().includes(value) ||
      user.email.toLowerCase().includes(value)
    user.element.classList.toggle("hide", !isVisible)
  })
})

fetch("https://jsonplaceholder.typicode.com/users")
  .then(res => res.json())
  .then(data => {
    users = data.map(user => {
      const card = userCardTemplate.content.cloneNode(true).children[0]
      const header = card.querySelector("[data-header]")
      const body = card.querySelector("[data-body]")
      header.textContent = user.name
      body.textContent = user.email
      userCardContainer.append(card)
      return { name: user.name, email: user.email, element: card }
    })
  })

styles.css Raw #

.search-wrapper {
  display: flex;
  flex-direction: column;
  gap: .25rem;
}

input {
  font-size: 1rem;
}

.user-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: .25rem;
  margin-top: 1rem;
}

.card {
  border: 1px solid black;
  background-color: white;
  padding: .5rem;
}

.card > .header {
  margin-bottom: .25rem;
}

.card > .body {
  font-size: .8rem;
  color: #777;
}

.hide {
  display: none;
}

index.html Raw #

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="styles.css">
  <script src="script.js" defer></script>
  <title>Document</title>
</head>
<body>
  <div class="search-wrapper">
    <label for="search">Search Users</label>
    <input type="search" id="search" data-search>
  </div>
  <div class="user-cards" data-user-cards-container></div>
  <template data-user-template>
    <div class="card">
      <div class="header" data-header></div>
      <div class="body" data-body></div>
    </div>
  </template>
</body>
</html>