summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMalcolm Tredinnick <malcolm.tredinnick@gmail.com>2008-12-05 04:22:00 +0000
committerMalcolm Tredinnick <malcolm.tredinnick@gmail.com>2008-12-05 04:22:00 +0000
commitbfab9d62ee815baac34b1872676ad26af91c7d94 (patch)
tree60a3f28b63726b4fa4c2a201e6d930983741b384
parentdfef20a7806073dab547eeb1c5e700c4bd0e1634 (diff)
Added a way to iterate over hidden/visible fields in a form. Useful for manual
form layout. git-svn-id: http://code.djangoproject.com/svn/django/trunk@9569 bcc190cf-cafb-0310-a4f2-bffc1f526a37
-rw-r--r--django/forms/forms.py16
-rw-r--r--docs/topics/forms/index.txt50
-rw-r--r--tests/regressiontests/forms/forms.py12
3 files changed, 77 insertions, 1 deletions
diff --git a/django/forms/forms.py b/django/forms/forms.py
index e28479fb8b..29c4f31115 100644
--- a/django/forms/forms.py
+++ b/django/forms/forms.py
@@ -303,6 +303,20 @@ class BaseForm(StrAndUnicode):
return True
return False
+ def hidden_fields(self):
+ """
+ Returns a list of all the BoundField objects that correspond to hidden
+ fields in the HTML output. Useful for manual form layout in templates.
+ """
+ return [field for field in self if field.is_hidden]
+
+ def visible_fields(self):
+ """
+ Returns a lits of BoundField objects that do not correspond to hidden
+ fields. The opposite of the hidden_fields() method.
+ """
+ return [field for field in self if not field.is_hidden]
+
class Form(BaseForm):
"A collection of Fields, plus their associated data."
# This is a separate class from BaseForm in order to abstract the way
@@ -363,7 +377,7 @@ class BoundField(StrAndUnicode):
else:
name = self.html_initial_name
return widget.render(name, data, attrs=attrs)
-
+
def as_text(self, attrs=None, **kwargs):
"""
Returns a string of HTML for representing this as an <input type="text">.
diff --git a/docs/topics/forms/index.txt b/docs/topics/forms/index.txt
index 1298ac3987..6cab5b5b90 100644
--- a/docs/topics/forms/index.txt
+++ b/docs/topics/forms/index.txt
@@ -292,6 +292,56 @@ templates:
case, each object in the loop is a simple string containing the error
message.
+ ``field.is_hidden``
+ This attribute is ``True`` is the form field is a hidden field and
+ ``False`` otherwise. It's not particularly useful as a template
+ variable, but could be useful in conditional tests such as::
+
+ {% if field.is_hidden %}
+ {# Do something special #}
+ {% endif %}
+
+Looping over hidden and visible fields
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you are manually laying out a form in a template, you will often want to
+work with any hidden fields in a single loop and then treat the visible fields
+differently. For example, since hidden fields don't display anything, putting
+their error messages "next to" the field isn't going to be very clear to the
+reader. So you need to handle errors for those fields a bit differently.
+
+Django provides two methods on a form that allow you to loop over the hidden
+and visible fields independently: ``hidden_fields()`` and
+``visible_fields()``. In a template, you might use these like this (this is a
+modification of an earlier example)::
+
+ <form action="/contact/" method="POST">
+ {% for field in form.visible_fields %}
+ <div class="fieldWrapper">
+
+ {# Include the hidden fields in the form #}
+ {% if forloop.first %}
+ {% for hidden in form.hidden_fields %}
+ {{ field }}
+ {% endfor %}
+ {% endif %}
+
+ {{ field.errors }}
+ {{ field.label_tag }}: {{ field }}
+ </div>
+ {% endfor %}
+ <p><input type="submit" value="Send message" /></p>
+ </form>
+
+This example does not handle any errors in the hidden fields. Usually, an
+error in a hidden field is a sign of form tampering, since normal form
+interaction won't alter them. However, you could easily insert some error
+displays for those form errors as well.
+
+.. versionadded:: 1.1
+ The ``hidden_fields`` and ``visible_fields`` methods are new in Django
+ 1.1.
+
Reusable form templates
-----------------------
diff --git a/tests/regressiontests/forms/forms.py b/tests/regressiontests/forms/forms.py
index 6bee94e579..642cd203ca 100644
--- a/tests/regressiontests/forms/forms.py
+++ b/tests/regressiontests/forms/forms.py
@@ -1757,4 +1757,16 @@ initial that returns False on a boolean call needs to be treated literally.
>>> form.is_valid()
True
+# Extracting hidden and visible fields ######################################
+
+>>> class SongForm(Form):
+... token = CharField(widget=HiddenInput)
+... artist = CharField()
+... name = CharField()
+>>> form = SongForm()
+>>> [f.name for f in form.hidden_fields()]
+['token']
+>>> [f.name for f in form.visible_fields()]
+['artist', 'name']
+
"""