Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added documentation for widgets in newforms.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@5867 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 3d012a18cec7edeb19f7fb579dc47dfae00a99bb 1 parent dd0f5d9
@freakboy3742 freakboy3742 authored
Showing with 151 additions and 1 deletion.
  1. +151 −1 docs/newforms.txt
View
152 docs/newforms.txt
@@ -962,7 +962,7 @@ validation if a particular field's value is not given. ``initial`` values are
~~~~~~~~~~
The ``widget`` argument lets you specify a ``Widget`` class to use when
-rendering this ``Field``. See "Widgets" below for more information.
+rendering this ``Field``. See "Widgets"_ below for more information.
``help_text``
~~~~~~~~~~~~~
@@ -1437,6 +1437,156 @@ like so::
senders = MultiEmailField()
cc_myself = forms.BooleanField()
+Widgets
+=======
+
+A widget is Django's representation of a HTML input element. The widget
+handles the rendering of the HTML, and the extraction of data from a GET/POST
+dictionary that corresponds to the widget.
+
+Django provides a representation of all the basic HTML widgets, plus some
+commonly used groups of widgets:
+
+ ============================ ===========================================
+ Widget HTML Equivalent
+ ============================ ===========================================
+ ``TextInput`` ``<input type='text' ...``
+ ``PasswordInput`` ``<input type='password' ...``
+ ``HiddenInput`` ``<input type='hidden' ...``
+ ``MultipleHiddenInput`` Multiple ``<input type='hidden' ...``
+ instances.
+ ``FileInput`` ``<input type='file' ...``
+ ``Textarea`` ``<textarea>...</textarea>``
+ ``CheckboxInput`` ``<input type='checkbox' ...``
+ ``Select`` ``<select><option ...``
+ ``NullBooleanSelect`` Select widget with options 'Unknown',
+ 'Yes' and 'No'
+ ``SelectMultiple`` ``<select multiple='multiple'><option ...``
+ ``RadioSelect`` ``<ul><li><input type='radio' ...``
+ ``CheckboxSelectMultiple`` ``<ul><li><input type='checkbox' ...``
+ ``MultiWidget`` Wrapper around multiple other widgets
+ ``SplitDateTimeWidget`` Wrapper around two ``TextInput`` widgets:
+ one for the Date, and one for the Time.
+ ============================ ===========================================
+
+Specifying widgets
+------------------
+
+Whenever you specify a field on a form, Django will use a default widget
+that is appropriate to the type of data that is to be displayed. To find
+which widget is used on which field, see the documentation for the
+built-in Field classes.
+
+However, if you want to use a different widget for a field, you can -
+just use the 'widget' argument on the field definition. For example::
+
+ class CommentForm(forms.Form):
+ name = forms.CharField()
+ url = forms.URLField()
+ comment = forms.CharField(widget=forms.TextArea)
+
+This would specify a form with a comment that uses a larger TextArea widget,
+rather than the default TextInput widget.
+
+Customizing widget instances
+----------------------------
+
+When Django renders a widget as HTML, it only renders the bare minimum
+HTML - Django doesn't add a class definition, or any other widget-specific
+attributes. This means that all 'TextInput' widgets will appear the same
+on your web page.
+
+If you want to make one widget look different to another, you need to
+specify additional attributes for each widget. When you specify a
+widget, you can provide a list of attributes that will be added to the
+rendered HTML for the widget.
+
+For example, take the following simple form::
+
+ class CommentForm(forms.Form):
+ name = forms.CharField()
+ url = forms.URLField()
+ comment = forms.CharField()
+
+This form will include three default TextInput widgets, with default rendering -
+no CSS class, no extra attributes. This means that the inputs boxes provided for
+each widget will be rendered exactly the same::
+
+ >>> f = CommentForm(auto_id=False)
+ >>> f.as_table()
+ <tr><th>Name:</th><td><input type="text" name="name" /></td></tr>
+ <tr><th>Url:</th><td><input type="text" name="url"/></td></tr>
+ <tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
+
+On a real web page, you probably don't want every widget to look the same. You
+might want a larger input element for the comment, and you might want the
+'name' widget to have some special CSS class. To do this, you specify a
+custom widget for your fields, and specify some attributes to use
+when rendering those widgets::
+
+ class CommentForm(forms.Form):
+ name = forms.CharField(
+ widget=forms.TextInput(attrs={'class':'special'}))
+ url = forms.URLField()
+ comment = forms.CharField(
+ widget=forms.TextInput(attrs={'size':'40'}))
+
+Django will then include the extra attributes in the rendered output::
+
+ >>> f = CommentForm(auto_id=False)
+ >>> f.as_table()
+ <tr><th>Name:</th><td><input type="text" name="name" class="special"/></td></tr>
+ <tr><th>Url:</th><td><input type="text" name="url"/></td></tr>
+ <tr><th>Comment:</th><td><input type="text" name="comment" size="40"/></td></tr>
+
+Custom Widgets
+--------------
+
+When you start to write a lot of forms, you will probably find that you will
+reuse certain sets of widget attributes over and over again. Rather than
+repeat these attribute definitions every time you need them, Django allows
+you to capture those definitions as a custom widget.
+
+For example, if you find that you are including a lot of comment fields on forms,
+you could capture the idea of a ``TextInput`` with a specific ``size`` attribute
+as a custom extension to the ``TextInput`` widget::
+
+ class CommentWidget(forms.TextInput):
+ def __init__(self, *args, **kwargs):
+ kwargs.setdefault('attrs',{}).update({'size': '40'})
+ super(forms.TextInput, self).__init__(*args, **kwargs)
+
+Then you can use this widget in your forms::
+
+ class CommentForm(forms.Form):
+ name = forms.CharField()
+ url = forms.URLField()
+ comment = forms.CharField(widget=CommentWidget)
+
+You can even customize your custom widget, in the same way as you would
+any other widget. Adding a once-off class to your ``CommentWidget`` is as
+simple as adding an attribute definition::
+
+ class CommentForm(forms.Form):
+ name = forms.CharField(max_length=20)
+ url = forms.URLField()
+ comment = forms.CharField(
+ widget=CommentWidget(attrs={'class': 'special'}))
+
+Django also makes it easy to specify a custom field type that uses your custom
+widget. For example, you could define a customized field type for comments
+by defining::
+
+ class CommentInput(forms.CharField):
+ widget = CommentWidget
+
+You can then use this field whenever you have a form that requires a comment::
+
+ class CommentForm(forms.Form):
+ name = forms.CharField()
+ url = forms.URLField()
+ comment = CommentInput()
+
Generating forms for models
===========================
Please sign in to comment.
Something went wrong with that request. Please try again.