Login

Forms splitted in fieldsets

Author:
gustavo80br
Posted:
March 25, 2008
Language:
Python
Version:
.96
Score:
3 (after 3 ratings)

This template tag build a Form splitted in fieldsets. The fieldsets are configured with a second parameter, that is a tuple like the one used in the Admin class in models in the attribute "fields".

You pass to the template the form and the tuple and than use them as parameters for the templatetag.

You can take a look at the source and modify It to build forms the way you like.

It is very useful If you do not like the way Django build forms with the methods as_p, as_ul or as_table and also do not like to write html by hand.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# -*- coding:utf-8 -*-
#
# Use the tag like this:
#
# {% draw_form form fieldsets %}
#
# Where 'form' is the form to be draw and 'fieldsets' is a tuple containing the
# fieldsets and the contained fields.
#
# Example on how to build the fieldsets parameter
#
# fiedsets = (
#     ('Personal Data', {'fields':('name','gender'), 'id':'personal_data'}),
#     ('Address', {'fields':('street','number','city','zip_code'), 'id':'address'}),
# )
#

from django.template import Library

register = Library()

@register.simple_tag
def draw_form(form, fieldsets=False):
    
    def get_fields_html(fields, f):
        fields_html = []
        append = fields_html.append
        for field_name in fields:
            field = f[field_name]
            cls = []
            help_text = ''
            errors = ''            
            if f.fields[field_name].required:
                cls.append('required')
            if field.help_text:
                help_text = '<span>%s</span>' % field.help_text
            if f[field_name].errors:
                errors = str(f[field_name].errors)
                cls.append('error')
            cls = ' class="%s"' % " ".join(cls)
            append('<li%s>%s<label for="%s">%s:</label> %s %s</li>' % (cls, errors, field_name, field.label, str(field), help_text))
        return "".join(fields_html)
    
    form_html = []
    append_to_form = form_html.append
    form.auto_id = True
    
    fieldset_template = '<fieldset%(id)s><legend>%(legend)s</legend><ul>%(fields)s</ul></fieldset>' 
    
    if fieldsets:
        for fieldset in fieldsets:
            context = {}
            id = fieldset[1].get('id')
            if id:
                context['id'] = ' id="%s"' % id
            else:
                context['id'] = ''
            context['legend'] = fieldset[0]
            fields = fieldset[1]['fields']
            context['fields'] = get_fields_html(fields, form)
            append_to_form(fieldset_template % context)   
        return "".join(form_html)
    else:
        fields = form.fields.keys()
        return get_fields_html(fields, form)
        

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 3 months, 1 week ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 3 months, 2 weeks ago
  3. Serializer factory with Django Rest Framework by julio 10 months, 1 week ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 11 months ago
  5. Help text hyperlinks by sa2812 11 months, 3 weeks ago

Comments

hakanw (on December 20, 2008):

This has a bug that makes it not work if you have translated your forms with gettext_lazy.

Change the code on line 42 to make it work properly:

append('<li%s>%s<label for="%s">%s:</label> %s %s</li>' % (cls, errors, field_name, unicode(field.label), str(field), help_text))

#

Please login first before commenting.