javascripthtmlcssdjangotoggleswitch

How to use multiple toggle switches created dynamically?


I am a beginner in Frontend. I am implementing toggle switches in HTML,CSS and Vanilla Javascript.

Structure:

I create an HTML with "n" number of rows depending on the data in my django database. Each row has some data like name, id, status. Status column has toggle switches for each row. I have implemented the toggle switch which works fine for one single toggle switch.

Problem:

When there are multiple rows, and hence, multiple toggle switches, only the first toggle switch is getting toggled not the others. When I click on other toggle switches then also the first one gets triggered. I want all toggle switches to work separately and to detect it in my vanilla javascript.

What I know:

I know that we need unique id for each toggle switches but I don't know how to do that when I don't know how many rows I will have and how to detect all of them in JS code.

Code:

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;
  box-sizing: border-box;
  height: 15.32px;
  width: 30.33px;
  border: 1px solid #b8cfd9;
  border-radius: 17.5px;
  background-color: #ffffff;
}
/* After slide changes */
.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;
}

/* Checkbox cheked toggle label bg color */
.toggle-checkbox:checked + .toggle {
  height: 15.32px;
  width: 30.33px;
  border-radius: 17.5px;
  background-color: #8566c1;
}

/* Checkbox vanished */
.toggle-checkbox {
  display: none;
}

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

/* Checkbox cheked toggle label bg color */
.toggle-checkbox:checked + .toggle {
  height: 15.32px;
  width: 30.33px;
  border-radius: 17.5px;
  background-color: #8566c1;
}

/* Checkbox vanished */
.toggle-checkbox {
  display: none;
}
<div class="idm-switch_div div-container">
                <input type="checkbox" id="switch" class="toggle-checkbox" />
                <label for="switch" class="toggle"> </label>
              </div>

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

Any help will be appreciated. Thank you in advance!.


Solution

    1. in html you can use {{forloop.counter}} in your checkbox id and label for attribute, so they can have their unique id

    2. in js, you can use your original addEventListener code, because you have unique toggle switch id now, so it can recognize which one you want to toggle

    Here is the code:

    <!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-ptions" /><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>