Dynamically hiding elements within tabs using jQuery

Previously, I created a functionality for handling a single set of tabs. However, as the application has expanded, this functionality is no longer sufficient to accommodate multiple sets of tabs.

The initial function looked like this:

var iconTabs = function () {

    $('#icons-tabs a:not(:first)').addClass('inactive');
    $('.icons-container').hide();
    $('.icons-container:first').show();

    $('#icons-tabs a').click(function(){
        var t = $(this).attr('id');
        if($(this).hasClass('inactive')) {
            $('#icons-tabs a').addClass('inactive');
            $(this).removeClass('inactive');
            $('.icons-container').hide();
            $('#'+ t + 'C').fadeIn('slow');
        }
    });
};

And here is the corresponding html:

<div id="fragment-1" class="fragments text-center">
    <div class="icons-container" id="tab1C">
        {{!-- Content --}}
    </div>

    <div class="icons-container" id="tab2C">
        {{!-- Content --}}
    </div>

    <div class="fragments-parent">
        <div class="fragments-icons fragments-parent--child">
            <div class="items" id="icons-tabs">
                <a href="#" class="item" id="tab1"></a>
                <a href="#" class="item" id="tab2"></a>
                <a href="#" class="item" id="tab3"></a>
                <a href="#" class="item" id="tab4"></a>
            </div>
        </div>
    </div>
</div>

Now, with additional sections being added in the html, such as the second section, the code has evolved:

<div id="fragment-1" class="fragments text-center">
    <div class="icons-container" id="tab1C">
        {{!-- Content --}}
    </div>

    <div class="icons-container" id="tab2C">
        {{!-- Content --}}
    </div>

    <div class="fragments-parent">
        <div class="fragments-icons fragments-parent--child">
            <div class="items" id="icons-tabs">
                <a href="#" class="item" id="tab1"></a>
                <a href="#" class="item" id="tab2"></a>
            </div>
        </div>
    </div>
</div>

<div id="fragment-2" class="fragments text-center">
    <div class="icons-container" id="tab5C">
        {{!-- Content --}}
    </div>

    <div class="icons-container" id="ta62C">
        {{!-- Content --}}
    </div>

    <div class="fragments-parent">
        <div class="fragments-icons fragments-parent--child">
            <div class="items" id="icons-tabs">
                <a href="#" class="item" id="tab5"></a>
                <a href="#" class="item" id="tab6"></a>
            </div>
        </div>
    </div>
</div>

A JSFiddle has been provided for testing purposes:

http://jsfiddle.net/ju3a9zx5/

The goal now is to make the functionality dynamic and ensure that each set of tabs behaves independently. In the current setup, the second set of tabs does not work as intended, and the aim is to isolate the behavior of each set of tabs without interference from others.

Answer №1

It is recommended to utilize classes instead of ids when targeting tabs. In the example provided below, there are a few key changes:

  1. Replace id="tabs" and id="tabs2" with class="tabs"
  2. Adjust event handlers to target the class rather than the ids
  3. For finding related a tags, use siblings()
  4. In locating the related .container, apply .nextUntil() to find the container further down in the DOM
  5. To display initial container classes, utilize $('.tabs').next('.container')

$(document).ready(function() {

  $('.tabs a:not(:first)').addClass('inactive');
  $('.container').hide();
  $('.tabs').next('.container').show();

  $('.tabs a').click(function() {
    var t = $(this).attr('id');
    if ($(this).hasClass('inactive')) { //beginning of condition 
      $(this).siblings('a').addClass('inactive');
      $(this).removeClass('inactive');

      $(this).parent().nextUntil(':not(.container)').hide();
      $('#' + t + 'C').fadeIn('slow');
    }
  });

});
.tabs {
  width: 100%;
  height: 30px;
  border-bottom: solid 1px #CCC;
  padding-right: 2px;
  margin-top: 30px;
}

a {
  cursor: pointer;
}

.tabs a {
  float: left;
  list-style: none;
  border-top: 1px solid #ccc;
  border-left: 1px solid #ccc;
  border-right: 1px solid #ccc;
  margin-right: 5px;
  border-top-left-radius: 3px;
  border-top-right-radius: 3px;
  outline: none;
  font-family: Arial, Helvetica, sans-serif;
  font-size: small;
  font-weight: bold;
  color: #5685bc;
  ;
  padding-top: 5px;
  padding-left: 7px;
  padding-right: 7px;
  padding-bottom: 8px;
  display: block;
  background: #FFF;
  border-top-left-radius: 3px;
  border-top-right-radius: 3px;
  text-decoration: none;
  outline: none;
}

.tabs a.inactive {
  padding-top: 5px;
  padding-bottom: 8px;
  padding-left: 8px;
  padding-right: 8px;
  color: #666666;
  background: #EEE;
  outline: none;
  border-bottom: solid 1px #CCC;
}

.tabs a:hover,
.tabs a.inactive:hover {
  color: #5685bc;
  outline: none;
}

.container {
  clear: both;
  width: 100%;
  border-left: solid 1px #CCC;
  border-right: solid 1px #CCC;
  border-bottom: solid 1px #CCC;
  text-align: left;
  padding-top: 20px;
}

.container h2 {
  margin-left: 15px;
  margin-right: 15px;
  margin-bottom: 10px;
  color: #5685bc;
}

.container p {
  margin-left: 15px;
  margin-right: 15px;
  margin-top: 10px;
  margin-bottom: 10px;
  line-height: 1.3;
  font-size: small;
}

.container ul {
  margin-left: 25px;
  font-size: small;
  line-height: 1.4;
  list-style-type: disc;
}

.container li {
  padding-bottom: 5px;
  margin-left: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="tabs">

  <a id="tab1">test1</a>
  <a id="tab2">test2</a>
  <a id="tab3">test3</a>
  <a id="tab4">test4</a>

</div>
<div class="container" id="tab1C">1Some content</div>
<div class="container" id="tab2C">2Some content</div>
<div class="container" id="tab3C">3Some content</div>
<div class="container" id="tab4C">4Some content</div>

<div class="tabs">

  <a id="tab5">test1</a>
  <a id="tab6">test2</a>
  <a id="tab7">test3</a>
  <a id="tab8">test4</a>

</div>
<div class="container" id="tab5C">5Some content</div>
<div class="container" id="tab6C">6Some content</div>
<div class="container" id="tab7C">7Some content</div>
<div class="container" id="tab8C">8Some content</div>

Answer №2

After experimenting with your fiddle, one suggestion stands out: replace id="tabs" with class="tabs", and update the selectors in both your javascript and css files. This adjustment should help you get started smoothly.

As a developer, I would recommend creating a jQuery plugin and implementing the code within an each() function to enhance flexibility, scalability, and maintainability.

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

Element positioning in Material UI is fluid and responsive across all devices, with the ability to place elements at

As a novice in layout design, I am currently developing a web application for both mobile and desktop using React and Material UI. My challenge lies in placing the app navigation at the bottom of the screen. The issue arises because the location of the app ...

What is the best way to implement a date range filter in AngularJS for a specific year or month?

I am just starting to learn AngularJS. I have a date formatted as follows: d MMM y. However, I have two fields - one called "from" and the other "to" - that should act as filters for the date range, based on a year range or month range. Here is how I am or ...

The logo image in the React application is having trouble rendering, showing a "Module Parse Failed" error

I am facing an issue while trying to render an image in my React component. The problem arises when I attempt to load and display my Logo within the component. A parse error is being thrown, and I am unsure of the reason for this error: Uncaught Error: Mo ...

Tips for automatically loading a new page or URL when a user scrolls to the bottom

I am working on implementing infinite scroll functionality, where a new page loads automatically when the user reaches the bottom of the page or a particular div. Currently, I have this code that loads a new page onclick. $("#about").click(function(){ ...

How can I manage file input within a Vue.js application?

After attempting to open a file input with a button, I encountered an issue. When clicking the button, the client reported: “this.$refs.image.click”. Below is my code snippet: <v-btn height="50" ...

Trouble with Excel Office Script setInterval functionality

Trying to automatically recalculate an Excel worksheet every second using Office Script. Unfortunately, my initial approach did not succeed. function sendUpdate(sheet: ExcelScript.Worksheet) { console.log('hi'); sheet.calculate(true); } func ...

I'm running into a "timeout" issue with socket.io and a self-signed SSL connection. Can anyone help me troubleshoot this?

After setting up a nodejs server with HTTPS, everything seems to be working fine when sending GET requests. However, I encountered an error message 'WebSocket was closed before the connection was established' when trying to connect another nodejs ...

Functioning Ajax Jquery form functionality

I've come across an issue while working on some jquery processes. It seems that the code I'm using doesn't work when a specific line is commented out, but works perfectly fine when uncommented. Can anyone shed some light on why this might be ...

Solving the Issue of Missing Minified Scripts in NPM Packages

When attempting to utilize the jquery-validation-unobtrusive NPM package, I encountered an issue where the minified version of the required script was not included by the package authors. It appears that they have excluded it via the files section in the p ...

Depending on external software packages

Can you explain the potential risks associated with using third-party packages and npm in a broader sense? If I were to install a third-party package like semantic-ui-react using npm, is there a possibility that I may not be able to use it on my website i ...

Retrieve data from a div element on a webpage using specific parameters

As I work on a form that includes various filters and a "Start" button in C# / ASP.NET MVC, my goal is to display database data in a partial view using Ajax when the button is clicked, based on certain parameters. Within this partial view, there is a link ...

Python.Selenium. Unable to locate current element. Techniques for switching frames

I am trying to collect feedback from a specific page at this URL. After waiting for the page to load, I attempted to locate elements using Google Chrome inspector. However, Selenium is unable to find these elements, and I also could not find them in the p ...

Print a <form> and specify the variable as the name

I'm encountering an issue with my code. I am attempting to use the variable $columnnames as the name for a checkbox. Despite multiple attempts, I have not been able to achieve success. <?php mysql_connect("host", "user", "password") or die("Connec ...

Django Ajax filter displaying issue on HTML page

I'm uncertain about the correctness of my Ajax implementation. When using Django's built-in tags, the objects I pass through Ajax are not appearing on my template HTML page. view_results.html <div> <input id="search" name="search" t ...

Can the name of the ngx-datatable-column be altered?

I recently started developing an angular2 web application that includes a ngx-datatable component. The header columns all have numeric names, but I would like to customize them in the view. Despite my efforts to research this issue, I haven't come ac ...

The Model.function method is not a valid function that can be used within a router

Currently facing a challenge with my router setup. I have exported the function as shown in the code snippet below. This is the Model I am using: "use strict"; var mongoose = require('mongoose'); var bcrypt = require("bcryptjs"); var Schema = m ...

How do you switch selection to "hold" mode using Javascript?

In my Markdown preview area, clicking on text will cause the preview area to switch to a markdown source editor automatically, with the cursor jumping to the position corresponding to where it was clicked. function onMouseDown(e) { const range = documen ...

As I continue to fill the child DIV element with more text, the shrink wrap is compromised and eventually breaks

Snippet of HTML code: <div id="container"> <div id="first"> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean lacinia velit ut magna ultricies. </div> <div id="second"> Blandit </div ...

Is it possible in Javascript to trace the origins of a particular element's property inheritance for debugging purposes?

I'm currently dealing with an issue where the computed style font-size of a particular element is "16px". I've been attempting to pinpoint where in the CSS or JavaScript this font size setting is coming from, specifically within one of its parent ...

Is it necessary for me to include body, html at the beginning of my CSS code?

For all of my pages, I have been including the following code at the top. body { color: #333333; font-family: Arial,sans-serif; font-size: 0.95em; line-height: 1.15; } However, a colleague of mine has informed me that I only need to targ ...