I added View buttons that show more detailed information about the characters into the card bodies that I created with the data I got from the APIs, but when I click the view button, it opens all of them instead of opening the boxes in the index I selected. where am I doing wrong.I tried for in instead of forEach, but at that time the first card body opens, the others do not open.When I click on the buttons with console.log(event.target) it shows the buttons correctly but they all refer to the cardbody at index 0
const getAgent = async() =>{
let url = 'https://valorant-api.com/v1/agents'
let res = await fetch(url);
let data = await res.json()
createAgentBox(data);
}
const createAgentBox = (element) =>{
const agentContainer = document.querySelector('.agent-container');
let agents = element.data;
agents.forEach(agent =>{
let agentName = agent.displayName;
let agentImage = agent.fullPortrait;
let desc = agent.description;
let abilitiesImage1 = agent.abilities[0].displayIcon;
let abilitiesImage2 = agent.abilities[1].displayIcon;
let abilitiesImage3 = agent.abilities[2].displayIcon;
let abilitiesImage4 = agent.abilities[3].displayIcon;
let abilitiesName1 = agent.abilities[0].displayName;
let abilitiesName2 = agent.abilities[1].displayName;
let abilitiesName3 = agent.abilities[2].displayName;
let abilitiesName4 = agent.abilities[3].displayName;
let x = `<div >
<img src=${agentImage} alt="">
<h1 class='agentname'>${agentName}</h1>
<button >View
<div >
<i ></i>
<p>${desc}</p>
<div class='boxs'>
<div >
<img src=${abilitiesImage1} alt="">
<p>${abilitiesName1}</p>
</div>
<div >
<img src=${abilitiesImage2} alt="">
<p>${abilitiesName2}</p>
</div>
<div >
<img src=${abilitiesImage3} alt="">
<p>${abilitiesName3}</p>
</div>
<div >
<img src=${abilitiesImage4} alt="">
<p>${abilitiesName4}</p>
</div>
</div>
</div>
</div>
</button>
</div>`
agentContainer.innerHTML = x;
});
let seeDetails = document.querySelectorAll('.seeDetails')
seeDetails.forEach(seeDetail =>{
seeDetail.addEventListener('click',showInfos)
})
function showInfos(e){
let showdetails = document.querySelectorAll('.showdetails');
showdetails.forEach((showdetail,index) =>{
showdetail.style.display = 'block'
})
}
}
getAgent()
let searcInput = document.querySelector('.searchbox');
searcInput.addEventListener('input',function(){
const agentsName = document.querySelectorAll('.agentname')
let container = document.querySelector('.container')
const search = searcInput.value;
agentsName.forEach((agentName) =>{
agentName.parentElement.style.display = 'block';
container.style.height = '100%'
if(!agentName.innerHTML.toLowerCase().includes(search)){
agentName.parentElement.style.display = 'none';
container.style.height = "100vh"
}
})
})
@import url("https://fonts.googleapis.com/css2?family=Audiowide&display=swap");
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
width: 100vw;
}
a {
text-decoration: none;
color: black;
font-family: "Audiowide", cursive;
}
/*Navbar CSS*/
.navbar {
width: 100%;
background: #fe4655;
border-bottom: 1px solid #fe4655;
display: flex;
align-items: center;
justify-content: space-between;
height: 75px;
box-shadow: rgba(0, 0, 0, 0.16) 0px 3px 6px, rgba(0, 0, 0, 0.23) 0px 3px 6px;
}
.navlogo {
margin-left: 2rem;
display: flex;
align-items: center;
gap: 0.3rem;
}
.navlogo > p {
font-family: "Audiowide", cursive;
font-size: 25px;
color: white;
}
.navList {
display: flex;
justify-content: space-between;
width: 30rem;
margin-right: 5rem;
}
li {
list-style: none;
}
ul > li > a {
text-decoration: none;
font-family: "Audiowide", cursive;
color: black;
font-size: 23px;
transition-duration: 1s;
cursor: pointer;
}
ul > li > a:hover {
color: white;
position: relative;
bottom: 5px;
}
/*Body*/
.container {
height: 100%;
width: 100%;
background-image: linear-gradient(to right, #2a1925, #651830, #ff425c);
display: flex;
flex-direction: column;
align-items: center;
}
.search-input {
display: flex;
margin: 5rem auto;
}
.searchbox {
outline: none;
border: 1px;
padding: 0.5rem;
width: 20rem;
border-top-left-radius: 10px;
border-bottom-left-radius: 10px;
}
.searchbox::placeholder {
font-family: "Audiowide", cursive;
}
.searcBtn {
border: 1px solid;
padding: 0.5rem;
width: 5rem;
border-bottom-right-radius: 10px;
border-top-right-radius: 10px;
cursor: pointer;
color: white;
background-image: linear-gradient(to right, #2a1925, #651830, #ff425c);
}
.agent-container {
display: flex;
flex-wrap: wrap;
height: 100%;
gap: 3rem;
justify-content: center;
}
.agentbox {
width: 270px;
height: 350px;
border: 1px solid white;
border-radius: 20px;
display: block;
flex-direction: column;
justify-content: center;
align-items: center;
position: relative;
}
.agentbox > img {
height: 70%;
width: 100%;
}
.agentbox > h1 {
font-family: "Audiowide", cursive;
color: white;
text-align: center;
}
.agentbox > button {
padding: 0.5rem;
border-radius: 10px;
margin: 10px auto;
border: 1px solid;
cursor: pointer;
font-family: "Audiowide", cursive;
display: flex;
}
.showdetails {
position: absolute;
width: 270px;
height: 250px;
border: 1px solid white;
border-top-left-radius: 20px;
border-top-right-radius: 20px;
top: 0.01rem;
background: black;
opacity: 0.7;
flex-direction: column;
display: none;
left: 0.2px;
}
.showdetails > p {
text-align: center;
margin-top: 0.9rem;
font-family: "Franklin Gothic Medium", "Arial Narrow", Arial, sans-serif;
color: white;
}
.boxs {
display: flex;
justify-content: center;
align-items: center;
gap: 1rem;
margin-top: 0.9rem;
}
.box1,
.box2,
.box3,
.box4 {
height: 50px;
width: 50px;
display: flex;
flex-direction: column;
}
.box1 > img,
.box2 > img,
.box3 > img,
.box4 > img {
height: 100%;
width: 100%;
}
.box1 > p,
.box2 > p,
.box3 > p,
.box4 > p {
color: white;
font-size: 13px;
text-align: center;
}
.fa-xmark {
color: white;
position: relative;
left: 7rem;
top: 0.5rem;
cursor: pointer;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="stylesheet" href="main.css">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.2/css/all.min.css" integrity="sha512-1sCRPdkRXhBV2PBLUdRb4tMg1w2YPf37qatUFeS7zlBy7jJI8Lf4VHwWfZZfpXtYSLy85pkm9GaYVYMfw5BC1A==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<title>Document</title>
</head>
<body>
<nav >
<div >
<a href=""><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/44/Valorant_logo.svg/2560px-Valorant_logo.svg.png" alt="#" height="30px" width="150px"></a>
<p>-wiki</p>
</div>
<div >
<ul >
<li >
<a href="/Valorant_wiki/home page/index.html">Home</a>
</li>
<li>
<a href="#">About Us</a>
</li>
<li>
<a href="#">Contact</a>
</li>
</ul>
</div>
</nav>
<div >
<div >
<input type="text" placeholder="Search Agents...">
<button ><i ></i></button>
</div>
<div >
</div>
</div>
</div>
<script src="app.js"></script>
</body>
</html>
const getAgent = async() =>{
let url = 'https://valorant-api.com/v1/agents'
let res = await fetch(url);
let data = await res.json()
createAgentBox(data);
}
const createAgentBox = (element) =>{
const agentContainer = document.querySelector('.agent-container');
let agents = element.data;
agents.forEach(agent =>{
let agentName = agent.displayName;
let agentImage = agent.fullPortrait;
let desc = agent.description;
let abilitiesImage1 = agent.abilities[0].displayIcon;
let abilitiesImage2 = agent.abilities[1].displayIcon;
let abilitiesImage3 = agent.abilities[2].displayIcon;
let abilitiesImage4 = agent.abilities[3].displayIcon;
let abilitiesName1 = agent.abilities[0].displayName;
let abilitiesName2 = agent.abilities[1].displayName;
let abilitiesName3 = agent.abilities[2].displayName;
let abilitiesName4 = agent.abilities[3].displayName;
let x = `<div >
<img src=${agentImage} alt="">
<h1 class='agentname'>${agentName}</h1>
<button >View
<div >
<i ></i>
<p>${desc}</p>
<div class='boxs'>
<div >
<img src=${abilitiesImage1} alt="">
<p>${abilitiesName1}</p>
</div>
<div >
<img src=${abilitiesImage2} alt="">
<p>${abilitiesName2}</p>
</div>
<div >
<img src=${abilitiesImage3} alt="">
<p>${abilitiesName3}</p>
</div>
<div >
<img src=${abilitiesImage4} alt="">
<p>${abilitiesName4}</p>
</div>
</div>
</div>
</div>
</button>
</div>`
agentContainer.innerHTML = x;
});
let seeDetails = document.querySelectorAll('.seeDetails')
seeDetails.forEach(seeDetail =>{
seeDetail.addEventListener('click',showInfos)
})
function showInfos(e){
/*open view buttons*/
let showdetails = document.querySelectorAll('.showdetails');
showdetails.forEach((showdetail,index) =>{
showdetail.style.display = 'block'
})
}
}
getAgent()
let searcInput = document.querySelector('.searchbox');
searcInput.addEventListener('input',function(){
const agentsName = document.querySelectorAll('.agentname')
let container = document.querySelector('.container')
const search = searcInput.value;
agentsName.forEach((agentName) =>{
agentName.parentElement.style.display = 'block';
container.style.height = '100%'
if(!agentName.innerHTML.toLowerCase().includes(search)){
agentName.parentElement.style.display = 'none';
container.style.height = "100vh"
}
})
})
@import url("https://fonts.googleapis.com/css2?family=Audiowide&display=swap");
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
width: 100vw;
}
a {
text-decoration: none;
color: black;
font-family: "Audiowide", cursive;
}
/*Navbar CSS*/
.navbar {
width: 100%;
background: #fe4655;
border-bottom: 1px solid #fe4655;
display: flex;
align-items: center;
justify-content: space-between;
height: 75px;
box-shadow: rgba(0, 0, 0, 0.16) 0px 3px 6px, rgba(0, 0, 0, 0.23) 0px 3px 6px;
}
.navlogo {
margin-left: 2rem;
display: flex;
align-items: center;
gap: 0.3rem;
}
.navlogo > p {
font-family: "Audiowide", cursive;
font-size: 25px;
color: white;
}
.navList {
display: flex;
justify-content: space-between;
width: 30rem;
margin-right: 5rem;
}
li {
list-style: none;
}
ul > li > a {
text-decoration: none;
font-family: "Audiowide", cursive;
color: black;
font-size: 23px;
transition-duration: 1s;
cursor: pointer;
}
ul > li > a:hover {
color: white;
position: relative;
bottom: 5px;
}
/*Body*/
.container {
height: 100%;
width: 100%;
background-image: linear-gradient(to right, #2a1925, #651830, #ff425c);
display: flex;
flex-direction: column;
align-items: center;
}
.search-input {
display: flex;
margin: 5rem auto;
}
.searchbox {
outline: none;
border: 1px;
padding: 0.5rem;
width: 20rem;
border-top-left-radius: 10px;
border-bottom-left-radius: 10px;
}
.searchbox::placeholder {
font-family: "Audiowide", cursive;
}
.searcBtn {
border: 1px solid;
padding: 0.5rem;
width: 5rem;
border-bottom-right-radius: 10px;
border-top-right-radius: 10px;
cursor: pointer;
color: white;
background-image: linear-gradient(to right, #2a1925, #651830, #ff425c);
}
.agent-container {
display: flex;
flex-wrap: wrap;
height: 100%;
gap: 3rem;
justify-content: center;
}
.agentbox {
width: 270px;
height: 350px;
border: 1px solid white;
border-radius: 20px;
display: block;
flex-direction: column;
justify-content: center;
align-items: center;
position: relative;
}
.agentbox > img {
height: 70%;
width: 100%;
}
.agentbox > h1 {
font-family: "Audiowide", cursive;
color: white;
text-align: center;
}
.agentbox > button {
padding: 0.5rem;
border-radius: 10px;
margin: 10px auto;
border: 1px solid;
cursor: pointer;
font-family: "Audiowide", cursive;
display: flex;
}
.showdetails {
position: absolute;
width: 270px;
height: 250px;
border: 1px solid white;
border-top-left-radius: 20px;
border-top-right-radius: 20px;
top: 0.01rem;
background: black;
opacity: 0.7;
flex-direction: column;
display: none;
left: 0.2px;
}
.showdetails > p {
text-align: center;
margin-top: 0.9rem;
font-family: "Franklin Gothic Medium", "Arial Narrow", Arial, sans-serif;
color: white;
}
.boxs {
display: flex;
justify-content: center;
align-items: center;
gap: 1rem;
margin-top: 0.9rem;
}
.box1,
.box2,
.box3,
.box4 {
height: 50px;
width: 50px;
display: flex;
flex-direction: column;
}
.box1 > img,
.box2 > img,
.box3 > img,
.box4 > img {
height: 100%;
width: 100%;
}
.box1 > p,
.box2 > p,
.box3 > p,
.box4 > p {
color: white;
font-size: 13px;
text-align: center;
}
.fa-xmark {
color: white;
position: relative;
left: 7rem;
top: 0.5rem;
cursor: pointer;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="stylesheet" href="main.css">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.2/css/all.min.css" integrity="sha512-1sCRPdkRXhBV2PBLUdRb4tMg1w2YPf37qatUFeS7zlBy7jJI8Lf4VHwWfZZfpXtYSLy85pkm9GaYVYMfw5BC1A==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<title>Document</title>
</head>
<body>
<nav >
<div >
<a href=""><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/44/Valorant_logo.svg/2560px-Valorant_logo.svg.png" alt="#" height="30px" width="150px"></a>
<p>-wiki</p>
</div>
<div >
<ul >
<li >
<a href="/Valorant_wiki/home page/index.html">Home</a>
</li>
<li>
<a href="#">About Us</a>
</li>
<li>
<a href="#">Contact</a>
</li>
</ul>
</div>
</nav>
<div >
<div >
<input type="text" placeholder="Search Agents...">
<button ><i ></i></button>
</div>
<div >
</div>
</div>
</div>
<script src="app.js"></script>
</body>
</html>
CodePudding user response:
If you call document.querySelectorAll(...)
you will get all matching elements over the whole document. That's why all info boxes are being displayed after clicking the "View" button.
function showInfos(e){
/* !!! open view buttons*/
let showdetails = document.querySelectorAll('.showdetails');
showdetails.forEach((showdetail,index) =>{
showdetail.style.display = 'block'
});
}
Simply change the code to:
function showInfos(e) {
const showdetails = e.target.querySelector('.showdetails');
showdetails.style.display = 'block';
}
This will get the reference to the clicked element (the button) and execute the query on that element.
Fully working example
const getAgent = async() =>{
let url = 'https://valorant-api.com/v1/agents'
let res = await fetch(url);
let data = await res.json()
createAgentBox(data);
}
const createAgentBox = (element) =>{
const agentContainer = document.querySelector('.agent-container');
let agents = element.data;
agents.forEach(agent =>{
let agentName = agent.displayName;
let agentImage = agent.fullPortrait;
let desc = agent.description;
let abilitiesImage1 = agent.abilities[0].displayIcon;
let abilitiesImage2 = agent.abilities[1].displayIcon;
let abilitiesImage3 = agent.abilities[2].displayIcon;
let abilitiesImage4 = agent.abilities[3].displayIcon;
let abilitiesName1 = agent.abilities[0].displayName;
let abilitiesName2 = agent.abilities[1].displayName;
let abilitiesName3 = agent.abilities[2].displayName;
let abilitiesName4 = agent.abilities[3].displayName;
let x = `<div >
<img src=${agentImage} alt="">
<h1 class='agentname'>${agentName}</h1>
<button >View
<div >
<i ></i>
<p>${desc}</p>
<div class='boxs'>
<div >
<img src=${abilitiesImage1} alt="">
<p>${abilitiesName1}</p>
</div>
<div >
<img src=${abilitiesImage2} alt="">
<p>${abilitiesName2}</p>
</div>
<div >
<img src=${abilitiesImage3} alt="">
<p>${abilitiesName3}</p>
</div>
<div >
<img src=${abilitiesImage4} alt="">
<p>${abilitiesName4}</p>
</div>
</div>
</div>
</div>
</button>
</div>`
agentContainer.innerHTML = x;
});
let seeDetails = document.querySelectorAll('.seeDetails')
seeDetails.forEach(seeDetail =>{
seeDetail.addEventListener('click', showInfos)
})
function showInfos(e) {
const showdetails = e.target.querySelector('.showdetails');
showdetails.style.display = 'block';
}
}
getAgent()
let searcInput = document.querySelector('.searchbox');
searcInput.addEventListener('input',function(){
const agentsName = document.querySelectorAll('.agentname')
let container = document.querySelector('.container')
const search = searcInput.value;
agentsName.forEach((agentName) =>{
agentName.parentElement.style.display = 'block';
container.style.height = '100%'
if(!agentName.innerHTML.toLowerCase().includes(search)){
agentName.parentElement.style.display = 'none';
container.style.height = "100vh"
}
})
})
@import url("https://fonts.googleapis.com/css2?family=Audiowide&display=swap");
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
width: 100vw;
}
a {
text-decoration: none;
color: black;
font-family: "Audiowide", cursive;
}
/*Navbar CSS*/
.navbar {
width: 100%;
background: #fe4655;
border-bottom: 1px solid #fe4655;
display: flex;
align-items: center;
justify-content: space-between;
height: 75px;
box-shadow: rgba(0, 0, 0, 0.16) 0px 3px 6px, rgba(0, 0, 0, 0.23) 0px 3px 6px;
}
.navlogo {
margin-left: 2rem;
display: flex;
align-items: center;
gap: 0.3rem;
}
.navlogo > p {
font-family: "Audiowide", cursive;
font-size: 25px;
color: white;
}
.navList {
display: flex;
justify-content: space-between;
width: 30rem;
margin-right: 5rem;
}
li {
list-style: none;
}
ul > li > a {
text-decoration: none;
font-family: "Audiowide", cursive;
color: black;
font-size: 23px;
transition-duration: 1s;
cursor: pointer;
}
ul > li > a:hover {
color: white;
position: relative;
bottom: 5px;
}
/*Body*/
.container {
height: 100%;
width: 100%;
background-image: linear-gradient(to right, #2a1925, #651830, #ff425c);
display: flex;
flex-direction: column;
align-items: center;
}
.search-input {
display: flex;
margin: 5rem auto;
}
.searchbox {
outline: none;
border: 1px;
padding: 0.5rem;
width: 20rem;
border-top-left-radius: 10px;
border-bottom-left-radius: 10px;
}
.searchbox::placeholder {
font-family: "Audiowide", cursive;
}
.searcBtn {
border: 1px solid;
padding: 0.5rem;
width: 5rem;
border-bottom-right-radius: 10px;
border-top-right-radius: 10px;
cursor: pointer;
color: white;
background-image: linear-gradient(to right, #2a1925, #651830, #ff425c);
}
.agent-container {
display: flex;
flex-wrap: wrap;
height: 100%;
gap: 3rem;
justify-content: center;
}
.agentbox {
width: 270px;
height: 350px;
border: 1px solid white;
border-radius: 20px;
display: block;
flex-direction: column;
justify-content: center;
align-items: center;
position: relative;
}
.agentbox > img {
height: 70%;
width: 100%;
}
.agentbox > h1 {
font-family: "Audiowide", cursive;
color: white;
text-align: center;
}
.agentbox > button {
padding: 0.5rem;
border-radius: 10px;
margin: 10px auto;
border: 1px solid;
cursor: pointer;
font-family: "Audiowide", cursive;
display: flex;
}
.showdetails {
position: absolute;
width: 270px;
height: 250px;
border: 1px solid white;
border-top-left-radius: 20px;
border-top-right-radius: 20px;
top: 0.01rem;
background: black;
opacity: 0.7;
flex-direction: column;
display: none;
left: 0.2px;
}
.showdetails > p {
text-align: center;
margin-top: 0.9rem;
font-family: "Franklin Gothic Medium", "Arial Narrow", Arial, sans-serif;
color: white;
}
.boxs {
display: flex;
justify-content: center;
align-items: center;
gap: 1rem;
margin-top: 0.9rem;
}
.box1,
.box2,
.box3,
.box4 {
height: 50px;
width: 50px;
display: flex;
flex-direction: column;
}
.box1 > img,
.box2 > img,
.box3 > img,
.box4 > img {
height: 100%;
width: 100%;
}
.box1 > p,
.box2 > p,
.box3 > p,
.box4 > p {
color: white;
font-size: 13px;
text-align: center;
}
.fa-xmark {
color: white;
position: relative;
left: 7rem;
top: 0.5rem;
cursor: pointer;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="stylesheet" href="main.css">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.2/css/all.min.css" integrity="sha512-1sCRPdkRXhBV2PBLUdRb4tMg1w2YPf37qatUFeS7zlBy7jJI8Lf4VHwWfZZfpXtYSLy85pkm9GaYVYMfw5BC1A==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<title>Document</title>
</head>
<body>
<nav >
<div >
<a href=""><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/44/Valorant_logo.svg/2560px-Valorant_logo.svg.png" alt="#" height="30px" width="150px"></a>
<p>-wiki</p>
</div>
<div >
<ul >
<li >
<a href="/Valorant_wiki/home page/index.html">Home</a>
</li>
<li>
<a href="#">About Us</a>
</li>
<li>
<a href="#">Contact</a>
</li>
</ul>
</div>
</nav>
<div >
<div >
<input type="text" placeholder="Search Agents...">
<button ><i ></i></button>
</div>
<div >
</div>
</div>
</div>
<script src="app.js"></script>
</body>
</html>