Reputation: 1
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
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
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">👁</i>
<span></span>
<label>Password</label>
</div>
<div class="txt_field">
<input type="password" required="" name="pw2">
<i class="far">👁</i>
<span></span>
<label>Confirm Password</label>
Upvotes: 2
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