8

Some front-end experts claim that wrapping an <input> with the <label> (implicit labels) is a preferable practice (compared to explicit ones, even if they have the for attribute).

Whatever the reasons for that, I'd like to see how this can be technically done with Django in an elegant way.

Dominic Rodger
  • 97,747
  • 36
  • 197
  • 212
kmt
  • 897
  • 2
  • 10
  • 19

1 Answers1

3

Write your own Widgets and use them on your Forms.

Hank Gay
  • 70,339
  • 36
  • 160
  • 222
  • 1
    Form._html_output is what controls the ouput, not the widgets. – kmt Jan 06 '11 at 18:39
  • 3
    @kmt `Widgets` have a `render` method that produces the markup for the `Widget` itself; you could have it produce the `label` tag, too (although you'll have to make sure the `BoundField` for your `Widget` doesn't somehow print a `label` of its own). To be clear: I don't recommend this. For one thing, it's a PITA for (to my eyes) no benefit. Also, it's likely to break most layouts since the `labels` are in one column and the `inputs`, etc. are in another. – Hank Gay Jan 06 '11 at 18:55
  • 1
    I have not looked at other versions but in 1.2.3 Form._html_output would append both the `BoundField` label and the `Widget`'s output to it's output. That's what I don't have control over unless I override that method (which is a *bad* idea). – kmt Jan 06 '11 at 19:43
  • @kmt I believe that if you specify `label=''` for the `Field` objects using your `Widgets`, that will prevent the double-`label` behavior, based on reading this line from the `BoundField` constructor: http://code.djangoproject.com/browser/django/trunk/django/forms/forms.py#L398 – Hank Gay Jan 06 '11 at 19:50
  • Yeah, but I think that's irrelevant. Take a look here: http://code.djangoproject.com/browser/django/trunk/django/forms/forms.py#L161 . The most minimalistic solution I can think of is to override `BoundField.label_tag` to not close the label tag and close it myself in normal_row (http://code.djangoproject.com/browser/django/trunk/django/forms/forms.py#L231) – kmt Jan 06 '11 at 20:02
  • @kmt I could be wrong, but the way I read that file, using `label=''` will cause `bf.label` there to be `''`, which is falsey, so the `else` block will execute, and `label_tag` never gets called at all. – Hank Gay Jan 06 '11 at 20:23
  • Ah, you *actually* make the label empty and then do the label separately, together with the widget. This would work... but it's a hack. Since I'd like to customize another thing (remove those inline errors), I'll just write my own rendering, it's the cleanest way and offers full control. – kmt Jan 06 '11 at 23:23
  • 1
    @kmt Yeah, it's definitely a hack. Tweaking things at this level is usually a good indicator that you may want to look at avoiding Django forms altogether. Maybe you should just do it manually, or something like WTForms is more your cup of tea? http://wtforms.simplecodes.com/ Maintaining patches on top of a dependency just wears on you (or me, at least). Luckily, this doesn't seem like an extremely fast-moving target. – Hank Gay Jan 07 '11 at 00:14
  • @Hank, I don't think it's too bad (yet). I'm open to using alternative forms though. How are WTFoms? What are the advantages? I'd like to build on top of something relatively stable and simple. How do they compare? – kmt Jan 07 '11 at 01:59
  • @kmt I'm not really familiar with WTForms, honestly. I just know that Flask (optionally) uses it for form handling, see http://flask.pocoo.org/docs/patterns/wtforms/ (Flask is on my list of frameworks to explore). It seems to share a lot with Django forms, and in fact has an extension to integrate with Django http://wtforms.simplecodes.com/docs/0.6.1/ext.html#module-wtforms.ext.django A quick glance through the repo on BitBucket https://bitbucket.org/simplecodes/wtforms/src/291367e62b7d/wtforms/widgets.py makes it look like customizing it should be straightforward. – Hank Gay Jan 07 '11 at 17:05