How to Dynamically Check a Radio Button (and Checkbox) in ColdFusion

Although this may seem to be a simple task, dynamically checking a radio button in ColdFusion is not always as easy as dynamically checking a checkbox in ColdFusion. It's definitely not difficult either. I just thought it might be worth a mention here.

Let's first look at how to dynamically check a checkbox in ColdFusion.

Checkboxes are cool. You see them everywhere in forms throughout the web. And, let's face it, they're extremely easy to use. When used in conjunction with XHTML labels, they're even easier to use for visitors. For example, if you have a label next to a checkbox input, you can wrap the label with a "label tag" which then makes the label itself "clickable." Simply match the label tag with the checkbox input tag name. Here's an example:


<cfform action="javascript:void();"
        method="post"
        name="form1"
        id="form1">


    <div class="formItem">
        <cfinput     type="checkbox"
                    name="ckAgree"
                    id="ckAgree"
                    value="1" />

        <label for="ckAgree">I agree</label>
    </div>

    <div class="formSubmit">
        <cfinput     type="submit"
                    name="submit"
                    label="Submit"
                    value="Submit"
                    validate="submitonce"
                    onkeyup="javascript:alert('Submitted!');"
                    onclick="javascript:alert('Submitted!');" />

    </div>

</cfform>

For me, the most common use of a checkbox input is in back-end admin areas to determine whether or not a particular record is active or not. This only requires me to have an "IsActive" field for the record in the database table with a boolean type (yes or no, true or false, 0 or 1). I usually set the default value to true so that when a record is added to the database, it automatically becomes "active" on the back-end. When a back-end user attempts to update the "active" record, they will (or should) see a "checked" checkbox with an "Is Active" label next to it. Once the back-end user no longer needs the record to be active, they simply un-check the "Is Active" checkbox and click submit.

Now that the item has been archived, when the back-end user attempts to update the record again, the "Is Active" checkbox shouldn't be "checked" now, should it? So, how do I dynamically check the checkbox?

Since I'm updating a database record, I'll need a query to get the current values of the records' fields. So we'll want to make sure the query contains the "IsActive" field. Assuming it does, just call the query and set the checked value to the query's "IsActive" value. Like so:


<!--- get details for the current record --->
<cfinvoke     component="extensions.components.myqueries"
            method="getQueryDetails"
            returnvariable="returnQueryDetails">

<cfif isDefined("URL.id") AND isNumeric(val(URL.id))>
        <cfinvokeargument name="id" value="#val(URL.id)#" />
</cfif>
</cfinvoke>

<cfif returnQueryDetails.recordcount EQ 1>

    <cfform action="#CGI.script_name#?#CGI.query_string#"
            method="post"
            name="form1"
            id="form1">

    
        <div class="formItem">
            <!--- dynamically check the checkbox --->
            <cfinput     type="checkbox"
                        name="ckIsActive"
                        id="ckIsActive"
                        value="1"
                        checked="#returnQueryDetails.IsActive#" />

            <label for="ckIsActive">Is Active</label>
        </div>
    
        <div class="formSubmit">
            <cfinput     type="submit"
                        name="submit"
                        label="Submit"
                        value="Submit"
                        validate="submitonce"
                        onkeyup="javascript:alert('Submitted!');"
                        onclick="javascript:alert('Submitted!');" />

        </div>
    
    </cfform>

    <cfelse>
    <p>Sorry, the selected record is no longer available.</p>
</cfif>

In the update query, to capture the new value, I use something similar to the following:


<!--- IsActive --->
, IsActive=<cfif IsDefined("FORM.isActive") AND isBoolean(FORM.isActive)>
<cfqueryparam value="#FORM.isActive#" cfsqltype="cf_sql_bit" />
<cfelse><cfqueryparam value="0" cfsqltype="cf_sql_bit" /></cfif>

If you're not using a query, the following code might also be helpful in dynamically checking a checkbox:


<!--- scope var --->
<cfparam name="isActive" default="0" type="boolean" />

<!--- set the current value of the variable --->
<cfset isActive = 1 />

<cfinput     type="checkbox"
            name="IsActive"
            value="1"
            checked="#IsActive#" />

Another reason for showing the code above is because it's similar to how I'll be dynamically checking a radio button. The previous code snippet should be easy enough to follow. We're simply setting the value of the variable "isActive" to equal true. Then, the checkbox input's "checked" state is set to be dependent upon the "isActive" variable. I guess it's easier to read the code than it is to articulate the meaning, eh?

So, as you may already know, radio buttons are used when you want to offer one, and only one, option from a list of options. We keep the list of options tied together with the "name" attribute. The "name" attribute simply groups the options together, so that of all options sharing the same "name," only one is actually selected. There are two differentiating attributes, one of which is obviously the "value" which is needed for passing to the database, etc. The other differentiating attribute is the "id." I use the "id" attribute to tie to the label tag. For usability, you should also use the "label" tag which will also allow the user to simply click the option label to select the desired radio button.

Let's assume you have two queries to work with. One contains the list of possible options for the radio buttons. The other query pulls the existing values for the specified record. The idea here is that we'll output all possible options for the radio button, then check to see if our current record has selected the option being looped over. If so, then "check" it. If not, don't. Simple enough, eh? Let's take a look at the code I've come up:


<!--- get details for the current record --->
<cfinvoke     component="extensions.components.myqueries"
            method="getQueryDetails"
            returnvariable="returnQueryDetails">

<cfif isDefined("URL.id") AND isNumeric(val(URL.id))>
            <cfinvokeargument name="id" value="#val(URL.id)#" />
</cfif>
</cfinvoke>

<!--- get options for radio buttons --->
<cfinvoke     component="extensions.components.myqueries"
            method="getRadioButtonOptions"
            returnvariable="returnRadioButtonOptions" />


<!--- scope var --->
<cfparam name="IsChecked" default="0" type="boolean" />

<cfif returnQueryDetails.recordcount EQ 1>

    <cfform action="#CGI.script_name#?#CGI.query_string#"
            method="post"
            name="form1"
            id="form1">


        <cfoutput query="returnRadioButtonOptions">

            <!---
                This should be self-explanatory, but just in case, this is where we
                set the current value of the isChecked variable based on whether or
                not the currently outputted query item matches the value of the
                currently selected record.
            --->

            <cfif returnQueryDetails.OptionID EQ returnRadioButtonOptions.OptionID>
                <cfset isChecked = 1 />
                <cfelse>
                <cfset isChecked = 0 />
            </cfif>

            <div class="formItem">
                <cfinput     type="radio"
                            name="OptionID"
                            id="Choice#OptionID#"
                            value="#OptionID#"
                            required="yes"
                            message="Please select a radio button."
                            checked="#isChecked#" />

                <!--- usability: if user clicks the title, the option should also be selected --->
                <label for="Choice#OptionID#">#htmleditformat(OptionTitle)#</label>
            </div>

            <div class="formSubmit">
                <cfinput     type="submit"
                            name="submit"
                            label="Submit"
                            value="Submit"
                            validate="submitonce"
                            onkeyup="javascript:alert('Submitted!');"
                            onclick="javascript:alert('Submitted!');" />

            </div>

        </cfoutput>

    </cfform>
    
    <cfelse>
    <p>Sorry, the selected record is no longer available.</p>
</cfif>

That's pretty much it folks. If you have a different way to handle this, please feel free to share. Hope this helps!

To learn more about the CFInput tag, visit http://cfquickdocs.com/cf8/?getDoc=cfinput#cfinput

Comments

Thanks for the ideas. I was struggling with the dynamic pre-populating of cfinput/radio field.
# Posted By Kelly | 12/9/08 9:15 AM
@Kelly,
You are most welcome.
# Posted By Stephen Withington | 12/10/08 10:04 PM
+1 on the radio button, thanks!
# Posted By Andrew | 7/17/09 12:54 PM

© 2024, Stephen J. Withington, Jr.  |  Hosted by Hostek.com

Creative Commons License   |   This work is licensed under a Creative Commons Attribution 3.0 Unported License.