Displaying articles with tag

Blog premier

Posted by fcoury, Fri Feb 06 19:55:00 UTC 2009

Well, I just stumbled upon something that I think is not really a bug, but rather a lack of consistency between some ActionView tag helper API methods.

For instance, let’s say you want to create a form with a radio button:

<%= radio_button_tag "webserver", "apache2.2" %>

And then, in order to create the label for it, you read the documentation:

Creates a radio button; use groups of radio buttons named the same to allow users to select from a group of options.

Hmmm… Nice! Those rails folks are really awesome, they even bothered throwing in some examples:

radio_button_tag 'gender', 'male'
=> <input id="gender_male" name="gender" 
          type="radio" value="male" />

“Got it!”, you think. “It’s just add the name and the value, separated by underscore and we’re good to go!”. Clickety, clickety:

<%= label_tag "webserver\_apache2.2", 
              "Yes, I want this Native American server dude!" %>

Then, really proud of your self you go and pay localhost, port 3000 a visit. Without further delay you go blindly clicking the label.

After a brief pause, you look at your mouse, and wonder: “What the fsck?”.

You just realized clicking on the label didn’t select the radio button as you’d expect. “Okay, that was way too easy indeed, I must have typed something wrong… Yeah, for sure…”.

You go back to your code, check everything’s right, touch absolutely nothing – and you RELOAD!

<philosophical_moment> Yeah, even though you changed nothing on your code, reloading sometimes works as a demonstration of faith on the force up above. I don’t know about you, but sometimes I just reload as if that was a sign I have faith and I deserved working code for that :). </philosophical_moment>

So, after loosing faith on Saint Reload, you start forensics: left click > show me the money code. You chase after that nasty little radio button tag, and stuck inside some unaligned divs, with more classes than a MIT student, you find it:

<input id="webserver_apache22" name="webserver" 
       type="radio" value="apache2.2" />

“Nah, c’mon!”, you think, “How come that motherf little pretty radio button ate my dot?”. It turns out that the radio_button_tag handles the id generation differently from label_tag. Here’s how label_tag sanitizes the id:

def label_tag(name, text = nil, options = {})
    content_tag :label, text || name.to_s.humanize, 
        { "for" => sanitize_to_id(name) }
        .update(options.stringify_keys)
end

And here’s sanitize_to_id:

# see http://www.w3.org/TR/html4/types.html#type-name
def sanitize_to_id(name)
    name.to_s.gsub(']','').gsub(/[^-a-zA-Z0-9:.]/, "_")
end

Finally, if you check how radio_button_tag comes up with its id:

def radio_button_tag(name, value, checked = false, options = {})
    pretty_tag_value = 
        value.to_s.gsub(/\s/, "_").gsub(/(?!-)\W/, "")
            .downcase
    pretty_name = 
        name.to_s.gsub(/\[/, "_").gsub(/\]/, "")
    html_options = {
        "type" => "radio", 
        "name" => name, 
        "id" => "#{pretty_name}_#{pretty_tag_value}", 
        "value" => value }.update(options.stringify_keys)
    html_options["checked"] = "checked" if checked
    tag :input, html_options
end

You’ll realize that the rules are slightly different. As I said: for me it’s more a lack of coherence among those methods than really a bug.

Here’s a live manifestation of the bug I created for helping out:
http://labelbug.felipecoury.com

And the project on GitHub:
http://github.com/fcoury/labelbug/tree/master

So, I was good to point what’s wrong, but unfortunately I am still not that comfortable as to point a solution, so I will leave this one to the experts for now. I’ll just go back to praying that someday Saint Reload guides me through the miracle of self-healing code.

0 comments | Filed Under: Rails | Tags:

Clicky Web Analytics