Using Prototype Javascript to set the value of a radio group

Not that long ago I wrote Using Prototype Javascript to get the value of a radio group, but I keep getting asked how to set the value of a radio group using prototype JS. Here are a couple ways to do just that.

$$("input[type=radio][name='radioGroupName'][value='yourDefaultValue']")[0].writeAttribute("checked", "checked");
$("someRadioGroupMember").writeAttribute("checked", "checked");

Using Prototype Javascript to get the value of a radio group

I am constantly asked how to find the value of the selected radio button in a radio group. The way I usually told people was something like this:

var radioGrp = document['forms']['form_name_or_id']['radio_grp_name'];
for(i=0; i < radioGrp.length; i++){
    if (radioGrp[i].checked == true) {
        var radioValue = radioGrp[i].value;
    }
}

To use it you need a reference to the radio group (not just a single button), which means you need to know the form, and the radio group name. Since I use prototype for almost everything now, I decided to use it to make a simple function for this purpose. First of all, here is the function:

/**
* Returns the value of the selected radio button in the radio group, null if
* none are selected, and false if the button group doesn't exist
*
* @param {radio Object} or {radio id} el
* OR
* @param {form Object} or {form id} el
* @param {radio group name} radioGroup
*/
function $RF(el, radioGroup) {
    if($(el).type && $(el).type.toLowerCase() == 'radio') {
        var radioGroup = $(el).name;
        var el = $(el).form;
    } else if ($(el).tagName.toLowerCase() != 'form') {
        return false;
    }

    var checked = $(el).getInputs('radio', radioGroup).find(
        function(re) {return re.checked;}
    );
    return (checked) ? $F(checked) : null;
}

You can pass it either a form (object or id) and a radio group name, or a radio button (object or id).

var value = $RF('radio_btn_id');
var value = $RF('form_id', 'radio_grp_name');

Hopefully this will help simplify things for someone. Maybe they will eventually add something similar into prototype itself.

Properly degrading JavaScript Effects with Script.aculo.us

I recently decided to use Script.aculo.us in a project that I’m working on. I was actually pretty impressed with it’s cross-browser compatibility and ease of use. I didn’t even think that the 200K size (including the Prototype Framework) was that bad. However, I did run into some issues while trying to make my site function properly for users that have JavaScript disabled, while still allowing the effects for those that do.

In my particular situation, I wanted to make some objects appear with an effect. You will notice that if you apply an Appear effect to an element, it will display, then disappear, the appear with the effect. The solution is to set an inline style with display:none, except that this will cause the element to be missing from users without JavaScript. The solution? Add the display:none style with Javascript.

First, I created a CSS class called effect_appear, with no styles.

.effect_appear {
}

Then I use Javascript to modify that class, and set the display to none.

function getStyleClass (className) {
    if (document.styleSheets.length < 1) {
        return null;
    }
    if (document.styleSheets[0].cssRules) {
        var cssRules = 'cssRules';
    } else {
        var cssRules = 'rules';
    }
    for (var s = 0; s < document.styleSheets.length; s++) {
        for (var r = 0; r < document.styleSheets[s][cssRules].length; r++) {
            if (document.styleSheets[s][cssRules][r].selectorText == '.' + className) {
                return document.styleSheets[s][cssRules][r];
            }
        }
    }
    return null;
}
getStyleClass('effect_appear').style.display = 'none';

Now, any element with that class will display normal to a user without JavaScript support, but will be missing for users with JavaScript. Next I added a ‘load’ event handler to the window element, which will make the elements appear with an effect.

Event.observe(window, 'load', effects);
function effects() {
    document.getElementsByClassName('effect_appear').each(
        function (el) {
            el.visualEffect('Appear');
        }
    );
}

However, there is still one problem. Because the style we created is not inline, it seems to override any effect that we add. The solution is to first remove the classname, and hide() the element (this will remove the class, but keep the element hidden, without the user ever seeing the element). Then we apply the visual effect (in this case, Appear).

Event.observe(window, 'load', effects);
function effects() {
    document.getElementsByClassName('effect_appear').each(
        function (el) {
            el.removeClassName('effect_appear').hide().visualEffect('Appear');
        }
    );
}

Here is the whole thing. Remember, the class “effect_appear” MUST exist in one of your stylesheets, or in a style tag ABOVE this code.

function getStyleClass (className) {
    if (document.styleSheets.length < 1) {
        return null;
    }
    if (document.styleSheets[0].cssRules) {
        var cssRules = 'cssRules';
    } else {
        var cssRules = 'rules';
    }
    for (var s = 0; s < document.styleSheets.length; s++) {
        for (var r = 0; r < document.styleSheets[s][cssRules].length; r++) {
            if (document.styleSheets[s][cssRules][r].selectorText == '.' + className) {
                return document.styleSheets[s][cssRules][r];
            }
        }
    }
    return null;
}
getStyleClass('effect_appear').style.display = 'none';
Event.observe(window, 'load', effects);
function effects() {
    document.getElementsByClassName('effect_appear').each(
        function (el) {
            el.removeClassName('effect_appear').hide().visualEffect('Appear');
        }
    );
}

My Javascript Date Chooser

If you just want the code, feel free to grab the files:

Give it a try:

All it takes to actually USE this, is to add onfocus=”cal.showCal(this);” to any text input like this:
<input name=”demo” type=”text” maxlength=”10″ size=”10″ onfocus=”cal.showCal(this);” />

Stop Censorship