Blah Blah Woof Woof

Archived content 2005-2007

observe_field for fields modified by javascript

Posted by Tim Riley Mon, 03 Apr 2006 09:17:00 GMT

The Rails PrototypeHelper observe_field is useful for calling JavaScript functions or sending XmlHttpRequests whenever a form field is modified.

For fields like checkboxes or radio buttons that have a limited number of states, it is fine for the observe_field callback to be triggered whenever a mouse click or keyboard event changes this state. On the other hand, for fields like text boxes, it makes more sense to provide a :frequency option to the helper, in which case it will check the field for a changed state at set intervals (a text box that triggered the callback with every letter typed would cause performance issues).

However, you can safely throw this rule out the window if you are using JavaScript to change the state of form fields. In this case, you definitely need to specify a :frequency option:


 <%= observe_field "field_id",
   :url => { :action => "foo" },
   :frequency => 0.25,
   :with => "'value='+ escape(value)" %>

The callback isn’t triggered when a state change is made with a script, but when the observer checks periodically, then the change will in the end be picked up and your callback request or function invoked.

Posted in Geek | 1 comment | no trackbacks

Installing Ruby Gems locally on a shared host

Posted by Tim Riley Tue, 28 Mar 2006 14:06:00 GMT

This took a little bit of fiddling around. On the Dreamhost servers which host my sites, there are many Ruby gems installed, but I wanted to install a couple of extra ones locally that were required by a few specific apps.

You can set $GEM_HOME and $GEM_PATH environment variables in order to customise where the gem command looks for gems. $GEM_HOME is the gem installation directory, where new gems will be installed, and $GEM_PATH is a colon-separated list of places on the system to look for already installed gems.

To install the extra gems locally, I needed to set $GEM_HOME to point to some place within my home directory. However, the gem command expects a sources gem to be installed (which provides a list of remote gem download sources), and it will refuse to find it outside of $GEM_HOME, even if it is installed somewhere in your $GEM_PATH. So, you need to install it locally as well, before installing your extra remote gems.

Here is how I did it:

  • mkdir -p ~/apps/lib/gems/1.8/cache
  • export GEM_HOME=$HOME/apps/lib/gems/1.8
  • export GEM_PATH=/usr/lib/ruby/gems/1.8
  • cp /usr/lib/ruby/gems/1.8/cache/sources-0.0.1.gem ~/apps/lib/gems/1.8/cache
  • gem install sources --local
  • gem install my_new_gem

Next, I need to figure out if there are any tricks required in order for Ruby apps to see and use these additional gems. However, that is for another night!

In other news, Rails 1.1 is out! Check out this post for a good rundown of what is new.

Posted in Geek | 1 comment | no trackbacks

Life imitates web

Posted by Tim Riley Mon, 20 Mar 2006 07:31:00 GMT

UI elements that make a good web experience are not necessarily exclusive to that medium. For example, I think that, just like when you add a comment to a weblog, you should be able to preview any voice message that you leave on someone’s phone before it gets saved permanently.

While it might be perfectly adequate to blunder around in a voice message in the same manner as the one character Hugh Grant has played in all of his films, some of us just don’t have the English accent to pull it off.

Posted in Geek | 4 comments | no trackbacks

Sortable objects in script.aculo.us

Posted by Tim Riley Fri, 17 Mar 2006 05:18:00 GMT

There are some really good pieces of Rails documentation popping up around the place these days, but as helpful as they are, it doesn’t mean you aren’t ever without enough rope to shoot yourself in the foot.

The sortable_element JavaScript helper makes it really simple to use script.aculo.us’ Sortable object to make lists of items that are sortable using drag and drop. However, despite the presence of the Rails helper method, it still pays to take careful note of the script.aculo.us’ API documentation.

In this case, I was wondering why the callback for my sortable list was not being invoked after a drop was completed. I referred to some examples in the above-mentioned Rails books and I didn’t seem to be doing anything different at all. In the end I discovered that a certain format for the id attributes of your sortable elements is necessary for the list to operate properly and the callback to be invoked:


 <ul id="sortable-list">
   <li id="item_1">First Item</li>
   <li id="item_2">Second Item</li>
 </ul>

The id attributes for the list items must contain a string, followed by an underscore, followed by an integer. I had been using an additional underscore in my string, which caused the list to break. This wasn’t mentioned explicitly in any of the books. So, extra research can never hurt you in the end!

Posted in Geek | no comments | no trackbacks

Adelaide GNOME 2.14 Release Party

Posted by Tim Riley Thu, 16 Mar 2006 04:22:00 GMT

Next Monday night some of us will be meeting to drink in the greatest and speediest GNOME release yet! All are welcome; here are the details:

WHEN: Mon 20th March, from 7:00pm

WHERE: Belgian Beer Cafe, off Rundle St

WHO: Adelaide lovers of Free Desktops

See you then!

Posted in Life, Geek | 2 comments | no trackbacks

observe_field and radio buttons

Posted by Tim Riley Tue, 14 Mar 2006 05:20:00 GMT

Without specifying any extra options for Ruby on Rails’ radio_button or radio_button_tag form tag helpers, each tag will share the same id and name attributes.

While the name attribute needs to be shared for a set of radio buttons to work properly, sharing the id attribute is not necessary and will also break the observe_field JavaScript helper. In this case, the field observer will only be triggered for any events in the first of the radio buttons with the specified id.

Fortunately, you can set the id manually:


 <%= radio_button_tag "button_name",
   "button_val",
   checked,
   :id => "my_custom_id" %>

Then, using a separate observer for each radio button in your set with a unique id, you can effectively observe any change in the set. Watch out, radio buttons!

Posted in Geek | no comments | no trackbacks

The plural of cul-de-sac is culs-de-sac

Posted by Tim Riley Mon, 30 Jan 2006 14:16:00 GMT

Tonight I started building a Ruby on Rails technology demo in order to sharpen some of my skills with the framework. Already I have learnt something – while Rails’ conventions are cool and help you write less code, sometimes you need to supplement them. For example, if you want to add an extra singular/plural pair, used for the names of models, controllers (singular) and tables (plural), add something like the following in config/environment.rb (some examples are in there already commented):


 Inflector.inflections do |inflect|
  inflect.irregular 'nudie', 'nudies'
 end

It is the Inflector that handles the magic of pluralisation in Rails. There is some useful info on its wiki page. You can test this pluralisation online.

Also, be sure to quickly peruse the wiki page about magic field names before creating fields in your database tables.

Posted in Geek | no comments | no trackbacks

Conditional periodically_call_remote in Rails

Posted by Tim Riley Tue, 24 Jan 2006 02:53:00 GMT

Loading new sections or pages in a Rails app using AJAX can do a lot to increase overall application snappiness and lengthen the life cycle of each page load, but if any of these pages use the periodically_call_remote helper, then these periodical calls may persist longer than you would like.

The trick to fix this is to note that in the documentation for periodically_call_remote, the options for defining the target URL and callbacks are the same for the link_to_remote helper, which include an option called :condition.

So if you want your periodical calls to cease when different pages in your app are loaded using AJAX, then use the :condition option to have periodically_call_remote check against a variable:


 <%= periodically_call_remote(
   :condition => "check_var == true",
   :update => "my_update_div",
   :frequency => 20,
   :url => { :action => "bar" }) %>

Then in your templates define check_var true or false depending on whether you want the periodical updates to take place:


 <script type="text/javascript">
   //<![CDATA[
     check_var = true;
   //]]>
 </script>

The :condition option can take any sort of JavaScript code, you can be as creative as you like in defining when and under exactly what conditions your periodical calls are made. Take back control!

Posted in Geek | no comments | no trackbacks

Multiple AJAX submit buttons in a Rails form

Posted by Tim Riley Mon, 16 Jan 2006 10:29:00 GMT

In a Ruby on Rails app, if you have multiple submit buttons in a web form, the value of the button pressed is not serialised with the rest of the form and so it won’t be available to the controller in the @params hash. This is a ticket for this in the Rails bug tracking system, where a workaround for the problem is documented:


 <%= hidden_field 'update_button', 'Edit' %>
 <%= submit_tag 'Edit', :name => '_update_button' %>
 <%= submit_tag 'Cancel', :name => '_update_button', 
   :onclick => "Form.getInputs(this.form, null, 'update_button')[0].value = 'Cancel'" %>

A hidden form element (which actually gets serialised) is used to pass the value of the submit buttons to the controller, and the JavaScript code in the onclick event for the second of the buttons above updates the value of the hidden field depending on which button is pressed.

I thought this was a pretty nifty workaround, but in my case, I was submitting a form using AJAX, and my buttons were created using submit_to_remote instead of submit_tag. The problem here was that submit_to_remote does not let you specify an :onclick option, since the method uses the onclick event internally in order to submit the form using JavaScript (see the code for the method in the documentation).

So, in order to have an AJAX-submitted form with multiple submit buttons that actually passes the value of the button clicked to the controller, it was necessary to quickly re-implement submit_to_remote in the view:


 <% hidden_field_tag 'per_page', '20' %>
 <% [ '20', '40', '60' ].each do |num| %>

   <% remote_options = {
     :update => "dock",
     :loading => "showLoading();",
     :complete => "hideLoading();",
     :with => "Form.serialize(this.form)",
     :url => { :action => "query" } } %>
   <%= tag("input", {
     :type => "button",
     :onclick => "Form.getInputs(this.form, null, 'per_page')[0].value = '#{num}'; #{remote_function(remote_options)}; return false;",
     :name => "show_num",
     :value => "Show #{num}" },
  false) %>

 <% end %>

This way, you can specify the script to update your hidden variable before including the script that was part of submit_to_remote that is used to submit the form.

Using the example above, you now you can refer to @params[:per_page] in order to get the value of the button that was clicked to submit the form.

The whole reason I had to head down this path was in order to work around a silly rendering bug in Internet Explorer that was causing problems for the NetFox administration interface. In the end, we decided that this particular workaround was suboptimal and chose a different solution altogether. Is it any coincidence that my left eye has started to twitch uncontrollably since I started having to fix bugs caused by IE?

Posted in Geek | 1 comment | no trackbacks

Music to hack to

Posted by Tim Riley Sat, 07 Jan 2006 23:20:00 GMT

Matt Palmer asks what music people like to listen to when coding. My preference is to listen so a good seamless mix of electronic music, usually driving and upbeat.

The Cloud Factory Collective’s web site is a great place to get music to hack by. Some choice mixes:

My friend Adam Bellinson has recently started DJing drum & bass mixes on Linux using the open source tool Mixxx. I have been enjoying his work a lot too. The mixes can be downloaded from his torrents page.

One track I acquired recently with an iTMS voucher I got for Christmas is the Back to the Future overture from the soundtrack of the first film. Although it is only 8 minutes in length, I have found this to be very enjoyable to have playing especially when overcoming big bugs or problems in code, because the emotion that is conveyed in the piece makes me feel like I am a hero like Marty McFly saving the fabric of space and time :-)

Posted in Geek, Music | no comments

Older posts: 1 2 3 4