From ec6121693f112ae33b653b4364e812722d2eb567 Mon Sep 17 00:00:00 2001 From: Jon Dufresne Date: Mon, 28 Mar 2016 11:02:04 -0700 Subject: Fixed #22383 -- Added support for HTML5 required attribute on required form fields. --- docs/ref/forms/api.txt | 189 ++++++++++++++++++++++++--------------------- docs/ref/forms/fields.txt | 44 +++++------ docs/ref/forms/widgets.txt | 30 +++---- 3 files changed, 137 insertions(+), 126 deletions(-) (limited to 'docs/ref/forms') diff --git a/docs/ref/forms/api.txt b/docs/ref/forms/api.txt index f1c46da947..c468dc38a0 100644 --- a/docs/ref/forms/api.txt +++ b/docs/ref/forms/api.txt @@ -244,9 +244,9 @@ precedence:: ... comment = forms.CharField() >>> f = CommentForm(initial={'name': 'instance'}, auto_id=False) >>> print(f) - Name: - Url: - Comment: + Name: + Url: + Comment: Checking which form data has changed ==================================== @@ -305,10 +305,10 @@ You can alter the field of :class:`Form` instance to change the way it is presented in the form:: >>> f.as_table().split('\n')[0] - 'Name:' + 'Name:' >>> f.fields['name'].label = "Username" >>> f.as_table().split('\n')[0] - 'Username:' + 'Username:' Beware not to alter the ``base_fields`` attribute because this modification will influence all subsequent ``ContactForm`` instances within the same Python @@ -317,7 +317,7 @@ process:: >>> f.base_fields['name'].label = "Username" >>> another_f = CommentForm(auto_id=False) >>> another_f.as_table().split('\n')[0] - 'Username:' + 'Username:' Accessing "clean" data ====================== @@ -421,9 +421,9 @@ simply ``print`` it:: >>> f = ContactForm() >>> print(f) - - - + + + If the form is bound to data, the HTML output will include that data @@ -438,9 +438,9 @@ include ``checked="checked"`` if appropriate:: ... 'cc_myself': True} >>> f = ContactForm(data) >>> print(f) - - - + + + This default output is a two-column HTML table, with a ```` for each field. @@ -485,11 +485,11 @@ containing one field:: >>> f = ContactForm() >>> f.as_p() - '

\n

\n

\n

' + '

\n

\n

\n

' >>> print(f.as_p()) -

-

-

+

+

+

``as_ul()`` @@ -504,11 +504,11 @@ flexibility:: >>> f = ContactForm() >>> f.as_ul() - '
  • \n
  • \n
  • \n
  • ' + '
  • \n
  • \n
  • \n
  • ' >>> print(f.as_ul()) -
  • -
  • -
  • +
  • +
  • +
  • ``as_table()`` @@ -522,11 +522,11 @@ it calls its ``as_table()`` method behind the scenes:: >>> f = ContactForm() >>> f.as_table() - '\n\n\n' + '\n\n\n' >>> print(f.as_table()) - - - + + + .. _ref-forms-api-styling-form-rows: @@ -597,19 +597,19 @@ tags nor ``id`` attributes:: >>> f = ContactForm(auto_id=False) >>> print(f.as_table()) - Subject: - Message: - Sender: + Subject: + Message: + Sender: Cc myself: >>> print(f.as_ul()) -
  • Subject:
  • -
  • Message:
  • -
  • Sender:
  • +
  • Subject:
  • +
  • Message:
  • +
  • Sender:
  • Cc myself:
  • >>> print(f.as_p()) -

    Subject:

    -

    Message:

    -

    Sender:

    +

    Subject:

    +

    Message:

    +

    Sender:

    Cc myself:

    If ``auto_id`` is set to ``True``, then the form output *will* include @@ -618,19 +618,19 @@ field:: >>> f = ContactForm(auto_id=True) >>> print(f.as_table()) - - - + + + >>> print(f.as_ul()) -
  • -
  • -
  • +
  • +
  • +
  • >>> print(f.as_p()) -

    -

    -

    +

    +

    +

    If ``auto_id`` is set to a string containing the format character ``'%s'``, @@ -641,19 +641,19 @@ attributes based on the format string. For example, for a format string >>> f = ContactForm(auto_id='id_for_%s') >>> print(f.as_table()) - - - + + + >>> print(f.as_ul()) -
  • -
  • -
  • +
  • +
  • +
  • >>> print(f.as_p()) -

    -

    -

    +

    +

    +

    If ``auto_id`` is set to any other true value -- such as a string that doesn't @@ -671,15 +671,15 @@ It's possible to customize that character, or omit it entirely, using the >>> f = ContactForm(auto_id='id_for_%s', label_suffix='') >>> print(f.as_ul()) -
  • -
  • -
  • +
  • +
  • +
  • >>> f = ContactForm(auto_id='id_for_%s', label_suffix=' ->') >>> print(f.as_ul()) -
  • -
  • -
  • +
  • +
  • +
  • Note that the label suffix is added only if the last character of the @@ -692,6 +692,17 @@ This will take precedence over :attr:`Form.label_suffix using the ``label_suffix`` parameter to :meth:`~django.forms.BoundField.label_tag`. +.. attribute:: Form.use_required_attribute + +.. versionadded:: 1.10 + +When set to ``True`` (the default), required form fields will have the +``required`` HTML attribute. + +:doc:`Formsets ` instantiate forms with +``use_required_attribute=False`` to avoid incorrect browser validation when +adding and deleting forms from a formset. + Notes on field ordering ----------------------- @@ -741,21 +752,21 @@ method you're using:: ... 'cc_myself': True} >>> f = ContactForm(data, auto_id=False) >>> print(f.as_table()) - Subject: - Message: - Sender: + Subject: + Message: + Sender: Cc myself: >>> print(f.as_ul()) -
  • Subject:
  • -
  • Message:
  • -
  • Sender:
  • +
  • Subject:
  • +
  • Message:
  • +
  • Sender:
  • Cc myself:
  • >>> print(f.as_p())

    -

    Subject:

    -

    Message:

    +

    Subject:

    +

    Message:

    -

    Sender:

    +

    Sender:

    Cc myself:

    .. _ref-forms-error-list-format: @@ -778,10 +789,10 @@ Python 2):: >>> f = ContactForm(data, auto_id=False, error_class=DivErrorList) >>> f.as_p()
    This field is required.
    -

    Subject:

    -

    Message:

    +

    Subject:

    +

    Message:

    Enter a valid email address.
    -

    Sender:

    +

    Sender:

    Cc myself:

    More granular output @@ -803,25 +814,25 @@ using the field's name as the key:: >>> form = ContactForm() >>> print(form['subject']) - + To retrieve all ``BoundField`` objects, iterate the form:: >>> form = ContactForm() >>> for boundfield in form: print(boundfield) - - - + + + The field-specific output honors the form object's ``auto_id`` setting:: >>> f = ContactForm(auto_id=False) >>> print(f['message']) - + >>> f = ContactForm(auto_id='id_%s') >>> print(f['message']) - + Attributes of ``BoundField`` ---------------------------- @@ -852,7 +863,7 @@ Attributes of ``BoundField`` >>> data = {'subject': 'hi', 'message': '', 'sender': '', 'cc_myself': ''} >>> f = ContactForm(data, auto_id=False) >>> print(f['message']) - + >>> f['message'].errors ['This field is required.'] >>> print(f['message'].errors) @@ -904,7 +915,7 @@ Attributes of ``BoundField`` .. code-block:: html - + .. attribute:: BoundField.is_hidden @@ -1125,11 +1136,11 @@ fields are ordered first:: ... priority = forms.CharField() >>> f = ContactFormWithPriority(auto_id=False) >>> print(f.as_ul()) -
  • Subject:
  • -
  • Message:
  • -
  • Sender:
  • +
  • Subject:
  • +
  • Message:
  • +
  • Sender:
  • Cc myself:
  • -
  • Priority:
  • +
  • Priority:
  • It's possible to subclass multiple forms, treating forms as mixins. In this example, ``BeatleForm`` subclasses both ``PersonForm`` and ``InstrumentForm`` @@ -1146,10 +1157,10 @@ classes:: ... haircut_type = CharField() >>> b = BeatleForm(auto_id=False) >>> print(b.as_ul()) -
  • First name:
  • -
  • Last name:
  • -
  • Instrument:
  • -
  • Haircut type:
  • +
  • First name:
  • +
  • Last name:
  • +
  • Instrument:
  • +
  • Haircut type:
  • It's possible to declaratively remove a ``Field`` inherited from a parent class by setting the name of the field to ``None`` on the subclass. For example:: @@ -1179,11 +1190,11 @@ You can put several Django forms inside one ``
    `` tag. To give each >>> mother = PersonForm(prefix="mother") >>> father = PersonForm(prefix="father") >>> print(mother.as_ul()) -
  • -
  • +
  • +
  • >>> print(father.as_ul()) -
  • -
  • +
  • +
  • The prefix can also be specified on the form class:: diff --git a/docs/ref/forms/fields.txt b/docs/ref/forms/fields.txt index 1748262de4..f21bae462a 100644 --- a/docs/ref/forms/fields.txt +++ b/docs/ref/forms/fields.txt @@ -115,9 +115,9 @@ We've specified ``auto_id=False`` to simplify the output:: ... comment = forms.CharField() >>> f = CommentForm(auto_id=False) >>> print(f) - Your name: - Your website: - Comment: + Your name: + Your website: + Comment: ``label_suffix`` ---------------- @@ -133,9 +133,9 @@ The ``label_suffix`` argument lets you override the form's ... captcha_answer = forms.IntegerField(label='2 + 2', label_suffix=' =') >>> f = ContactForm(label_suffix='?') >>> print(f.as_p()) -

    -

    -

    +

    +

    +

    ``initial`` ----------- @@ -157,9 +157,9 @@ field is initialized to a particular value. For example:: ... comment = forms.CharField() >>> f = CommentForm(auto_id=False) >>> print(f) - Name: - Url: - Comment: + Name: + Url: + Comment: You may be thinking, why not just pass a dictionary of the initial values as data when displaying the form? Well, if you do that, you'll trigger validation, @@ -172,9 +172,9 @@ and the HTML output will include any validation errors:: >>> default_data = {'name': 'Your name', 'url': 'http://'} >>> f = CommentForm(default_data, auto_id=False) >>> print(f) - Name: - Url: - Comment: + Name: + Url: + Comment: This is why ``initial`` values are only displayed for unbound forms. For bound forms, the HTML output will use the bound data. @@ -201,7 +201,7 @@ Instead of a constant, you can also pass any callable:: >>> class DateForm(forms.Form): ... day = forms.DateField(initial=datetime.date.today) >>> print(DateForm()) - Day: + Day: The callable will be evaluated only when the unbound form is displayed, not when it is defined. @@ -237,19 +237,19 @@ fields. We've specified ``auto_id=False`` to simplify the output:: ... cc_myself = forms.BooleanField(required=False) >>> f = HelpTextContactForm(auto_id=False) >>> print(f.as_table()) - Subject:
    100 characters max. - Message: - Sender:
    A valid email address, please. + Subject:
    100 characters max. + Message: + Sender:
    A valid email address, please. Cc myself: >>> print(f.as_ul())) -
  • Subject: 100 characters max.
  • -
  • Message:
  • -
  • Sender: A valid email address, please.
  • +
  • Subject: 100 characters max.
  • +
  • Message:
  • +
  • Sender: A valid email address, please.
  • Cc myself:
  • >>> print(f.as_p()) -

    Subject: 100 characters max.

    -

    Message:

    -

    Sender: A valid email address, please.

    +

    Subject: 100 characters max.

    +

    Message:

    +

    Sender: A valid email address, please.

    Cc myself:

    ``error_messages`` diff --git a/docs/ref/forms/widgets.txt b/docs/ref/forms/widgets.txt index e347876724..f2b132ce3d 100644 --- a/docs/ref/forms/widgets.txt +++ b/docs/ref/forms/widgets.txt @@ -135,9 +135,9 @@ provided for each widget will be rendered exactly the same:: >>> f = CommentForm(auto_id=False) >>> f.as_table() - Name: - Url: - Comment: + Name: + Url: + Comment: 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 @@ -154,9 +154,9 @@ Django will then include the extra attributes in the rendered output: >>> f = CommentForm(auto_id=False) >>> f.as_table() - Name: - Url: - Comment: + Name: + Url: + Comment: You can also set the HTML ``id`` using :attr:`~Widget.attrs`. See :attr:`BoundField.id_for_label` for an example. @@ -204,7 +204,7 @@ foundation for custom widgets. >>> from django import forms >>> name = forms.TextInput(attrs={'size': 10, 'title': 'Your name',}) >>> name.render('name', 'A name') - '' + '' If you assign a value of ``True`` or ``False`` to an attribute, it will be rendered as an HTML5 boolean attribute:: @@ -627,16 +627,16 @@ Selector and checkbox widgets .. code-block:: html
    - +
    - +
    - +
    - +
    That included the ``