Blog

How To Develop a Custom Widget in Django

- Thursday, August 13, 2015

Sometimes you need a custom form widget for use with forms on frontend or in admin interface in Django. For such purposes Django provides a very useful tools for implement almost everything which you could want. In one of our projects we had a necessity to implement a widget for password with "Show" button. User should be able to click "Show" button and copy password to clipboard. Let's create something like that:


 

Better way is create the separate file widgets.py. Than we can write something like that:

from django import forms
from django.forms.utils import flatatt
from django.utils.safestring import mark_safe
class ShowHidePasswordWidget(forms.PasswordInput):
    def render(self, name, value, attrs=None):
        super().render(name, value, attrs)
        flat_attrs = flatatt(attrs)
        html = '''
<input %(attrs)s name="password" type="password" value="%(value)s"/>
<span id="__action__%(id)s__show_button">
<a href="javascript:show_pwd_%(id)s()">Show</a></span>
<span id="__action__%(id)s__hide_button" style="display:none;">
<a href="javascript:hide_pwd_%(id)s()">Hide</a></span>
<script type="text/javascript">
function show_pwd_%(id)s() {
    document.getElementById("%(id)s").setAttribute('type', 'text');
    document.getElementById("__action__%(id)s__show_button")
        .style.display="none";
    document.getElementById("__action__%(id)s__hide_button")
        .style.display=null;
}
function hide_pwd_%(id)s() {
    document.getElementById("%(id)s").setAttribute('type', 'password');
    document.getElementById("__action__%(id)s__hide_button")
        .style.display="none";
    document.getElementById("__action__%(id)s__show_button")
        .style.display=null;
}
</script>
        ''' % {
            'attrs': flat_attrs,
            'id': attrs['id'],
            'value': value,
        }
        return mark_safe(html)


As you see an implementation of a form widget is simple. We just inherit new class from the most similar standard widget and reimplement the render method as we need.

Now we can use our new widget in form:

class EditHostAdminForm(forms.ModelForm):
    password = forms.CharField(widget=ShowHidePasswordWidget())

Of course it is a simple example but there are no problems to improve it and implement any widget you need.

Oleh Korkh

Get A Free Quote

You will receive quarterly promotions and news. Unsubscribe with one click.

Drop us a line