Utilizing data attributes instead of IDs for connecting buttons and tabs in Javascript tab navigation

I'm currently exploring a new approach to creating Javascript tabs by utilizing data attributes instead of IDs to connect the tab with its content.

Here's the concept in action:

  • When clicking on a
    <button class="tab" data-tab-trigger="1">
    , it should add the class is-active and remove any existing is-active classes from other buttons
  • The value of data-tab-trigger should match the value of data-tab-content on the corresponding
    <div class="tab-content" data-tab-content="1">
    and add the class is-open to it
  • The is-active class indicates the active tab, while is-open displays the related tab content

Here's the Javascript code I've been working on, but it's not behaving as expected:

var tabTriggerBtns = document.querySelectorAll('.tabs li button');

tabTriggerBtns.forEach(function(tabTriggerBtn, index){
  tabTriggerBtn.addEventListener('click', function(){
    var tabTrigger = this;
    var tabTriggerData = tabTrigger.getAttribute('data-tab-trigger');
    var tabContent = document.querySelector('.tab-content');
    var currentTabData = document.querySelector('.tab-content[data-tab-content="' + tabTriggerData + '"]').classList.add('is-open');

    if(tabContent !== currentTabData) {
      tabContent.classList.toggle('is-open');
    }

    if(tabTrigger.classList.contains('is-active')) {
      tabTrigger.classList.remove('is-active');
    }
    else {
      tabTriggerBtn.classList.remove('is-active');
      tabTrigger.classList.add('is-active');
    }   
  });
});

You can view the ongoing script on Codepen: https://codepen.io/abbasarezoo/pen/752f24fc896e6f9fcce8b590b64b37bc

I'm struggling to identify the issue here. While I'm comfortable with jQuery, I'm still learning vanilla JS, so any guidance would be greatly appreciated.

Answer №1

Identifying a key issue in the code:

The problematic line appears to be: tabContent !== currentTabData

Consider utilizing the dataset feature to access data attributes effectively. Additionally, you can streamline your code with these steps:

  • Eliminate unnecessary classes.
  • Introduce essential classes.

The revised snippet:

var tabTriggerBtns = document.querySelectorAll('.tabs li button');

tabTriggerBtns.forEach(function(tabTriggerBtn, index){
    tabTriggerBtn.addEventListener('click', function(){
        var currentTabData = document.querySelector('.tab-content[data-tab-content="' + this.dataset.tabTrigger + '"]');

        // Eliminate unnecessary classes
        document.querySelector('.tab-content.is-open').classList.remove('is-open');
        document.querySelector('.tabs li button.is-active').classList.remove('is-active');
        // Introduce essential classes
        currentTabData.classList.add('is-open');
        this.classList.add('is-active');
    });
});
* {
    margin: 0;
    padding: 0;
}

body {
    display: flex;
}
.tabs {
    width: 25%;
    border: 2px solid red;
}

button.is-active {
    background-color: red;
}

.tab-content__outer {
    width: 75%;
}

.tab-content {
    display: none;
}
.tab-content.is-open {
    display: block;
    background-color: yellow;
}
<ul class="tabs">
    <li>
        <button class="tab is-active" data-tab-trigger="1">First</button>
    </li>
    <li>
        <button class="tab" data-tab-trigger="2">Second</button>
    </li>
    <li>
        <button class="tab" data-tab-trigger="3">Third</button>
    </li>
</ul>
<div class="tab-content__outer">
    <div class="tab-content is-open" data-tab-content="1">
        First
    </div>
    <div class="tab-content" data-tab-content="2">
        Second
    </div>
    <div class="tab-content" data-tab-content="3">
        Third
    </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

Tips for transferring the output of a JavaScript async function to a Python variable

var = driver.execute_script("setTimeout(function(){ return [1,2,3]; }, 1000);") Utilizing the Selenium method execute_script, I am attempting to extract data from a website using javascript and assign it to a python variable var. The challenge a ...

Rotate camera around item when dragged

In my three.js scene, there is an object positioned at {x: 0, y: 0, z: -150}, while the camera is placed at {x: 0, y: 0, z: 75}. I am trying to allow the user to drag the camera around the object, keeping it in view at all times. https://i.sstatic.net/dp6 ...

Submitting information to the server utilizing a POST request through jQuery

What I'm attempting to achieve: I am currently working on sending data to my server using the $.post jQuery shortcut. The issue at hand: It seems that my program is not entering my switch case, possibly due to a problem with sending the action prop ...

Is it possible to create and access a PDF file using file handling in PHP?

In my PHP code, I am utilizing file handling to write and then read a PDF file. However, after successfully creating the PDF file, I encounter an issue where I am unable to open it. When attempting to open the file, Adobe Reader displays an error message s ...

Exploring the realm of styling with React JS

Currently, I am facing an issue while working with material-ui for my web design. Here is the code snippet that I am using: const useStyles = makeStyles((theme) => ({ card: { marginTop: theme.spacing(10), direction:"column", alig ...

The AJAX request is failing to reach the server

I'm currently using AJAX to populate a dropdown, but for some reason the call isn't reaching the server. Upon checking Firebug, I see the following error: POST 0 status 404 not found This is the code I'm working with: function selec ...

Is the file corrupt using node.js?

Looking for ways to determine if a file is corrupted using node.js? I have attempted various File System methods, such as fs.readFile, fs.open, and fs.access, but all of them are showing an OK status. However, I am confident that my file is corrupted base ...

Dropdown fails to update upon selection using Ajax technology

My issue involves two select dropdowns: regions and towns. When a region is selected, it should update the towns dropdown with the appropriate towns using Ajax. My approach is to use an imagemap to select the dropdown for the region, which will trigger th ...

Utilizing tables for inquiries in email communication

Currently tackling a basic mailer with html. It seems like tables are recommended and inline styling is the safer route. However, I'm encountering an issue where there's a mysterious space when setting up my td and I can't seem to pinpoint ...

How can Play framework be used to display static HTML pages with static JavaScript and CSS files?

I'm currently exploring options for rendering or routing to static web apps stored in the Play's public folder. Here is my project structure: myapp + app + conf + modules + public | + webapp1 | + css | + ...

Serialize the prototype strictly based on the visible form field

Is there a way to serialize only the visible form field values in prototype.js? I have a form where two elements share the same name, but one is visible while the other is hidden. When I serialize the form using $('formid').serialize(), both fiel ...

Incorporating additional information into the database

When I run the code, I see a table and a button. After entering data in the prompts as instructed, the table does not get updated. I'm unsure why this is happening. Can someone please explain? <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Trans ...

Calculating the combined cost of items in the shopping cart

I encountered a small problem while working on my project. I'm trying to calculate the total price of all items in the cart by summing them up, but my mind is drawing a blank at the moment. Below is the code snippet I am currently using: const { ca ...

How can I define the PropType for an object containing a combination of strings and functions?

Trying to define a prop, which is an object of strings and functions. I set proptypes as component.propTypes = { propName: PropTypes.objectOf(PropTypes.oneOf([PropTypes.string, PropTypes.func]) } However, I encountered an error message stating that it r ...

Enhance your web design with the mesmerizing jQuery UI drop effect combined

I'm attempting to create an animated toggle effect on a box using jQuery UI's drop feature. However, I've encountered some trouble due to the box having box-sizing: border-box applied which is causing issues with the animation. During the a ...

Retrieving PHP output from multiple arrays using AJAX

I'm new to AJAX and I'm struggling to retrieve arrays. My goal is to update a notification bar in real time using AJAX. I've managed to update the count displayed on the balloon, but I can't figure out how to also fetch messages from My ...

Exploring the realm of arrays in jQuery and JavaScript

Seeking assistance as a beginner in Javascript/jQuery, I am looking for guidance on the following challenge: I have created a basic form with 7 questions, each containing 3 radio buttons/answers (except for question 5 which has 8 possible choices). My goa ...

Converting an array of date strings to a single string in JavaScript

Here is the JSON format I received with dynamic data: {"range":["2018-07-23T16:03:26.861Z","2018-07-23T16:03:26.861Z"]} Now, I need to convert this into the following format: range(20180723,20180723) Below is my code snippet : var data:Date[] = {"rang ...

The slice() method in arrays provides a reference to the elements rather than copying

In my file, I am exporting an object in the following manner: export const LINECHART2_DATA = { series: [{ data: [], name: 'HR', }, { etc... }] } The way I import it is like this: import { LINECHART2_DAT ...

Django DRF functions properly, however it returns an error when sending a response to an AJAX request

Successfully implemented an AJAX request using PUT in DRF. All functionalities are functioning correctly except for the error callback being triggered: DRF section: class ProductDataViewSet(viewsets.ViewSet): authentication_classes = [SessionAuthentic ...