Horizontal Django RadioSelect Using Only CSS Stlying

I'm working on the re-write of a web application that is currently written in PHP using Django. Part of this application contains a questionaire that has answers that are displayed as radio buttons since only one answer is acceptible. This is where I ran into the issues of Django RadioSelect having a vertical layout and not property or method to make in display as a horizontal layout. So as most people do, I search the web for a quick answer. It seemed that the accepted answer was to write a new widget decendant from RadioSelect that allowed for a horizontal layout. This just was not acceptable to me as it seemed this all could be done using CSS. And this is how I did so.

A Simple Horizontal RadioSelect

If you refer to the image below, you can see that the first RadioSelect is a simple selection of values from 1 to 10. So to render this I only needed a single row and column. Here is the relavent code from my template:

<label id="number_of_times_moved_label"> Number of times moved:</label>
<div id="number_of_times_moved"> {{form.number_of_times_moved}} </div>


But, what we really need to know is, how is this piece of the code, {{form.number_of_times_moved}}, rendered in HTML to be able to style it correctly using HTML. So let's look at that.

<div id="number_of_times_moved">
<ul>
<li>
<label for="id_number_of_times_moved_0">
<input type="radio" id="id_number_of_times_moved_0" value="0" name="number_of_times_moved" /> 0</label>
</li>
<li>
<label for="id_number_of_times_moved_1">
<input type="radio" id="id_number_of_times_moved_1" value="1" name="number_of_times_moved" /> 1</label>
</li>
<li> <label for="id_number_of_times_moved_2">
<input type="radio" id="id_number_of_times_moved_2" value="2" name="number_of_times_moved" /> 2</label>
</li>
<li>
<label for="id_number_of_times_moved_3">
<input type="radio" id="id_number_of_times_moved_3" value="3" name="number_of_times_moved" /> 3</label>
</li>
<li>
<label for="id_number_of_times_moved_4">
<input type="radio" id="id_number_of_times_moved_4" value="4" name="number_of_times_moved" /> 4</label>
</li>
...CODE REMOVE FOR BREVITY...


We can see from the HTML that the Djano RadioSelect renders as an un-ordered list containing radio inputs. All we need to do then is style the list. We need to increase the number of columns in the list row. Here is the CSS I used for that:

ul{columns: 18;}

Why 18? This gave me the right amount of spacing and width. Using 10 made the spacing between buttons too wide, 20 cut off part of the radio buttons. Here is what that produced.

radio_buttons_are_almost_done

As you can see the numbers for each button are below the buttons and of center. I wanted the number to be to the right side of each individual radio button. If we look back at out HTML we can see that each individual radio button has an id in the format of id_number_of_times_moved_# were # is value. So for the first radio button the id is id_number_of_times_moved_0 and the last is id_number_of_times_moved_10. So all we need to do is create a style for these that moves the number up and to the right. So here is it.

#id_number_of_times_moved_0{position: relative; left:-20px; top:15px;} #id_number_of_times_moved_1{position: relative; left:-20px; top:15px;} #id_number_of_times_moved_2{position: relative; left:-20px; top:15px;} #id_number_of_times_moved_3{position: relative; left:-20px; top:15px;} #id_number_of_times_moved_4{position: relative; left:-20px; top:15px;} #id_number_of_times_moved_5{position: relative; left:-20px; top:15px;} #id_number_of_times_moved_6{position: relative; left:-20px; top:15px;} #id_number_of_times_moved_7{position: relative; left:-20px; top:15px;} #id_number_of_times_moved_8{position: relative; left:-20px; top:15px;} #id_number_of_times_moved_9{position: relative; left:-20px; top:15px;} #id_number_of_times_moved_10{position: relative; left:-20px; top:15px;}


DISCLAIMER: I am in no way a CSS guru so there may be more concise way to apply the same style to all the radio buttons.

So that gives you the finaly layout as in the last image on this page. But what about multi-column layouts?

Multi-column Horizontal RadioSelect

The next task I needed to do was to create two columns of three radio buttons. Now we know that the RadioSelect is an unordered list, but I have already give the ul element a style. It would be better if I could give the ul elements and id, but I could not find a way to do this since Django didn't give access to that element. So I decided to put the RadioSelect element into a FieldSet element. This is the code in the template

<fieldset id="ppg_select"> {{form.population_group}} </fieldset>

By placing the RadioSelect within a fieldset I can now create a style for the individual elements with in this specific element. In other words, the ul and li elements contained with in the fieldset with the id of ppg_select. Here is the CSS code for that.

fieldset#ppg_select ul{position: relative; columns: 2; } fieldset#ppg_select ul li{width: 350px;}

The first style creates the two columns, since there are six items they are evenly divided. The second style I needed because the list item text was wrapping, in some case up to 4 rows. I need each it to only one row and since the entire with of that area is 720px I decided to give the items 350px so that there would be a little bit of buffer room. This is how we get the final product in the image below.

django_css_radioselect_horizontal_style

Hope this helps.








Two Python scripts for text files. Row manipulation and swapping column

I created these two scripts because I had a need for them at work. Swap column swaps columns in a delimited text file with each other. Row Man, will allow you to remove duplicate rows, find only the unique rows, find duplicate rows and count the occurance if wanted. This script was written quickly and as a blueprint - but it works for my needs. Although I should clean it up and make it nicer

Swap Columns
Row Man
Right Click Save As..







Mail Convert

I need a script that would convert my email from the format that Claws Mail uses (MH) to a Maildir format so that I could use mutt to read my email.

I looked around the net for a few days and couldn't find anything so, I took a few hours over one day and whipped up this script. I'd call this a 0.0.1 release as I know it works for what I wanted, but I have tested it much beyond that. I'm working on some enhancements to allow it to convert to and from other formats.

Mailconvert is written in Python 2.5. It has no other requirements but that.

MailConvert_0.0.1
Right Click Save As..







PyPanel Patch

From a discussion in the forums on BSDnexus, came the idea from a friend to create a patch for pypanel. I spent a day or so looking over the code and decided to give it a go. Here are the results.

This patch add two new functionalities to pypanel.
  1. Setting the width of the panel as a percentage of the screen.
  2. Aligning the pypanel by using the keyword RIGHT, CENTER or LEFT.
To set the width as a percentage you need to edit your pypanelrc file by setting the P_WIDTH variable to a percentage. So if you wanted the panel to be 50% of the screen you would set the variable like this.
P_WIDTH = ‘50%’

To set the alignment to right:
P_START = ‘RIGHT’

To set the alignment to center:
P_START = ‘CENTER’

To set the alignment to left:
P_START = ‘LEFT’

These changes DO NOT override the orignal way of setting the width and starting position.

This patch was created on FreeBSD 7.0 and tested also on FreeBSD 8.0. This is the 20080411.patch

For those using FreeBSD you can just download pypanel and replace your existing pypanel with this one. Make sure that it is executable.

Special thanks to Scott Robbins (scottro) for the idea and the testing.