Iterate through a nodelist and on-click toggle the its content

Viewed 55

I have created a set of questions and answers, using a function to loop through an array of objects, this part is working fine, the issue is that I only want the answers to show once a question is clicked, but my addEventListner is not working. Can anyone help please?

$(document).ready(function() {
  $(renderReturns()).appendTo('#Returns');
})

let renderReturns = () => {
  let returnsCard = "";
  for (let i = 0; i < returnContent.length; i++) {
    returnsCard += `<div class="question-container"> <div class="questions"> <a onclick=""><h3>${returnContent[i].question}</h3></a><img src="${returnContent[i].icon}" class="toggle-icon"> </div> <div class="answer" hidden><p>${returnContent[i].answer}</p></div></div>`
  }
  return `<div class="returnsWrapper">${returnsCard}</div>`
}

let questions = document.querySelectorAll('.questions');
let answers = document.querySelectorAll('.answer');
questions.forEach(question => {
  question.addEventListener('click', (e) => {
    console.log("It's alive, it's ALIVE!")
  })
})

let returnContent = [{
    question: "How do I return an item?",
    icon: "https://via.placeholder.com/50x50",
    answer: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
  },
  {
    question: "NEW! Instant Returns with InPost Lockers",
    icon: "https://via.placeholder.com/50x50",
    answer: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
  },
  {
    question: "What happens if I miss my delivery?",
    icon: "https://via.placeholder.com/50x50",
    answer: "Our carrier delivers between 9am and 10pm, which may vary depending on the service selected and a signature is required. <br> There are a number of options available if you think you won't be in to sign for your order. We'll pass your e-mail address and mobile number (if provided) to Hermes or DPD and they'll provide you with information about your delivery by e-mail or text message the evening before. <br> Please note deliveries outside of the UK can take anything up to 10 days. Follow your order using the tracking link in your despatch email to check if any delivery attempt has been made.",
  },
  {
    question: "Can I track my delivery?",
    icon: "https://via.placeholder.com/50x50",
    answer: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
  },
  {
    question: "Do I pay customs or import charges?",
    icon: "https://via.placeholder.com/50x50",
    answer: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
  },
  {
    question: "Can I change my address after ordering?",
    icon: "https://via.placeholder.com/50x50",
    answer: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
  },
  {
    question: "Is the site secure?",
    icon: "https://via.placeholder.com/50x50",
    answer: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
  },
]
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="tab-content" id="Returns">
  <div class="title-container">
    <p>Returns</p>
  </div>
</div>

1 Answers

To achieve this you need to relate the .question element which was clicked on to its child .answer. To do that you can use jQuery's next() method.

In addition the logic which creates the HTML from the array of objects and also that which attaches the event handlers can be simplified greatly by using jQuery more effectively; if you've already included it in the page you may as well use it.

Try this:

jQuery($ => {
  let questionHtml = returnContent.map(obj => `<div class="question-container"><div class="questions"> <a onclick=""><h3>${obj.question}</h3></a><img src="${obj.icon}" class="toggle-icon"></div><div class="answer" hidden><p>${obj.answer}</p></div></div>`).join('');
  $('#Returns').append(`<div class="returnsWrapper">${questionHtml}</div>`);

  $('.questions').on('click', e => $(e.currentTarget).next('.answer').toggle());
})

let returnContent = [{
    question: "How do I return an item?",
    icon: "https://via.placeholder.com/50x50",
    answer: "Lorem ipsum dolor sit amet...",
  }, {
    question: "NEW! Instant Returns with InPost Lockers",
    icon: "https://via.placeholder.com/50x50",
    answer: "Lorem ipsum dolor sit amet...",
  }, {
    question: "What happens if I miss my delivery?",
    icon: "https://via.placeholder.com/50x50",
    answer: "Our carrier delivers between 9am and 10pm, which may vary depending on the service selected and a signature is required....",
  }
  // truncated for brevity...
]
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="tab-content" id="Returns">
  <div class="title-container">
    <p>Returns</p>
  </div>
</div>

Related