Joe M
Joe M

Reputation: 3

Jquery click on anchor link and scroll to and open specific accordion/tab

I have a set of tabs that contain content. The tabs convert to accordions on mobile. This part is already working. The first tab is the default open tab on page load. I have a jump link on the page that I'm trying to code to scroll to the tabs and open (make active) the appropriate tab.

Trying to figure out how to have a link at the top of the page jump to the accordion section and also open tab 2 data-actab-id="2"

HTML

<section class="accordion">
  <!-- Tabs -->
  <section class="accordion-tabs">
    <button class="accordion-tab accordion-active" data-actab-group="0" data-actab-id="0">Title-one</button>
    <button class="accordion-tab" data-actab-group="0" data-actab-id="1">Title-two</button>
    <button class="accordion-tab" data-actab-group="0" data-actab-id="2">Title-three</button>
    <button class="accordion-tab" data-actab-group="0" data-actab-id="3">Title-four</button>
    <button class="accordion-tab" data-actab-group="0" data-actab-id="4">Title-five</button>
    <button class="accordion-tab" data-actab-group="0" data-actab-id="5">Title-six</button>
  </section>

  <!-- Tabbed Content -->
  <section class="accordion-content">
    <article class="accordion-item accordion-active" data-actab-group="0" data-actab-id="0">
      <h4 class="accordion-item__label">Description</h4>
      <div class="accordion-item__container">
      </div>
    </article>
    <article class="accordion-item" data-actab-group="0" data-actab-id="1">
      <h4 class="accordion-item__label">Specs</h4>
      <div class="accordion-item__container">
      </div>
    </article>
    <article class="accordion-item" data-actab-group="0" data-actab-id="2">
      <h4 class="accordion-item__label">Reviews</h4>
      <div class="accordion-item__container">
          <div id="reviews">
          </div>
      </div>
    </article>
    <article class="accordion-item" data-actab-group="0" data-actab-id="3">
      <h4 class="accordion-item__label">Q&A</h4>
      <div class="accordion-item__container">
      </div>
    </article>
    <article class="accordion-item" data-actab-group="0" data-actab-id="4">
      <h4 class="accordion-item__label">Videos</h4>
      <div class="accordion-item__container">
      </div>
    </article>
    <article class="accordion-item" data-actab-group="0" data-actab-id="5">
      <h4 class="accordion-item__label"><span class="chart-title-indicator">Size Chart</span></h4>
      <div class="accordion-item__container">
      </div>
    </article>
  </section>
</section>

Javascript that controls open and closing tabs/accordions (this works)

<script>
  $(document).ready(function () {
    console.log("document ready");

    const labels = document.querySelectorAll(".accordion-item__label");
    const tabs = document.querySelectorAll(".accordion-tab");

    function toggleShow() {
      const target = this;
      const item = target.classList.contains("accordion-tab") ?
        target :
        target.parentElement;
      const group = item.dataset.actabGroup;
      const id = item.dataset.actabId;

      tabs.forEach(function (tab) {
        if (tab.dataset.actabGroup === group) {
          if (tab.dataset.actabId === id) {
            tab.classList.add("accordion-active");
          } else {
            tab.classList.remove("accordion-active");
          }
        }
      });

      labels.forEach(function (label) {
        const tabItem = label.parentElement;

        if (tabItem.dataset.actabGroup === group) {
          if (tabItem.dataset.actabId === id) {
            tabItem.classList.add("accordion-active");
          } else {
            tabItem.classList.remove("accordion-active");
          }
        }
      });
    }

    labels.forEach(function (label) {
      label.addEventListener("click", toggleShow);
    });

    tabs.forEach(function (tab) {
      tab.addEventListener("click", toggleShow);
    });

  });
</script>

I've tried just a basic #hash jump link that will go to the div, but since the div is inside a tab, it will only work when that tab is already open/active, and not when it's not active.

I can use a jump link to go to the outside div but that just jumps down the page and doesn't make the appropriate tab active.

<a href="#reviews">Read Reviews</a>
or
<a href="#" class="reviews">Read Reviews</a>

with this function:

$(document).ready(function () {
  $("a.reviews").click(function (event) {
    event.preventDefault();
    $("html, body").animate(
      {
        scrollTop: $(".accordion").offset().top - 150,
      },
      500
    );
  });
});

But these solutions don't solve the issue of also opening/making the tab active. I've reviewed many other questions on here but I can't figure out how to address integrating the scroll to into my existing code of opening the tab.

Upvotes: 0

Views: 255

Answers (1)

imvain2
imvain2

Reputation: 15847

For my answer, I'm first opening the tab, then using jquery's scrollTo to scroll to the div within the tab.

I'm passing the tab ID via a data attribute and using the HREF as the target div.

const labels = document.querySelectorAll(".accordion-item__label");
const tabs = document.querySelectorAll(".accordion-tab");

function toggleShow() {
  const target = this;
  const item = target.classList.contains("accordion-tab") ?
    target :
    target.parentElement;
  const group = item.dataset.actabGroup;
  const id = item.dataset.actabId;

  tabs.forEach(function(tab) {
    if (tab.dataset.actabGroup === group) {
      if (tab.dataset.actabId === id) {
        tab.classList.add("accordion-active");
      } else {
        tab.classList.remove("accordion-active");
      }
    }
  });

  labels.forEach(function(label) {
    const tabItem = label.parentElement;

    if (tabItem.dataset.actabGroup === group) {
      if (tabItem.dataset.actabId === id) {
        tabItem.classList.add("accordion-active");
      } else {
        tabItem.classList.remove("accordion-active");
      }
    }
  });
}

labels.forEach(function(label) {
  label.addEventListener("click", toggleShow);
});

tabs.forEach(function(tab) {
tab.addEventListener("click", toggleShow);
});

$(document).ready(function() {
      $("a.scrollTo").click(function(event) {
        let tab = $(".accordion-item[data-actab-id='" + $(this).data("actab-id") + "']");
        let target = $(this).prop("hash");
        tab.addClass("accordion-active");
        
        event.preventDefault();
        $("html, body").animate({
            scrollTop: $(target).offset().top - 150            
          },
          500
        );
      });
});
.accordion{margin-top:300px;}
#reviews{margin-top:1500px}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a href="#reviews" data-actab-id="2" class="scrollTo">Read Reviews</a>

<section class="accordion">
  <!-- Tabs -->
  <section class="accordion-tabs">
    <button class="accordion-tab accordion-active" data-actab-group="0" data-actab-id="0">Title-one</button>
    <button class="accordion-tab" data-actab-group="0" data-actab-id="1">Title-two</button>
    <button class="accordion-tab" data-actab-group="0" data-actab-id="2">Title-three</button>
    <button class="accordion-tab" data-actab-group="0" data-actab-id="3">Title-four</button>
    <button class="accordion-tab" data-actab-group="0" data-actab-id="4">Title-five</button>
    <button class="accordion-tab" data-actab-group="0" data-actab-id="5">Title-six</button>
  </section>

  <!-- Tabbed Content -->
  <section class="accordion-content">
    <article class="accordion-item accordion-active" data-actab-group="0" data-actab-id="0">
      <h4 class="accordion-item__label">Description</h4>
      <div class="accordion-item__container">de
      </div>
    </article>
    <article class="accordion-item" data-actab-group="0" data-actab-id="1">
      <h4 class="accordion-item__label">Specs</h4>
      <div class="accordion-item__container">ss
      </div>
    </article>
    <article class="accordion-item" data-actab-group="0" data-actab-id="2">
      <h4 class="accordion-item__label">Reviews</h4>
      <div class="accordion-item__container">
        <div id="reviews">
        REVIEWS!
        </div>
      </div>
    </article>
    <article class="accordion-item" data-actab-group="0" data-actab-id="3">
      <h4 class="accordion-item__label">Q&A</h4>
      <div class="accordion-item__container">
      </div>
    </article>
    <article class="accordion-item" data-actab-group="0" data-actab-id="4">
      <h4 class="accordion-item__label">Videos</h4>
      <div class="accordion-item__container">
      </div>
    </article>
    <article class="accordion-item" data-actab-group="0" data-actab-id="5">
      <h4 class="accordion-item__label"><span class="chart-title-indicator">Size Chart</span></h4>
      <div class="accordion-item__container">
      </div>
    </article>
  </section>
</section>

Upvotes: 0

Related Questions