Have seen similar questions but in my case am handling dynamic data from an API. Want when the user clicks the message with only Subject then the body shows and after the user can click again for the body to hide. it works fine but want to add that functinality
if(data.status == 200){
data.data.forEach(message => {
msg += `
<div id="read">
<p id="header">${message.subject}<span>......</span></span></p>
<p id="body">${message.message_details}</p>
<p>Sent on: ${message.created_on}</p>
</div>
<hr>`
});
document.getElementById("inbox").innerHTML = msg
}```
first, you need to add all of your dynamic blocks inside a wrapper div
let's call it articles
for example
after that, you need to add eventListener
at this wrapper to listen for click
event then check if the clicked element is the title toggle the hide
class that is predefined in the css
like this example below
const wrapperEl = document.querySelector('#articles'); wrapperEl.addEventListener('click', function(e){ if(e.target.id == 'header'){ e.target.nextElementSibling.classList.toggle('hide') } });
.hide { display: none }
<div id="articles"> <div> <p id="header">title 1<span>......</span></p> <p id="body" class="hide">article content here</p> <p>Sent on: 02/17/2020</p> </div> <hr /> <div> <p id="header">title 2<span>......</span></p> <p id="body" class="hide">article content here</p> <p>Sent on: 02/17/2020</p> </div> <hr /> <div> <p id="header">title 3<span>......</span></p> <p id="body" class="hide">article content here</p> <p>Sent on: 02/17/2020</p> </div> <hr /> <div> <p id="header">title 4<span>......</span></p> <p id="body" class="hide">article content here</p> <p>Sent on: 02/17/2020</p> </div> </div>
NOTE : in this example, i just added some hardcoded blocks for testing but in your case, it will become from
API
in a dynamic way but in booth case, it should be inside a wrapper element
Added the missing code to hide body div
, and use class="body"
instead of id
for paragraph and div element, because these will be repeated.
const data = [ {subject: "test123", message_details: "msg123", created_on: "12-05-2021"}, {subject: "test456", message_details: "msg456", created_on: "02-05-2020"}, {subject: "test789", message_details: "msg789", created_on: "11-07-2011"}, ]; let msg = ""; data.forEach(message => { msg += ` <div class="read"> <p id="header">${message.subject}<span>......</span></span></p> <p class="body">${message.message_details}</p> <p>Sent on: ${message.created_on}</p> </div> <hr>` }); document.getElementById("inbox").innerHTML = msg; const bodyElements = document.querySelectorAll(".read"); bodyElements.forEach(function(bodyEle) { bodyEle.addEventListener("click", (e) => { bodyEle.children[1].classList.toggle("hide"); }); });
.hide { display: none; }
<html> <head></head> <body> <h1>My title</h1> <div id="inbox"> </div> </body> </html>
First of all, you shouldn't use ids, because you will have the same id multiple times. So, you should make them class.
Let's say you use axios, or fetch API, doesn't matter actually:
axis.get('api-url').then(response => {
// create your HTML outputs here
}).then(() => {
document.querySelectorAll('.header').forEach(x => x.addEventListener('click', toggleBody));
})
const toggleBody = (event) => {
event.closest('.read').querySelector('.body').classList.toggle('is-open')
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.