[Django] #20765: HTML5 number input type not working for DecimalField with big decimal_places

65 views
Skip to first unread message

Django

unread,
Jul 18, 2013, 10:16:19 AM7/18/13
to django-...@googlegroups.com
#20765: HTML5 number input type not working for DecimalField with big
decimal_places
----------------------------------+------------------------
Reporter: aleksey.kladov@… | Owner: nobody
Type: Bug | Status: new
Component: Forms | Version: 1.6-beta-1
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
----------------------------------+------------------------
DecimalFiled's widget is a NumberInput with step attribute equal to
10^-decimal_placecese^.
https://github.com/django/django/blob/stable/1.6.x/django/forms/fields.py#L374).

If decimal_places is too big(the exact value for `big` should be found
here http://www.w3.org/TR/2012/WD-html5-20121025/common-microsyntaxes.html
#rules-for-parsing-floating-point-number-values) the step value parses to
0, which is not valid (http://www.w3.org/TR/2012/WD-html5-20121025/common-
input-element-attributes.html#attr-input-step). It is not good in itself,
but it also causes surprising and unwanted behaviour.

For example in Google Chrome input with type="number" and
step="0.0000000000000000000000000000001" accepts only integer values!

A possible fix is to add optional `step` argument to DecimalField and,
and if it is not provided just use "any".

--
Ticket URL: <https://code.djangoproject.com/ticket/20765>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Jul 18, 2013, 12:00:14 PM7/18/13
to django-...@googlegroups.com
#20765: HTML5 number input type not working for DecimalField with big
decimal_places
----------------------------------+--------------------------------------

Reporter: aleksey.kladov@… | Owner: nobody
Type: Bug | Status: new
Component: Forms | Version: 1.6-beta-1
Severity: Release blocker | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
----------------------------------+--------------------------------------
Changes (by charettes):

* severity: Normal => Release blocker
* cc: charettes (added)
* needs_better_patch: => 0
* needs_tests: => 0
* needs_docs: => 0
* stage: Unreviewed => Accepted


Comment:

We shouldn't add a `step` argument to `DecimalField` since it only concern
the `widget`.

Do you know the exact value for `big`?

We could attempt defaulting `step` to the current behavior when
`decimal_place < big` and fallback to `any` just how
[https://github.com/django/django/blob/stable/1.6.x/django/forms/fields.py#L286
`FloatField`] does.

--
Ticket URL: <https://code.djangoproject.com/ticket/20765#comment:1>

Django

unread,
Jul 18, 2013, 12:14:58 PM7/18/13
to django-...@googlegroups.com
#20765: HTML5 number input type not working for DecimalField with big
decimal_places
----------------------------------+--------------------------------------

Reporter: aleksey.kladov@… | Owner: nobody
Type: Bug | Status: new
Component: Forms | Version: 1.6-beta-1
Severity: Release blocker | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
----------------------------------+--------------------------------------

Comment (by anonymous):

>Do you know the exact value for big?

No, I'm not an IEEE 754 expert =(

>We could attempt defaulting step to the current behavior when

decimal_place < big and fallback to any just how ​`FloatField` does.

I think that step > 0.001 is anyway useless in general. May be just
`.setdefault("step", "any")` exactly as in FloatField? In the face of
ambiguity, refuse the temptation to guess.

--
Ticket URL: <https://code.djangoproject.com/ticket/20765#comment:2>

Django

unread,
Jul 18, 2013, 12:48:57 PM7/18/13
to django-...@googlegroups.com
#20765: HTML5 number input type not working for DecimalField with big
decimal_places
----------------------------------+--------------------------------------

Reporter: aleksey.kladov@… | Owner: nobody
Type: Bug | Status: new
Component: Forms | Version: 1.6-beta-1
Severity: Normal | Resolution:

Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
----------------------------------+--------------------------------------
Changes (by charettes):

* severity: Release blocker => Normal


Comment:

It [http://jsfiddle.net/cnSsU/7/ seems to work until] 1^-18^.

IMHO [http://www.w3.org/TR/2012/WD-html5-20121025/common-
microsyntaxes.html#rules-for-parsing-floating-point-number-values the
float parsing algorithm] is quite unambiguous and the default `step`
attribute is still overridable. I think we should be safe assuming our
`step` generation mechanism works for `decimal_places <= 18`.

--
Ticket URL: <https://code.djangoproject.com/ticket/20765#comment:3>

Django

unread,
Jul 18, 2013, 1:31:23 PM7/18/13
to django-...@googlegroups.com
#20765: HTML5 number input type not working for DecimalField with big
decimal_places
----------------------------------+--------------------------------------

Reporter: aleksey.kladov@… | Owner: nobody
Type: Bug | Status: new
Component: Forms | Version: 1.6-beta-1
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
----------------------------------+--------------------------------------

Comment (by matklad):

> the default step attribute is still overridable

Not really, look again at
https://github.com/django/django/blob/stable/1.6.x/django/forms/fields.py#L374

Even if I do
{{{
answer = fields.DecimalField(max_digits=50,
decimal_places=25,
widget=NumberInput(attrs={"step": "any"}))
}}}

the step gets overriden.

--
Ticket URL: <https://code.djangoproject.com/ticket/20765#comment:4>

Django

unread,
Jul 18, 2013, 1:35:23 PM7/18/13
to django-...@googlegroups.com
#20765: HTML5 number input type not working for DecimalField with big
decimal_places
----------------------------------+--------------------------------------

Reporter: aleksey.kladov@… | Owner: nobody
Type: Bug | Status: new
Component: Forms | Version: 1.6-beta-1
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
----------------------------------+--------------------------------------

Comment (by charettes):

I guess we should use `setdefault` here instead of direct assignment.

--
Ticket URL: <https://code.djangoproject.com/ticket/20765#comment:5>

Django

unread,
Jul 18, 2013, 1:47:10 PM7/18/13
to django-...@googlegroups.com
#20765: HTML5 number input type not working for DecimalField with big
decimal_places
----------------------------------+--------------------------------------

Reporter: aleksey.kladov@… | Owner: nobody
Type: Bug | Status: new
Component: Forms | Version: 1.6-beta-1
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
----------------------------------+--------------------------------------

Comment (by matklad):

`setdefult` defenetelly should be there.

However I think that it's still worth to check that decimal_places <= 18
and use `any` as a default otherwise(or just always use `any`).

--
Ticket URL: <https://code.djangoproject.com/ticket/20765#comment:6>

Django

unread,
Jul 18, 2013, 4:58:13 PM7/18/13
to django-...@googlegroups.com
#20765: HTML5 number input type not working for DecimalField with big
decimal_places
----------------------------------+--------------------------------------

Reporter: aleksey.kladov@… | Owner: nobody
Type: Bug | Status: new
Component: Forms | Version: 1.6-beta-1
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
----------------------------------+--------------------------------------

Comment (by claudep):

What's definitely a bug is that `step` is not overridable.

As of the number of decimal places, it's browser-dependant, and I'm less
enthousiast to do something about it.

--
Ticket URL: <https://code.djangoproject.com/ticket/20765#comment:7>

Django

unread,
Jul 18, 2013, 5:50:20 PM7/18/13
to django-...@googlegroups.com
#20765: HTML5 number input type not working for DecimalField with big
decimal_places
----------------------------------+--------------------------------------
Reporter: aleksey.kladov@… | Owner: charettes
Type: Bug | Status: assigned
Component: Forms | Version: 1.6-beta-1

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
----------------------------------+--------------------------------------
Changes (by charettes):

* owner: nobody => charettes
* status: new => assigned


Comment:

I'll write a patch and fix tests for the `setdefault` behavior.

--
Ticket URL: <https://code.djangoproject.com/ticket/20765#comment:8>

Django

unread,
Jul 18, 2013, 5:51:44 PM7/18/13
to django-...@googlegroups.com
#20765: HTML5 number input type not working for DecimalField with big
decimal_places
----------------------------------+--------------------------------------
Reporter: aleksey.kladov@… | Owner: charettes
Type: Bug | Status: assigned
Component: Forms | Version: 1.6-beta-1

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
----------------------------------+--------------------------------------

Comment (by matklad):

I would be completely happy if I could override `step`. But it's because I
'''know''' that I have to override it. Let me try to convince you for the
last time that guessing step is not a good idea. There will be three
points.

1. Suppose I know nothing about this issue and just wrote in one of my
forms `number = fields.DecimalField(max_digits=50, decimal_places=25)`. I
use firefox and the form is working OK in it. Moreover, tests are working
too. However, very soon I get a bug report that it's impossible to use
non-integer numbers in Chrome! So I have to look into the source of the
page, notice suspicious `step="0.0000000000000000000000000001"`, and find
out that it is the reason of strange behaviour. Next, I have to look
inside django's source, to find out, from where this `step` emerges. And
only then I realize that I need to override it.

2. Current default can produce invalid html.

The step attribute, if specified, must either have a value that is a
'''valid floating-point number that parses to a number that is greater
than zero''', or must have a value that is an ASCII case-insensitive match
for the string "any".

3. If I close my eyes, forget about everything in the universe and ask
myself, "what is the most reasonable default for `step`?" I hear a voice
whispering "`any`".


Also, this issue can show more often than it seems. 10^-18^ is quit a
little number, and it looks like most users won't use such a high
precision. However, it is the '''Decimal'''Field. And if someone is using
a Decimal instead of Float, it means that he cares about high precision.
So it's rather likely that he uses many decimal places. Also, python's
default prec for decimals is 28 places!

--
Ticket URL: <https://code.djangoproject.com/ticket/20765#comment:9>

Django

unread,
Jul 18, 2013, 10:07:51 PM7/18/13
to django-...@googlegroups.com
#20765: HTML5 number input type not working for DecimalField with big
decimal_places
----------------------------------+--------------------------------------
Reporter: aleksey.kladov@… | Owner: charettes
Type: Bug | Status: assigned
Component: Forms | Version: 1.6-beta-1

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
----------------------------------+--------------------------------------
Changes (by charettes):

* has_patch: 0 => 1


Comment:

Added a patch that still sets `step` as '''default''' for `max_digits <=
18` and `'any'` in the other case.

--
Ticket URL: <https://code.djangoproject.com/ticket/20765#comment:10>

Django

unread,
Jul 19, 2013, 2:43:38 AM7/19/13
to django-...@googlegroups.com
#20765: HTML5 number input type not working for DecimalField with big
decimal_places
----------------------------------+--------------------------------------
Reporter: aleksey.kladov@… | Owner: charettes
Type: Bug | Status: assigned
Component: Forms | Version: 1.6-beta-1

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
----------------------------------+--------------------------------------

Comment (by matklad):

This looks good. I can see only one very minor caveat. If decimal_places=0
then step is equal to any, while 1 seems more reasonable.

--
Ticket URL: <https://code.djangoproject.com/ticket/20765#comment:11>

Django

unread,
Jul 19, 2013, 11:42:43 AM7/19/13
to django-...@googlegroups.com
#20765: HTML5 number input type not working for DecimalField with big
decimal_places
----------------------------------+--------------------------------------
Reporter: aleksey.kladov@… | Owner: charettes
Type: Bug | Status: assigned
Component: Forms | Version: 1.6-beta-1

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
----------------------------------+--------------------------------------

Comment (by charettes):

I think I've found a middleground. Parsing works flawlessly in
[http://jsfiddle.net/cnSsU/12/ exponential form]. Submitting an updated
patch.

--
Ticket URL: <https://code.djangoproject.com/ticket/20765#comment:12>

Django

unread,
Jul 19, 2013, 12:05:54 PM7/19/13
to django-...@googlegroups.com
#20765: HTML5 number input type not working for DecimalField with big
decimal_places
----------------------------------+--------------------------------------
Reporter: aleksey.kladov@… | Owner: charettes
Type: Bug | Status: assigned
Component: Forms | Version: 1.6-beta-1

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
----------------------------------+--------------------------------------

Comment (by matklad):

Looks perfect!

As a bonus, exponential form improves html readability.

--
Ticket URL: <https://code.djangoproject.com/ticket/20765#comment:13>

Django

unread,
Jul 19, 2013, 5:00:55 PM7/19/13
to django-...@googlegroups.com
#20765: HTML5 number input type not working for DecimalField with big
decimal_places
-------------------------------------+-------------------------------------

Reporter: aleksey.kladov@… | Owner: charettes
Type: Bug | Status: assigned
Component: Forms | Version:
Severity: Normal | 1.6-beta-1
Keywords: | Resolution:
Has patch: 1 | Triage Stage: Ready for
Needs tests: 0 | checkin
Easy pickings: 0 | Needs documentation: 0
| Patch needs improvement: 0
| UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by claudep):

* stage: Accepted => Ready for checkin


Comment:

RFC, but please either add a comment about the rationale or refer to this
ticket. Thanks!

--
Ticket URL: <https://code.djangoproject.com/ticket/20765#comment:14>

Django

unread,
Jul 19, 2013, 11:31:50 PM7/19/13
to django-...@googlegroups.com
#20765: HTML5 number input type not working for DecimalField with big
decimal_places
-------------------------------------+-------------------------------------
Reporter: aleksey.kladov@… | Owner: charettes
Type: Bug | Status: closed

Component: Forms | Version:
Severity: Normal | 1.6-beta-1
Keywords: | Resolution: fixed

Has patch: 1 | Triage Stage: Ready for
Needs tests: 0 | checkin
Easy pickings: 0 | Needs documentation: 0
| Patch needs improvement: 0
| UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Simon Charette <charette.s@…>):

* status: assigned => closed
* resolution: => fixed


Comment:

In [changeset:"415a36947cb4b8b61230698e13cca2df9400e245"]:
{{{
#!CommitTicketReference repository=""
revision="415a36947cb4b8b61230698e13cca2df9400e245"
Fixed #20765 -- Set small values of `step` using exponential notation.

Browsers parse small factors of 10 as 0 under decimal notation.

Thanks to Trac alias matklad for the report and Claude Paroz for the
review.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/20765#comment:15>

Django

unread,
Jul 19, 2013, 11:46:42 PM7/19/13
to django-...@googlegroups.com
#20765: HTML5 number input type not working for DecimalField with big
decimal_places
-------------------------------------+-------------------------------------
Reporter: aleksey.kladov@… | Owner: charettes
Type: Bug | Status: closed
Component: Forms | Version:
Severity: Normal | 1.6-beta-1
Keywords: | Resolution: fixed
Has patch: 1 | Triage Stage: Ready for
Needs tests: 0 | checkin
Easy pickings: 0 | Needs documentation: 0
| Patch needs improvement: 0
| UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Simon Charette <charette.s@…>):

In [changeset:"9d3f7a21a337aa82d5c9ac5ef9a6a3888bff62a8"]:
{{{
#!CommitTicketReference repository=""
revision="9d3f7a21a337aa82d5c9ac5ef9a6a3888bff62a8"
[1.6.x] Fixed #20765 -- Set small values of `step` using exponential
notation.

Browsers parse small factors of 10 as 0 under decimal notation.

Thanks to Trac alias matklad for the report and Claude Paroz for the
review.

Backport of 415a36947c from master.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/20765#comment:16>

Reply all
Reply to author
Forward
0 new messages