Home > Blockchain >  Toggle text inserted with innerHTML from Javascript
Toggle text inserted with innerHTML from Javascript

Time:10-22

As an exercise I am trying to create a small quiz app and a part of it are the question cards. On these cards I have a question and then a button to show the answer. When the button is clicked, then the answer (which doesn't exist in the HTML DOM yet, therefore not visible) will show up and with the next click, the answer should be hidden again. Basically it will look something like this:

Before Show Answer is clicked

After Show Answer is clicked

Here is the HTML code:

<section >
  <p>
    Lorem ipsum dolor sit amet consectetur adipisicing elit. Ipsam vitae
    labore repudiandae tenetur. Qui maiores animi quibusdam voluptatum
    nobis. Nam aperiam voluptatum dolorem quia minima assumenda velit libero
    saepe repellat. Tempore delectus deleniti libero aliquid rem velit illum
    expedita nostrum quam optio maiores officiis consequatur ea, sint enim
    cum repudiandae inventore ab nemo?
  </p>
  <div >
    <i ></i>
  </div>
  <button  data-js="answer-button">Show Answer</button>
  <ul  data-js="answer-container">
  </ul>
  <div >
    <button >#html</button>
    <button >#flexbox</button>
    <button >#css</button>
    <button >#js</button>
  </div>
</section>

I have added an EventListener for the Show Answer button that adds a list item in the already existing ul when it is clicked. I have done this with innerHTML:

const answerButton = document.querySelector(".answer-button");
const answerContainer = document.querySelector(".answer-container");
const answer1 = "Lorem ipsum dolor sit amet consectetur adipisicing elit.";

answerButton.addEventListener("click", () => {
  answerContainer.innerHTML = `<li >${answer1}</li>`;
});

Now what I can't seem to manage is to hide the answer when the button is clicked again (the next challenge will be that the button will change the text to "Hide Answer" after the first click, but I have no idea how to approach that yet). The closest I got was this:

answerButton.addEventListener("click", () => {
  answerContainer.innerHTML = `<li >${answer1}</li>`;
 answerContainer.classList.toggle("hide-answer");
});

However, this method displays the .hide-answer class first, after which the 2 classes are toggled and everything is as it should be. So after the first click, the answer is still hidden and only after the 2nd click the button behaves the way I want it to.

I have tried this as well:

answerButton.addEventListener("click", () => {
  answerContainer.innerHTML = `<li >${answer1}</li>`;
  answerContainer.classList.toggle("show-answer");
});

But for some reason this shows the container with all the CSS properties, but there is no text:

Answer Container is there, but no text

This is the CSS for the 2 classes (show-answer and hide-answer):

.show-answer {
background-color: hotpink;
border-radius: 7px;
border: none;
list-style: none;
width: 50%;
display: flex;
justify-content: center;
align-items: center;
padding: 1rem;
box-shadow: rgba(0, 0, 0, 0.3) 0px 19px 38px;
}

.hide-answer {
display: none;
}

If anybody has any idea how I could get the result I need, I would be extremely grateful...

CodePudding user response:

Would something like this work?

You just use if the container has the class show-answer to determine if the answer needs to be shown or hidden

answerButton.addEventListener("click", () => {

    if (answerContainer.classList.contains('show-answer')) {
        // container has `showing` class
        // hide the answer
        answerContainer.innerHTML = ``; // ? - my guess, not sure how to want to hide it
    }else{
        // container doesn't have `showing` class
        // show the answer
        answerContainer.innerHTML = `<li >${answer1}</li>`;
    };

    // update class
    answerContainer.classList.toggle("show-answer");

});

CodePudding user response:

You're mixing up the answer-container with the answer-container's child (the innerHtml <li> element).

  1. initially there's a visible, but empty <ul ></ul>.

  2. Next on click of the button, you add the content into the answer-container expecting it to be visible with a show-answer class

  3. Immediately after, you add the hide-answer class to the <ul > parent element which hides the newly added content.

  4. Click the button again and you finally see your answer because the container element has the hide-answer class toggled off. From here it works as you're expecting.

You can fix this by having the answer-container be hidden initially and then continue to toggle the display of the container. You can also just use a DOM element's hidden attribute to do this as I do in this code snippet below where I've taken your exact example and just modified the answer-container to start with hidden and toggle the hidden attribute on click. You can do the same thing w/ a CSS display: none class too.

const answerButton = document.querySelector(".answer-button");
const answerContainer = document.querySelector(".answer-container");
const answer1 = "Lorem ipsum dolor sit amet consectetur adipisicing elit.";

answerButton.addEventListener("click", () => {
   answerContainer.innerHTML = `<li >${answer1}</li>`;
   answerContainer.hidden = !answerContainer.hidden;
});
.answer {
  background-color: hotpink;
  border-radius: 7px;
  border: none;
  list-style: none;
  width: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 1rem;
  box-shadow: rgba(0, 0, 0, 0.3) 0px 19px 38px;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<section >
  <p>
    Lorem ipsum dolor sit amet consectetur adipisicing elit. Ipsam vitae
    labore repudiandae tenetur. Qui maiores animi quibusdam voluptatum
    nobis. Nam aperiam voluptatum dolorem quia minima assumenda velit libero
    saepe repellat. Tempore delectus deleniti libero aliquid rem velit illum
    expedita nostrum quam optio maiores officiis consequatur ea, sint enim
    cum repudiandae inventore ab nemo?
  </p>
  <div >
    <i ></i>
  </div>
  <button  data-js="answer-button">Show Answer</button>
  <ul  hidden data-js="answer-container">
  </ul>
  <div >
    <button >#html</button>
    <button >#flexbox</button>
    <button >#css</button>
    <button >#js</button>
  </div>
</section>

  • Related