pax_global_header00006660000000000000000000000064112045347070014515gustar00rootroot0000000000000052 comment=621cb58c68e76ca17b4c95858be84627d8002ece LICENSE.txt000066400000000000000000000030221120453470700127010ustar00rootroot00000000000000Copyright (c) 2006, Atamert Ölçgen (http://www.muhuk.com) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of django-formfieldset nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.README.markdown000066400000000000000000000021461120453470700135650ustar00rootroot00000000000000**django-formfieldset** is a simple Django app that provides a mix-in class for admin-like fieldset rendering. Features ======== * Fieldset functionality similar to `ModelAdmin` * Shorthand rendering functions with fieldsets * as `P` * as `TABLE` * as `UL` * Overrides nothing in `django.forms.Form` Installation ============ 1. Add 'django-formfieldset' directory to your Python path. 2. Add 'formfieldset' to your `INSTALLED_APPS` tuple found in your settings file. (optional - to be able to run tests) 3. Create your forms with `FieldsetMixin` Usage ===== * Add a `fieldsets` attribute to your form. See [admin docs][ref1] for detailed explanation. * Render your form with fieldset enabled methods: * You can use `iter_fieldsets()` for custom form rendering. It will yield `Fieldset` objects. `Fieldset`s act as iterators for widgets in them. * You can use `as_fieldset_table()`, `as_fieldset_ul()` and `as_fieldset_p()` methods that act like built-in `as_*` method except fieldset support. [ref1]: http://docs.djangoproject.com/en/dev/ref/contrib/admin/#fieldsets formfieldset/000077500000000000000000000000001120453470700135445ustar00rootroot00000000000000formfieldset/__init__.py000066400000000000000000000000001120453470700156430ustar00rootroot00000000000000formfieldset/forms.py000066400000000000000000000175751120453470700152630ustar00rootroot00000000000000from django import forms as django_forms from django.utils.html import escape from django.utils.safestring import mark_safe from django.utils.encoding import force_unicode class Fieldset(object): "Simple iterable for holding fieldset information." def __init__(self, form, name=None, fields=(), description=None, extra_content={}): self.form = form self.name = name self.fields = fields self.description = description self.extra_content = extra_content def __iter__(self): "Iterates through fields in the fieldset." for field in self.fields: yield django_forms.forms.BoundField(self.form, self.form.fields[field], field) def html_output(self, normal_row, error_row, row_ender, help_text_html, errors_on_separate_row, top_errors=[], hidden_fields=[], stand_alone=True, error_class=django_forms.util.ErrorList, label_suffix=':'): output = [] for bf in self: # Escape and cache in local variable. bf_errors = error_class([escape(error) for error in bf.errors]) if bf.is_hidden: if bf_errors: top_errors.extend( [u'(Hidden field %s) %s' % (bf.name, force_unicode(e)) for e in bf_errors]) hidden_fields.append(unicode(bf)) else: if errors_on_separate_row and bf_errors: output.append(error_row % force_unicode(bf_errors)) if bf.label: label = escape(force_unicode(bf.label)) # Only add the suffix if the label does not end in # punctuation. if label_suffix: if label[-1] not in ':?.!': label += label_suffix label = bf.label_tag(label) or '' else: label = '' if bf.field.help_text: help_text = help_text_html % force_unicode( bf.field.help_text) else: help_text = u'' output.append(normal_row % {'errors': force_unicode(bf_errors), 'label': force_unicode(label), 'field': unicode(bf), 'help_text': help_text}) if stand_alone: if top_errors: output.insert(0, error_row % force_unicode(top_errors)) if hidden_fields: # Insert any hidden fields in the last row. str_hidden = u''.join(hidden_fields) if output: last_row = output[-1] # Chop off the trailing row_ender (e.g. '') # and insert the hidden fields. output[-1] = last_row[:-len(row_ender)] + \ str_hidden + row_ender else: # If there aren't any rows in the output, just append # the hidden fields. output.append(str_hidden) return output def as_table(self): fields = self.html_output( u'%(label)s' u'%(errors)s%(field)s%(help_text)s', u'%s', '', u'
%s', False, stand_alone=True) description = '' if self.description is not None: description = self.description return mark_safe( u'' u'

%(name)s

%(description)s%(fields)s' % {'name': self.name, 'description': description, 'fields': u'\n'.join(fields), }) class FieldsetMixin(object): def iter_fieldsets(self): "Iterates fieldsets." for name, options in self.fieldsets: yield Fieldset(self, name, **options) def _html_fieldset_output(self, fieldset_row, normal_row, error_row, row_ender, help_text_html, errors_on_separate_row): "Helper function for outputting fieldsets as HTML. " \ "Used by as_fieldset_table(), as_fieldset_ul(), as_fieldset_p()." # Errors that should be displayed above all fields. top_errors = self.non_field_errors() output, hidden_fields = [], [] for fieldset in self.iter_fieldsets(): fieldset_output = fieldset.html_output( normal_row, error_row, row_ender, help_text_html, errors_on_separate_row, top_errors, hidden_fields, stand_alone=False, error_class=self.error_class, label_suffix=self.label_suffix) if fieldset.description: description = help_text_html % force_unicode( fieldset.description) else: description = u'' output.append(fieldset_row % { 'name': fieldset.name, 'description': description, 'fields': u'\n'.join(fieldset_output)}) if top_errors: output.insert(0, error_row % force_unicode(top_errors)) if hidden_fields: # Insert any hidden fields in the last row. str_hidden = u''.join(hidden_fields) if output: last_row = output[-1] # Chop off the trailing row_ender (e.g. '') and # insert the hidden fields. output[-1] = last_row[:-len(row_ender)] + str_hidden + \ row_ender else: # If there aren't any rows in the output, just append the # hidden fields. output.append(str_hidden) return mark_safe(u'\n'.join(output)) def as_fieldset_table(self): "Returns this form's fieldsets rendered as HTML s -- " \ "excluding the
." return self._html_fieldset_output( u'

%(name)s

%(description)s%(fields)s', u'%(label)s%(errors)s%(field)s%(help_text)s' \ u'', u'%s', '', u'
%s', False) def as_fieldset_ul(self): "Returns this form's fieldsets rendered as HTML
  • s -- " \ "excluding the ." return self._html_fieldset_output( u'
  • \n

    %(name)s

    %(description)s\n\n
  • ', u'
  • %(errors)s%(label)s %(field)s%(help_text)s
  • ', u'
  • %s
  • ', '', u' %s', False) def as_fieldset_p(self): "Returns this form's fieldsets rendered as HTML

    s." return self._html_fieldset_output( u'

    \n

    %(name)s

    %(description)s\n%(fields)s\n
    ', u'

    %(label)s %(field)s%(help_text)s

    ', u'%s', u'

    ', u' %s', True) formfieldset/models.py000066400000000000000000000000001120453470700153670ustar00rootroot00000000000000formfieldset/tests.py000066400000000000000000000043771120453470700152730ustar00rootroot00000000000000from django.test import TestCase from django import forms as django_forms import forms class FieldsetRenderTestCase(TestCase): def _test_form(self): class TestForm(django_forms.Form, forms.FieldsetMixin): test_field1 = django_forms.CharField() test_field2 = django_forms.CharField() test_field3 = django_forms.CharField() fieldsets = ( (u'Fieldset1', { 'description': u'Test Description', 'fields': ('test_field1',), }), (u'Fieldset2', { 'fields': ('test_field2', 'test_field3'), }), ) def clean_test_field2(self): raise django_forms.ValidationError( [u'Test Error - Field Level - 1', u'Test Error - Field Level - 2']) def clean(self): raise django_forms.ValidationError(u'Test Error - Top Level') return TestForm def testFieldsetRender(self): RESPONSE = u"""
    Fieldset1Test Description
    Fieldset2
    """ form = self._test_form()(data={'test_field2': u'Test Value'}) self.assertEqual(form.is_valid(), False) self.assertEqual( form._html_fieldset_output( '
    \n%(name)s' \ '%(description)s\n%(fields)s\n
    ', '%(errors)s%(field)s%(help_text)s', '%s', '', '%s', False), RESPONSE ) setup.py000066400000000000000000000005761120453470700126030ustar00rootroot00000000000000#coding=utf-8 from distutils.core import setup setup( name = 'django-formfieldset', version = 'git20090312-a822fad', url = 'http://github.com/muhuk/django-formfieldset/tree/master', author = 'Atamert Ölçgen', author_email = 'muhuk@muhuk.com', license = 'BSD', packages = ['formfieldset'], description = 'Fieldset Rendering For Non-Admin Forms', )