Deactivating the class from a button

On my website, I have 3 buttons that represent different product categories. The initial state of the page should load with the "All Products" button having an active class. However, when clicked, this active class should be removed from the "All Products" button and added to another button. Unfortunately, there seems to be a glitch causing the active class to either be added twice to a button or not removed at all, resulting in two buttons being active simultaneously. Seeing Two Active Buttons? and Experiencing Duplicate Active Classes?

To solve this issue, I can remove the active class from the "All Products" button entirely, but ideally, I want it to be initially set as active when the page loads. These buttons also need to toggle visibility for elements based on the category they belong to.

Below is the code snippet:

HTML:

<div class="list-group" id="myBtnContainer">
        <button class="btn list-group-item active" onclick="filterSelection('all')">All Products</button>
        <button class="btn list-group-item" onclick="filterSelection('shirts')">Shirts</button>
        <button class="btn list-group-item" onclick="filterSelection('pants')">Pants</button>
      </div>

Example HTML Element:

<div class="col-lg-4 col-md-6 mb-4 filterDiv shirts">
              <div class="card h-100 ">
                <a href="product.html"><img class="card-img-top" src="blackshirt.png" alt=""></a>
                <div class="card-body">
                  <h4 class="card-title">
                    <a href="product.html" class="product-title">Black Shirt</a>
                  </h4>
                  <h5>$24.99</h5>
                  <p class="card-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet numquam aspernatur!</p>
                </div>
                <div class="card-footer">
                  <a href="product.html" class="btn btn-success view-btn" role="button"><i class="fa fa-search"></i> View Product</a>
                </div>
              </div>
            </div>

JavaScript

filterSelection("all")
function filterSelection(c) {
    var x, i;
    x = document.getElementsByClassName("filterDiv");
    if (c == "all") c = "";
    for (i = 0; i < x.length; i++) {
      w3RemoveClass(x[i], "show");
      if (x[i].className.indexOf(c) > -1) w3AddClass(x[i], "show");
    }
  }

  function w3AddClass(element, name) {
    var i, arr1, arr2;
    arr1 = element.className.split(" ");
    arr2 = name.split(" ");
    for (i = 0; i < arr2.length; i++) {
      if (arr1.indexOf(arr2[i]) == -1) {element.className += " " + arr2[i];}
    }
  }

  function w3RemoveClass(element, name) {
    var i, arr1, arr2;
    arr1 = element.className.split(" ");
    arr2 = name.split(" ");
    for (i = 0; i < arr2.length; i++) {
      while (arr1.indexOf(arr2[i]) > -1) {
        arr1.splice(arr1.indexOf(arr2[i]), 1);
      }
    }
    element.className = arr1.join(" ");
  }

  // Add active class to the current button (highlight it)
  var btnContainer = document.getElementById("myBtnContainer");
  var btns = btnContainer.getElementsByClassName("btn");
  for (var i = 0; i < btns.length; i++) {
    btns[i].addEventListener("click", function(){
      var current = document.getElementsByClassName("active");
      current[0].className = current[0].className.replace(" active", "");
      this.className += " active";
    });
  }

Answer №1

  • How to deal with two active buttons simultaneously

    To address this issue, the logic within the function filterSelection needs to be examined.

  • Issue of active class being added twice

    A solution for adding a class only once can be found by utilizing the toggle function from the classList attribute.

  • Display products based on the selected button

    • You can achieve this functionality by using the data attributes and working in conjunction with the classList attribute.
    • For example, assign the following values to your buttons: data-target='shirts', data-target='pants', and so forth.
    • Create a class called hide with the style: display: none

var btnContainer = document.getElementById("myBtnContainer");
var btns = btnContainer.getElementsByClassName("btn");
for (var i = 0; i < btns.length; i++) {
  btns[i].addEventListener("click", function() {
    var current = document.getElementsByClassName("active");
    current[0].classList.toggle('active');
    this.classList.toggle('active');
    
    var target = this.dataset.target;
    filterSelection(target);
  });
}

function filterSelection(target) {
  document.querySelectorAll('.filterDiv').forEach((div) => {
    if (target === 'all' || div.classList.contains(target)) {
      div.classList.remove('hide');
    } else {
      div.classList.add('hide');
    }
  });
}
.active {
  background-color: lightgreen;
}

.hide {
  display: none
}
<div class="list-group" id="myBtnContainer">
  <button class="btn list-group-item active" data-target='all'>Show all</button>
  <button class="btn list-group-item" data-target='shirts'>Shirts</button>
  <button class="btn list-group-item" data-target='pants'>Pants</button>
</div>

<div class="col-lg-4 col-md-6 mb-4 filterDiv shirts">
  <div class="card h-100 ">
    <a href="product.html"><img class="card-img-top" src="blackshirt.png" alt=""></a>
    <div class="card-body">
      <h4 class="card-title">
        <a href="product.html" class="product-title">Black Shirt</a>
      </h4>
      <h5>$24.99</h5>
      <p class="card-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet numquam aspernatur!</p>
    </div>
    <div class="card-footer">
      <a href="product.html" class="btn btn-success view-btn" role="button"><i class="fa fa-search"></i> View Product</a>
    </div>
  </div>
</div>


<div class="col-lg-4 col-md-6 mb-4 filterDiv pants">
  <div class="card h-100 ">
    <a href="product.html"><img class="card-img-top" src="blackshirt.png" alt=""></a>
    <div class="card-body">
      <h4 class="card-title">
        <a href="product.html" class="product-title">Pants</a>
      </h4>
      <h5>$44.99</h5>
      <p class="card-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet numquam aspernatur!</p>
    </div>
    <div class="card-footer">
      <a href="product.html" class="btn btn-success view-btn" role="button"><i class="fa fa-search"></i> View Product</a>
    </div>
  </div>
</div>

Useful Resource

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

What is the process for creating a multi-word argument?

Is there a way to create multi-word arguments, such as reasons for bans or mutes? Currently, I am using args[2], args[3], args[4], args[5]... but this approach is limited and if nothing is written in those arguments, it will display "undefined". If you k ...

Purpose of triggering another function during an ajax request

I have encountered an issue while working on a project. There is a page with an input field called balance within a div named balanceDiv. This field should not be visible to the admin, so I used ng-show to hide/show the div based on the user's login I ...

Transform and command the data acquired through an AJAX request using jQuery

My code includes an AJAX call using jQuery: $('.add a').click(function() { $.ajax({ type: 'POST', url: '/api/fos', context: this, datatype: 'html', success: function(data) ...

In Vue, it is not accurate to measure overflow

I am working on creating an overflow effect with tagging that fades out at the beginning to provide a subtle hint to users that there is more content. Here is what it currently looks like: https://i.stack.imgur.com/fXGBR.png To achieve this, I added a fa ...

Transform the arrow function into a standard JavaScript function

Here is the React return code snippet I'm working with: return ( <div className='App'> <form onSubmit={this.submit.bind(this)}> <input value={this.state.input} onChange={(e) ...

Using RabbitMQ in a Node.js application to illustrate an example of header exchange

I've been on a quest to find an example of using RabbitMQ with Node.js for a headers exchange. If anyone could guide me in the right direction, I would greatly appreciate it. Here's what I've managed to put together so far: The publisher me ...

Switch off JavaScript beyond the parent element

Struggling with implementing an event to toggle a div using an element located outside of the parent container. I am attempting to achieve the same functionality by targeting elements beyond the parent structure utilizing a span tag. Any assistance on th ...

The magical form component in React using TypeScript with the powerful react-final-form

My goal is to develop a 3-step form using react-final-form with TypeScript in React.js. I found inspiration from codesandbox, but I am encountering an issue with the const static Page. I am struggling to convert it to TypeScript and honestly, I don't ...

a service that utilizes $http to communicate with controllers

My situation involves multiple controllers that rely on my custom service which uses $http. To tackle this issue, I implemented the following solution: .service('getDB', function($http){ return { fn: function(){ return $http({ ...

(JS) utilizing an external .js function by using the <script> tag

Looking to execute the function cookiefix() from main.js, which is linked at the bottom of my HTML file. echo '<body>'; if(!isset($_COOKIE['clicked'])) { if(!isset($_COOKIE['count'])) { echo '<script type="text/ ...

Learn the steps to activate on-page editing feature!

Is there a way to make a section of a webpage editable when a button is clicked? (e.g. edit & view on the same page) For instance, imagine you could click "edit" on this very page (the one you are currently reading), and the title and content become edita ...

What is the best way to assign a unique ID to every element in this situation?

Here is the given code: var words = ['ac', 'bd', 'bf', 'uy', 'ca']; document.getElementById("wordTable").innerHTML = arr2tbl(2); function arr2tbl(ncols) { return words.reduce((a, c, i) => { ...

Click event to reset the variable

The code snippet in Javascript below is designed to execute the function doSomethingWithSelectedText, which verifies if any text is currently selected by utilizing the function getSelectedObj. The getSelectedObj function returns an object that contains in ...

"Utilizing an exported constant from a TypeScript file in a JavaScript file: A step-by-step guide

I am facing an issue when trying to import a constant from a TypeScript file into a JavaScript file. I keep encountering the error Unexpected token, expected ,. This is how the constant looks in the ts file: export const articleQuery = (slug: string, cate ...

Learn how to update a form dynamically using the Ajax.BeginForm feature

I am currently working on updating a form within my application using Ajax.BeginForm. The update process is functioning correctly, however, upon executing the function in the controller, it redirects to a view with the controller function name displayed. ...

Organizing content into individual Div containers with the help of AngularJS

As someone who is new to the world of AngularJS, I am currently in the process of learning the basics. My goal is to organize a JSON file into 4 or 5 separate parent divs based on a value within the JSON data, and then populate these divs with the correspo ...

"Jquery with 3 buttons for toggling on and off individually, as well

There are 3 buttons available: button 1, button 2, and button 3. Button 1 toggles the show/hide functionality of the left side, button 2 does the same for the right side, and button 3 affects both sides simultaneously. What is the best approach to achieve ...

Is it possible to import files in Vue JavaScript?

I want to incorporate mathematical symbols from strings extracted from a JSON file. While it seems to work perfectly on this example, unfortunately, I encountered an issue when trying it on my own machine. The error message 'Uncaught (in promise) Refe ...

JavaScript Event Listener causing the Sticky Position to Break

I am currently dealing with a situation where I want to create a slide-in side menu that remains sticky. However, when I apply the position: sticky CSS property to my menu container, it causes the entire menu to be displayed (instead of being pushed off th ...

What strategies can be employed to reduce the need for numerous if-else statements in my JavaScript code?

In my input form, users have the ability to make edits. I need to send only the data that has been changed by the user. Currently, I am repeating the same lines of code multiple times to compare and determine what data needs to be sent. Is there a more e ...