Login

Forms splitted in fieldsets

Author:
gustavo80br
Posted:
March 25, 2008
Language:
Python
Version:
.96
Tags:
forms fieldset form fieldsets
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. SectionedForm by marinho 6 years, 11 months ago
  2. FieldsetForm by Ciantic 8 years, 1 month ago
  3. Fieldsets for Views by Nad 5 years, 4 months ago
  4. CallTag - Just like include, but can pass parameters to it by limodou 8 years, 3 months ago
  5. Dictionary of choices based in models by marcoslhc 5 years, 1 month 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.