M1guelp
M1guelp

Reputation: 1

Using 2 HTML elements with non-unique ids

I am using 2 same id's in my HTML file that connect to my JavaScript file and I know this brings up issues because you can't use 2 id's with the same name, but I wanted to see if there's a short way around this?

HTML code below

<div class="txt_field">
  <input type="password" required="" id="id_password">
  <i class="far fa-eye" id="togglePassword"></i>
  <span></span>
  <label>Password</label>
</div>
<div class="txt_field">
  <input type="password" required="" id="id_password">
  <i class="far fa-eye" id="togglePassword"></i>
  <span></span>
  <label>Confirm Password</label>

Below is my JavaScript code

const togglePassword1 = document.querySelector('#togglePassword');
  const password = document.querySelector('#id_password');

  togglePassword.addEventListener('click', function (e){
    // toggle the type attribute
    const type = password.getAttribute('type') === 'password' ? 'text' : 'password';
    password.setAttribute('type', type);
    // toggle the eye slash icon
    this.classList.toggle('fa-eye-slash');
});

Upvotes: 0

Views: 574

Answers (3)

Arleigh Hix
Arleigh Hix

Reputation: 10897

You definitely must always use unique id attribute values, or you will not have valid HTML (inputs also need a name attribute set if you want them submitted with a form). In your case I would recommend using a common classname to identify which elements will have the desired functionality (i.e. class="togglePassword")

You can explicitly declare exactly which element the toggle will control by adding it's unique id to a data attribute of the toggle, then use that in the event handler to get the element. To make it work smoothly use the id selector string (i.e. data-toggle="#id_password") and pass that to document.querySelector().

In the snippet below, I have also slightly altered the function to insure the eye slash icon is toggled correctly (in sync with input).

const togglePasswords = document.querySelectorAll('.togglePassword');

togglePasswords.forEach(togglePassword => {

  togglePassword.addEventListener('click', function(e) {
    // get the associated input to toggle
    const pwInput = document.querySelector(this.dataset.toggle)
    // get the toggle direction
    const to_text = pwInput.getAttribute('type') === 'password'
    // toggle the type attribute
    const type = to_text ? 'text' : 'password';
    pwInput.setAttribute('type', type);
    // toggle the eye slash icon (force present when text, absent when password)
    this.classList.toggle('fa-eye-slash', to_text);
  })

})
.togglePassword {
  cursor: pointer;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.2/css/all.min.css" rel="stylesheet" />

<div class="txt_field">
  <input type="password" required="" id="id_password" name="password">
  <i class="far fa-eye togglePassword" data-toggle="#id_password"></i>
  <label for="id_password">Password</label>
</div>
<div class="txt_field">
  <input type="password" required="" id="id_password_repeated" name="password_repeated">
  <i class="far fa-eye togglePassword" data-toggle="#id_password_repeated"></i>
  <label for="id_password_repeated">Confirm Password</label>
</div>

Upvotes: 0

Carsten Massmann
Carsten Massmann

Reputation: 28206

Here is a simple way of doing it without IDs:

document.body.addEventListener('click', function (e){
 if(e.target.classList.contains("far")){
  const inp=e.target.previousElementSibling;
  inp.type=inp.type=="text"?"password":"text";
 }
});
<div class="txt_field">
 <input type="password" required="" name="pw1">
 <i class="far">&#x1F441;</i>
 <span></span>
 <label>Password</label>
</div>
<div class="txt_field">
 <input type="password" required="" name="pw2">
 <i class="far">&#x1F441;</i>
 <span></span>
 <label>Confirm Password</label>

Upvotes: 2

niklasbec
niklasbec

Reputation: 1044

You never ever ever want to use duplicate ids, you could still differentiate between the two if you do

querySelectorAll("#id_password")

and then grab index 0 or index 1 according to your correct variable, again NOT RECOMMENDED don't use duplicate ids.

Upvotes: 1

Related Questions