In this tutorial you will learn how to create a button attached to a password input form that toggles the visibility of your password.
django version==4.2.2
Start by installing the following packages:
pip install django-crispy-forms
pip install crispy-bootstrap5
Make sure to include them both in installed apps, in settings.py:
INSTALLED_APPS = [
# ...
'crispy_forms',
'crispy_bootstrap5'
]
And define the CRISPY TEMPLATES PACK in settings.py:
CRISPY_ALLOWED_TEMPLATE_PACKS = 'bootstrap5'
CRISPY_TEMPLATE_PACK = 'bootstrap5'
Add the following CDN links to your template:
<!-- Bootstrap CDN -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.4.1/dist/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<!-- Bootstrap icons CDN -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
In forms.py (in the same directory as views.py), add the following form class:
from django.contrib.auth import get_user_model
from django.contrib.auth.forms import UserCreationForm
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Div
from crispy_forms.bootstrap import FieldWithButtons, StrictButton
class CreateUserForm(UserCreationForm):
helper = FormHelper()
helper.form_tag = False
helper.layout = Layout(
Div(
Div('username', css_class='col-12'),
Div(FieldWithButtons('password1', StrictButton('<i class="bi bi-eye"></i>', type='button', css_class='btn btn-outline-secondary', id='password1Button')), css_class='col-6'
),
Div(FieldWithButtons('password2', StrictButton('<i class="bi bi-eye"></i>', type='button', css_class='btn btn-outline-secondary', id='password2Button')), css_class='col-6'
),
css_class='row'
)
)
class Meta:
model = get_user_model()
fields = ['username', 'password1', 'password2']
In views.py, create the SignupView, if you use Class Based Views:
from django.urls import reverse_lazy
from django.views.generic import CreateView
from .forms import CreateUserForm
class SignUpView(CreateView):
template_name = 'signup.html'
form_class = CreateUserForm
success_url = reverse_lazy('')
If you use Function Based Views, add the following code to views.py:
from .forms import CreateUserForm
from django.shortcuts import render
def sign_up(request):
if request.method == 'POST':
form = CreateUserForm(request.POST)
if form.is_valid():
form.save()
else:
form = CreateUserForm()
return render(request, 'signup.html', {'form': form})
Add the following html code to signup.html:
{% load crispy_forms_tags %}
<script>
document.addEventListener('DOMContentLoaded', function () {
for (i of [1, 2]) {
const togglePassword = document.querySelector(`#password${i}Button`);
const password = document.querySelector(`#id_password${i}`);
togglePassword.addEventListener('click', function (e) {
const type = password.getAttribute('type') === 'password' ? 'text' : 'password';
password.setAttribute('type', type);
if (this.firstChild.classList.contains('bi-eye-slash')) {
this.firstChild.classList.remove('bi-eye-slash')
this.firstChild.classList.add('bi-eye');
}
else {
this.firstChild.classList.remove('bi-eye');
this.firstChild.classList.add('bi-eye-slash');
}
});
}
});
</script>
<form method="post">
{% csrf_token %}
{% crispy form %}
</form>
Make sure you do include
{% crispy form %}
instead of the usual
{{ form|crispy }}
This ensures that the modifications to the form made in forms.py actually see the daylight.
Finally, add the URL of the view to urls.py:
from django.urls import path
from . import views
urlpatterns = [
# Class Based Views
path('signup/', views.SignUpView.as_view(), name='signup'),
# Function Based Views (Choose one of the two)
path('signup/', views.sign_up, name='signup')
]
Top comments (0)