Opened 8 years ago

Closed 12 months ago

#9153 closed Bug (needsinfo)

Forms (and formsets) don't always generate valid HTML for hidden fields

Reported by: Malcolm Tredinnick Owned by: nobody
Component: Forms Version: 1.0
Severity: Normal Keywords:
Cc: asendecka@… Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Creating a form with only hidden fields and than calling as_p() on it generates invalid (X)HTML. The input elements must reside inside certain block-level elements and this doesn't always happen. In r9067 I made a change that made this work when displaying error messages for such fields, but the general case is trickier.

The problem is that we can't just apply the same change as r9067 because that would introduce, for example, an empty table row in the as_table() method. This normally wouldn't be an issue (why, exactly, are you calling as_p() on a form that doesn't display anything?), but it arises fairly naturally with formsets. The management form for formsets is a form that only contains hidden fields. Thus, any formset display is slightly invalid. Fixing this doesn't appear to be entirely trivial, so I didn't drop in any kind of patch around the time of r9067.

There are some tests in regressiontests/forms/forms.py that actually demonstrate the problem here: except they consider the invalid output to be valid. So any patch fixing this will cause a couple of tests for hidden fields to "fail" and the tests will need to be fixed.

Change History (6)

comment:1 Changed 8 years ago by Jacob

Needs documentation: unset
Needs tests: unset
Patch needs improvement: unset
Triage Stage: UnreviewedAccepted

comment:2 Changed 5 years ago by Luke Plant

Severity: Normal
Type: Bug

comment:3 Changed 5 years ago by anonymous

Easy pickings: unset
UI/UX: unset

When using ajax to load a formset, this can cause improper rendering in the browser. In my case the formset content is sent using HttpResponse(formset.as_table(),mimetype='application/text'). The management form at the beginning of the formset is not in a <tr>. The result is that the tr tags are removed from the entire formset (by the browser when jQuery.html(data) is called).

comment:4 in reply to:  3 Changed 5 years ago by Nate

Replying to anonymous:

When using ajax to load a formset, this can cause improper rendering in the browser. In my case the formset content is sent using HttpResponse(formset.as_table(),mimetype='application/text'). The management form at the beginning of the formset is not in a <tr>. The result is that the tr tags are removed from the entire formset (by the browser when jQuery.html(data) is called).

The following jQuery patched this specific case:

function fixManagement(astable) {
	var mngForm = astable.split('<tr>', 1);
	var trIndex = astable.indexOf('<th>',1)+4;
	var latter = astable.substr(trIndex);
	return '<tr><th>'+ mngForm + latter;
}
Last edited 12 months ago by Tim Graham (previous) (diff)

comment:5 Changed 5 years ago by Aleksandra Sendecka

Cc: asendecka@… added

I could not reproduce the bug, but I'm not sure, if I understand the ticket well. Does anybody have an example that generates invalid (X)HTML?

comment:6 Changed 12 months ago by Tim Graham

Resolution: needsinfo
Status: newclosed

I'm also not sure how to reproduce this. This seems fine:

>>> from django import forms
>>> 
>>> class Foo(forms.Form):
...     baz = forms.CharField(widget=forms.HiddenInput)
...     bar =  forms.CharField(widget=forms.HiddenInput)
... 
>>> foo = Foo()
>>> foo.as_p()
'<input id="id_baz" name="baz" type="hidden" /><input id="id_bar" name="bar" type="hidden" />'

Maybe things have changed since 7 years ago when the ticket was reported.

Note: See TracTickets for help on using tickets.
Back to Top