How to Switch CSS Class between Buttons Rendered with Map()?


When building web applications, developers often need to create buttons with dynamic styles. One of the most efficient ways to do this is by using the map() method in JavaScript. This method allows you to render multiple buttons with different styles based on their data. However, sometimes you might want to change the CSS class of a button dynamically based on user interaction or other events. In this article, we will discuss two different approaches to switch CSS class between buttons rendered with map() in JavaScript.

Algorithm

The algorithm to switch CSS class between buttons rendered with map() involves the following steps −

  • Create an array of objects with data for each button

  • Render the buttons using the map() method and assign a default CSS class

  • Add an event listener to each button to listen for user interaction

  • When a user interacts with a button, switch its CSS class to the desired one using the classList property

Approach 1: Using State and Ternary Operator

In this approach, we use the useState hook to create a state variable called "activeButton" that will store the ID of the button that is currently active. We then pass this state variable to the className attribute of the button as a ternary operator. If the button's ID matches the activeButton state, we add the "active" CSS class, otherwise, we leave it blank.

When a user clicks on a button, the handleButtonClick function updates the activeButton state with the ID of the clicked button, causing the component to re-render and switch the CSS class of the corresponding button.

import React, { useState } from "react";
const buttonsData = [
   { id: 1, label: "Button 1" },
   { id: 2, label: "Button 2" },
   { id: 3, label: "Button 3" },
];
const App = () => {
   const [activeButton, setActiveButton] = useState(null);
   const handleButtonClick = (id) => {
      setActiveButton(id);
   };

   return (
      <div>
         {
            buttonsData.map(({ id, label }) => (
               <button
                  key={id}
                  onClick={() => handleButtonClick(id)}
                  className={activeButton === id ? "active" : ""}
                  >
                  {label}
               </button>
            ))
         }
      </div>
   );
};
export default App;

Approach 2: Using Class-based Components and Conditional Rendering

In this approach, we use a class-based component instead of a functional component. We define the state and event handler in the class itself. The rest of the code is almost the same as the previous approach.

import React, { Component } from "react";
const buttonsData = [
   { id: 1, label: "Button 1" },
   { id: 2, label: "Button 2" },
   { id: 3, label: "Button 3" },
];

class App extends Component {
   state = {
      activeButton: null,
   };

   handleButtonClick = (id) => {
      this.setState({ activeButton: id });
   };

   render() {
      const { activeButton } = this.state;

      return (
         <div>
            {
               buttonsData.map(({ id, label }) => (
                  <button
                     key={id}
                     onClick={() => this.handleButtonClick(id)}
                     className={activeButton === id ? "active" : ""}
                     >
                     {label}
                  </button>
               ))
            }
         </div>
      );
   }
}

export default App;

Example 1: Switching CSS Class With a Click

In this example, we will switch the CSS class of a button when the user clicks on it.

<!DOCTYPE html>
<html>
<head>
   <style>
      .default {
         background-color: gray;
         color: white;
      }
      .active {
         background-color: blue;
         color: white;
      }
   </style>
</head>
<body>
   <div id="buttons-container"></div>
   <script>
      const buttonsData = [
         { id: 1, label: "Button 1" },
         { id: 2, label: "Button 2" },
         { id: 3, label: "Button 3" },
      ];

      const buttonsContainer = document.getElementById("buttons-container");

      buttonsData.forEach(({ id, label }) => {
         const button = document.createElement("button");
         button.textContent = label;
         button.className = "default";
         button.addEventListener("click", () => {
            const activeButton = buttonsContainer.querySelector(".active");
            if (activeButton) {
               activeButton.classList.remove("active");
            }
            button.classList.add("active");
         });
         buttonsContainer.appendChild(button);
      });
   </script>
</body>
</html>

In this example, we create a simple HTML page that includes a container for our buttons and the CSS styles for the default and active classes. We then use the forEach() method to iterate over the buttonsData array and create a button element for each item. We set the default CSS class for each button and add an event listener to listen for click events.

When the user clicks on a button, we first find the currently active button (if any) and remove the active class from it. We then add the active class to the clicked button.

Example 2: Switching CSS Class With Keyboard Navigation

In this example, we will switch the CSS class of a button when the user navigates to it using the keyboard.

<!DOCTYPE html>
<html>
<head>
   <style>
      .default {
         background-color: gray;
         color: white;
      }
      .active {
         background-color: red;
         color: white;
      }
   </style>
</head>
<body>
   <div id="buttons-container"></div>
   <script>
      const buttonsData = [
         { id: 1, label: "Button 1" },
         { id: 2, label: "Button 2" },
         { id: 3, label: "Button 3" },
      ];

      const buttonsContainer = document.getElementById("buttons-container");

      buttonsData.forEach(({ id, label }) => {
         const button = document.createElement("button");
         button.textContent = label;
         button.className = "default";
         button.addEventListener("focus", () => {
            const activeButton = buttonsContainer.querySelector(".active");
            if (activeButton) {
               activeButton.classList.remove("active");
            }
            button.classList.add("active");
         });
         buttonsContainer.appendChild(button);
      });
   </script>
</body>
</html>

In this example, we use the same HTML and CSS styles as in the previous example. Instead of adding a click event listener, we add a focus event listener to each button. This event listener is triggered when the user navigates to a button using the keyboard (e.g., by pressing the Tab key).

When the focus event is triggered, we follow the same logic as in the previous example to switch the CSS class of the buttons.

Conclusion

In this article, we discussed two different approaches to switch CSS class between buttons rendered with map() in JavaScript. We first explained the algorithm to accomplish this task and then provided two different approaches with code and explanations. The first approach involves using the useState hook in React to create a state variable that stores the ID of the currently active button. We then use a ternary operator to switch the CSS class of the button based on the activeButton state. The second approach involves using a class-based component and conditional rendering to achieve the same result. We also provided two working examples to demonstrate how to switch the CSS class of buttons with user interaction and keyboard navigation. By following these approaches, you can create dynamic buttons with different styles and easily switch between them based on user interaction or other events.

Updated on: 17-Apr-2023

183 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements