Radio Group On Change

Yesterday radio buttons were the bane of my existence. Trying to accurately observe change in a radio group was somewhere between challenging and [Heisenbergain](http://en.wikipedia.org/wiki/Uncertainty_principle “Werner Heisenberg - Wikipedia, the free encyclopedia”)™. I sometimes thought that looking at what was happening was causing the outcome to change. I am sure all the electron huggers out there will tell me how I am taking Heisenberg’s work lightly, but it is the best explanation I can think of right now.

Instead of complain tirelessly like usual, I decided to write some code. This will most likely become simpler once [prototype 1.6](http://www.prototypejs.org/2007/8/15/prototype-1-6-0-release-candidate “Prototype JavaScript framework: Prototype 1.6.0 release candidate”) is released to the wild. I would simplify it by making my own event, but I still needed to work so I wrote this instead.

Here is the code I came up with to observe a group of radio buttons. It can either take an array or a css selector of radio buttons to observe. It should probably also take a DOM id but since I didn’t need it I didn’t write it. Like most code I write, it is heavily based on prototype.

<code><br />
var RadioGroup = Class.create();<br />
Object.extend(RadioGroup.prototype, {<br />
&nbsp;&nbsp;initialize: function(radioButtons, onChange) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;if(radioButtons instanceof Array) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.radioButtons = radioButtons.collect(function(rb) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return $(rb);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br />
&nbsp;&nbsp;&nbsp;&nbsp;} else {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.radioButtons = $$(radioButtons);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;this.radioButtons.each(function(rb) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rb.observe(&quot;click&quot;,this._click.bindAsEventListener(this));<br />
&nbsp;&nbsp;&nbsp;&nbsp;}.bind(this));<br />
&nbsp;&nbsp;&nbsp;&nbsp;this.selected = this.findSelected();<br />
&nbsp;&nbsp;&nbsp;&nbsp;this.onChange = onChange;<br />
&nbsp;&nbsp;},<br />
&nbsp;&nbsp;_click: function(event) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;var element = Event.element(event);<br />
&nbsp;&nbsp;&nbsp;&nbsp;if(element.checked) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(element != this.selected) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.onChange(element, this.selected);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.selected = element;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;} else {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var currentSelected = this.findSelected();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(currentSelected) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.onChange(currentSelected, this.selected);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.selected = currentSelected;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;},<br />
&nbsp;&nbsp;findSelected: function() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;return this.radioButtons.find(function(rb) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return rb.checked;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}.bind(this));<br />
&nbsp;&nbsp;}<br />
});<br />
&nbsp;<br />
//USAGE<br />
new RadioGroup(&quot;#someForm input[type=radio]&quot;,<br />
function(newlyClicked, previouslyClicked) {<br />
//fire bug logging<br />
console.log(newlyClicked);<br />
console.log(previouslyClicked);<br />
});<br />
&nbsp;<br />
//OR<br />
new RadioGroup($(someForm).getElementsBySelector(&quot;input[type=radio]&quot;),<br />
function(newlyClicked, previouslyClicked) {<br />
//fire bug logging<br />
console.log(newlyClicked);<br />
console.log(previouslyClicked);<br />
});</code>

Basically, you tell it which radio buttons to observe and you tell it which function to call when a change in those radio buttons occurs. Pretty straight forward, but I included the two usages, if you have any improvements please let me know.

Prototype 1.6 == sugar high

I have been bitching for a while about [prototype's](http://www.prototypejs.org/ “Prototype JavaScript framework: Easy Ajax and DOM manipulation for dynamic web applications”) subclassing. Specifically, the inability to call a super version of a method, from a subclass. Well, they decided (after over a year of my complaining) to fix it. And I wouldn’t call it perfect.

The one complaint I have is that if you override a method, your first param needs to be the superclass. That is shitty, it feels kinda like perl or python. Here is there code example:

<code><br />
var Animal = Class.create({<br />
&nbsp;&nbsp;initialize: function(name) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;this.name = name;<br />
&nbsp;&nbsp;},<br />
&nbsp;&nbsp;eat: function() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;return this.say(&quot;Yum!&quot;);<br />
&nbsp;&nbsp;},<br />
&nbsp;&nbsp;say: function(message) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;return this.name + &quot;: &quot; + message;<br />
&nbsp;&nbsp;}<br />
});<br />
&nbsp;<br />
// subclass that augments a method<br />
var Cat = Class.create(Animal, {<br />
&nbsp;&nbsp;eat: function(, food) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;if (food instanceof Mouse) return ();<br />
&nbsp;&nbsp;&nbsp;&nbsp;else return this.say(&quot;Yuk! I only eat mice.&quot;);<br />
&nbsp;&nbsp;}<br />
});<br />
</code>

In the **Cat** class, the **eat** method takes **$super** as the first argument. That is what I would classify as exposing implementation details unnecessary. Usually, I consider functions or variable that start with $ to be global. It would have been far better if **$super** referred to the parent class, but that is just my opinion. Overall, great work on 1.6 and I will have a more definitive review after I use some of the other features.

CSS Versioning with Rails

One trick that all experienced designers rely on, is that the browser will cache css, so that it doesn’t need to be download on subsequent page loads. That is a life saver! On my current work project, the css weighs in at 41k. The downside to that is that sometimes the browser is stupid about caching and won’t redownload even after you have changed your stylesheet.

Here is the trick, put a date at the end of your stylesheet indicating the time you last saved the file. So instead of

<code>&amp;lt;link type=&quot;text/css&quot; rel=&quot;Stylesheet&quot; media=&quot;screen&quot; &amp;raquo; <br />
href=&quot;/stylesheets/main.css&quot;/&amp;gt;</code>

You would have:

<code>&amp;lt;link type=&quot;text/css&quot; rel=&quot;Stylesheet&quot; media=&quot;screen&quot; &amp;raquo; <br />
href=&quot;/stylesheets/main.css?1186435642&quot;/&amp;gt;</code>

Notice the random string of digits in the query string. That represents seconds from the epoch, a common way to represent time for computers.Obviously a human didn’t put those digits there, Rails did it for me. The built in **stylesheet\_link\_tag** helper, automatically adds those digits. As long as your file doesn’t change, the user’s browser shouldn’t download it twice.In my opinion this is the best solution for this problem. It doesn’t create any extra work for developers or designers and it works the same in production as it does in development.

The only time a browser might miss the cache is after a release. Your css file might not have changed but the modified time might be incremented anyway. I think this is a small price to pay for the simplicity of this approach to problem solving.

Rails also provides this for **javascript\_include\_tag** and **image_tag**.

Feeds/Syndication