Tips on utilizing multiple dynamically generated toggle switches efficiently

As a Frontend beginner, I am working on implementing toggle switches using HTML, CSS, and Vanilla JavaScript.

Approach:

I am generating an HTML table with multiple rows based on the data from my Django database. Each row contains details like name, id, and status, with a toggle switch for each row. Although I have successfully implemented the toggle switch functionality for a single switch, I am facing an issue with multiple switches.

Challenge:

The problem arises when there are multiple rows and toggle switches, as only the first switch toggles correctly while the others remain unresponsive. Clicking on any toggle switch activates the first one instead of the intended target. My goal is to ensure that each toggle switch functions independently within my Vanilla JavaScript code.

Knowledge:

I understand that assigning unique IDs to each toggle switch is essential, but I am unsure how to achieve this dynamically without knowing the exact number of rows beforehand and how to handle these IDs effectively in my JavaScript code.

Code Snippet:

var myswitch = document.querySelectorAll(".idm-switch_div .toggle");
myswitch.forEach((element) => {
  element.addEventListener("click", function () {
    var isChecked = document.querySelector(".toggle-checkbox").checked;
    localStorage.setItem("checkstate", !isChecked);
    console.log(!isChecked);
  });
});
.toggle {
  position: relative;
  display: inline-block;
  ... (CSS code continues)
}

/* Checkbox styling and behavior */
... (CSS code continues)

/* Toggle switch structure */
<div class="idm-switch_div div-container">
                <input type="checkbox" id="switch" class="toggle-checkbox" />
                <label for="switch" class="toggle"> </label>
              </div>

If you have any advice or solutions to offer, I would greatly appreciate your help. Thank you for your assistance!

Answer №1

You have the ability to use this for individual toggling purposes. By utilizing the parrentElement, I included an additional div element outside of each switch to ensure that values are retrieved from separate classes when invoked

function toggleSwitch(el) {
  var isChecked = el.parentElement.getElementsByClassName("toggle-checkbox")[0];
  if (isChecked.checked == true) {
    isChecked.checked = false;
  } else {
    isChecked.checked = true;
  }
}
.toggle {
  position: relative;
  display: inline-block;
  box-sizing: border-box;
  height: 15.32px;
  width: 30.33px;
  border: 1px solid #b8cfd9;
  border-radius: 17.5px;
  background-color: #ffffff;
}


/* Styling after switch is toggled */

.toggle:after {
  content: "";
  position: absolute;
  border-radius: 50%;
  top: 1px;
  left: 1px;
  transition: all 0.5s;
  height: 11.62px;
  width: 11.96px;
  background-color: #8566c1;
  box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.5);
}

.toggle-checkbox:checked+.toggle::after {
  left: 59%;
  background-color: white;
}


/* Changing label background color when checkbox is checked */

.toggle-checkbox:checked+.toggle {
  height: 15.32px;
  width: 30.33px;
  border-radius: 17.5px;
  background-color: #8566c1;
}


/* Hiding the checkbox */

.toggle-checkbox {
  display: none;
}

.toggle-checkbox:checked+.toggle::after {
  left: 59%;
  background-color: white;
}


/* Changing label background color when checkbox is checked */

.toggle-checkbox:checked+.toggle {
  height: 15.32px;
  width: 30.33px;
  border-radius: 17.5px;
  background-color: #8566c1;
}


/* Removing checkbox visibility */

.toggle-checkbox {
  display: none;
}
<div>
  <div class="idm-switch_div div-container" onclick="toggleSwitch(this)">
    <input type="checkbox" id="switch" class="toggle-checkbox" />
    <label for="switch" class="toggle"> </label>
  </div>
</div>


<div>
  <div class="idm-switch_div div-container" onclick="toggleSwitch(this)">
    <input type="checkbox" id="switch" class="toggle-checkbox" />
    <label for="switch" class="toggle"> </label>
  </div>
</div>

Answer №2

  1. When working in HTML, make use of {{forloop.counter}} in the checkbox id and label for attribute to ensure they each have a unique identifier.

  2. In JavaScript, you can continue to utilize your original addEventListener code now that you have unique toggle switch IDs, allowing it to identify which one to toggle.

Below is the provided code snippet:

<!DOCTYPE html>
{% load static %}
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Show User List</title>
    <link rel="stylesheet" href="{% static "css/list.css" %}" />
  </head>

  <body>
    <ul>
      <li>
        <div class="grace-name">
          <img
            src="{% static 'images/arrow-left.svg' %}"
            class="idm-product-icon idm-product-icon-left"
          /><label class="idm-product_name idm-bold">GRACE </label>
          <img
            src="{% static 'images/arrow-left.svg' %}"
            class="idm-product-icon idm-product-icon-right"
          />
        </div>
      </li>
      <li><a class="active" href="#news">USERS</a></li>
      <li><a href="#contact">MACHINES</a></li>
      <li><a href="#about">AUTHORIZED CONNECTIONS</a></li>
    </ul>
    <div class="idm-batch-table-container">
      <table class="idm-data-grid">
        <thead>
          <th></th>
          <th>User ID</th>
          <th>Username</th>
          <th>Full Name</th>
          <th>Enabled</th>
          <th class="idm-status_header">User Connections</th>
          <th>Edit</th>
        </thead>
        <tbody>
          {% for user in users %} {% if not user.is_staff %}
          <tr>
            <td>
              <label class="idm-container-checkbox idm-checkmark-batch-table"
                ><input
                  type="checkbox"
                  class="yeschecked"
                  name="
                        batch-options" /><span
                  class="idm-checkmark idm-batch-checkmark"
                ></span
              ></label>
            </td>
            <td>{{ user.id }}</td>
            <td>{{ user.username }}</td>
            <td>{{ user.fullname }}</td>
            <td>
              <div class="idm-switch_div div-container">
                <!-- give forloop.counter in input id and label for attribute -->
                <input
                  type="checkbox"
                  id="switch_{{forloop.counter}}"
                  class="toggle-checkbox"
                />
                <label for="switch_{{forloop.counter}}" class="toggle"> </label>
              </div>
            </td>
            <td>
              <button class="table-connect">
                <img src="{% static 'images/Vector.png' %}"
              </button>
            </td>
            <td>
              <button class="table-edit">
                <img src="{% static 'images/edit.png' %}"
              </button>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
    <script
      type="text/javascript"
      src="{% static 'javascript/user.js' %}"
    ></script>
  </body>
</html>


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

How can I send a form without having the page reload using a combination of AJAX, PHP

I am struggling to submit a form without refreshing the page. I have tried using ajax as mentioned in some resources, but it's not working for me. What could be the issue? When I use the following code, everything works fine with PHP: document.getEl ...

JavaScript alert box

I'm fairly new to the world of web development, with knowledge in CSS & HTML and currently learning TypeScript. I'm attempting to create a message icon that opens and closes a notifications bar. Here's where I'm at so far: document.getE ...

retrieve a static method that returns an asynchronous value

Is there a way to have a static ES6 method in my code that simply returns a value instead of a promise? I'm looking for a solution to this problem: export default class Member { static existingMember() { var _existingMember; // DB.findExist ...

Is there a way to link table A's ID to table B's userID in a postgreSQL database?

Is it possible in PostgreSQL to establish a relational index between table A ID and table B userId for the purpose of joining two tables based on their ids? To provide further clarification, here is an example using MongoDB and Mongoose: const Billing = ...

How to Retrieve the Value of <input type=date> Using TypeScript

I am currently developing a survey website and need assistance with retrieving user input for two specific dates: the start date and end date. I aim to make the survey accessible only between these dates, disabling the "take survey" button after the end da ...

Implementing specific actions based on user selections in an Oracle APEX navigation bar

Within the application's navigation bar, there is a Home item that is present on all pages. I want to implement a feature where if the user clicks on the Home item, a warning message will pop up based on the page number, alerting them that any unsaved ...

Using gradients in the app bar with ReactJS and Material UI is not currently supported

Recently, I decided to create my own custom appbar for a personal project and opted to use the Erica One font. As it is still in its initial stages, there isn't much code written yet. However, I've encountered two issues related to linear and ra ...

Object.assign changes the original array object in place

I am facing a challenge while attempting to modify the value of a specific index in my state, specifically the property post_comments. The issue lies in the fact that even though I am only modifying a copy of the state, the actual state is also being alter ...

What is the best way to link JavaScript files from a Grails plugin in a separate Grails application?

I have developed a unique plugin that offers multiple Grails controllers and domain objects. Additionally, I have created several AngularJS UI components that I wish to utilize in various other projects. These specific files are located within the web-app ...

The proper method to establish a ModelForm metaclass

My goal is to create a dynamic ModelForm that generates additional fields based on specific class attributes for use in a ModelAdmin. Here's an example: class MyModelForm(forms.ModelForm): config_fields = ('book_type', 'is_featured ...

Tips for creating an element that maintains its dimensions when a border is added during a hover effect

One issue I often face is the desire to add a border to an element on hover, only to find that as the border appears, the element's height and width change, causing it to visually jump and potentially push other elements. Is there a solution for this ...

Exploring the integration of Styled-components in NextJs13 for server-side rendering

ERROR MESSAGE: The server encountered an error. The specific error message is: TypeError: createContext only works in Client Components. To resolve this issue, add the "use client" directive at the top of the file. More information can be found here i ...

What is the best way to trigger an API call using AJAX whenever the page loads and at regular intervals using `setInterval()` function?

New to coding and seeking guidance: I have a basic AJAX feature in my project that triggers a GET API request every 3 seconds: <script> $(document).ready( function() { setInterval(function() { $.get(&apos ...

Serve Webpack bundle on various routes - Express Way

I recently completed a web application using an Express backend and React frontend. Upon sending a request to the Express server, it undergoes a process where the URL is checked against the backend routes. If there isn't a match, the React bundle gen ...

When I navigate to the URL using a router-link, the v-for in my Vue.js component renders properly. However, if I manually type the URL or refresh the page, the v-for fails to render

Whenever I navigate to a specific URL that showcases icons of characters from a game, everything functions as expected and the icons are displayed. However, upon refreshing the page, the icons vanish. If I manually enter www.example.com/champions, the ico ...

Using Javascript, access the 'second child' element by referencing the 'first child' element within a shared 'parent element'

// Retrieve the child_2 element using core javascript let parent = document.querySelector('.child_1').closest('.parent'); let child_2 = parent.querySelector('.child_2'); How can I achieve the same functionality as the jQuery ...

According to Intelijj IDEA, the success function in the AJAX request is reported as unused

I've encountered an issue and I'm unsure of the cause. This is my code for testing AJAX requests: function sendAJAX() { var dataToSend = {}; dataToSend["username"] = $("#username").val(); dataToSend["age"] = $("#age").val(); data ...

Sending information to a child component causes the parent's data to be modified as well

Transferring information from the parent to the child component has always been easy for me. However, I recently encountered an issue where updating the data in the child component also updates the data in the parent component simultaneously. Now, I am loo ...

Step-by-step guide on using nodemon on a web hosting server

I am currently designing a website that includes a login form and I am in the process of uploading it to a web hosting service In order to activate my login form, I have to use node index Is there a way to change the destination of this tag: <li class ...

It appears that the home page of next.js is not appearing properly in the Storybook

Currently, I am in the process of setting up my next home page in storybooks for the first time. Following a tutorial, I successfully created my next-app and initialized storybooks. Now, I am stuck at importing my homepage into storybooks. To achieve this, ...