Refactoring: avoiding nested conditional statements

Recently at I was given the task of adding an new validation routine to an existing validation process.  In this piece of code, the requirements mandated that a series of sequential tests would be run, but in the event of a failure of any of them, the process would kick out and set an error state, provide user feedback, and whatever other tasks needed to occur.  We have all seen processes like this before.  Essentially it looked like this:

error = true;
if ( testOne() )  {
    if ( testTwo() ) {
        if ( testThree() ) {
            if (testFour() )  {
                 error = false;
                 doAllTestsPassedStuff()
            } 
        }
    }
}
if ( error ) {
	handleErrorCondition()
}

Looking at this block of code, the intent is pretty obvious as we progressively run tests as long as the previous test returned true, eventually firing the doAllTestsPassedStuff() method.  If any of the tests failed, we would call handleErrorCondition().  While this approach is completely functional, the maintainability of it is no fun, and it just feels wrong to me.  For the task I was given, I had to add a new test davesSuperTest()  between the 2nd and 3rd conditional blocks.   If I were to follow the previous approach, I would insert it there, and tab out the previous testThree() and testFour() conditional statements further to the right.  In my opinion this is an ugly block that is getting uglier by the minute.

By altering the approach to use try/catch blocks, we can still maintain the same level of control and order or operations as dictated in the requirements, but each condition becomes insulated from the others,  like this:

try {
	if ( !testOne() )	{
		throw "fail:testOne";
	}
	if ( !testTwo() )	{
		throw "fail:testTwo";
	}
	if ( !davesSuperTest() )	{
		throw "fail:davesSuperTest";
	}
	if ( !testThree() )	{
		throw "fail:testThree";
	}
	if ( !testFour() )	{
		throw "fail:testFour";
	}
	// if we reach this point, then all of the above tests passed.
	 doAllTestsPassedStuff()
}	
catch(e)	{
	handleErrorCondition()
}

Given this approach, it is very simple to add/remove conditions without disrupting other conditions, even better, I don’t have to scroll to my second monitor on the right!

Related checkbox validation with JQuery

I was given a problem yesterday where I needed to do the following client-side validation. If a user selects a checkbox that they wish to enable credit card transactions, I need to display a panel of specific credit card companies and they need to select at least one before submitting.

If you think about writing the JS to do this without a library it is a somewhat lengthy task. In essence, you would need to do some type of an onsubmit function on your form, check the value of the key checkbox. If it was checked, check the value of each credit card checkbox to see if the user had selected one of the children. After writing this in JQuery, I thought it might be worth demonstrating what an easy task this is.

Let’s start with the specific part of my form that has my checkboxes:

<label for="RequireCCInfo">Require Credit Card Information?</label>
<input name="RequireCCInfo" id="RequireCCInfo" value="1" type="checkbox">
<div id="CreditCardCompanyPanel">
	<div>
		<input id="ccAmex" value="1" type="checkbox">
		<label for="ccAmex">American Express</label>
	</div>
	<div>
		<input id="ccVisa" value="1" type="checkbox">
		<label for="ccVisa">Visa</label>
	</div>
	<div>
		<input id="ccDiscover" value="1" type="checkbox">
		<label for="ccDiscover">Discover</label>
	</div>
	<div>
		<input id="ccMc" value="1" type="checkbox">
		<label for="ccMc">Master Card</label>
	</div>
</div>

There is nothing too notable in all of that other than the fact that you should notice that I have added a class “ccCheckBox” to all of my dependent checkboxes. I will explain more on that in a bit, but I wanted to point out that it is there. You will also notice that I am not doing anything in the way of hiding the “CreditCardCompanyPanel” div. We need to determine at request time whether that will be hidden or not based on whether the “RequireCCInfo” checkbox is checked.

Now, here is the fun part… I am including the JS that I use for this task below:

<script language="javascript">
(document).ready(function(){
	$("#RequireCCInfo").change(function(){
		toggleCreditCardCompanyPanel();
	});
	function toggleCreditCardCompanyPanel()	{
		if ($("#RequireCCInfo").attr("checked") == true) 	$("#CreditCardCompanyPanel").show();
		else $("#CreditCardCompanyPanel").hide();
	}
	$("#SaveButton").click(function(){
		var pass = false;
		if ($("#RequireCCInfo").attr("checked") == true){
			$(".ccCheckBox").each(function() {
               			if ($(this).attr("checked") == true) pass = true;
            		});
		}
		else pass = true;
		if (pass) $("#frmMyForm").submit();
		else alert('You must select at least on credit card company if "Require Credit Card Information" is checked.');
	});
	toggleCreditCardCompanyPanel();
});
</script>

First, by using the $(document).ready() function we are telling JQuery to run this JS once the DOM has been completely loaded. Let’s look at each section within that ready() block…

The first thing you will see is the $(“#RequireCCInfo”).change() method. JQuery gives us the concept of binding a listener to an element. For our example, this listener says that anytime that an element with an ID of “RequireCCInfo” is changed, that we will run the code in its function(). You will see that anytime our “RequireCCInfo” checkbox is changed we are going to run a function called toggleCreditCardCompanyPanel(). As you can see we have that method defined immediately after our “RequireCCInfo” checkbox.

In our toggleCreditCardCompanyPanel() method, we are making the decision as to whether or not our “CreditCardCompanyPanel” will be displayed based on whether our user has decided to check the box labeled “Require Credit Card Information?”. By using the JQuery selectors we are in essence saying: If a checkbox with an ID of “RequireCCInfo” is checked, display an element with the ID “CreditCardCompanyPanel”. Otherwise we will hide this element.

Next comes our validation on form submit… and pretty cool stuff!

Basically I have added a listener which is bound to our submit button with the ID of “SaveButton” which will submit our form “frmMyForm”. Anytime that this button is clicked, we will run the code in the function() block. We start this function by setting a value pass=false. We will use this variable to determine whether our form has passed validation. Next we get just a small taste of the magic of JQuery selectors. First, as we did in the toggleCreditCardCompanyPanel() function, we are determining if the element with the ID of “RequireCCInfo” is checked. If so, by using the each() function, we are going to loop through all elements on the page with the class “ccCheckBox” (remember that from above?). In each iteration of the loop we are going to determine if the element has been checked. If so, we are going to set pass=true since we know that our validation has passed.

Lastly, now that we have determined that our form is either going to pass/fail, we take the appropriate action. If pass==fail, we are simply going to alert a message telling the user that if they are going to enable credit cards that they have to choose at least one credit card company. Otherwise, we are going to call the submit() method on our form.

I almost took the time to write out the equivalent of this in POJS (plain old JavaScript) to show how much easier life is with JQuery, but I realized I didn’t have the time, patience, or will. JQuery has spoiled me!

slick little multi-file upload tool

I recently had a need to allow users to upload multiple files at the same time.  I came across a cool little script that I used that allows users to append multiple files that works much in the vein of Gmail’s attachment utility using a single file input element.   It was a breeze to implement and was a big time saver over reinventing the wheel.

60 More Ajax Tutorials

As I was searching for an Ajax example of how to accomplish a task that I am working on, I came across a posting by Max Kiesler entitled 60 More Ajax Tutorials, which is apparently a follow-up to an earlier post Round-up of 30 Ajax Tutorials.  In just a cursory browsing over the lists, there appear to be a ton of good examples there, although unfortunately not the scrolling paginated recordset example I need!

Just in case you were all caught up… AFLAX!

This was sent to me by fellow DFWCFUGger Ryan Everhart.   As if my head was not already spinning from Flash remoting, Flex, AJAX…. introduce yourself to AFLAX!  I know nothing more about it than its definition:

“AFLAX is a method through which developers may use JavaScript and Flash together to create AJAX-type applications, but with a much richer set of vector drawing controls than are available in either Internet Explorer or FireFox. Developers using this library have access to the full range of Flash features, but without ever touching the Flash IDE.”

Sounds awesome, but where oh where can I find the time!

… is it just me or do I hear a duck quacking?

Problem: Javascript single quotes from CF variable

On the DFWCFUG list someone asked if anyone had a solution regarding a problem with passing a ColdFusion variable into an agument of a Javascript call when single quotes might exist in the variable, causing the function call to barf.

Someone suggested replacing all single quotes with double quotes.  This however might not be optimal if you are dealing with someone’s name like Conan O”Brian, of if the text was Don”t do this.   I suggested doing the following to avoid this problem.  Assume the following code:

<cfoutput>
onclick=”doIt(‘#ourColdFusionString#’);”
</cfoutput>

If you wanted to make that same function call safe from single quotes, you could do this:

<cfoutput> onclick=”doIt(‘#replace(ourColdFusionString,”‘”,”‘”,”all”)#’);” </cfoutput>

Of course in most cases, it would make more sense to create a user defined function to manage this so you don’t have to continually type the same replace code. Additionally, it would easily allow you to change the rules for what might be safe for your Javascript function.

Adding field focus to every form on your site

Someone on an email list I follow posted up question asking for ideas on a good way to make every form in their application display with the focus set to the first field.  He had hit a bump since he was working in fusebox and needed this to work using a common header file.  My suggestion was that he use an onload event that checks to see if there is a form on the page, and if there is a form, focus() the first element.  I thought this might be a nice snippit to hold onto and share.

<script>
function setFocus() {
if ( typeof ( document.forms[0] ) != “undefined” ) {
document.forms[0].elements[0].focus();
}
}
</script>

<body onload=”setFocus()”>