Skip to content

Commit

Permalink
Fixed #3193 -- newforms: Modified as_hidden() to handle MultipleChoic…
Browse files Browse the repository at this point in the history
…eField correctly. Thanks for the report, Honza Kral

git-svn-id: http://code.djangoproject.com/svn/django/trunk@4298 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information
adrianholovaty committed Jan 9, 2007
1 parent 2e148d7 commit fb60a6f
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 5 deletions.
5 changes: 4 additions & 1 deletion django/newforms/fields.py
Expand Up @@ -4,7 +4,7 @@

from django.utils.translation import gettext
from util import ValidationError, smart_unicode
from widgets import TextInput, PasswordInput, CheckboxInput, Select, SelectMultiple
from widgets import TextInput, PasswordInput, HiddenInput, MultipleHiddenInput, CheckboxInput, Select, SelectMultiple
import datetime
import re
import time
Expand All @@ -29,6 +29,7 @@

class Field(object):
widget = TextInput # Default widget to use when rendering this type of Field.
hidden_widget = HiddenInput # Default widget to use when rendering this as "hidden".

# Tracks each time a Field instance is created. Used to retain order.
creation_counter = 0
Expand Down Expand Up @@ -336,6 +337,8 @@ def clean(self, value):
return value

class MultipleChoiceField(ChoiceField):
hidden_widget = MultipleHiddenInput

def __init__(self, choices=(), required=True, widget=SelectMultiple, label=None, initial=None):
ChoiceField.__init__(self, choices, required, widget, label, initial)

Expand Down
4 changes: 2 additions & 2 deletions django/newforms/forms.py
Expand Up @@ -5,7 +5,7 @@
from django.utils.datastructures import SortedDict, MultiValueDict
from django.utils.html import escape
from fields import Field
from widgets import TextInput, Textarea, HiddenInput
from widgets import TextInput, Textarea, HiddenInput, MultipleHiddenInput
from util import StrAndUnicode, ErrorDict, ErrorList, ValidationError

__all__ = ('BaseForm', 'Form')
Expand Down Expand Up @@ -238,7 +238,7 @@ def as_hidden(self, attrs=None):
"""
Returns a string of HTML for representing this as an <input type="hidden">.
"""
return self.as_widget(HiddenInput(), attrs)
return self.as_widget(self.field.hidden_widget(), attrs)

def _data(self):
"""
Expand Down
14 changes: 12 additions & 2 deletions django/newforms/widgets.py
Expand Up @@ -3,8 +3,8 @@
"""

__all__ = (
'Widget', 'TextInput', 'PasswordInput', 'HiddenInput', 'FileInput',
'Textarea', 'CheckboxInput',
'Widget', 'TextInput', 'PasswordInput', 'HiddenInput', 'MultipleHiddenInput',
'FileInput', 'Textarea', 'CheckboxInput',
'Select', 'SelectMultiple', 'RadioSelect', 'CheckboxSelectMultiple',
)

Expand Down Expand Up @@ -87,6 +87,16 @@ class HiddenInput(Input):
input_type = 'hidden'
is_hidden = True

class MultipleHiddenInput(HiddenInput):
"""
A widget that handles <input type="hidden"> for fields that have a list
of values.
"""
def render(self, name, value, attrs=None):
if value is None: value = []
final_attrs = self.build_attrs(attrs, type=self.input_type, name=name)
return u'\n'.join([(u'<input%s />' % flatatt(dict(value=smart_unicode(v), **final_attrs))) for v in value])

class FileInput(Input):
input_type = 'file'

Expand Down
13 changes: 13 additions & 0 deletions tests/regressiontests/forms/tests.py
Expand Up @@ -1849,6 +1849,17 @@
<option value="P" selected="selected">Paul McCartney</option>
</select>
MultipleChoiceField rendered as_hidden() is a special case. Because it can
have multiple values, its as_hidden() renders multiple <input type="hidden">
tags.
>>> f = SongForm({'name': 'Yesterday', 'composers': ['P']}, auto_id=False)
>>> print f['composers'].as_hidden()
<input type="hidden" name="composers" value="P" />
>>> f = SongForm({'name': 'From Me To You', 'composers': ['P', 'J']}, auto_id=False)
>>> print f['composers'].as_hidden()
<input type="hidden" name="composers" value="P" />
<input type="hidden" name="composers" value="J" />
MultipleChoiceField can also be used with the CheckboxSelectMultiple widget.
>>> class SongForm(Form):
... name = CharField()
Expand Down Expand Up @@ -1905,6 +1916,8 @@
>>> f.clean_data
{'composers': [u'J', u'P'], 'name': u'Yesterday'}
# Validating multiple fields in relation to another ###########################
There are a couple of ways to do multiple-field validation. If you want the
validation message to be associated with a particular field, implement the
clean_XXX() method on the Form, where XXX is the field name. As in
Expand Down

0 comments on commit fb60a6f

Please sign in to comment.