====================
The newforms library
====================

``django.newforms`` is a new replacement for ``django.forms``, the old Django
form/manipulator/validation framework. This document explains how to use this
new form library.

Migration plan
==============

``django.newforms`` currently is only available in the Django development version
-- i.e., it's not available in the Django 0.95 release. For the next Django
release, our plan is to do the following:

    * As of revision [4208], we've copied the current ``django.forms`` to
      ``django.oldforms``. This allows you to upgrade your code *now* rather
      than waiting for the backwards-incompatible change and rushing to fix
      your code after the fact. Just change your import statements like this::

          from django import forms             # old
          from django import oldforms as forms # new

    * At an undecided future date, we will move the current ``django.newforms``
      to ``django.forms``. This will be a backwards-incompatible change, and 
      anybody who is still using the old version of ``django.forms`` at that
      time will need to change their import statements, as described in the
      previous bullet.

    * We will remove ``django.oldforms`` in the release *after* the next Django
      release -- the release that comes after the release in which we're
      creating the new ``django.forms``.

With this in mind, we recommend you use the following import statement when
using ``django.newforms``::

    from django import newforms as forms

This way, your code can refer to the ``forms`` module, and when
``django.newforms`` is renamed to ``django.forms``, you'll only have to change
your ``import`` statements.

If you prefer "``import *``" syntax, you can do the following::

    from django.newforms import *

This will import all fields, widgets, form classes and other various utilities
into your local namespace. Some people find this convenient; others find it
too messy. The choice is yours.

Overview
========

As the ``django.forms`` ("manipulators") system before it, ``django.newforms``
is intended to handle HTML form display, validation and redisplay. It's what
you use if you want to perform server-side validation for an HTML form.

For example, if your Web site has a contact form that visitors can use to
send you e-mail, you'd use this library to implement the display of the HTML
form fields, along with the form validation. Any time you need to use an HTML
``<form>``, you can use this library.

The library deals with these concepts:

    * **Widget** -- A class that corresponds to an HTML form widget, e.g.
      ``<input type="text">`` or ``<textarea>``. This handles rendering of the
      widget as HTML.

    * **Field** -- A class that is responsible for doing validation, e.g.
      an ``EmailField`` that makes sure its data is a valid e-mail address.

    * **Form** -- A collection of fields that knows how to validate itself and
      display itself as HTML.

Form objects
============

The primary way of using the ``newforms`` library is to create a form object.
Do this by subclassing ``django.newforms.Form`` and specifying the form's
fields, in a declarative style that you'll be familiar with if you've used
Django database models. In this section, we'll iteratively develop a form
object that you might to implement "contact me" functionality on your personal
Web site.

Start with this basic ``Form`` subclass, which we'll call ``ContactForm``::

    from django import newforms as forms

    class ContactForm(forms.Form):
        subject = forms.CharField(max_length=100)
        message = forms.CharField()
        sender = forms.EmailField()
        cc_myself = forms.BooleanField()

A form is composed of ``Field`` objects. In this case, our form has four
fields: ``subject``, ``message``, ``sender`` and ``cc_myself``. We'll explain
the different types of fields -- e.g., ``CharField`` and ``EmailField`` --
shortly.

Outputting forms as HTML
------------------------

The first thing we can do with this is output it as HTML. To do so, instantiate
it and ``print`` it::

    >>> f = ContactForm()
    >>> print f
    <tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" /></td></tr>
    <tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr>
    <tr><th><label for="id_sender">Sender:</label></th><td><input type="text" name="sender" id="id_sender" /></td></tr>
    <tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" /></td></tr>

This default output is a two-column HTML table, with a ``<tr>`` for each field.
Notice the following:

    * For flexibility, the output does *not* include the ``<table>`` and
      ``</table>`` tags, nor does it include the ``<form>`` and ``</form>``
      tags or an ``<input type="submit">`` tag. It's your job to do that.

    * Each field type has a default HTML representation. ``CharField`` and
      ``EmailField`` are represented by an ``<input type="text">``.
      ``BooleanField`` is represented by an ``<input type="checkbox">``. Note
      these are merely sensible defaults; you can specify which HTML to use for
      a given field by using ``widgets``, which we'll explain shortly.

    * The HTML ``name`` for each tag is taken directly from its attribute name
      in the ``ContactForm`` class.

    * The text label for each field -- e.g. ``'Subject:'``, ``'Message:'`` and
      ``'CC myself:'`` is generated from the field name by converting all
      underscores to spaces and upper-casing the first letter. Again, note
      these are merely sensible defaults; you can also specify labels manually.

    * Each text label is surrounded in an HTML ``<label>`` tag, which points
      to the appropriate form field via its ``id``. Its ``id``, in turn, is
      generated by prepending ``'id_'`` to the field name. The ``id``
      attributes and ``<label>`` tags are included in the output by default, to
      follow best practices, but you can change that behavior.

Although ``<table>`` output is the default output style when you ``print`` a
form, other output styles are available. Each style is available as a method on
a form object, and each rendering method returns a Unicode object.

``as_p()``
~~~~~~~~~~

``Form.as_p()`` renders the form as a series of ``<p>`` tags, with each ``<p>``
containing one field::

    >>> f = ContactForm()
    >>> f.as_p()
    u'<p><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></p>\n<p><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></p>\n<p><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></p>\n<p><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></p>'
    >>> print f.as_p()
    <p><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></p>
    <p><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></p>
    <p><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></p>
    <p><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></p>

``as_ul()``
~~~~~~~~~~~

``Form.as_ul()`` renders the form as a series of ``<li>`` tags, with each
``<li>`` containing one field. It does *not* include the ``<ul>`` or ``</ul>``,
so that you can specify any HTML attributes on the ``<ul>`` for flexibility::

    >>> f = ContactForm()
    >>> f.as_ul()
    u'<li><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></li>\n<li><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></li>\n<li><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></li>\n<li><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></li>'
    >>> print f.as_ul()
    <li><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></li>
    <li><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></li>
    <li><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></li>
    <li><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></li>

``as_table()``
~~~~~~~~~~~~~~

Finally, ``Form.as_table()`` outputs the form as an HTML ``<table>``. This is
exactly the same as ``print``. In fact, when you ``print`` a form object, it
calls its ``as_table()`` method behind the scenes::

    >>> f = ContactForm()
    >>> f.as_table()
    u'<tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" /></td></tr>\n<tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr>\n<tr><th><label for="id_sender">Sender:</label></th><td><input type="text" name="sender" id="id_sender" /></td></tr>\n<tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" /></td></tr>'
    >>> print f.as_table()
    <tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" /></td></tr>
    <tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr>
    <tr><th><label for="id_sender">Sender:</label></th><td><input type="text" name="sender" id="id_sender" /></td></tr>
    <tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" /></td></tr>

Configuring HTML ``<label>`` tags
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

An HTML ``<label>`` tag designates which label text is associated with which
form element. This small enhancement makes forms more usable and more accessible
to assistive devices. It's always a good idea to use ``<label>`` tags.

By default, the form rendering methods include HTML ``id`` attributes on the
form elements and corresponding ``<label>`` tags around the labels. The ``id``
attribute values are generated by prepending ``id_`` to the form field names.
This behavior is configurable, though, if you want to change the ``id``
convention or remove HTML ``id`` attributes and ``<label>`` tags entirely.

Use the ``auto_id`` argument to the ``Form`` constructor to control the label
and ``id`` behavior. This argument must be ``True``, ``False`` or a string.

If ``auto_id`` is ``False``, then the form output will not include ``<label>``
tags nor ``id`` attributes::

    >>> f = ContactForm(auto_id=False)
    >>> print f.as_table()
    <tr><th>Subject:</th><td><input type="text" name="subject" maxlength="100" /></td></tr>
    <tr><th>Message:</th><td><input type="text" name="message" /></td></tr>
    <tr><th>Sender:</th><td><input type="text" name="sender" /></td></tr>
    <tr><th>Cc myself:</th><td><input type="checkbox" name="cc_myself" /></td></tr>
    >>> print f.as_ul()
    <li>Subject: <input type="text" name="subject" maxlength="100" /></li>
    <li>Message: <input type="text" name="message" /></li>
    <li>Sender: <input type="text" name="sender" /></li>
    <li>Cc myself: <input type="checkbox" name="cc_myself" /></li>
    >>> print f.as_p()
    <p>Subject: <input type="text" name="subject" maxlength="100" /></p>
    <p>Message: <input type="text" name="message" /></p>
    <p>Sender: <input type="text" name="sender" /></p>
    <p>Cc myself: <input type="checkbox" name="cc_myself" /></p>

If ``auto_id`` is set to ``True``, then the form output *will* include
``<label>`` tags and will simply use the field name as its ``id`` for each form
field::

    >>> f = ContactForm(auto_id=True)
    >>> print f.as_table()
    <tr><th><label for="subject">Subject:</label></th><td><input id="subject" type="text" name="subject" maxlength="100" /></td></tr>
    <tr><th><label for="message">Message:</label></th><td><input type="text" name="message" id="message" /></td></tr>
    <tr><th><label for="sender">Sender:</label></th><td><input type="text" name="sender" id="sender" /></td></tr>
    <tr><th><label for="cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="cc_myself" /></td></tr>
    >>> print f.as_ul()
    <li><label for="subject">Subject:</label> <input id="subject" type="text" name="subject" maxlength="100" /></li>
    <li><label for="message">Message:</label> <input type="text" name="message" id="message" /></li>
    <li><label for="sender">Sender:</label> <input type="text" name="sender" id="sender" /></li>
    <li><label for="cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="cc_myself" /></li>
    >>> print f.as_p()
    <p><label for="subject">Subject:</label> <input id="subject" type="text" name="subject" maxlength="100" /></p>
    <p><label for="message">Message:</label> <input type="text" name="message" id="message" /></p>
    <p><label for="sender">Sender:</label> <input type="text" name="sender" id="sender" /></p>
    <p><label for="cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="cc_myself" /></p>

If ``auto_id`` is set to a string containing the format character ``'%s'``,
then the form output will include ``<label>`` tags, and will generate ``id``
attributes based on the format string. For example, for a format string
``'field_%s'``, a field named ``subject`` will get the ``id``
``'field_subject'``. Continuing our example::

    >>> f = ContactForm(auto_id='id_for_%s')
    >>> print f.as_table()
    <tr><th><label for="id_for_subject">Subject:</label></th><td><input id="id_for_subject" type="text" name="subject" maxlength="100" /></td></tr>
    <tr><th><label for="id_for_message">Message:</label></th><td><input type="text" name="message" id="id_for_message" /></td></tr>
    <tr><th><label for="id_for_sender">Sender:</label></th><td><input type="text" name="sender" id="id_for_sender" /></td></tr>
    <tr><th><label for="id_for_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></td></tr>
    >>> print f.as_ul()
    <li><label for="id_for_subject">Subject:</label> <input id="id_for_subject" type="text" name="subject" maxlength="100" /></li>
    <li><label for="id_for_message">Message:</label> <input type="text" name="message" id="id_for_message" /></li>
    <li><label for="id_for_sender">Sender:</label> <input type="text" name="sender" id="id_for_sender" /></li>
    <li><label for="id_for_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></li>
    >>> print f.as_p()
    <p><label for="id_for_subject">Subject:</label> <input id="id_for_subject" type="text" name="subject" maxlength="100" /></p>
    <p><label for="id_for_message">Message:</label> <input type="text" name="message" id="id_for_message" /></p>
    <p><label for="id_for_sender">Sender:</label> <input type="text" name="sender" id="id_for_sender" /></p>
    <p><label for="id_for_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></p>

If ``auto_id`` is set to any other true value -- such as a string that doesn't
include ``%s`` -- then the library will act as if ``auto_id`` is ``True``.

By default, ``auto_id`` is set to the string ``'id_%s'``.

Notes on field ordering
~~~~~~~~~~~~~~~~~~~~~~~

In the ``as_p()``, ``as_ul()`` and ``as_table()`` shortcuts, the fields are
displayed in the order in which you define them in your form class. For
example, in the ``ContactForm`` example, the fields are defined in the order
``subject``, ``message``, ``sender``, ``cc_myself``. To reorder the HTML
output, just change the order in which those fields are listed in the class.

More coming soon
================

That's all the documentation for now. For more, see the file
http://code.djangoproject.com/browser/django/trunk/tests/regressiontests/forms/tests.py
-- the unit tests for ``django.newforms``. This can give you a good idea of
what's possible.

Using forms to validate data
----------------------------

Using forms with templates
==========================

Using forms in views
====================
