Kunal Tanwar
Kunal Tanwar

Reputation: 1291

Tabs created using JavaScript aren't working as expected

I created tabs using js but they aren't working quite well. i.e. when I am clicking on Tab 1 it is displaying Tabpanel 2 and vice versa.

Also on first click nothing is happening at all and after the initial click it doing opposite of what I wanted and expected.

Below is the example of what I have created without styling

const tabs = Array.from(document.querySelectorAll("[role='tab']"));

tabs.map((tab, index) => {
  const tabpanel = Array.from(document.querySelectorAll("[role='tabpanel']"))[
    index
  ];

  tab.addEventListener("click", (event) => {
    event.preventDefault();

    if (
      tab.ariaSelected === "true" &&
      tab.id === tabpanel.getAttribute("aria-labelledby")
    ) {
      // don't do anything because selected tab will have `pointer-events: none`
    } else {
      const selectedTabs = Array.from(
        document.querySelectorAll("[role='tab'][aria-selected='true']")
      );
      const hiddenTabpanels = Array.from(
        document.querySelectorAll("[role='tabpanel'][hidden]")
      );

      selectedTabs.map((selectedTab, hiddenTabpanel) => {
        selectedTab.ariaSelected = "false";
        hiddenTabpanels[hiddenTabpanel].hidden = false;
      });

      tab.ariaSelected = "true";
      tabpanel.hidden = true;
    }
  });
});
[role='tab'][aria-selected='true'] {
  color: white;
  pointer-events: none;
  background-color: green;
}
<ul role="tablist">
  <li role="presentation">
    <a href="#" id="tab-1" role="tab" aria-selected="true">Tab 1</a>
  </li>

  <li role="presentation">
    <a href="#" id="tab-2" role="tab" aria-selected="false">Tab 2</a>
  </li>
</ul>

<div class="container">
  <ul role="tabpanel" aria-labelledby="tab-1">
    <h1>Tabpanel 1</h1>
  </ul>
  <ul role="tabpanel" aria-labelledby="tab-2" hidden>
    <h1>Tabpanel 2</h1>
  </ul>
</div>

Suggest any good title for this post

Upvotes: 0

Views: 45

Answers (1)

Alexsander Gutierreez
Alexsander Gutierreez

Reputation: 310

I made some tweaks and it seems to work fine now, just hide the visible panels and remove the last line which re-hides the panel that should be visible

    const tabs = Array.from(document.querySelectorAll("[role='tab']"));

    tabs.map((tab, index) => {
    const tabpanel = Array.from(document.querySelectorAll("[role='tabpanel']"))[
      index
    ];

    tab.addEventListener("click", (event) => {
      event.preventDefault();

      if (
        tab.ariaSelected === "true" &&
        tab.id === tabpanel.getAttribute("aria-labelledby")
      ) {
        // don't do anything because selected tab will have `pointer-events: none`
      } else {
        const selectedTabs = Array.from(
          document.querySelectorAll("[role='tab'][aria-selected='true']")
        );
        // add this
        const visibleTabpanels = Array.from(
          document.querySelectorAll("[role='tabpanel']:not([hidden])")
        );

        const hiddenTabpanels = Array.from(
          document.querySelectorAll("[role='tabpanel'][hidden]")
        );

        visibleTabpanels.map((visibleTabpanel) => {
          visibleTabpanel.hidden = true;
        });

        selectedTabs.map((selectedTab, hiddenTabpanel) => {
          selectedTab.ariaSelected = "false";
          hiddenTabpanels[hiddenTabpanel].hidden = false;
        });

        tab.ariaSelected = "true";
        // remove it
        // tabpanel.hidden = true;
      }
    });
   });

Upvotes: 1

Related Questions