Can anyone share their tips on ongoing work with forms and designers?
I asked a particularly well-known web designer on a django team how
they deal with the issue and his answer in short is that they don't:
he creates all the html by hand, including any form elements. Since I
imagine that his programmers have the same data validation issues that
the developers at my work do, I'm curious how they get around it.
--
Al Abut
--
web designer, crimefighter
http://alabut.com
--
"We use this in Satchmo:
<form method="post" action=".">
<table>
<tr><td><h4>Discounts</h4></td></tr>
<tr><td><label for="id_discount">Discount code</label></td><td>
{{
form.discount }}</td></tr>
<tr><td></td><td>{% if form.discount.errors %}*** {{
form.discount.errors|join:", " }}{% endif %}</td></tr>
</table>
<input type="submit" value="Confirm"/>
</form>
Does that give you enough control?"
No, that's exactly the type of problem I'm having, with the
{{ form.discount }} shortcut rather than it being an <input/> or
<textarea/> element. The only control that offers me as a designer is
knowing that the id in this case would be "id_discount" as a matter of
convention and that's it - I can't stick a class on it or add any
other attributes, like onFocus or an initial value or all the other
range of stuff I'd be able to monkey with if it was a plain old html
element rather than something auto-generated.
Does using a newform shortcut make things that much easier from a
programmatic standpoint? Or to ask the opposite, is using <input/> and
<textarea/> elements in a template make things that much harder for
things like data validation?
What would be rad is if I could work with the django tags as if they
were html, so for example:
{{ form.whatever class="red small" onFocus="someJavascriptFunction" }}
All that the shortcut does is give you less to type. It doesn't affect
validation at all. As long as you have a form element with the same
name, validation will work fine.
All you need to write is <input name="whatever" class="red small"
onFocus="jsfunction" />. The validators will work just as well.
<script type="text/javascript">
$(function() {
$('input#id_whatever').focus(someJavascriptFunction);
});
</script>
As for classes, I've taken to applying them to a div surrounding my
input elements. So I have something like:
<label>{{ form.whatever.label }}</label>
<div class="red small">{{ form.whatever }}</div>
The CSS isn't much longer...
form .red input { color: red; }
Nathan Ostgard
Ok, thanks John, I'm calling out the developers at work and pointing
them to this :)
Well, the thing to remember is that you're not just displaying an
empty input element -- it's fairly common, due to the data validation
step, to have to go back and show the form again with values filled
in. Which raises the question of how you take the
<input type="text" class="foo" />
in the original form and turn it into
<input type="text" class="foo" value="Some bad text here" />
after the validation step -- if you're just writing raw HTML form
elements you have no way of being able to fill in input, or indicate
selected elements, or handle pre-populated data... that's why the {{
form.fieldname }} shortcut exists.
--
"Bureaucrat Conrad, you are technically correct -- the best kind of correct."
James, thanks for the clarification about the exact utility of using
the form shortcuts. So would I be correct in saying that if you don't
need to programmatically manipulate the values of a form element, then
you can stick to plain html form elements instead?
Not that I don't care about highlighting errors after the validation
step - one method we've been using is to modify the text of the
associated <label/> and give it a class="error" for me to style up
with red text and hazard icons and whatnot.
If that's the case, then fair enough, I'll just have to deal with the
existing setup.
Right, so use:
<input name="{{ fieldname }}" value="{{
form.data.fieldname|escape_filters }}" />
It gets really messy with default values, though.
Hopefully Nathan's tips are enough for you, Al. If not, have your
programmers make a templatetag or filter:
{{ form.fieldname|add_field_attrs:"class='cls'" }}
def add_field_attrs:
[make a dict out of attrs]
return form.fieldname.as_widget(form.fieldname.field.widget, attrs)
A templatetag is better, but I outlined a filter because I'm tired.
The proper templatetag would let you keep all the standard
functionality but still give you the power to add any attribute that
you want.
On Jul 8, 9:52 pm, "John Shaffer" <jshaffer2...@gmail.com> wrote:
I would definitely leave this to the programmer. Values are retrieved
by, supplied by, and validated by the programmer. Let them deliver it,
too.
> Not that I don't care about highlighting errors after the validation
> step - one method we've been using is to modify the text of the
> associated <label/> and give it a class="error" for me to style up
> with red text and hazard icons and whatnot.
I've found this structure to be pretty straightforward and flexible
for styling:
<form>
<fieldset class="some_fieldset">
<div class="some_field {{ form.some_field.field.required|
yesno:"required," }} {{ form.some_field.errors|length_is:0|
yesno:",errors" }}">
<label for="id_some_field">{{ form.some_field.label }}:</label>
<span>{{ form.some_field }}</span>
{{ form.some_field.errors }}
</div>
... more fields ...
</fieldset>
... more fieldsets ...
<div class="submit"><input type="submit" /> or <a href="">cancel</
a></div>
</form>
----
Nathan Ostgard