0

what is the proper way to create dynamic buttons that share a class.

in my case i have 2 inputs that share class

enter image description here

<div class="input-group">
<input autocomplete="new-password" rel="tooltip" data-bs-toggle="tooltip" data-bs-placement="top" title="La contraseña debe ser de 8 caracteres y tener al menos una letra minúscula, una letra mayúscula, un número y un caracter especial (#$%&amp;*+-;.:=@!_?/)" class="form-control password" type="password" name="user[password]" id="user_password" aria-autocomplete="list">
<div class="btn btn-outline-dark visor" id="button" type="button">
<svg class="svg-inline--fa fa-eye-slash fa-w-20 icon" id="button" aria-hidden="true" focusable="false" data-prefix="fa" data-icon="eye-slash" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512" data-fa-i2svg=""><path fill="currentColor" d="M320 400c-75.85 0-137.25-58.71-142.9-133.11L72.2 185.82c-13.79 17.3-26.48 35.59-36.72 55.59a32.35 32.35 0 0 0 0 29.19C89.71 376.41 197.07 448 320 448c26.91 0 52.87-4 77.89-10.46L346 397.39a144.13 144.13 0 0 1-26 2.61zm313.82 58.1l-110.55-85.44a331.25 331.25 0 0 0 81.25-102.07 32.35 32.35 0 0 0 0-29.19C550.29 135.59 442.93 64 320 64a308.15 308.15 0 0 0-147.32 37.7L45.46 3.37A16 16 0 0 0 23 6.18L3.37 31.45A16 16 0 0 0 6.18 53.9l588.36 454.73a16 16 0 0 0 22.46-2.81l19.64-25.27a16 16 0 0 0-2.82-22.45zm-183.72-142l-39.3-30.38A94.75 94.75 0 0 0 416 256a94.76 94.76 0 0 0-121.31-92.21A47.65 47.65 0 0 1 304 192a46.64 46.64 0 0 1-1.54 10l-73.61-56.89A142.31 142.31 0 0 1 320 112a143.92 143.92 0 0 1 144 144c0 21.63-5.29 41.79-13.9 60.11z"></path></svg><!-- <div class="icon fa fa-eye-slash" id="button"></div> Font Awesome fontawesome.com -->
</div>
</div>

<div class="input-group">
<input autocomplete="new-password" rel="tooltip" title="Debe coincidir con la contraseña" class="form-control password" type="password" name="user[password_confirmation]" id="user_password_confirmation">
<div class="btn btn-outline-dark visor" id="button2" type="button">
<svg class="svg-inline--fa fa-eye-slash fa-w-20 icon" id="button2" aria-hidden="true" focusable="false" data-prefix="fa" data-icon="eye-slash" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512" data-fa-i2svg=""><path fill="currentColor" d="M320 400c-75.85 0-137.25-58.71-142.9-133.11L72.2 185.82c-13.79 17.3-26.48 35.59-36.72 55.59a32.35 32.35 0 0 0 0 29.19C89.71 376.41 197.07 448 320 448c26.91 0 52.87-4 77.89-10.46L346 397.39a144.13 144.13 0 0 1-26 2.61zm313.82 58.1l-110.55-85.44a331.25 331.25 0 0 0 81.25-102.07 32.35 32.35 0 0 0 0-29.19C550.29 135.59 442.93 64 320 64a308.15 308.15 0 0 0-147.32 37.7L45.46 3.37A16 16 0 0 0 23 6.18L3.37 31.45A16 16 0 0 0 6.18 53.9l588.36 454.73a16 16 0 0 0 22.46-2.81l19.64-25.27a16 16 0 0 0-2.82-22.45zm-183.72-142l-39.3-30.38A94.75 94.75 0 0 0 416 256a94.76 94.76 0 0 0-121.31-92.21A47.65 47.65 0 0 1 304 192a46.64 46.64 0 0 1-1.54 10l-73.61-56.89A142.31 142.31 0 0 1 320 112a143.92 143.92 0 0 1 144 144c0 21.63-5.29 41.79-13.9 60.11z"></path></svg><!-- <div class="icon fa fa-eye-slash" id="button2"></div> Font Awesome fontawesome.com -->
</div>
</div>

Javascript code:

const input = () => {
    $(".visor").on('click',function() {
        var userChosenInput = $(this).attr("id")
        console.log(userChosenInput)
        visor(userChosenInput)
    });
}


const visor = () => {
    var cambio = document.querySelector(".password")

    if(cambio.type === "password"){
        cambio.type = "text"
        $('.icon').removeClass('fa fa-eye-slash').addClass('fa fa-eye');
    }else{
        cambio.type = "password"
        $('.icon').removeClass('fa fa-eye').addClass('fa fa-eye-slash');
    }
}

no matter what icon I press it changes the 2 icons and a single field, I want them to be individual behaviors.

enter image description here

1
  • You're calling visor with an argument but it doesn't accept any parameter. Instead it always selects the first document.querySelector(".password") and all $('.icon'). Commented Oct 4, 2022 at 2:54

3 Answers 3

1

This will also do the trick: One function for all buttons ...

$(".input-group button").on("click",function(){
 $("i",this).toggleClass(['fa-eye-slash','fa-eye']); // change icon
 const inp=$(this).prev()[0]; // get the previous DOM element
 inp.type=inp.type=="text"?"password":"text"; // change type
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<div class="input-group">
  <input autocomplete="new-password" rel="tooltip" data-bs-toggle="tooltip" data-bs-placement="top" title="La contraseña debe ser de 8 caracteres y tener al menos una letra minúscula, una letra mayúscula, un número y un caracter especial (#$%&amp;*+-;.:=@!_?/)"
    class="form-control password" type="password" name="user[password]" id="user_password" aria-autocomplete="list" />
  <button><i class="fa fa-eye-slash" id="icon"></i></button>
</div>
<div class="input-group">
  <input autocomplete="new-password" rel="tooltip" title="Debe coincidir con la contraseña" class="form-control password" type="password" name="user[password_confirmation]" id="user_password_confirmation">
  <button><i class="fa fa-eye-slash" id="icon"></i></button>
</div>

Sign up to request clarification or add additional context in comments.

Comments

1

just use an click event on button . you can use my below code . i hope this will help you

    let user=document.getElementById("user_password")
    let password=document.getElementById("user_password_confirmation");
    let show1=()=>{
        user.type=="password"?user.type = "text":user.type="password"
    }
    let show2=()=>{
        password.type=="password"?password.type = "text":password.type="password"
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<div class="input-group">
    <input autocomplete="new-password" rel="tooltip" data-bs-toggle="tooltip" data-bs-placement="top" title="La contraseña debe ser de 8 caracteres y tener al menos una letra minúscula, una letra mayúscula, un número y un caracter especial (#$%&amp;*+-;.:=@!_?/)" class="form-control password" type="password" name="user[password]" id="user_password" aria-autocomplete="list"/>
    <button><i class="fa fa-eye-slash" id="icon" onclick="show1()"></i></button>
    </div>
    
    <div class="input-group">
    <input autocomplete="new-password" rel="tooltip" title="Debe coincidir con la contraseña" class="form-control password" type="password" name="user[password_confirmation]" id="user_password_confirmation">
    <button onclick="show2()"><i class="fa fa-eye-slash" id="icon"></i></button>
    </div>

Comments

1

Since your question doesn't directly specify whether to use jQuery or not, I took the liberty of doing it in vanilla js.

<div class="input-group">
  <input class="form-control password" type="password" id="user_password">
  <button class="btn btn-outline-dark">
    <i class="fa-solid fa-eye"></i>
  </button>
</div>

<div class="input-group">
  <input class="form-control password" type="password" id="user_password_confirmation">
  <button class="btn btn-outline-dark">
    <i class="fa-solid fa-eye"></i>
  </button>
</div>
const $ = selector => document.querySelector(selector)
const $$ = selector => document.querySelectorAll(selector)

const inputs = $$('input.password')
inputs.forEach((input) => {
  const button = $(`#${input.id} + button`)
  const icon = button.children[0]

  button.addEventListener('click', () => {
    input.type = input.type === 'password' ? 'text' : 'password'
    icon.classList.toggle('fa-eye')
    icon.classList.toggle('fa-eye-slash')
  })
})

Demo in codi.link

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.