views:

3757

answers:

4

Assume I have a form

class SampleClass(forms.Form):
    name = forms.CharField(max_length=30)
    age = forms.IntegerField()
    django_hacker = forms.BooleanField(required=False)

Is there a way for me to define css classes on each field such that I can then use jQuery based on class in my rendered page?

I was hoping not to have to manually build the form.

+8  A: 

Answered my own question. Sigh

http://docs.djangoproject.com/en/dev/ref/forms/widgets/#django.forms.Widget.attrs

I didn't realize it was passed into the widget constructor.

ashchristopher
A: 

I'm not really familiar wit jQuery, but I do know that Firefox (and thus any good browser) will render CSS for any element that has CSS and exists in the HTML. In other words, I can make the following:

<

<form>
<name>Name:<input type="text" /></name>
<age>Age:<input type="text" /></age>
<favcolor>Favorite Color:<input type="text" /><favcolor>
</form>

And then have my css, instead of written to modify a class/id, can be written to modify anything inside that element. Like:

name {
color: black;
}

name input {
background-color: yellow;
border: 3px dotted black;
}
Anthony
That seems more like a hack than a solution.
ashchristopher
It may be a hack now, in that it's not standard, but the whole point of CSS is to be able to apply style to anything. This keeps CSS useful and forward-compatible for when we eventually get rid of HTML and have everything XML/XSLT based. Also other xml-based objects, like svg images, can use css.
Anthony
+8  A: 

Here is another solution for adding class definitions to the widgets after declaring the fields in the class.

def __init__(self, *args, **kwargs):
    super(SampleClass, self).__init__(*args, **kwargs)
    self.fields['name'].widget.attrs['class'] = 'my_class'
ashchristopher
For ModelForms, this is often better as you don't need to be aware of the default form field being used, and you can dynamically set different classes based on runtime conditions. Cleaner than meta coding hacks...
Daniel
That assumes that you want an input for every field in a form, which is often not the case. A form is not necessarily tied to a model - it might be tied to many models. In the case that the model fields and the form fields have a 1:1 relationship, then yes, ModelForm is a much better choice.
ashchristopher
A: 

Here is a variation on the above which will give all fields the same class (e.g. jquery nice rounded corners).

  # Simple way to assign css class to every field
  def __init__(self, *args, **kwargs):
    super(TranslatedPageForm, self).__init__(*args, **kwargs)
    for myField in self.fields:
      self.fields[myField].widget.attrs['class'] = 'ui-state-default ui-corner-all'
timlinux