Unable to conceal tab content upon clicking the identical tab

I recently implemented a tab system with panels that seems to be working well when switching between tabs. However, I'm facing an issue where clicking on the same tab does not hide the corresponding panel and reset the aria attributes as intended. I've attempted a solution, but it has not yielded the desired results.

This is the approach I took:

 if (thisTab.attr('aria-expanded') == 'true') {
            thisTab.attr('aria-expanded', 'false');
            thisTab.removeClass('is-active');
            thisTabPanel.attr('aria-hidden', 'true');
  } else {
            thisTab.attr('aria-expanded', 'true');
            thisTab.addClass('is-active');
            thisTabPanel.attr('aria-hidden', 'false');
  }

Thank you for any assistance you can provide!

$(document).ready(function() {

  $('.tablist li').attr('role', 'presentation');
  $('.tablist li a').attr({
    "aria-selected": "false",
    "role": "tab",
    "tabindex": "0"
  });


  $('.tablist__panel').attr({
    "aria-hidden": "true",
    "role": "tabpanel"
  });


  $('.tab').attr('id', function(IDcount) {
    return 'tab' + IDcount;
  });

  $('.tab').attr('href', function(IDcount) {
    return '#panel' + IDcount;
  });

  $('.tab').attr('aria-controls', function(IDcount) {
    return 'panel' + IDcount;
  });

  $('.panel').attr('id', function(IDcount) {
    return 'panel' + IDcount;
  });

  $('.panel').attr('aria-labelledby', function(IDcount) {
    return 'tab' + IDcount;
  });


  $(".panel").hide();


  $(function() {

    // Cache selectors
    var tabs = $('.tablist li a'),
      tabPanels = $('.panel');

    tabs.on('click', function() {
      event.preventDefault();

      var thisTab = $(this),
        thisTabPanelId = thisTab.attr('aria-controls'),
        thisTabPanel = $('#' + thisTabPanelId);

      tabs.attr('aria-selected', 'false').removeClass('is-active');
      thisTab.attr('aria-selected', 'true').addClass('is-active');
      tabPanels.attr('aria-hidden', 'true').hide();
      thisTabPanel.attr('aria-hidden', 'false').show();
     
      //HERE'S WHAT I CAN'T GET TO WORK
      if (thisTab.attr('aria-expanded') == 'true') {
        thisTab.attr('aria-expanded', 'false');
        thisTab.removeClass('is-active');
        thisTabPanel.attr('aria-hidden', 'true');
      } else {
        thisTab.attr('aria-expanded', 'true');
        thisTab.addClass('is-active');
        thisTabPanel.attr('aria-hidden', 'false');

      }
    });

  });

});
.wrapper {
  max-width: 500px;
  margin: 0 auto;
}

.tablist {
  display: flex;
  margin: 0;
  padding: 0;
  list-style: none;
}

.tab {
  display: inline-block;
  margin: 15px;
  padding: 15px;
  background-color: gray;
  color: white;
  cursor: pointer;
}

.tab.is-active {
  font-weight: 700;
  background-color: gray;
}

.panel {
  border: 1px solid gray;
  margin: 15px;
  padding: 0 15px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
  <ul class="tablist" role="tablist">
    <li><a class="tab">Tab 1</a></li>
    <li><a class="tab">Tab 2</a></li>
    <li><a class="tab">Tab 3</a></li>
  </ul>

  <div class="panel">
    <p>PANEL 1 Pellentesque in ipsum id orci porta dapibus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus suscipit tortor eget felis porttitor volutpat.</p>
  </div>
  <div class="panel">
    <p>PANEL 2 Pellentesque in ipsum id orci porta dapibus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus suscipit tortor eget felis porttitor volutpat.</p>
  </div>
  <div class="panel">
    <p>PANEL 3 Pellentesque in ipsum id orci porta dapibus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus suscipit tortor eget felis porttitor volutpat.</p>
  </div>
</div>

Answer №1

To streamline the code, you can implement a condition that checks for active classes and aria attributes at the beginning. There's no need for an additional if statement. Simply hide all panels, remove classes, and reset areas if they are already clicked. If not clicked, proceed as before:

  if (thisTab.attr('aria-selected') == "false") {
    tabs.attr('aria-selected', 'false').removeClass('is-active');
    thisTab.attr('aria-selected', 'true').addClass('is-active');
    tabPanels.attr('aria-hidden', 'true').hide();
    thisTabPanel.attr('aria-hidden', 'false').show();
  } else {
     tabPanels.hide().attr('aria-hidden', 'true');
     thisTab.attr('aria-selected', 'false').removeClass('is-active') 
  }

$(document).ready(function() {

  $('.tablist li').attr('role', 'presentation');
  $('.tablist li a').attr({
    "aria-selected": "false",
    "role": "tab",
    "tabindex": "0"
  });


  $('.tablist__panel').attr({
    "aria-hidden": "true",
    "role": "tabpanel"
  });


  $('.tab').attr('id', function(IDcount) {
    return 'tab' + IDcount;
  });

  $('.tab').attr('href', function(IDcount) {
    return '#panel' + IDcount;
  });

  $('.tab').attr('aria-controls', function(IDcount) {
    return 'panel' + IDcount;
  });

  $('.panel').attr('id', function(IDcount) {
    return 'panel' + IDcount;
  });

  $('.panel').attr('aria-labelledby', function(IDcount) {
    return 'tab' + IDcount;
  });


  $(".panel").hide();


  $(function() {

    // Cache selectors
    var tabs = $('.tablist li a'),
      tabPanels = $('.panel');

    tabs.on('click', function() {
      event.preventDefault();

      var thisTab = $(this),
        thisTabPanelId = thisTab.attr('aria-controls'),
        thisTabPanel = $('#' + thisTabPanelId);

      if (thisTab.attr('aria-selected') == "false") {
        tabs.attr('aria-selected', 'false').removeClass('is-active');
        thisTab.attr('aria-selected', 'true').addClass('is-active');
        tabPanels.attr('aria-hidden', 'true').hide();
        thisTabP... (CONTINUE TO NEXT LINE)
      // here is code to reset all if tab is clicked again
        tabPanels.hide().attr('aria-hidden', 'true');
        thisTab.attr('aria-selected', 'false').removeClass('is-active')
      }



    });

  });

});
.wrapper {
  max-width: 500px;
  margin: 0 auto;
}

.tablist {
  display: flex;
  margin: 0;
  padding: 0;
  list-style: none;
}

.tab {
  display: inline-block;
  margin: 15px;
  padding: 15px;
  background-color: gray;
  color: white;
  cursor: pointer;
}

.tab.is-active {
  font-weight: 700;
  background-color: gray;
}

.panel {
  border: 1px solid gray;
  margin: 15px;
  padding: 0 15px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
  <ul class="tablist" role="tablist">
    <li><a class="tab">Tab 1</a></li>
    <li><a class="tab">Tab 2</a></li>
    <li><a class="tab">Tab 3</a></li>
  </ul>

  <div class="panel">
    <p>PANEL 1 Pellentesque in ipsum id orci porta dapibus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus suscipit tortor eget felis porttitor volutpat.</p>
  </div>
  <div class="panel">
    <p>PANEL 2 Pellentesque in ipsum id orci porta dapibus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus suscipit tortor eget felis porttitor volutpat.</p>
  </div>
  <div class="panel">
    <p>PANEL 3 Pellentesque in ipsum id orci porta dapibus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus suscipit tortor eget felis porttitor volutpat.</p>
  </div>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Display the name of the file on the screen

Is there a way to dynamically display the file name in a view instead of hardcoding it? I would appreciate any assistance. Thank you! Here is my code snippet: <li> @if (Model.Picture2 != null) { base2 = Convert.ToBase64String(Model.Pict ...

Pass information from Vue JS v-for to a button when it is clicked

Just started learning Vue JS and encountered a small issue I'm currently looping through an array with a button inside the div I'm iterating over The goal is to grab the data of the selected item after clicking on the button For example, suppo ...

Issue with connecting Drupal 8 theme styling to website pages

Although the theme is functioning properly, the CSS styles are not being applied. Even when inspecting the developer console in Firefox, there seems to be a disconnect with the page. I verified that manually applying the CSS through the developer console i ...

What is the best way to use jQuery to animate a particular height up to 100%?

To provide a sneak peek of the content in the div, I have minimized it so only the first line is visible. Now, I want to add an animation that will expand the div to 100% height when you click the title. However, using animate(height:"100%") does not res ...

Tabbed form design using Twitter Bootstrap

Currently, I am working on a website using the Bootstrap framework. My goal is to create a single page that features a pop-up form with two or three tabs. Specifically, I envision these tabs as "The Markup," "The CSS," and "The JavaScript." While I have ma ...

Is it possible to combine ng-class with conditional expression and ng-class with string syntax in a single statement?

To assign classes based on the ngRepeat index, I am using ng-init="myIndex = $index". With this setup, I can apply classes like color-0, color-1, color-2, etc. by using ng-class='"color-" + myindex'. Furthermore, I need to add a different class ...

Tips for incorporating a custom CSS design into a jQueryUI tooltip

I am struggling to apply my custom CSS class on top of the jQueryUI tooltip. Although the tooltip is displaying correctly, my styles are not being applied. Here is the code I'm using: $(document).ready(function () { $("#roles").tooltip({ content: ...

Refining an array data table within a nested component

Transitioning my old PHP/jquery single-page applications to VueJS/Webpack has been a journey I'm undertaking to familiarize myself with the latter technology. It involves converting a simple table that pulls data from a JSON API and incorporates filte ...

When utilizing "reques" in Node.js code, the parameter response.timings may be found to be undefined

The code I created in node.js is giving me trouble - for some reason, response.timing is showing up as undefined. Any idea what could be causing this issue? const request = require("request"); request.get({ time : true, url : 'https://www.bbc.com ...

Struggling with developing a chrome extension

I have successfully developed a Chrome extension that, when clicked, says hello world. However, I am facing an issue with creating a simple button that triggers an alert when pressed. Could it be due to the inclusion of JavaScript in an HTML extension file ...

Why won't the audio tag play any audio on IE10 Windows7?

Encountering issues with the audio tag on Internet Explorer 10/Windows 7. Discovered a test page where IE is unable to display any audio tags. Interestingly, when the file is saved and tested locally, it works perfectly (see image below). Confirming that ...

When initializing a new instance of Stripe using cartalyst/stripe-laravel, an error occurs stating "The Stripe API key has not been properly defined!"

I am eager to explore Stripe and learn how to process payments. Currently, I am utilizing the cartalyst/stripe-laravel package to create a new instance of Stripe following the instructions provided here. The code snippet should resemble this: $stripe = ...

the jquery auto complete plugin is having trouble parsing the data as JSON

I am trying to integrate an auto-complete feature into a Rails application and have opted for the jQuery auto-complete plugin. The goal is to implement this feature for a specific array, as shown below. @testers = User.find_by_sql("select * from users w ...

When text is inserted into an inline-block div, it causes the div to shift downwards in

Consider the following HTML code snippet: <div class="one"> Test </div> <div class="two"> </div> <div class="three"> </div> If we apply the following CSS styles: div { display:inline-block; height:30px; ...

Trouble initiating a jquery function in componentDidMount in a React component

I have encountered an issue with my ReactJS application. The $(document).ready(function(){}); function stops working after I switch paths using React Router Dom. In order to find a solution, I turned to Google and came across this helpful article: React- ...

Uploading files using HTML 5, Ajax, and jQuery

I am attempting to utilize jQuery to upload a file by using the ajax POST method and sending the uploaded file to url:"/files/uploads" with the parameter file. To achieve this, I have set up the following input elements: <form id="fileUploadForm"> ...

Is there a way to choose columns 2 to 6 of the row that is currently selected

I am looking to create a hover effect for columns 1 through 7 of a row where, when the user hovers over any column within that range, certain styles are applied to all columns in the row except for columns 1 and 7. This means that the background color shou ...

Using radio buttons to toggle the visibility of a div element within a WordPress website

I am currently working on creating a WordPress page using the custom page tool in the admin interface. My goal is to have 3 radio buttons, with 2 visible and 1 hidden. The hidden button should be automatically checked to display the correct div (although ...

What steps do I need to take in order to change an HTML div's background to a black

My current project involves dynamically loading HTML content stored on disk into a specific div element. This is achieved by using the following code: $('#FictionContent').load('Content/HuckFinn.html'); Just to provide some background ...

What steps should I take to transform [“link”, “395868”] into [title: “link”, content: “395868”]?

As a newcomer to javascript, I am finding it challenging to articulate my issue due to lack of adequate vocabulary. My current project involves building a chart with d3 and here is the data I require : data=[ ...