Thursday, September 20, 2007

Processing Dynamic Checkboxes with CF

One of the more common tasks that I deal with is the processing of dynamically created check boxes:

The code below generates a list of checkboxes from a query (they are groups pulled from a Active Directory), if the name of the group is in a list (as in a list of groups that an AD user is a member of) the box is checked.

<cfoutput>
<cfloop query="DirectoryTree">

<!--- SHOW A LIST OF CHECK BOXES FOR EACH GROUP AVAILABLE,
IF THE SELECTED USER IS A MEMBER MARK THAT GROUP AS CHECKED --->
<input type="checkbox" name="#DirectoryTree.Name#"
<cfif listContainsNoCase(MembersList, #DirectoryTree.Name#)>checked</cfif> >
#DirectoryTree.Name#<br />

</cfloop>
</cfoutput>



Simple enough... based on the information in my AD query a list of 150 groups is displayed.

There are a couple of different ways to process these checkboxes, you can
  • Preform another query against the AD (or what ever datasource your using), loop over it and create a series of cfparam tags with the name of the checkbox and a default value of false.
  • Use a hidden form field and pass a list of names and again create a series of cfparams
I'm not a big fan of those, I don't want to do a separate query (code duplication, speed/efficiency, lazy coder syndrome) and I don't want to create a hidden form field (messy code, lazy coder syndrome).

So here is my (usual) solution:

<!--- LOOP OVER ALL OF THE FIELDS FROM THE FORM USING THE FORM.FIELDNAMES LIST
(WHICH PROVIDES A COMPLETE LIST OF ALL THE FIELDS PASSED IN VIA THE
SUBMISSION PAGE MINUS THE 'FIELDNAMES' COLUMN) --->
<cfloop list="#Form.FieldNames#" index="FieldName">

<!--- TAKE A LOOK AT THE VALUE OF THE FORM FIELDS LOOKING FOR A VALUE
OF 'ON'; KEEP IN MIND THAT IF YOU HAVE ANY OTHER FIELDS WHICH PASS
THE SAME VALUE YOU WILL GET FALSE POSITIVES, WHICH CAN BE AVOIDED BY
A LITTLE MORE LOGIC AND GOOD NAMING CONVENTIONS --->
<cfif evaluate("Form.#FieldName#") EQ "on">
<cfoutput>#FieldName# is a checked box!<br /></cfoutput>
</cfif>
</cfloop>



Wow, take out the comments and your down to 5 lines of code which handle all of the work you would have to do for the other solutions.

And YES I know that in general you want to avoid using cfevaluate but running a quick time trial; my code vs. re-querying the AD my code was 50% faster, my code against a simple DB query was still 20% faster...

No comments: