Customizing Django forms with RadioSelect widget
django, django-forms, django-templates
Solution
Since it doesn't seem to be a good way to do this I chose to rearrange the generated code using jQuery.
// First remove the ul and li tags
$('.radio ul').contents().unwrap();
$('.radio li').contents().unwrap();
// Then move the input to outside of the label
$('.radio > label > input').each(function() {
$(this).parent().before(this);
});
// Then apply the jQuery UI buttonset
$( ".radio" ).buttonset();
This made it go from:
<ul>
<li><label for="id_notify_new_friends_0"><input type="radio" id="id_notify_new_friends_0" value="0" name="notify_new_friends" /> Immediately</label></li>
<li><label for="id_notify_new_friends_1"><input type="radio" id="id_notify_new_friends_1" value="1" name="notify_new_friends" /> Never</label></li>
</ul>
to:
<input type="radio" id="id_notify_new_friends_0" value="0" name="notify_new_friends" /><label for="id_notify_new_friends_0"> Immediately</label></li>
<input type="radio" id="id_notify_new_friends_1" value="1" name="notify_new_friends" /><label for="id_notify_new_friends_1"> Never</label></li>
and my jQuery UI styling works fine.
Problem
So I'm using jQuery UI to skin the radio buttons but I can't get Django to render my form the way it has to be done. I need to have this structure: ``` <table> <tr> <td><label for="notify_new_friends">Notify when new friends join</label></td> <td class="radio"> <input type="radio" name="notify_new_friends" id="notify_new_friends_immediately" value="1" checked="checked"/><label for="notify_new_friends_immediately">Immediately</label> <input type="radio" name="notify_new_friends" id="notify_new_friends_never" value="0"/><label for="notify_new_friends_never">Never</label> </td> </tr> </table> ``` So to summarize that I need the radio buttons within a class (radio) where they have an `input` and a `label for`. When I render the form in my template with `{{ profile_form.notify_new_friends }}` I get the following: ``` <ul> <li><label for="id_notify_new_friends_0"><input type="radio" id="id_notify_new_friends_0" value="0" name="notify_new_friends" /> Immediately</label></li> <li><label for="id_notify_new_friends_1"><input type="radio" id="id_notify_new_friends_1" value="1" name="notify_new_friends" /> Never</label></li> </ul> ``` Which is exactly what I want except for the list-part. So I tried looping over it which gives me the labels formatted differently: ``` {% for item in profile_form.notify_new_friends %} {{ item }} {% endfor %} ``` which gives me: ``` <label><input type="radio" name="notify_new_friends" value="0" /> Immediately</label> <label><input type="radio" name="notify_new_friends" value="1" /> Never</label> ``` So the problem here is that it stops using `label for` and starts using just `label` to wrapp it all with. I also tried doing something like this, but then the `label` and `label_tag` don't render anything. ``` {{ profile_form.notify_new_friends.0 }} {{ profile_form.notify_new_friends.0.label_tag }} {{ profile_form.notify_new_friends.0.label }} ``` So does anyone know how I can render this properly!? FYI, this is my forms.py: ``` self.fields['notify_new_friends'] = forms.ChoiceField(label='Notify when new friends join', widget=forms.RadioSelect, choices=NOTIFICATION_CHOICES) ```