Home > Net >  Accordion not working correctly (active states not being applied for each parent instance)
Accordion not working correctly (active states not being applied for each parent instance)

Time:04-17

I have accordions which on click, grow in height and also changes the image to what is relevant to that section (this is done based on data-id).

Here are the requirements that I'm trying to achieve:

  • Each accordion group is contained within .accordionRepeater__wrapper and for each instance of that class, I'm trying to get the first .accordionCard. to have the open state.
  • Only have the first .accordionCard in each accordionRepeater__wrapper open on page load, so the user can see some content by default.
  • Only have one .accordionCard in each accordionRepeater__wrapper open at a time (user cannot have two or more accordionCard open in a accordionRepeater__wrapper at one time).

Currently results:

  • The first .accordionCard in the first .accordionRepeater__wrapper has the class of .accordionCard--open on page load, but doesn't show the content for it.
  • The first instance of .accordionCard in the second .accordionRepeater__wrapper doesn't have the class of .accordionCard--open and doesn't show the image. Only when I click on it does the image and content show.

See my attempt here:

$(function() {

  const card = $(".accordionCard");
  const expand_icon = $(".accordionCard__expand");


  // open first accordion in each .accordionRepeater__wrapper by default
  $(".accordionCard:first accordionCard__expand").addClass("expanded");
  $(".accordionCard:first").addClass("accordionCard--open");
  $(".accordionRepeater__image:first").addClass("d-block");


  card.click(function() {
    var hidden = $(this).children(".accordionCard__body--hidden");

    // only have one card open at a time
    expand_icon.removeClass("expanded");
    card.removeClass("accordionCard--open");

    /* CLOSE CARD */

    if ($(this).hasClass("accordionCard--open")) {
      TweenMax.to(hidden, 0.3, {
        height: 0,
        immediateRender: false,
        ease: Power1.easeOut
      });
      $(this).removeClass("accordionCard--open");
      $(this).find(expand_icon).removeClass("expanded");
    }

    /* OPEN CARD */
    else {
      TweenMax.set(hidden, {
        height: "auto"
      });
      TweenMax.from(hidden, 1, {
        height: 0,
        immediateRender: false,
        ease: Back.easeOut
      });
      $(this).addClass("accordionCard--open");
      $(this).find(expand_icon).addClass("expanded");

      // show correct image
      var id = $(this).attr('data-item');
      $(".accordionRepeater__image").removeClass("d-block");
      $(".accordionRepeater__image[data-item='"   id   "']").addClass("d-block");
    }

    /* END */

  });



});
:root {
  --green: #089F84;
  --white-2: #F7F7F7;
  --black-2: #2C3645;
}

.accordionRepeater {
  padding: 130px 0 156px 0;
}

.accordionRepeater__wrapper {
  padding-bottom: 140px;
}

.accordionRepeater__wrapper:last-child {
  padding-bottom: 0;
}

.accordionRepeater__row--even {
  flex-direction: row-reverse;
}

.accordionRepeater .accordionCard {
  margin: 13px 0;
  cursor: pointer;
  padding-left: 26px;
}

.accordionRepeater .accordionCard:hover .accordionCard__body-label {
  color: var(--green);
}

.accordionRepeater .accordionCard--open {
  background-color: var(--white-2);
  padding: 36px 48px 45px 26px;
  border-radius: 10px;
}

.accordionRepeater .accordionCard__expand {
  position: absolute;
}

.accordionRepeater .accordionCard__expand:before,
.accordionRepeater .accordionCard__expand:after {
  content: "";
  display: block;
  position: absolute;
  top: 50%;
  transform: translate(0px, 10px);
  right: 0;
  margin: 0 0 -8px;
  background-color: var(--green);
  border-radius: 5px;
}

.accordionRepeater .accordionCard__expand:before {
  right: 8px;
  width: 3px;
  height: 16px;
  transition: all 0.5s ease;
  margin-top: -7.5px;
}

.accordionRepeater .accordionCard__expand:after {
  right: 1px;
  width: 16px;
  height: 3px;
  margin-top: -1.5px;
}

.accordionRepeater .accordionCard__expand.expanded:before,
.accordionRepeater .accordionCard__expand.expanded:after {
  background-color: var(--black-2);
}

.accordionRepeater .accordionCard__expand.expanded:before {
  height: 0;
  margin-top: 0;
}

.accordionRepeater .accordionCard__body {
  margin-left: 20px;
}

.accordionRepeater .accordionCard__body--visible {
  width: 100%;
}

.accordionRepeater .accordionCard__body--hidden {
  overflow: hidden;
  height: 0;
}

.accordionRepeater .accordionCard__body-label {
  transition: all 0.5s ease;
  margin-left: 20px;
}

.accordionRepeater .accordionCard__body-copy {
  padding: 24px 0 17px 0;
}

.accordionRepeater .accordionCard__body-link {
  transition: none;
}

.accordionRepeater__image {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP u1T9qYdvdihz0PPSiiqn/ /3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/gsap.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

<div >

  <div >

    <!-----------
     -- FIRST SET
     -------------->

    <div >
      <div >
        <div >
          <div >

            <div >

              <!-- CARD 1 -->

              <div  data-item="1">
                <div >
                  <div ></div>
                  <span >Lorum</span>
                </div>
                <div >
                  <div >
                    <p>Lorum ipsum</p>
                  </div>
                </div>
              </div>

              <!-- CARD 2 -->

              <div  data-item="2">
                <div >
                  <div ></div>
                  <span >Lorum 2</span>
                </div>
                <div >
                  <div >
                    <p>Lorum ipsum 2</p>
                  </div>
                </div>
              </div>

              <!-- CARD END -->

            </div>
          </div>
        </div>


        <div >
          <div >
            <img  src="https://picsum.photos/500" alt="placeholder-graphic" loading="lazy" style="max-width: 100%; height: auto;" data-item="1">
            <img  src="https://picsum.photos/550" alt="placeholder-graphic" loading="lazy" style="max-width: 100%; height: auto;" data-item="2">
            <img  src="https://picsum.photos/500" alt="placeholder-graphic" loading="lazy" style="max-width: 100%; height: auto;" data-item="3">
          </div>
        </div>

      </div>
    </div>

    <!-----------
    -- FIRST SET END
    -------------->

    <!-----------
     -- SECOND SET
     -------------->

    <div >
      <div >
        <div >
          <div >

            <div >

              <!-- CARD 1 -->

              <div  data-item="1">
                <div >
                  <div ></div>
                  <span >Lorum</span>
                </div>
                <div >
                  <div >
                    <p>Lorum ipsum</p>
                  </div>
                </div>
              </div>

              <!-- CARD END -->

            </div>
          </div>
        </div>


        <div >
          <div >
            <img  src="https://picsum.photos/500" alt="placeholder-graphic" loading="lazy" style="max-width: 100%; height: auto;" data-item="1">
          </div>
        </div>

      </div>
    </div>

    <!-----------
    -- SECOND SET END
    -------------->

  </div>
</div>

CodePudding user response:

Change this line:

if ($(this).hasClass("accordionCard--open")) {

To:

if ($(this).hasClass("accordionCard--open") == true) {

Otherwise, it doesn't really do anything. I Hope this is what you needed!

CodePudding user response:

You are not expanding the accordions at the start. You are doing it only on click.
Also the method needs to handle expansion and close at set level. And not globally.

It can be done like this:

$(function() {
  const card = $('.accordionCard');
  const expand_icon = $('.accordionCard__expand');

  $('.accordionCard:first-child').each((i, a) => toggleAc(a));

  card.click(function() {
    toggleAc(this);
  });

  // expand/close given accordions
  function toggleAc(acdn) {
    var hidden = $(acdn).children('.accordionCard__body--hidden');
    const isOpen = $(acdn).hasClass('accordionCard--open');

    /* CLOSE CARD */
    if (isOpen) {
      TweenMax.to(hidden, 0.3, {
        height: 0,
        immediateRender: false,
        ease: Power1.easeOut,
      });
      $(acdn).removeClass('accordionCard--open');
      $(acdn).find(expand_icon).removeClass('expanded');
      
    } else {
      // close previous card in the same set
      const parent = $(acdn).parent();
      const expandedCard = parent.find('.accordionCard--open');
      const expandedIcon = parent.find('.expanded');
      const expandedCardHidden = expandedCard.children('.accordionCard__body--hidden');
      TweenMax.to(expandedCardHidden, 0.3, {
        height: 0,
        immediateRender: false,
        ease: Power1.easeOut,
      });
      expandedIcon.removeClass('expanded');
      expandedCard.removeClass('accordionCard--open');

      /* OPEN CARD */
      TweenMax.set(hidden, {
        height: 'auto',
      });
      TweenMax.from(hidden, 1, {
        height: 0,
        immediateRender: false,
        ease: Back.easeOut,
      });
      $(acdn).addClass('accordionCard--open');
      $(acdn).find(expand_icon).addClass('expanded');

      // show correct image
      var id = $(acdn).attr('data-item');
      const grandParent = parent.parent().parent().parent();
      grandParent.find('.accordionRepeater__image').removeClass('d-block');
      grandParent
        .find(".accordionRepeater__image[data-item='"   id   "']")
        .addClass('d-block');
    }

    /* END */
  }
});
:root {
  --green: #089f84;
  --white-2: #f7f7f7;
  --black-2: #2c3645;
}

.accordionRepeater {
  padding: 130px 0 156px 0;
}

.accordionRepeater__wrapper {
  padding-bottom: 140px;
}

.accordionRepeater__wrapper:last-child {
  padding-bottom: 0;
}

.accordionRepeater__row--even {
  flex-direction: row-reverse;
}

.accordionRepeater .accordionCard {
  margin: 13px 0;
  cursor: pointer;
  padding-left: 26px;
}

.accordionRepeater .accordionCard:hover .accordionCard__body-label {
  color: var(--green);
}

.accordionRepeater .accordionCard--open {
  background-color: var(--white-2);
  padding: 36px 48px 45px 26px;
  border-radius: 10px;
}

.accordionRepeater .accordionCard__expand {
  position: absolute;
}

.accordionRepeater .accordionCard__expand:before,
.accordionRepeater .accordionCard__expand:after {
  content: '';
  display: block;
  position: absolute;
  top: 50%;
  transform: translate(0px, 10px);
  right: 0;
  margin: 0 0 -8px;
  background-color: var(--green);
  border-radius: 5px;
}

.accordionRepeater .accordionCard__expand:before {
  right: 8px;
  width: 3px;
  height: 16px;
  transition: all 0.5s ease;
  margin-top: -7.5px;
}

.accordionRepeater .accordionCard__expand:after {
  right: 1px;
  width: 16px;
  height: 3px;
  margin-top: -1.5px;
}

.accordionRepeater .accordionCard__expand.expanded:before,
.accordionRepeater .accordionCard__expand.expanded:after {
  background-color: var(--black-2);
}

.accordionRepeater .accordionCard__expand.expanded:before {
  height: 0;
  margin-top: 0;
}

.accordionRepeater .accordionCard__body {
  margin-left: 20px;
}

.accordionRepeater .accordionCard__body--visible {
  width: 100%;
}

.accordionRepeater .accordionCard__body--hidden {
  overflow: hidden;
  height: 0;
}

.accordionRepeater .accordionCard__body-label {
  transition: all 0.5s ease;
  margin-left: 20px;
}

.accordionRepeater .accordionCard__body-copy {
  padding: 24px 0 17px 0;
}

.accordionRepeater .accordionCard__body-link {
  transition: none;
}

.accordionRepeater__image {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP u1T9qYdvdihz0PPSiiqn/ /3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/gsap.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous" />

<div >
  <div >
    <!-----------
     -- FIRST SET
     -------------->

    <div >
      <div >
        <div >
          <div >
            <div >
              <!-- CARD 1 -->

              <div  data-item="1">
                <div >
                  <div ></div>
                  <span >Lorum</span>
                </div>
                <div >
                  <div >
                    <p>Lorum ipsum</p>
                  </div>
                </div>
              </div>

              <!-- CARD 2 -->

              <div  data-item="2">
                <div >
                  <div ></div>
                  <span >Lorum 2</span>
                </div>
                <div >
                  <div >
                    <p>Lorum ipsum 2</p>
                  </div>
                </div>
              </div>

              <!-- CARD END -->
            </div>
          </div>
        </div>

        <div >
          <div >
            <img  src="https://picsum.photos/500" alt="placeholder-graphic" loading="lazy" style="max-width: 100%; height: auto;" data-item="1" />
            <img  src="https://picsum.photos/550" alt="placeholder-graphic" loading="lazy" style="max-width: 100%; height: auto;" data-item="2" />
            <img  src="https://picsum.photos/500" alt="placeholder-graphic" loading="lazy" style="max-width: 100%; height: auto;" data-item="3" />
          </div>
        </div>
      </div>
    </div>

    <!-----------
    -- FIRST SET END
    -------------->

    <!-----------
     -- SECOND SET
     -------------->

    <div >
      <div >
        <div >
          <div >
            <div >
              <!-- CARD 1 -->

              <div  data-item="1">
                <div >
                  <div ></div>
                  <span >Lorum</span>
                </div>
                <div >
                  <div >
                    <p>Lorum ipsum</p>
                  </div>
                </div>
              </div>

              <!-- CARD END -->
            </div>
          </div>
        </div>

        <div >
          <div >
            <img  src="https://picsum.photos/500" alt="placeholder-graphic" loading="lazy" style="max-width: 100%; height: auto;" data-item="1" />
          </div>
        </div>
      </div>
    </div>

    <!-----------
    -- SECOND SET END
    -------------->
  </div>
</div>

  • Related