简体   繁体   中英

How do I add an onclick to a div to display or hide data

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM