seularts 0 Light Poster

I have managed to achieve this action through this:

<link href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="input-group">
                    <input type="password" id="pass-on" title="<?php echo $user->valid_password_error; ?>" class="form-control" name="txt_upass" placeholder="Enter Password" autocomplete="off" value="" oninvalid="setCustomValidity('<?php echo $user->password_error; ?>')" oninput="setCustomValidity('')" required />
                    <label>Password</label>
                    <div class="input-group-append">
                        <span class="password-button password-button-main" data-id="pass-on"><i class="fas fa-eye-slash"></i></span>
                    </div>
                </div>
                <div class="form-group progress jquery-result-1" style="height: 10px;">

                    <div class="form-group input-group">
                        <input type="password" id="pass-verify-on" title="<?php echo $user->valid_password_error; ?>" class="form-control" name="txt_upass_ok" placeholder="Retype Password" autocomplete="off" value="" oninvalid="setCustomValidity('<?php echo $user->password_error; ?>')" oninput="setCustomValidity('')" required />
                        <label>Retype Password</label>
                        <div class="input-group-append">
                            <span class="password-button password-button-verify" data-id="pass-verify-on"><i class="fas fa-eye-slash"></i></span>
                        </div>
                    </div>

                    <script>
                        function togglePasswordVisibility($pw, on, id) {
        $pw.attr('type', on ? 'password' : 'text');
        $('[data-id=' + id + '] > i').toggleClass('fa-eye-slash fa-eye');
    }

    // $("#pass-on").after('<div class="input-group-append"><span class="password-button password-button-main"><i class="fas fa-eye-slash"></i></span></div>');

    $('[data-id]').on('click', function() {
        var id = $(this).data('id'),
            $pw = $('#' + id);

        togglePasswordVisibility($pw, false, id);

        setTimeout(function() {
            togglePasswordVisibility($pw, true, id);
        }, 800);
    });
    </script>

But I would like to place the password button from within the function using the commented line with the after callback and making it apply the same effect. Right now the button correlates with the input through the association of data-id and id. If I would to place it inside the function I would have to get rid of the data-id and still make it act individually on each input, I just can't figure how. Thank you for your time.

Dani AI

Generated

Nice start — you can avoid the data-id mapping by creating the toggle inside a setup loop and binding the handler to the created button. Capture the input in the closure (or find it via DOM traversal) so each button acts on its own input. Using a real button type="button" also improves keyboard/accessibility behavior.

$(function() {
  $('.input-group input[type="password"]').each(function() {
    var $input = $(this);
    var $append = $('<div class="input-group-append"></div>');
    var $btn = $('<button type="button" class="pw-toggle" aria-label="Show password" aria-pressed="false">Show</button>');
    $append.append($btn);
    $input.after($append);

    $btn.on('click', function() {
      var showing = $input.prop('type') === 'text';
      if (showing) {
        clearTimeout($btn.data('timer'));
        $input.prop('type', 'password');
        $btn.text('Show').attr('aria-pressed', 'false');
      } else {
        $input.prop('type', 'text');
        $btn.text('Hide').attr('aria-pressed', 'true');
        $input.focus();
        var t = setTimeout(function() {
          $input.prop('type', 'password');
          $btn.text('Show').attr('aria-pressed', 'false');
        }, 800);
        $btn.data('timer', t);
      }
    });
  });
});

Notes and troubleshooting:

  • Use type="button" so the toggle never submits the form. aria-pressed and an aria-label make the control screen-reader friendly.
  • Changing type directly works in modern browsers; if you must support very old browsers that refuse to change type, replace the input with a cloned element of the desired type (copy value/attributes), then reattach listeners.
  • If you want delegated handling for inputs added later, initialize the button on insert or use event delegation and DOM-traversal (find the nearest input from the clicked button).
  • Preserve focus/caret if you need to; save selectionStart/End before swapping and restore afterwards.

This pattern keeps your markup DRY, removes the need for data-id/id pairing, and gives each password field an independent, accessible toggle.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.