Search code examples
htmljquerycssdjangodjango-crispy-forms

add a show password button inside of input field - crispy forms


I want to add a show password button inside of the password input field. I am using crispy forms for styling so I am a little bit stuck on the best practice here.

Currently I have a seperate checkbox field which is showing the password on check. Js is working fine here. I'd like to change de checkbox to a eye icon which is inside of the input field. I've managed to add the eye icon to the input field via css background: url(path-to-icon).

I can't figure out how to change the icon to a button (1) and add my js to it (2).

My form:

class CustomSignupForm(SignupForm):
    user_group = forms.ModelChoiceField(queryset=Group.objects.exclude(name='admin').exclude(name='personeel').exclude(name='onderhoud'),
                                        widget=forms.RadioSelect(attrs={'placeholder': 'Soort klant:'}),
                                        initial=('particulier'), label='Soort klant'
                                        )
    first_name = forms.CharField(max_length=30,
                                 label='Voornaam',
                                 widget=forms.TextInput(attrs={'placeholder': 'Voornaam'}),)
    last_name = forms.CharField(max_length=30, 
                                label='Achternaam',
                                widget=forms.TextInput(attrs={'placeholder': 'Achternaam'}),)

My HTML :

<div class="form-row">
   <div class="form-group col-md-6 mb-0">
        <a>{{ form.password1 | as_crispy_field}}</a>
   </div>
   <div class="form-group col-md-6 mb-0">
        <a>{{ form.password2 | as_crispy_field}}</a>
   </div>
</div>

<div class="form-row">
   <div class="form-group col-md-12 mb-0">
        <input class="ml-2" type="checkbox" onclick="ShowPassword()"> show password
   </div>
</div>

My css:

#id_password1 {
    background: url("http://127.0.0.1:8000/static/user/media/eye_icon.png") no-repeat;
    background-size: 20px 20px;
    background-position: right;
    background-position-x: 97%;
}

#id_password2 {
    background: url("http://127.0.0.1:8000/static/user/media/eye_icon.png") no-repeat;
    background-size: 20px 20px;
    background-position: right 10px;
    background-position-x: 97%;
}

My js :

function ShowPassword() {
    var x = document.getElementById("id_password");
      if (x.type === "password") {
       x.type = "text";
       } else {
       x.type = "password";
    }
}

Does anyone have any ideas to make this work?


Solution

  • Made it almost!

    Did everything in HTML, CSS and JS.

    HTML

    <a>{{ form.password2 | as_crispy_field}}</a>
    <button class="toggle-password ml-2 fa fa-eye"></button>
    

    CSS

    .toggle-password {
        position: absolute;
        top: 50%;
        right: 6%;
        width: 20px;
        height: 20px;
        border: none;
        background-color: transparent;
    }
    

    HTML

    $("body").on('click','.toggle-password',function(){
        var $pass1 = document.getElementById("id_password1");
        var $pass2 = document.getElementById("id_password2");
        var toggle = $(this).toggleClass("fa-eye fa-eye-slash");
        [$pass1, $pass2].forEach(function($passwords) {
            if ($passwords.type === "password") {
            $passwords.type = "text";
            toggle.toggleClass()
            } else {
            $passwords.type = "password";
            }
        })
    
    });
    

    Still figuring out how to make both icons toggle at the same time. Now they doing it seperately.