Troublesome button appearance

I set up two sections to gather user information using buttons. My goal is for the button styles to change when clicked, making it clear to users which option they have selected, even if they switch between sections. However, I encountered an issue where clicking on a button in one section caused the style of the other section's buttons to revert back to their default state. Below is the HTML code snippet that illustrates this problem:

<div>
    <p><strong>Network</strong></p>

     <button class="btn25" onclick = "gfg_Run()">                  
         MTN
     </button>
     <button class="btn25">         
         Glo
     </button>
     <button class="btn25">         
         9 Mobile
     </button>
     <button class="btn25">          
          Airtel
     </button>
</div>

<div>
     <p><strong>Data</strong></p>

     <button class="btn25">        
         1Gb
     </button>
     <button class="btn25">        
         2Gb
     </button>
     <button class="btn25">         
         3Gb
     </button>
     <button class="btn25">       
          5Gb
     </button>
     <button class="btn25">         
          10Gb
     </button>
</div>

Answer №1

I require a change in style to make it visually distinct for the user.

To achieve this, create a new CSS class called "active" and apply it to the buttons when they are selected by the user.

Currently, the issue is that when one button is clicked, the style of the other section gets reset.

In order to resolve this, you should separate the buttons into different groups. I have added a class to the parent div to differentiate between the two groups: "data" and "speed". The styling changes will be isolated within each group based on their respective classes, as demonstrated in the code snippet below:

document.querySelectorAll('.data .btn25');

Below is an example snippet illustrating the implementation of this technique.

const dataChoices = document.querySelectorAll('.data .btn25');
dataChoices.forEach(function(choice) {
  choice.addEventListener('click', function() {
    removeClass(dataChoices);
    this.classList.add('active');
  });
});

const speedChoices = document.querySelectorAll('.speed .btn25');
speedChoices.forEach(function(choice) {
  choice.addEventListener('click', function() {
    removeClass(speedChoices);
    this.classList.add('active');
  });
});

function removeClass(dataGroup) {
  dataGroup.forEach(function(choice) {
    choice.classList.remove('active');
  });
}
.active {
  background-color: lightblue;
}

div {
  float: left;
  margin-right: 10px;
}
<div class="data">
  <p><strong>Data</strong></p>
  <button id="1" class="btn25">1Gb</button>
  <button id="2" class="btn25">2Gb</button>
  <button id="3" class="btn25">3Gb</button>
  <button id="4" class="btn25">5Gb</button>
  <button id="5" class="btn25">10Gb</button>
</div>
<div class="speed">
  <p><strong>Speed</strong></p>
  <button id="1" class="btn25">1Mbps</button>
  <button id="2" class="btn25">2Mbps</button>
  <button id="3" class="btn25">3Mbps</button>
  <button id="4" class="btn25">5Mbps</button>
  <button id="5" class="btn25">10Mbps</button>
</div>

Answer №2

While Christopher Taleck's answer is perfectly fine, I have an alternative way to approach this problem that may be informative for others facing a similar situation.

For a working example, you can check out this JSFiddle: JSFiddle

Below is the complete code along with explanations:

index.html

<!DOCTYPE html>
<html>
<head>
  <title>Button Practice</title>
  <link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>

  <div class="network-container">
    <h2>Network</h2>
    <button type="button" class="btn25">MTN</button>
    <button type="button" class="btn25">Glo</button>
    <button type="button" class="btn25">9 Mobile</button>
    <button type="button" class="btn25">Airtel</button>
  </div>

  <div class="speed-container">
    <h2>Speed</h2>
    <button type="button" class="btn25">1Mbps</button>
    <button type="button" class="btn25">2Mbps</button>
    <button type="button" class="btn25">3Mbps</button>
    <button type="button" class="btn25">5Mbps</button>
    <button type="button" class="btn25">10Mbps</button>
  </div>

  <script type="text/javascript" src="script.js"></script>
</body>
</html>

script.js

function ButtonContainer(element) {
  this.element = element;
  this.selectedButton = null;
  this.element.addEventListener('click', function(e) {
    if (e.target.type !== 'button') return;
    if (this.selectedButton) this.selectedButton.classList.remove('active');
    e.target.classList.add('active');
    this.selectedButton = e.target;
  });
}

const networkContainer = new ButtonContainer(document.querySelector('.network-container'));
const speedContainer = new ButtonContainer(document.querySelector('.speed-container'))

style.css

.active {
  background-color: #9AD58E;
}

GENERAL CODE EXPLANATION

To improve readability and maintainability, it's recommended to separate the JavaScript from the HTML. Create a constructor function called ButtonContainer that handles button interactions within specific container elements:

// script.js
function ButtonContainer(element) {
  // Constructor function implementation
}

ButtonContainer CONSTRUCTOR FUNCTION EXPLANATION

The ButtonContainer constructor function sets up properties for the respective element and selected button. It adds event listeners for button clicks within the container element and updates the styling accordingly.

By creating instances of ButtonContainer for different groups of buttons, you streamline event handling and keep code organized:

const networkContainer = new ButtonContainer(document.querySelector('.network-container'));
const speedContainer = new ButtonContainer(document.querySelector('.speed-container'));

This approach simplifies button management and reflects the logical separation between different button groups in the UI.

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

Encountering the "Invalid Element Type" error in a Vue Native project right after setting it up

After creating a vue-native project with the command vue-native init henry-pager, I navigated to the directory and initiated the online builder by running expo start. However, when attempting to run it on the web platform, an error message appeared: Error: ...

Highlight the parent item when the child item is being hovered over

I am working on a menu that has 2 submenus. I want to use jQuery to highlight the item when it is hovered over. However, I am struggling with how to also highlight the parent item when the cursor is on the child item. The class I am using for highlighting ...

Unable to show input in Javascript HTML

Every time I try to run this code on my webpage, the buttons do not seem to respond when clicked. I am aiming to have the user input for full name, date of birth, and gender displayed in the text box when the display button is clicked. When the next butt ...

Utilize Angular 2 to search and filter information within a component by inputting a search term from another component

In my application, I have a Component named task-board which contains a table as shown below: <tr *ngFor="let task of tasks | taskFilter: searchText" > <td>{{ task.taskName }}</td> <td>{{ task.location }}</td> <td>{{ ta ...

When using Vue.js, the class binding feature may not function properly if it is referencing another data property that has variants

I am currently developing a basic TODO application. Within my index.html file, I have a main div with the id #app. Inside this div, there is another div with the class .todobox where I intend to display different tasks stored in my main.js file. Each task ...

Capture table screenshot using Selenium with unique font style

Below is a Python script that uses Selenium to load a specific page and capture a screenshot of the table on the page. from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.by import By from sel ...

Headers cannot be set once they have already been sent in NodeJS

Here is the code where I authenticate users in a group, push accounts into an array, and save them using a POST request on /addaccount. groupRouter.post('/addaccount', Verify.verifyOrdinaryUser, function(req, res, next) { Groups.findById(req.bod ...

What could be causing my router UI in angular.js to malfunction?

Having an issue with routing not functioning as intended, here is the relevant code: $urlRouterProvider. otherwise('/list'); $stateProvider. state('home', { abstract: true, views: { 'header': { templateUrl: &apos ...

Generating unique spreadsheet identifiers in an HTML file

When it comes to displaying a chart using Google Sheets, I encounter an issue where the data is sourced from the same spreadsheet: function updateChart() { var ui = HtmlService.createHtmlOutputFromFile('ChartLine').setWidth(1350).setHeight(550) ...

The video player in HTML may not be compatible with all MP4 files, as some may work while

I have included the following code for embedding mp4 videos on my website: <video class="video" controls="" width="100%" src="videopath/videoname.mp4"></video> Despite using this code for 3 videos, all in mp4 format, only one of them is funct ...

Real-time audio feed permanently stuck in Chromium-powered web browsers

Here is how the audio element appears. No interaction seems to take place with it. (Experimented on ungoogled chromium, Edge, and an android device using a default Chrome browser) Below is the HTML code for the audio element: <div> <audio co ...

Leveraging createMuiTheme to customize default styles for divs, paragraphs, and the body element

Seeking guidance on customizing a Material UI Theme I aim to modify the default styles for elements like <body>. Currently, at the root of my React tree: import theme from './mui-theme' ReactDOM.render( <Router> <ThemePr ...

"Uncovering the dangers of XMLHttpRequest: How automatic web-page refresh can lead

Hello, I have been developing a web interface for some hardware that utilizes an 8-bit microcontroller. The webpage includes HTML, JavaScript, JSON, and XHR (XMLHttpRequest) for communication purposes. My goal is to create a page that updates every 250 ...

using jquery to retrieve the current time and compare it

This is the code I currently have: var currentTime = new Date() var month = currentTime.getMonth() + 1 var day = currentTime.getDate() var year = currentTime.getFullYear() var hours = currentTime.getHours() var minutes = currentTime.getMinutes() aler ...

Attempting to add text one letter at a time

Hey there! I'm new to JavaScript and Jquery, and I need some help. My goal is to display text letter by letter when a button is clicked using the setTimeout function. However, I seem to be encountering some issues. Any assistance would be greatly appr ...

How can I pass a value as an attribute from an Angular template to a directive?

Here's a directive I'm working with: <g-map-locations center={{myLocation}} zoom="4" id="map" class="map"></g-map-locations> The zoom parameter is used in Angular to set the zoom level for a Google Map: attrs.zoom = zoom setMapOpti ...

Bootstrap implementation for personalized notifications

I am utilizing bootstrap notifications to display important messages to my users. Within my code, there is a DIV element named <div class="notifications bottom-right"></div> Theoretically, the library should be handling the JavaScript. I ha ...

Tips for integrating an arrow function as a property in a functional programming approach using JavaScript or TypeScript

Suppose I were to create a constructor for a functional class with TypeA as an argument, and TypeB representing the type of the class itself. In such cases, I can implement it using: functionName(argument: TypeA): TypeB { this.property = argument; ...

Determine the number of objects in a JSON array and compile a new array containing the sum of the

I am working with a JSON array that looks like this: const arrayVal = [{ "DATE": "2020-12-1", "NAME": "JAKE", "TEAM_NO": 2, }, { "DATE": "2020-12-2"`, "NAME" ...

How to disable CSS transition on Angular 4 component initialization

I am facing a major issue with css transitions and Angular 4. The problem arises when using an external library that includes an input counter feature. Despite knowing that no additional styling is being applied to the wrapped input, the application has a ...