The problem with Django's default Radio button widget is that it puts the buttons in a vertical format and the documentation is somewhat silent on how to make them horizontal. If you are dealing with a long list of buttons then veritical is probably the way to go but if you are dealing with "YES/NO" situation or any other boolean choice then you will probably want them horizontal. 

So let's start off by adding the following class to our forms.py[or comparable] module:

class HorizRadioRenderer(forms.RadioSelect.renderer):
    """ this overrides widget method to put radio buttons horizontally
        instead of vertically.
    """
    def render(self):
            """Outputs radios"""
            return mark_safe(u'\n'.join([u'%s\n' % w for w in self]))

Then within the same form.py module we can define our class form using the widget.

class PartAForm(forms.Form):
    us_citizen = forms.CharField(label="Are you a US Citizen?",
                                 widget=forms.RadioSelect(renderer=HorizRadioRenderer,
                                 choices=(('yes','YES'),('no','NO'))), required=True)
    first_name = forms.CharField(label="First Name",
                 widget=forms.TextInput(attrs={'size':'12'}), required=False)
    middle_name = forms.CharField(label="Middle Name",
                  widget=forms.TextInput(attrs={'size':'12'}), required=False)
    last_name = forms.CharField(label="Last Name",
                widget=forms.TextInput(attrs={'size':'16'}), required=False)

The class "HorizRadioRenderer" is sent to the RadioSelect widget as a new renderer and displays the buttons on the horizontal not vertical.

16 Comments

  1. Anonymous

    Thank you so much! This works perfectly (smile)

  2. Anonymous

    doesn't work

  3. Anonymous

    Doesn't work, no output.

  4. Anonymous

    oops, my bad...noted it is a CharField

    1. Anonymous

      Love this code.  However, how do you set a default value?

      1. Anonymous

        Oops, meant to reply to the main thread...

      2. I guess there would be two ways to accomplish that:

        1) in the creation of the form instance have an "initial value

         us_citizen = forms.CharField(label="Are you a US Citizen?",                                 widget=forms.RadioSelect(renderer=HorizRadioRenderer,
                                         choices=(('yes','YES'),('no','NO'))), initial='yes',
                                         required=True)
        

        2) in your view function after you have created the form instance you can update the initial value

        form = PartAForm()
        form.initial.update({'us_citizen':'yes',})
        

        There may be a difference as to which is actually bound to the form and which is not. You might want to test that before using.

        see http://docs.djangoproject.com/en/1.2/ref/forms/api/#ref-forms-api-bound-unbound

  5. Anonymous

    You could also use CSS to style the list so that it is horizontal.

    1. yes you could, do you have an example?

      barry

  6. Anonymous

    Thank you, this is almost exactly what I was looking for. In my case, I needed to render the radio buttons in a series of <td>...</td> cells, and a slightly modified version of your code works perfectly.

  7. Anonymous

    awsome, thanks!

  8. Anonymous

    God job Barry :)

  9. Anonymous

    Thanks, works fine!

  10. Anonymous

    All this does is insert return characters into the html.  That does not change the layout.

  11. Anonymous

    Great thanks! : )

    Can Kavakl?o?lu