-1

I have a background image within a button that I would like to rotate/flip when the button is clicked. The background image is a down arrow, and I would like it to flip to a up arrow. The button is for a collapsible drawer, so I would like the arrow to flip back when the drawer is closed. The button open and closes the drawer, and the background image is applied through CSS.

    document.querySelectorAll(".collapsible").forEach((coll) => {
      coll.addEventListener("click", () => {
        coll.classList.toggle("active");

        const content = coll.nextElementSibling;

        if (content.style.maxHeight) {
          content.style.maxHeight = null;
          // Add this:
          content.style.borderWidth = 0;
        } else {
          content.style.maxHeight = content.scrollHeight + "px";
          // And this:
          content.style.borderWidth = "1px";
        }
      });
    });

function myFunction() {
  var element = document.getElementById("toggling");
  element.classList.toggle("toggled");
  };
    .content {
      padding: 0 18px;
      max-height: 0;
      overflow: hidden;
      transition:
      border 0.2s ease-out,
      max-height 0.2s ease-out;
      background-color: white;
      border: 0px solid #D1D3D4;
      border-radius: 3px;
    }

    .collapsible {
      background-color: white;
      color: #021032;
      cursor: pointer;
      padding: 14px;
      width: 100%;
      border: solid 1px #D1D3D4;
      border-radius: 6px;
      text-align: left;
      outline: none;
      font-size: 15px;
      margin: 5px 0px;
    }

    button {

      background-image: url("../images/upArrow.svg");
      background-repeat: no-repeat;
      background-position: right;
      background-size: 25px;
      font-weight: 900;

    }

.toggled {

  background-image: url("../images/downArrow.svg");
  background-repeat: no-repeat;
  background-position: right;
  background-size: 25px;
  font-weight: 900;

}
<button type="button" class="collapsible" onclick="myFunction()" id="toggling"> Consult Logs </button>

    <div class="content">
      <div class="column">
        <p>Ensure the disc strength is not at “0”.</p>
      </div>
      <div class="column">
        <img src="../images/discStrength.png" alt="Picture of Logs">
      </div>
    </div>

    <button type="button" class="collapsible" disabled> Ensure All Connectors to Nebuliser Boards are Fully Connected </button>

    <button type="button" class="collapsible" onclick="myFunction()" id="toggling"> Loose Crimp Issue </button>

    <div class="content">
      <div class="column">
        <p>Check that the wires and crimps are fully inserted into J1, J4, and trandsducer connectors.</p>
      </div>
      <div class="column">
        <img src="../images/looseCrimp.png" alt="Picture of Connectors">
      </div>
    </div>
Jason
  • 27
  • 5
  • Does this answer your question? [How to rotate the background image in the container?](https://stackoverflow.com/questions/5087420/how-to-rotate-the-background-image-in-the-container) – Sysix Feb 20 '23 at 23:44
  • No, unfortunately it did not. – Jason Feb 20 '23 at 23:45
  • 1
    you will have to toggle a class that apply a rotate transform with css. or you can rotate directly from JS. feel free to post what you tried ;) – lovis91 Feb 20 '23 at 23:56
  • 1
    toggle a class on `.collapsible.open{}` which contains the diff image or transform – Lawrence Cherone Feb 20 '23 at 23:56
  • Could you show me what that would look like? I am still learning and I am unsure on how to implement that. – Jason Feb 20 '23 at 23:59
  • 1
    search in google "how to toggle a class with javascript" and "how to rotate and element with css" – lovis91 Feb 21 '23 at 00:01
  • Oh my gosh! I did it, thank you so much, this was a great learning experience. I will update the question with my successful attempt. You friends, are legends. – Jason Feb 21 '23 at 00:11
  • Hmm I might have gotten a little too excited, it is applied to an ID, but I would like it to be applied to a class, because you can't multiples of the same ID right? – Jason Feb 21 '23 at 00:16
  • show us your updated code. maybe we can help more :) – Sysix Feb 21 '23 at 00:21

1 Answers1

3

I don't want to take away from your learning journey, but I thought I'd point out that you were already setting an active class on your button. That means you could just tap into that active class to rotate your icon.

Below I created a separate div so that I could just rotate that div when the active class is applied to the button. You could also do this with an ::after pseudo element and keep your markup clean. If you had two separate images, you could just swap the background-image. Hopefully this inspires you to try all of these options to keep learning new techniques.

document.querySelectorAll(".collapsible").forEach((coll) => {
  coll.addEventListener("click", () => {
    coll.classList.toggle("active"); //<-- you're already toggling this class

    const content = coll.nextElementSibling;

    if (content.style.maxHeight) {
      content.style.maxHeight = null;
      // Add this:
      content.style.borderWidth = 0;
    } else {
      content.style.maxHeight = content.scrollHeight + "px";
      // And this:
      content.style.borderWidth = "1px";
    }
  });
});
.content {
  padding: 0 18px;
  max-height: 0;
  overflow: hidden;
  transition:
  border 0.2s ease-out,
  max-height 0.2s ease-out;
  background-color: white;
  border: 0px solid #D1D3D4;
  border-radius: 3px;
}

.collapsible {
  background-color: white;
  color: #021032;
  cursor: pointer;
  padding: 14px;
  width: 100%;
  border: solid 1px #D1D3D4;
  border-radius: 6px;
  text-align: left;
  outline: none;
  font-size: 15px;
  margin: 5px 0px;
}

button {
  font-weight: 900;
  /* 
  I put your background image in
  its own div so I removed it from
  the button styles.
  
  I added flex to make it easier to 
  align the image and push it to the 
  right inside the button.
  */
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.icon {
  /* 
  I just added an inline SVG so you 
  see it working in the snippet, but you
  can use your existing local image.
  */
  background-image: url("data:image/svg+xml,%3Csvg stroke='currentColor' fill='currentColor' stroke-width='0' viewBox='0 0 16 16' height='1em' width='1em' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M16 8A8 8 0 1 0 0 8a8 8 0 0 0 16 0zm-7.5 3.5a.5.5 0 0 1-1 0V5.707L5.354 7.854a.5.5 0 1 1-.708-.708l3-3a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1-.708.708L8.5 5.707V11.5z'%3E%3C/path%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-size: 25px;
  /*
  Added height and width to the div
  the same size as your background-size
  since it doesn't have an content
  */
  height: 25px;
  width: 25px;
  /* 
  Added a transition so it rotates smoothly
  between the two states
  */
  transition: rotate .25s ease-in-out;
}

button.active > .icon {
  /*
  When the button has the active class
  apply the rotate to any direct child
  with the clas of icon.
  */
  rotate: 180deg;
}
<button type="button" class="collapsible"> Consult Logs <div class="icon"><div></button>

<div class="content">
  <div class="column">
    <p>Ensure the disc strength is not at “0”.</p>
  </div>
  <div class="column">
    <img src="../images/discStrength.png" alt="Picture of Logs">
  </div>
</div>
jme11
  • 17,134
  • 2
  • 38
  • 48