I have a search.js file that reads a json file and retrieves information about some products, and then displays it in the page.
I am trying to show a error message if no product is found when searching, and this part is almost working.
If a search for a non-existent product, the error message appears correctly:
enter image description here
The problem is, if I search for a product that the name isn’t similar to another one, the error still appears.. for example:
enter image description here
Json file structure is like this:
[
{
"nome": "Carro",
"apelido": "ft.car",
"desc": "descrição",
"img": "/img/carro.png",
"link": "/pag/carro.html"
},
{
"nome": "Carreta Bi-Trem",
"apelido": "ft.big.truck",
"desc": "descrição",
"img": "/img/carreta.png",
"link": "/pag/carreta.html"
}
...
]
HTML of the error div:
<div class="col-12 d-none" id="avisoDeErro">
<div class="alert alert-danger p-5 rounded shadow">
<i class="bi bi-x-circle-fill"></i> <strong>Erro</strong>
<hr>
<div class="fs-1 ">
Nenhum produto encontrado.
<p class="fw-light">Acha que deveria ter algo aqui? Entre em contato com o suporte.</p>
</div>
</div>
</div>
search.js file:
const produtosCardTemplate = document.querySelector("[data-produtos-template]");
const produtosCardContainer = document.querySelector("[data-produtos-cards-container]");
const searchInput = document.querySelector("[data-search]");
let produtos = [];
searchInput.addEventListener("input", (e) => {
const value = e.target.value.toLowerCase()
produtos.forEach(produto => {
console.log(value)
const isVisible = value.split(' ').every(word => produto.nome.toLowerCase().includes(word)) || value.split('.').every(word => produto.apelido.toLowerCase().includes(word))
produto.element.classList.toggle("hide", !isVisible) //hide = display: none !important;
console.log(isVisible)
// Show a error message
if (!isVisible){
let avisoErro = document.getElementById("avisoDeErro")
avisoErro.classList.remove('d-none')
} else {
let avisoErro = document.getElementById("avisoDeErro")
avisoErro.classList.add('d-none');
}
})
})
fetch("/produtos.json")
.then(res => res.json())
.then(data => {
produtos = data.map(produto => {
// console.log(produto)
const card = produtosCardTemplate.content.cloneNode(true).children[0]
const nome = card.querySelector("[data-nome]")
const desc = card.querySelector("[data-desc]")
const img = card.querySelector("[data-img]")
const imgLink = card.querySelector("[data-img-link]")
const link = card.querySelector("[data-link]")
nome.textContent = produto.nome
desc.textContent = produto.desc
img.setAttribute("src", produto.img)
imgLink.setAttribute("href", produto.link)
link.setAttribute("href", produto.link)
produtosCardContainer.append(card)
return {nome: produto.nome, apelido: produto.apelido, element: card}
});
});
I know that the problem is in my way of showing the error message
if (!isVisible){
let avisoErro = document.getElementById("avisoDeErro")
avisoErro.classList.remove('d-none')
} else {
let avisoErro = document.getElementById("avisoDeErro")
avisoErro.classList.add('d-none');
}
But i can’t think of another way of doing this
Tried changing the way to see if no product matched, with no success
2
Answers
Using the logic provided by Yash Maheshwari above, i was able to solve my problem with this:
})
As you have added the logic to display the error message inside the forEach loop, and as the loop runs for each product, if any of the products from the list does not match the search value, then an error message will be displayed, and also the matched products will be displayed.