There’s something good around the corner
Up until now we have been using images to fake rounded edges on divs etc. This is fine until you want to change the styling and resize anything. So, I had a look at doing it in pure CSS. Luckily, so have lots of other people eg. Nifty Corners and Spiffy Corners. I used the Spiffy Corners one since it comes with a nice code creator which saves lots of time and is easy to re-use. All you have to do is enter in the class name for the CSS, colour of the bar and the background colour and it generates both the CSS and the html. Job done.
Sorry for the delay - we’ve been on the rails
So it’s been a few months since the last post about adventures in flex. The final verdict, quite nice but without more developer support the obesity-elab project was too big for one person. So, we decided to go with the flow and follow the rails path like myExperiment and Sysmo. This gave us a big codebase to play with. We still needed some back end components to handle csv file parsing and creation so a jetty based webapp was created using the Ostermiller Utilities for the CSV handling. We (well, me) also used Apache solr with the ruby acts_as_solr plugin for searching the metadata.
Writing complex apps in html is certainly an interesting challenge and after having created the first version of what we now call methodbox I can see why frameworks like Google Web Toolkit and flex are so appealing. Having to insert hidden objects into the html so the application can remember them between clicks gets a bit tedious after a while! However, we overcame a few hurdles along the way and here are some things I found useful:
Things I needed to know about Rails but was too much of a newby to find out from the books
1. routes.rb. How to specify routes correctly. Part of the functionality of methodbox is selecting multiple surveys and searching them. I couldn’t get the app to return to the correct route after doing the search. Of course, I had not specified the route correctly. So, if you are returning a collection you need something like this:
map.resources:surveys, :member => {:download => :get}, :collection => {:add_to_pseudo_cart => :get, :data => :get, :datagrid => :get,:hide_info => :get, :more_info => :get, :search_variables => :get,:sort_variables => :get } do |survey|
2. Check box tag. Use check_box_tag to allow you to select multiple objects in the page and send them across inside a hash to the controller.
<%= check_box_tag “entry_ids[]”, item.id,false, :class=>’survey_checkbox’ %>
where item is the object which you want to select or not, false means unchecked when created
3. Selecting, unselecting checkboxes programatically. Lets say you want a gmail style select all, none (and an ‘invert’ selection - ie. select those not selected and vice versa). Use link to function and some javascript like this:
<%= link_to_function ‘All’, “$$(’input.survey_checkbox’).each(function(checkbox) { checkbox.checked = true; });” %>
<%= link_to_function ‘None’, “$$(’input.survey_checkbox’).each(function(checkbox) { checkbox.checked = false; });” %>
<%= link_to_function ‘Invert selection’, “$$(’input.survey_checkbox’).each(function(checkbox) { if (checkbox.checked == true) {checkbox.checked = false;} else {checkbox.checked = true; } });” %>
where ’survey_checkbox’ is the class name of the check_box_tag (see 2 above).
4. XML creation and parsing. Tried the various libraries but found libxml the fastest. I needed to parse some fairly big (1 meg+) xml files which contained the metadata for the surveys we are using. These surveys take the form
<metadata year=“2000″> <variable> <name>difbpc1</name> <description>BP Probs: No problems taking blood pressure</description> <information> <info> <Value>-9</Value> <Label>Refusal (8)</Label> </info><info><Value>-8</Value> <Label>Don’t know (9)</Label> </info></information> <MissingValues>-99 thru -1</MissingValues> </variable> …. …. </metadata>
Here is some sample code to parse (some of) this using libxml (don’t forget your require ‘xml’ bit):
parser = XML::Parser.file(’metadata.xml’)
doc = parser.parse
nodes = doc.find(’//metadata/variable’)
nodes.each do |node|
namenode = node.find(’child::name’)
namecontent = namenode.first.content
variable.name = namecontent
descnode = node.find(’child::description’)
desccontent = descnode.first.content
catnode = node.find(’child::category’)
catcontent = catnode.first.content
dernode = node.find(’child::derivation’)
dercontent = dernode.first
dertype = dercontent.find(’child::type’)
dertypecontent = dertype.first.content
dermethod = dercontent.find(’child::method’)
dermethodcontent = dermethod.first.content
infonode = node.find(’child::information’)
infocontent = infonode.first.content
end
5. gotAPI. I used this online resource ‘a lot’. A superb go to when the books are confusing or hard to navigate.
So, a few things which confused me and one major resource you really need. See you on the Rails.
Your FLEXible friend
For the last 3 months I have been using Adobe FLEX to develop a front end for the Obesity eLab. Now, I don’t want to get into discussions about the rights and wrongs of RIAs etc. but just thought I would pass on a few interesting FLEX/Flash/Actionscript things I have found out during this coding voyage.
- Remember your Cross Domain policy or your client will not be able to talk to your server
- When adding custom MXML modules programatically there is no guarantee that any of the components inside will exist. Can lead to lots of annoying null pointer exceptions. You might have to check that they are not null and create them in actionscript. I have found that doing something with the parent module eg. adding to a tab navigator forced the child components into life. Setting the creationPolicy to ALL seems to have no affect. I look forward to finding out the correct way to do this because I have found little to help on the web.
- When downloading files using FileReference you have to add an event listener to handle the IOErrorEvent.IO_ERROR or else you get a #2038 IO Error
- To add an icon to a button that has been created in ActioScript you have to declare the icon you want to use like this:
- [Embed(source=’/assets/analysis_small.png’)]
[Bindable]
private var analysisImage:Class; - Assign using code: analysisButton.setStyle(”icon”, analysisImage);
- Events seem to pass from child to parent but not the other way. When adding event listeners you need to add them to the level above the originator of the event. Has meant all sorts of weird things like systemManager.addEventListener and Application.application.addEventListener. Now, I might be getting this wrong but no amount of googling has led to a sensible answer.
Overall, FLEX seems great for UIs which are not reacting to data changes but needs a bit of tweeking by Adobe to make it a real power users language of choice. Doing things like grids which react to check box clicks needs quite a bit of code. There also seems to be some fundamental UI components missing eg. dockable drag and drop panels. Sure, there is usually some open source solution available or you can write your own but it would be nice if the core API had these things.
Statistically speaking
We have been investigating data requirements for the Obesity e-Lab project recently. This required some analysis of data created by the stata stats package. However, we had to read it using the R tool instead (firstly because we can then use Taverna workflows to execute R scripts and secondly because Stata is not free). After some head scratching we figured out that you had to use the ‘foreign’ library and the read.dta function. This mean turning on the foreign library in the Package Manager using the R gui first and then executing the following command:
read.dta(”filename”, convert.dates = TRUE, tz = NULL, convert.factors = TRUE, missing.type = FALSE, convert.underscore=TRUE, warn.missing.labels=TRUE)
Remote control debugging
If you are developing in java with eclipse then add this to the start up script of any apps you are developing -Xrunjdwp:transport=dt_socket,suspend=n,server=y,address=8993
You can then connect to them remotely using the Remote Java Application debug configuration in eclipse. You can then use the eclipse debugger to step through any tricky code.
The application will start with “Listening for transport dt_socket at address: 8993″ and you connect to it through this port. Inside eclipse you can add any jars, local projects etc. to the debugger as it steps into new classes and you can then view the code (and the application) as it runs.


