Conway’s Game of Life in Angular.js

I know there are a lot of posts for Angular, so I will spare everyone a rehash of setup and Hello World. Instead, I thought it would be fun to show a simple example of Angular recreating Conway’s Game of Life.

This example will use the following technologies:

  • HTML
  • CSS
  • Angular.js
  • Bootstrap

If you would like to see a sample of the working application, click here: http://www.nicholasbarger.com/demos/conways-game-of-life.

What is Conway’s Game of Life

Check out Wikipedia: http://en.wikipedia.org/wiki/Conway%27s_Game_of_Lifefor a more in depth definition and origin of the game, but in short, it’s a simulation that allows you to observe evolutions based on an initial starting configuration while applying the following four basic rules at each round:

  1. Any live cell with fewer than two live neighbors dies, as if caused by under-population.
  2. Any live cell with two or three live neighbors lives on to the next generation.
  3. Any live cell with more than three live neighbors dies, as if by overcrowding.
  4. Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction.

The game can continue indefinitely resulting in either a repeating pattern or a “still life” where no more moves can occur.

Since this article is more about Angular, I’ve simplified the game a bit as well to randomly select the starting positions and limited the board to 30 by 30 cells, but feel free to improve the code to allow the gamer to specify starting positions or infinite space. All source code can be found here: https://github.com/nicholasbarger/conways-game-of-life.

Let’s set up the UI

To start, let’s set up a form and board to play on. The form is pretty straightforward and allows you to specify the number of starting life forms, how many generations to simulate and finally, a button to start the game.


            Enter the number of spontaneous lifeforms:
            
            Enter the number of generations to simulate:
            
            Start

Notice, that we’re using a few Angular tags to collect the data and fire off the game.

First, the data to interact with is wrapped with a div that specifies an ng-controllerattribute. This attribute is used to specify what controller will be used to execute logic against the HTML DOM elements. It is common to place this controller logic in another Javascript file.

Next, ng-submitis used to specify what function will be called on the controller when the form is submitted. When we wire up the controller, this is the method that will start iterating over generations in the game.

Finally, ng-modelis used to bind data values from the input form fields into variables that can be accessed in the controller. When the values on the form are changed, the variables backing them are automatically notified of the change and updated.

Now that we have a form created to gather some basic information about starting the game, let’s create the board that the game will actually play on.

<strong ng-show="rows.length > 0">Generation </strong>
        <table id="board" class="table table-bordered">
            <tr ng-repeat="row in rows">
                <td ng-repeat="cell in row">
                    <i class="glyphicon glyphicon-fire" ng-show="cell.isAlive == true"></i>
                    
                </td>
            </tr>
        </table>

In this code snippet, we see a few new Angular components used for controlling presentation of data.

First, ng-showallows us to toggle the visibility of DOM elements by evaluating a true/false statement. Essentially, when the expression is true, we’re setting a CSS style “display: block”, and when false, setting “display: none”.

Next, we get our first look at the mustache-inspired template rendering (http://mustache.github.io) used by Angular. Notice the double curly braces surrounding the variable name in . This allows rendering of this variable and is automatically updated whenever the value of the variable changes.

The Angular control we have not yet covered is ng-repeatand is used when building out the table as we create rows and cells based on the number of items in the “rows” variable. This simply iterates over the collection and continues to generate the content where the attribute is specified and all information that is a child within it.

Finally, we revisit the ng-show attribute to show a small icon in the cell based on whether it is alive or dead. The “== true” is a bit redundant (and admittedly, should be “===” if used anyway to strictly check the value).

Wire up the Controller to Play

The controller is just a function that sets up all of the code to interact with the UI and exposes the necessary variables through a special parameter called $scope. You can read quite a bit more on $scope through the Angular documentation https://docs.angularjs.org/guide/scopebut for simplicity, it’s a way to expose variables to binding in the UI.

If the UI is going to use a variable or call a function, it must be attached to $scope through the following syntax:

$scope.myVariable = ‘Some value’;
$scope.myFunction = function(param1, param2) { return param1 + param2; };

For brevity sake, I will just link to the file hosted on Github since its code is not truly Angular specific and mostly controls running the game. I’ve attempted to comment the rules fairly well so it is evident what is happening in each “generation” of the game. https://github.com/nicholasbarger/conways-game-of-life/blob/master/game.html

Take Away

At my company, we’ve adopted Angular to use every day in production development and haven’t looked back. The benefits of creating a single page applications (SPA) which limits full trips back and forth on the server has allowed us to provide a more native experience over the web while reducing our server load by pushing some of the processing back onto the client.

The example shown in this article is by no means production code and is structured all in one file, which is usually not appropriate for production use. Enterprise level applications need to fully utilize separation into various modules that are comprised of controllers, views, partials, directives, services, and so on.

I’ve learned to stop promising future blog posts since I tend to write in short waves and then neglect my blog for months at a time; however, I think it would be great to write several posts on architecting large Angular web applications and some of the challenges we have faced. Stay tuned (but don’t hold your breath)!

Learning Knockout JS – Crazy Mom Baby Tracker Demo

I’m thrilled to be able to report my wife and I had our second daughter on May 8th, 2012. Vanessa was 7 pounds even and very healthy. Due to the birth, I took a few days off of work to help out (in many ways, I think I was more work for my wife being home). Most of my time has been spent getting acquainted with my new daughter, but occasionally, I’ve grabbed an hour here and there, usually in the middle of the night after a feeding, to read about knockout and even write a small demo as a learning exercise.

This little app is not meant to serve any commercial value and is very simplistic, but given the current situation I felt it was a fun and fitting topic.

To any mom’s out there, I mean the title to be lighthearted – no offense intended!

Ok, on with the article.

Knockout Demo Screenshot

What’s It Made Out Of?

The Crazy Mom Baby Tracker is intended to exercise the following technologies:

At the Southwest Florida .NET User Group, we recently had a Battle of the UI Frameworks which highlighted a general movement towards JavaScript-centric applications in the .net community. I thought we were aggressive at work, perhaps even cutting edge, but alas – it turns out we’re about where everyone else appears to be right now.

HTML5 is, of course, the latest version of HTML (at the time of this blog post) and all the rage. Though I will display HTML5 semantics, there are not any earth shattering HTML5 snippets throughout this demo.

jQuery is found throughout, as it has become the de facto standard for working with JavaScript these days.

Bootstrap was shown to me by our non-.NET marketing development team and it has been a nice addition for standardizing the HTML structure, CSS (or LESS) classes, and general user experience.

Knockout is very recent for me and the main purpose of this educational demo. It is a responsive MVVM JavaScript implementation that binds the UI to the underlying view model.

jqPlot is a jQuery charting library that I added into the project to visualize the data more interestingly.

A Little Prep Work Before We Get Building

This application is pure HTML, CSS, and JavaScript. As such, there is no need for the .net framework or Visual Studio. However, it certainly is a nice IDE to work in and by using the Nuget Package Manager you can get up and running very quickly. Therefore, all screenshots will be provided using Visual Studio, but this is not a requirement and you can ignore these references if you like.

First, let’s create a new Web Site. In Visual Studio, click File > New Website. Then under the template selector, choose ASP.NET Empty Web Site. By selecting this, you get a pretty bare web site that does not need to contain any ASP-related tags or code. After selecting an appropriate location to store the files you should be ready to begin.

Next, right click the project and select Manage Nuget Packages. You will want the following packages: jQuery, Bootstrap from Twitter, Knockout JS, and jqPlot.

Nuget Packages

Let’s also add a few placeholder files that we’ll work with later. Please create the following:

  • /Content/my.css
  • /Scripts/my.js
  • /index.html

Let’s Start Building

At this point, everything should be ready for us to start getting to the good stuff. Let’s open the index.html (our main application page) and add the css references for the selected Nuget packages, as well as our custom css file.

<head>
    <title>Crazy Mom Demo</title>
    <link rel="stylesheet" type="text/css" href="Content/bootstrap.min.css" />
    <link rel="stylesheet" type="text/css" href="Content/bootstrap-responsive.min.css" />
    <link rel="stylesheet" type="text/css" href="Scripts/jqPlot/jquery.jqplot.min.css" />
    <link rel="stylesheet" type="text/css" href="Content/my.css" />
</head>

Next, let’s add our script tags to bring in the code for the Nuget packages, and our own placeholder js file which we will use to add all of our custom logic to drive the application.

<body>
    <script type="text/javascript" src="Scripts/jquery-1.7.2.min.js"></script>
    <script type="text/javascript" src="Scripts/bootstrap.min.js"></script>
    <script type="text/javascript" src="Scripts/knockout-2.1.0.js"></script>
    <script type="text/javascript" src="Scripts/jqPlot/jquery.jqplot.min.js"></script>
    <script type="text/javascript" src="Scripts/my.js"></script>
</body>

Now that the references are in place, we need to build the structure of the html. Since we’re using bootstrap, we’re going to use the fixed grid layout they provide (hence the css classes “row” and “spanX”). The basics are below.

<div class="container">
	<h1 data-bind="text: title">Title</h1>
	<div class="row">
		<!—-panel for data entry -->
		<div class="span8">
                
		</div>

		<!—-panel for my cute kids picture -->
		<div class="span4">
			<!-—we won’t cover adding this in the blog post -->
		</div>
	</div>
</div>

We need a container wrapping the layout, and a few other layout related div’s to format the page. Notice the h1 tag which has our first knockout data-bind attribute. This is going to look for a property on the viewmodel called “title” and bind the innerText to it’s value.

Next, inside the data entry panel, let’s add two textboxes and a pair of buttons to control adding baby weight entries.

<form class="form-inline well" data-bind="submit: addItem">
	<h3>Enter the babies weight below</h3>
	
	<label>Pounds</label>
	<input id="pounds" type="text" class="input-mini" data-bind="hasfocus: true" />

	<label>Remaining ounces</label>
	<input id="ounces" type="text" class="input-mini" />

	<button type="submit" class="btn btn-primary"><i class="icon-ok icon-white"></i> Add Baby Weight</button>
	<button type="reset" class="btn btn-danger" data-bind="click: clearItems"><i class="icon-remove icon-white"></i> Start Over</button>
</form>

The css classes for the form are also from bootstrap and help to stylize the form. You can view the bootstrap documentation for more details.

The form has a knockout binding for submit to call the function on the viewmodel “addItem”. There is also a binding for the click event of the reset button to clear all data in the viewmodel (not just the form fields as normal).

Directly below the form, let’s add a section for displaying notifications and data validation. We’ll again use knockout to bind the results of the messages based on what is happening in the viewmodel.

<div id="alert" class="alert" 
	data-bind="
		visible: msg().length > 0, 
		css: { 
			'alert-success': msgType() == 'success', 
			'alert-error': msgType() == 'error', 
			'alert-info': msgType() == 'info' }"<
                    
	<a class="close" href="#" data-bind="click: hideAlert">×</a>
	<p data-bind="text: msg"></p>
</div>

Let’s now add the final pieces to allow for a bit of data visualization. We’re going to use a chart control from jqPlot and a table displaying the individual entries.

<div id="resultsChart" data-bind="chart: items()"></div>

<table class="table table-striped" data-bind="visible: items().length > 0">
	<thead>
		<tr>
			<td>Weight</td>
			<td>Total Pounds</td>
			<td>Total Ounces</td>
		</tr>
	</thead>
	<tbody data-bind="foreach: items">
		<tr>
			<td data-bind="text: display()"></td>
			<td data-bind="text: totalPounds()"></td>
			<td data-bind="text: totalOunces()"></td>
			<td><a href="#" data-bind="click: $parent.removeItem"><i class="icon-remove"></i></a></td>
		</tr>
	</tbody>
</table>

The chart is interesting, as it will be a custom binding we create for knockout to work with jqPlot. Data within the table are bound to an array of items and looped through using the foreach knockout binding. I’ve also added a remove button next to each entry to allow for the removal of entries added by mistake. Notice the scoping when specifying the knockout binding; while looping through the items, we’re at the individual item level – therefore, we must move up one level to access the viewmodel directly ($parent) and call the removeItem function.

jqPlot Chart Screenshot

Wiring Up the Logic with Knockout and jQuery

Now that we have a clear picture of what we want this application to look like, let’s wire up the viewmodel and make it actually perform.

Open up your my.js file and begin by creating a good old jQuery ready event:

$(function () {
});

We’ll put our code in here. Let’s also create our own namespace with the following code to avoid any collisions.

// global namespace
var my = my || {};

We now need a model to structure the baby weight entries. Let’s create it as follows:

// models
my.BabyWeight = function(pounds, ounces) {
	var self = this;

	self.pounds = pounds;
	self.remainingOunces = ounces;

	self.totalOunces = function () {
		return (self.pounds * 16) + (self.remainingOunces * 1);
	};
	self.totalPounds = function () {
		return (self.pounds * 1) + (self.remainingOunces / 16);
	};
	self.display = function () {
		return self.pounds + 'lbs - ' + self.remainingOunces + 'oz';
	};
};

This could contain knockout observables and computed values, but it’s not particularly necessary the way the demo is set up. The BabyWeight model has two properties: pounds and remainingOunces which together make up for the entire weight of the baby. I’ve also added a few calculated properties to add to the tabular data for each entry.

Let’s now create the viewmodel which will contain the bulk of our knockout observables.

// view model
my.vm = function(existingItems) {
	var self = this;

	// properties
	self.items = ko.observableArray(existingItems);
	self.msg = ko.observable("");
	self.msgType = ko.observable("info");
	self.title = ko.observable("Crazy Mom Baby Tracker v.001");

	// methods
	self.addItem = function () {
		var pounds = $('#pounds').val();
		var remainingOunces = $('#ounces').val();
		var itemToAdd = new my.BabyWeight(pounds, remainingOunces);
		
		// validate
		if (itemToAdd.pounds == "" || itemToAdd.ounces == "") {
			self.msgType("error");
			self.msg("Oops, either the baby has become weightless or you didn't enter any data.");
			return;
		}
		else {
			self.msg("");
		}

		// add to items array
		self.items.push(itemToAdd);

		// update msg
		self.msgType("success");
		self.msg("You've successfully weighed the baby in at " + itemToAdd.display());
	},
	self.clearItems = function () {

		// clear items
		self.items([]);

		// update msg
		self.msgType("info");
		self.msg("All weight entries have been cleared.");
	},
	self.hideAlert = function () {
		self.msg("");  //clearing the message will auto-hide since it's bound
	},
	self.removeItem = function (item) {

		// remove item from items array
		self.items.remove(item);

		// update msg
		self.msgType("info");
		self.msg("The weight entry has been successfully removed.");
	}
};    

Note the use of this line:

var self = this;

This helps to maintain reference to the proper this when inside callbacks from anonymous functions.

The observables ensure that changes to their values will be automatically reflected in the UI for any bindings. For example, as an item is added or removed from the items array, the UI for the chart and table will automatically be updated, well as soon as we add the custom binding to the chart that is. Let’s add that now:

// kick off knockout bindings
ko.applyBindings(new my.vm([]));
    
// add custom binding for charting
ko.bindingHandlers.chart = {
	init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
		// empty - left as placeholder if needed later
	},
	update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
		// prepare chart values
		var items = ko.utils.unwrapObservable(valueAccessor);
		var chartValues = [[]];
		for (var i = 0; i < items().length; i++) {
			chartValues[0].push(items()[i].totalOunces());
		}

		// clear previous chart
		$(element).html("");

		// plot chart
		$.jqplot(element.id, chartValues, {
			title: 'Baby Weight'
		});
	}
};

The custom binding simply updates the chart on any change to the passed in valueAccessor, which we specified in the html as the items array in the viewmodel. jqPlot uses the element.id, in our case a div tag, to act as the placeholder container to drop the chart into. See the jqPlot documentation for much more detail on creating significantly more elaborate charting capabilities.

Some Odds and Ends

I didn’t cover the my.css file but I used this to add some very minor additional styling to the page. Most of the styles though do come “out of the box” from bootstrap. I hope someone finds this useful and please feel free to correct any mistakes I’ve made – this is certainly meant to reinforce my own pursuit in working with knockout and I welcome any advice.

jQuery Makes 100% Height So Much Easier

jQuery gets an insane amount of hype these days and for the most part it is warranted. The interesting thing to me is that I never see amazingly new things with jQuery that you couldn’t do with plain old javascript before; however, jQuery just makes it so much easier.

One simple example is the infamous “CSS 100% height” issue. If you’ve done any CSS work, at some point you’ve come across the desire to have a 100% height div or table and have shuffled through all of the hacks and tweaks on how to do this. Often times, the examples use javascript to not only set the height, but also maintain the proper height when resizing the window.

I remember writing client-side code to set the height based on the DOM object height or clientheight and then finding out that it only worked in a particular browser. To maintain the same results across multiple browsers meant an extensive amount of hacky code checking browser type and version.

jQuery to the Rescue

Enter jQuery, where with a single attribute of height() you can abstract all of the difficulty of finding the appropriate height of an object regardless of browser or operating system.

Below, I’ve setup an example of using jQuery to autoset the height of a content div in the middle of the screen. The code also automatically adjusts on resizing the browser window.

Setting Up the HTML

Below is a very basic HTML layout. It consists of a header, a content section, and a footer.

<div id="header">&nbsp;</div>
    
<div id="content">&nbsp;</div>
    
<div id="footer">&nbsp;</div>
        

Add a Bit of CSS

Below, I’ve set the HTML and Body tags to 100% and 0px padding/margin. This allows the javascript method to key off the total height of the HTML element. I’ve also set some colors and fixed heights for the header and footer just for visibility in the demonstration.

html, body
{
    height: 100%;
    padding: 0px;
    margin: 0px;
}
        
#header
{
    background-color: Blue;
    height: 100px;
}
        
#content
{
    background-color: Red;
}
        
#footer
{
    background-color: Blue;
    height: 50px;
}
        

A Short jQuery Snippet

First, we need to discuss the sizeContent() method. This method simply gets the total height of the page via $(“html”).height() and then subtracts the header and footer heights. This gives us the necessary height for the content. We then simply set the CSS height attribute for the content div to the newHeight value.

$(document).ready() and $(window).resize() are pretty self explanatory and simply call the sizeContent() method upon page_load and on any event the window is resized.

//Initial load of page
$(document).ready(sizeContent);

//Every resize of window
$(window).resize(sizeContent);

//Dynamically assign height
function sizeContent() {
    var newHeight = $("html").height() - $("#header").height() - $("#footer").height() + "px";
    $("#content").css("height", newHeight);
}
        

Where to Host My jQuery Web Application?

If you’re looking for a place to host your web application there was recently some interesting news. Web.com made a big move by purchasing Network Solutions for (reports vary) $560 million!

Network Solutions now has VPS hosting (“Virtual Private Server” hosting), for more advanced and technologically-inclined website builders who want more control over their websites, and more capability in the structure they’re using. Head over to Network Solutions to check it out today.

Happy coding!

Staying in Touch – How to Build a Contact Form

Whether you are a Fortune 500 company or a mom-and-pop shop online, you need some way for visitors to contact you. Most contact forms are pretty much the same, you choose what information you want your visitors to provide to you as well as an open area for any comments/questions they would like to leave. The information is then sent to an administrator email account for correspondence. You may also want to display a confirmation to the user that their email has been sent.

To demonstrate how to do this, I will use my own contact form in ASP.NET (VB.NET) and an old PHP version I used to run a long time ago.

ASP.NET

For those of you Microsoft-based developers, here is some sample code that can be used as a base for your contact forms.

ASPX (frontend)

<h1>Contact Nicholas Barger</h1>
<p>Please feel free to contact me with questions, comments, or anything else that you would like to discuss. I appreciate your interest/involvement so I try and respond as quickly as possible.</p>

<p>You can also find me on <i>LinkedIn</i> at: <a href="http://www.linkedin.com/in/nicholasbarger" target="_blank">http://www.linkedin.com/in/nicholasbarger</a></p>

<div class="formdisplay">
	<span>Please enter your email address:</span><br />
	<asp:TextBox ID="tbEmail" runat="server" Width="700px"></asp:TextBox><br />
	<span>Please enter a subject for this message:</span><br />
	<asp:TextBox ID="tbSubject" runat="server" Width="700px"></asp:TextBox><br />
	<span>Please enter your message below:</span><br />
	<asp:TextBox ID="tbMessage" runat="server" TextMode="MultiLine" Width="700px" Height="250px"></asp:TextBox><br />
</div>

<asp:Button ID="btnSubmit" runat="server" Text="Send Message" />

VB.NET (backend/codebehind)

Protected Sub btnSubmit_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSubmit.Click
	'Prep basic values
	Dim strFromEmail As String = tbEmail.Text
	Dim strToEmail As String = ConfigurationManager.AppSettings("AdminEmail")
	Dim strSubject As String = tbSubject.Text

	'Prep custom values
	Dim strBody As String = ""
	Dim strFromName As String = ""

	strBody = tbMessage.Text

	Dim oCommonFunc As New Common.Functions
	Try
		oCommonFunc.sendEmail(strFromEmail, strFromName, strToEmail, strSubject, strBody, Nothing, Nothing, Nothing, True)
		Response.Redirect("contactcomplete.aspx")
	Catch ex As Exception
		'TODO - Display Error Message
	Finally
		oCommonFunc = Nothing
	End Try
End Sub

VB.NET (common class/codebehind)

Public Function sendEmail(ByVal strFromEmail As String, _
	ByVal strFromName As String, _
	ByVal strToEmail As String, _
	ByVal strSubject As String, _
	ByVal strBody As String, _
	Optional ByVal strCCEmail As String = Nothing, _
	Optional ByVal strBCCEmail As String = Nothing, _
	Optional ByVal strAttachmentPath As String = Nothing, _
	Optional ByVal bIsHTML As Boolean = False) As Boolean

	'Check for proper from email
	If String.IsNullOrEmpty(strFromEmail) = True Then
		Throw New Exception("From email is not specified.")
	End If

	'Check for proper to email
	If String.IsNullOrEmpty(strToEmail) = True Then
		Throw New Exception("To email is not specified.")
	End If

	'Check for a non-empty message subject
	If String.IsNullOrEmpty(strSubject) = True Then
		Throw New Exception("Subject was not specified.")
	End If

	'Check for a non-empty message body
	If String.IsNullOrEmpty(strBody) = True Then
		Throw New Exception("Body of email was not specified.")
	End If

	'Create mail object
	Dim oMail As New MailMessage()
	'oMail.Host = ConfigurationManager.AppSettings("MailHost")

	'Convert all "," into ";"
	strToEmail = strToEmail.Replace(",", ";")

	'Check if "To" email contains multiple emails
	If strToEmail.IndexOf(";") >= 0 Then 'add multiple emails
		Dim strToArray As String() = Split(strToEmail, ";")
		For i As Integer = 0 To strToArray.Length - 1
			oMail.To.Add(strToArray(i))
		Next
	Else 'add single email
		oMail.To.Add(strToEmail)
	End If

	'If CC exists
	If String.IsNullOrEmpty(strCCEmail) = False Then
		'Convert all "," into ";"
		strCCEmail = strCCEmail.Replace(",", ";")

		'Check if "CC" email contains multiple emails
		If strCCEmail.IndexOf(";") >= 0 Then 'add multiple emails
			Dim strCCArray As String() = Split(strCCEmail, ";")
			For i As Integer = 0 To strCCArray.Length - 1
				oMail.CC.Add(strCCArray(i))
			Next
		Else 'add single email
			oMail.CC.Add(strCCEmail)
		End If
	End If

	'If BCC Exists
	If String.IsNullOrEmpty(strBCCEmail) = False Then
		'Convert all "," into ";"
		strBCCEmail = strBCCEmail.Replace(",", ";")

		'Check if "BCC" email contains multiple emails
		If strBCCEmail.IndexOf(";") >= 0 Then 'add multiple emails
			Dim strBCCArray As String() = Split(strBCCEmail, ";")
			For i As Integer = 0 To strBCCArray.Length - 1
				oMail.Bcc.Add(strBCCArray(i))
			Next
		Else 'add single email
			oMail.Bcc.Add(strBCCEmail)
		End If
	End If

	'Add additional information to mail object
	oMail.From = New MailAddress(strFromEmail, strFromName)

	oMail.Subject = strSubject
	oMail.Body = strBody

	If bIsHTML = True Then
		'oMail.IsHTML = True
		oMail.IsBodyHtml = True
	End If

	Dim strSMTPUserName As String = ConfigurationManager.AppSettings("SMTPEmail")
	Dim strSMTPPassword As String = ConfigurationManager.AppSettings("SMTPPassword")

	Dim smtpClient As New SmtpClient(ConfigurationManager.AppSettings("MailHost"))
	smtpClient.Credentials = New Net.NetworkCredential(strSMTPUserName, strSMTPPassword)

	oMail.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure

	If String.IsNullOrEmpty(strFromEmail) = False Then
		oMail.ReplyTo = New MailAddress(strFromEmail)
	End If

	If String.IsNullOrEmpty(strFromEmail) = False Then
		oMail.Headers.Add("Return-Path", strFromEmail)
		oMail.Headers.Add("Errors-To", strFromEmail)
		oMail.Headers.Add("Bounces_To", strFromEmail)
	End If

	'Add attachment
	If String.IsNullOrEmpty(strAttachmentPath) = False Then
		oMail.Attachments.Add(New Attachment(strAttachmentPath))
	End If

	'Send email
	Try
		smtpClient.Send(oMail)
	Catch ex As Exception
		Return getErrorMessage(ErrorMessage.ErrorSendingEmail)
	Finally
		oMail = Nothing
	End Try

	Return True
End Function

PHP

And now for all things open-source, a PHP version.

Disclaimer: I haven’t professionally worked with PHP since 2004, so if you have any suggestions to improve the code please add them to the comments.

All-In-One (spaghetti-code)

<?php
if(isset($_POST['btnSubmit'])) { 
	$mailto = "nicholas@nicholasbarger.com";
	$email = $_POST['tbEmail'];
	$subject = $_POST['tbSubject'];
	$message = $_POST['tbMessage'];
	$headers = 'From: $mailto'."\r\n"
.'Reply-To: $mailto'."\r\n";

	#Mail to Administrator
	if(mail($mailto, $subject, $message, $headers))
	{
		 header('Location:contact_complete.php');
	}
	else
	{
		//Display an error
	}
}
?>

<html>
<head>
	<title>PHP Contact Page Demo</title>
</head>
<body>
<h1>Contact Nicholas Barger</h1>
<p>Please feel free to contact me with questions, comments, or anything else that you would like to discuss. I appreciate your interest/involvement so I try and respond as quickly as possible.</p>

<p>You can also find me on <i>LinkedIn</i> at: <a href="http://www.linkedin.com/in/nicholasbarger" target="_blank">http://www.linkedin.com/in/nicholasbarger</a></p>

<div class="formdisplay">
	<span>Please enter your email address:</span><br />
	<input type="text" id="tbEmail" name="tbEmail" style="width:700px;"></input><br />
	<span>Please enter a subject for this message:</span><br />
	<input type="text" id="tbSubject" name="tbSubject" style="width:700px;"></input><br />
	<span>Please enter your message below:</span><br />
	<textarea id="tbMessage" name="tbMessage" style="width:700px; height:250px;"></textarea><br />
</div>

<input type="submit" id="btnSubmit" name="btnSubmit" value="Send Message" />
</body>
</html>

Make It Your Own

What I’ve outlined here is just a beginning demonstration. There is still work to be done, such as creating the contact complete page and notifying users that they successfully (or unsucessfully) contacted an administrator. Additionally, you may want to add additional fields to be captured, add field validation to ensure proper data entry, or perhaps add a confirmation email response to the user as well.

Have fun with it, and take a boring contact page and make it something really powerful. Hope this was helpful in getting you started, or refreshed on how to stay in touch with your visitors through a simple contact form!

CSS Zen Garden

For years when trying to convey the power and pupose of CSS I’ve deferred to a single example; CSS Zen Garden. I’ve always been so impressed by the demonstation of this project and contributions from designers all over the world. The basis of CSS Zen Garden is to take the exact same HTML content, and without making ANY changes to the HTML, create a completely unique visual design and portrayal of the content.

For those of you who think CSS is merely changing fonts and colors, try out a few examples found on CSS Zen Garden and you will be amazed at the huge range in presentations.

Here are a few of my favorites:

Care to take a look at the base HTML? Click here to view the HTML without any CSS styling.

CSS Zen Garden: The Book

If you are interested in learning more about the history behind this project, the original creators have released a book which I highly recommend.

A Simple Tableless Form

Why Use CSS (A brief recap)

By now, just about anyone who has worked on web-based development has heard the arguments against tables in HTML design. Although the vast majority of websites in earlier web development were table based, times have changed and most web developers are coming over to the benefits of purely CSS based design.

There are of course many reasons for this change; namely the separation of page structure and visual aesthetics. Software developers, above all others, should appreciate this singular advantage of using CSS based design over tables and fixed graphics within the HTML.

With a CSS based website or web application you gain the advantage of being able to quickly change the entire look of a website by simply changing an external CSS stylesheet (or collection of css stylesheets) and functionality of the webpage should stay in tact since the underlying HTML structure is unchanged. Additionally, there are SEO advantages to using CSS and div’s versus tables and worse, nested tables.

Common CSS Problem-Area: Forms

So now that we briefly recapped the reasons why as well as a few significant advantages of using CSS, let’s discuss a common CSS problem area; forms.

We’ll use a very simple example which incorporates the majority of elements within a form. The following code examples are written in good-old-fashioned HTML instead of ASP.NET and do not contain validation, ID’s, etc. like a production form would have:

A Basic Form Screenshot

The old way of doing this in HTML would look something like this:

<html>
<head>
<title>A Simple Table Form</title>
</head>
<body>
	<h1>A Simple Table Form</h1>
	
	<table>
		<tr>
			<td>Name</td>
			<td colspan="5"><input type="text" size="65" /></td>
		</tr>
		<tr>
			<td>Property Address</td>
			<td colspan="5"><input type="text" size="65" /></td>
		</tr>
		<tr>
			<td>City</td>
			<td><input type="text" /></td>
			<td>State</td>
			<td>
				<select>
					<option value="FL">FL</option>
				</select>
			</td>
			<td>Zip</td>
			<td><input type="text" size="14" /></td>
		</tr>
		<tr>
			<td>Email</td>
			<td colspan="5"><input type="text" size="65" /></td>
		</tr>
		<tr>
			<td colspan="6">Message</td>
		</tr>
		<tr>
			<td colspan="6"><textarea cols="65" rows="10"></textarea></td>
		</tr>
		<tr>
			<td colspan="6"><input type="button" value="Submit" /></td>
		</tr>
	</table>
</body>
</html>

Let’s take a look at one approach without tables and using CSS styles (the CSS is incorporated into the head of the HTML for demonstration purposes):

<html>
<head>
<title>A Simple Tableless Form</title>
<style>
.form
{
}
.form span
{
	float: left;
	width: 120px;
	clear: both;
}
.form .normal
{
	width: 120px;
	float: none;
}
.form .short
{
	width: 50px;
}
.form input, .form select, .form textarea
{
	margin-top: 2px;
	margin-bottom: 2px;
}
</style>
</head>
<body>

<div class="form">
	<h1>A Simple Tableless Form</h1>
	
	<span>Name</span>
	<input type="text" size="65" /><br />

	<span>Property Address</span>
	<input type="text" size="65" /><br />

	<span>City</span>
	<input type="text" />

	<span class="normal short">State</span>
	<select>
		<option value="FL">FL</option>
	</select>
	
	<span class="normal short">Zip</span>
	<input type="text" size="14" /><br />

	<span>Email</span>
	<input type="text" size="65" /><br />
	
	<span>Message</span><br />
	<textarea cols="65" rows="10"></textarea><br />

	<input type="button" value="Submit" />
</div>

</body>
</html>

In production, don’t forget to move the CSS to an external file – which is usually cached by the browser after initially being downloaded. This improves download speed and code maintenance.

The key is the form class and styles within the form class. all ‘s are treated special, so they float left and default to a specified width (which can change based on the form). This lines up the input and the input tag’s vertically so the form looks clean. I generally also include a short style for closer width when necessary. The normal style is to allow non-floated spans for laying form elements out horizontally. Finally, I’ve added some additional spacing to form input controls to make the form easier to read.

A Nice Advantage for CSS Forms

To demonstrate one final advantage let’s take the following scenario: you need to be able to hide or show the state and state dropdown from codebehind, a common example when working with ASP.NET. With the CSS version, you can simply wrap the state span and select input with an ASP Panel and turn the visibility on/off. With a table, this would break the table structure if you remove a column, and if not, you are left with a large gap.

I hope this helps in your next HTML form!

It’s The Little Things That Make The Difference

Constructive Criticism

Please indulge me for a minute… you’ve just completed a huge launch of a new e-commerce website. The website does everything; all the bells and whistles of a multi-language, multi-currency, real-time shipping, dynamic inventory, dropshipping, customer portal, full administration, on and on…

You’re feeling pretty good, knowing that no where else can you get everything that you’ve packed into this online presence. Your happy tester/client/customer/fellow developer takes one look at it and says the following:

“Where’s the little icon in the address bar? Why don’t I see it on Google? How much traffic does the website have yet? Can you give me a report on signups, traffic, and other minutia? I changed one of the page names and it says file not found, could it show something friendlier? It doesn’t look right on my Mac with Safari.”

Man, all that hard work, and what’s the response; criticism. Well, get over it. They’re right, you’re wrong. As much as that sucks some times, remember that criticism from colleagues is almost always constructive. You should always be happy that somenoe cares enough to give you feedback. So take the feedback, roll up your sleeves and fix the little things that really make the project, it’s just part of the process.

I’ve always noticed that as cynical as it is, the things you do wrong always garner the most attention, so put some time into the details and try and avoid little mistakes so people can focus on how amazing this application is.

Finishing Tips

Here’s a few tips that I try and remember for every project, perhaps it might help you too:

Meta Information such as keywords, description, and author. Meta information is not dead, even Google uses meta information for search criteria as evidenced by their webmasters section which describes errors found in your crawl statistics referring to missing or duplicate meta information across pages.

Titles. It looks a bit silly having a dynamite page with an Untitled bar at the top of the browser. Not only does it display to the user a proper title for your website/application, but it most likely helps SEO as well.

Sitemaps, both in XML and as user facing pages. Sitemaps provide search engines such as Google and Yahoo quicker information for page indexing which allows these search engines to crawl your website more frequently. User facing sitemaps do actually help some users navigate to the information they’re after. Check out a search for Google Sitemap Generator, where you can find services that generate XML sitemaps for you.

Favicon, yes this is “cutesy”, but remember that brand identity is what advertising agencies get paid millions for! A simple icon can help give visual connections to your users that could make the difference in them finding and remembering you again. You can find favicon generators which convert your uploaded image to a favicon.ico to place on your website.

Robots.txt; Google recommends it, I do it. A robots.txt file helps tell crawling bots where not to look. This free’s up search engine resources by limiting their crawls of non-indexable or unimportant data. A good rule of thumb is, if you don’t want a user to get to a certain directory, throw it in the robots.txt file. Find out more information on robots.txt.

IIS Error Pages (or ASP.NET error pages) provide a way to clean up errors or unexpected behavior. Errors happen, but when they do, it would be a lot nicer if the user sees what’s going on in a friendly, explained way, with similar navigation, branding, and look and feel as the rest of the website. Add pages such as:

  • error.htm (catch-all for non-specified errors)
  • noaccess.htm (when a user requests a resource they do not have access to)
  • notfound.htm (404 errors)
  • etc.

You can wire these up in IIS, or for ASP.NET applications, in web.config (though I would do both personally).

Analytics. Invariably, someone will request some type of benchmarking of how successful the website/application is, and this generally comes in the form of analytics. If no one is asking, then maybe you should be the one. Google Analytics is a good, quick, and easy implementation of analytics for most businesses. However, if you want to inhouse the data, there are several other solutions you can go with. (Webtrends is a pretty large one).

This One is so Important, It Get’s It’s Own Heading – Graphics

Lipstick on a pig…Well, in the case of applications (especially web-based for some reason), great graphics really do cover up a lot. A top-tier designer, is extremely hard to find and can be worth their weight in gold. However, the reverse is usually not true; great applications that look like garbage usually don’t get a first look, let alone a second; there just tends to be too much competition. Graphic design is important for inhouse or business applications as well, not just public facing websites. A design that is well liked by the users acquires much quicker acceptance and in some cases even helps create evangelist-style users. It sounds superficial, especially for most of the developers reading this, but graphics are the single most important finishing touch to any application in my opinion.

I’m sure there are a ton of other tips and common gotcha’s that developers forget to do at the end of projects, so please leave a few in the comments and help us all out!

Homegrown CSS Standards

The following is a brief outline of a few tips, tricks, and personal preferences for standardizing your HTML/CSS websites and web applications. These suggestions have been pulled from personal experience and tend to fit 99% of the projects I’ve been involved in. Remember, even though I’m calling them standards, there are always exception, so don’t simply mimic any set of standards – evaluate the situation and apply the most appropriate solution.

Good Foundations

It is generally easier to begin style implementation with div’s. A CSS-based HTML design typically will have appropriately used div’s to section off major groupings of HTML data. For example:

…
<body>
	<div class=”container”>
		<div class=”header”>
			<h1>My Example HTML</h1>
		</div>
	
		<div class=”nav”>
			<ul>
				<li>Microsoft</li>
				<li>Yahoo</li>
			</ul>
		</div>

		<div class=”content”>
			<h2>My Example Subheader</h2>
			<p>Some lorem ipsum goes here…</p>
			<p>And now a bit more…</p>
		</div>
	</div>
</body>
…

As you can see, there are no tables being used for design purposes, table should generally be used for tabular data and not design layout. HTML with heavily used tables limits the ability for design to be fully manipulated by a CSS style sheet.

Now that we’ve written HTML that is geared to a CSS-based design, we can use the “hooks” we created to manipulate the CSS however we need and it will be readable for both an HTML designer/developer and a CSS developer.

For an example of design being completely dictated by CSS see CSSZenGarden for more. The HTML is always the same and only the CSS file changes in each example.

HTML that is developed in Visual Studio under the default validation settings for HTML will provide warnings/errors of invalid or inappropriate HTML. Please heed these warnings to provide the cleanest amount of HTML to work from. This is the foundation of any web application and for all other aspects such as CSS, JavaScript, and even code-behind to function properly, HTML should be sound. After all warnings have been addressed through Visual Studio, take time to also validate the HTML in an HTML Validator provided by W3 Consortium.

CSS File Organization

When developing a hierarchy of style sheets, separate styles into common and specific categories, then create a common.css file to store all common styles and individual specific CSS files for other major collections of CSS styles. See below example:

If I have a website that consists of three major portals, Public, Vendors, Administration; I would most likely create four CSS style sheets; one for each major portal, as well as one common.css file for common styles used in all portals.

Example: Use of Multiple Cascading Style Sheets

Common.css

a img 
{
	border: none;
}

Public.css

@import url(“common.css”);

body 
{
	background-color: #CCC;
}

Vendors.css

@import url(“common.css”);

body 
{
	background-color: #AAA;
}

Administration.css

@import url(“common.css”);

body 
{
	background-color: #FFF;
}

This allows us to gain the true benefits of “cascading” style sheets, as each style sheet is importing and thus inheriting (or overloading, when appropriate) the parent style sheet(s).

Use discretion as to the number of CSS files to import against. In most cases, there is only need for a single import per CSS file. Several imports can become unwieldy and difficult to track down CSS class inheritance.

CSS Formatting

When adding CSS styles to a CSS style sheet, format the document in the following general sections:

Import CSS file(s)
HTML overloads
Custom CSS styles

Example: External CSS Sample

Example.css
import url(“common.css”);

body 
{
	background-color: #FFFFCC;
}

input, textarea, select 
{
	background-color: #FFFFAA;
}

/*Content found within the main content placeholder.*/
.content 
{
	padding: 15px;
}

/*Main navigation section.*/
.nav 
{
	border: 1px solid #000;
}
.nav ul 
{
	list-style-type: none;
}
.nav ul li 
{
	margin-left: 10px;
margin-right: 10px;
}

All HTML overloads are located first and grouped together, and custom styles make up the rest of the document. Notice, that all custom styles have comments as to what they affect to assist in maintaining changes. HTML overloads can have comments as well, but are not really necessary. Additionally, styles either as HTML overloads, or custom, that are cascading within a document should be grouped together without vertical spacing as demonstrated with “.nav”. Please note that there are no CSS styles applied to ID elements! These are commonly used as follows:

Example: CSS Style Based on Element ID

#nav 
{
padding: 15px;
}

The reason for this is that we want only class declarations in the HTML because it specifically tells the HTML observer (developer) that this object/tag has a CSS style applied to it, whereas the use of CSS against an ID tag does not convey this. When CSS is complex and uses repositioning or floats, etc. this can become very difficult to identify where HTML issues are occurring verses applied CSS. ID tags in HTML should be used for identification of objects/tags (for use with javascript/codebehind, etc.) and not for CSS styling.

Miscellaneous Formatting

Use spaces to enhance readability such as the following:

Bad:
.nav{background-color:#000000;}
.header{
	padding:10px;
}

Good:
.nav 
{
	background-color: #000000;
}

.header 
{
	padding: 10px;
}

Always terminate style attributes with a semi-colon, even when there is only one style attribute being applied.

Explicitly write out style attributes for less-common or hard to read attribute values instead of combining them into a single line:

Example(s): Readability

Bad:
padding: 10px 5px 10px 5px;

Good:
padding-top: 10px;
padding-right: 5px;
padding-bottom: 10px;
padding-left: 5px;

Additionally, when managing page layout widths, adjust widths from the highest containing item possible rather than specific nested objects. See the following HTML/CSS example:

…
<body>
	<div class="container">
		<div class="header">This is the header!</div>
		<div class="nav">
			<ul>
				<li>Link 1</li>
				<li>Link 2</li>
			</ul>
		</div>
		<div class="content">
			<p>Here is some content.</p>
		</div>
	</div>
</body>
…
CSS:

Bad:
.header 
{
	width: 780px;
}

.nav 
{
	width: 780px;
}

.content 
{
	width: 780px;
}

Good:
.container 
{
	width: 780px;
}

CSS Style Naming

Some common things to remember while naming styles:

  • Avoid using names which are too specific to the styles being applied, for example: “bluetext” or “leftNav”. Today you may be developing the text to be blue, or the navigation to be on the left, but tomorrow the text may change to green and the navigation may be right or top of the page.
  • Use consistent naming convention: Florida Family will be using camel case (“mainNav” or “nav”).
  • Don’t use acronyms or uncommon abbreviations such as “hlsm” (highlighted sub-menu).
  • Attempt to keep names fairly short, generally less than 15 characters.
  • .

  • Do not prefix CSS styles with “css” such as “cssNav”.

CSS Validation

Don’t forget, it’s never a bad idea to validate your CSS (W3 CSS Validator)!

Thanks for reading, I hope this makes life a little easier when working with your HTML/CSS projects!

Very good benefit, for very little work – IIS Compression for IIS6

I’ve seen quite frequently that many applications have not implemented compression. I personally, think it’s great, simply because processor power is fairly cheap and the faster I can deliver content to my users the better. To me, the negligible difference in processing power is definately worth the increase in user experience when pages load sometimes 2 to 3 times faster.

Before we get started, I think it would be beneficial to take a trip to a compression reporting service to see if your server is currently using compression and if not, what potential benefit you would most likely receive. These compression reports are usually free and only require a URL to do the analysis. I have used PipeBoost in the past to display compression reports.

Ok, now that you can quantify the potential benefit, let’s get started by showing you my personal settings for IIS compression. Many thanks to Frendy who originally turned me on to the benefits of IIS compression and allowing Microsoft’s IIS compression engine to do all the work rather than writing my own HTTP modules for it.

Keep in mind, for your own application you may want to have different settings than what I’ve chosen. I will not go into the detail of each setting, however, this should give you a jumping point to dive a little deeper for your particular application.

Changing IIS to Enable Compression

The first change needs to be made by going to:

IIS Manager > Right click on Web Sites > Click Properties > Click the Service Tab

Change the screen to look similar to the following (Checkmark Compress application files and Compress static files):

Website Properties in IIS

Changing the Metabase.xml

Next, we want to change the metabase.xml file to direct IIS on the compression scheme we want to use. I set up schemes for both gzip and deflate (though gzip is most often used I believe).

You will want to add the following section to your metabase.xml file directly below the <IIsFilter></IIsFilter> section.

Note: This may already be there, if so, simply review the values and match them up appropriately.

<IIsCompressionScheme	Location ="/LM/W3SVC/Filters/Compression/deflate"
		HcCompressionDll="%windir%\system32\inetsrv\gzip.dll"
		HcCreateFlags="0"
		HcDoDynamicCompression="TRUE"
		HcDoOnDemandCompression="TRUE"
		HcDoStaticCompression="FALSE"
		HcDynamicCompressionLevel="9"
		HcFileExtensions="htm
			html
			txt
			js
			css"
		HcOnDemandCompLevel="10"
		HcPriority="1"
		HcScriptFileExtensions="asp
			dll
			exe
			aspx
			asmx
			ashx
			asbx
			axd"
	>
</IIsCompressionScheme>
<IIsCompressionScheme	Location ="/LM/W3SVC/Filters/Compression/gzip"
		HcCompressionDll="%windir%\system32\inetsrv\gzip.dll"
		HcCreateFlags="1"
		HcDoDynamicCompression="TRUE"
		HcDoOnDemandCompression="TRUE"
		HcDoStaticCompression="TRUE"
		HcDynamicCompressionLevel="9"
		HcFileExtensions="htm
			html
			txt
			js
			css"
		HcOnDemandCompLevel="10"
		HcPriority="1"
		HcScriptFileExtensions="asp
			dll
			exe
			aspx
			asmx
			ashx
			asbx
			axd"
	>
</IIsCompressionScheme>       
    

That’s all there is to it. You should get a pretty strong benefit from compression depending on your particular setup; hope this helps!

Someday I Need to Write a JS Library

Unfortunately, I’ve never sat down and written a full blown out JS library; at least not in a really clean and reusable way. However, I do have a few custom Javascript functions that I tend to use in several projects.

The majority of these can be found by doing a quick search on google or some equivalent; but I figured I could keep them here for an easy find and if anyone else happened upon them they might be useful as a small collection.

Javascript Cookie Management

//create cookie
function createCookie(name,value,mins) {
	if (mins) {
		var date = new Date();
		date.setTime(date.getTime()+(mins*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

//read cookie
function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

//erase cookie
function eraseCookie(name) {
	createCookie(name,"",-1);
}

String Manipulation

function inStr(strSearch, charSearchFor) {
	for (i=0; i < len(strSearch); i++)
	{
	    if (charSearchFor == mid(strSearch, i, len(charSearchFor)))
	    {
			return i;
	    }
	}
	return -1;
}

function len(str) {
    return String(str).length;
}

function mid(str, start, len) {
    if (start < 0 || len  iLen) {
        iEnd = iLen;
    }
    else {
        iEnd = start + len;
    }
    
    return String(str).substring(start,iEnd);
}

function left(str, n) {
    if (n  String(str).length) {  // Invalid bound, return
        return str;                // entire string
    }
    else { // Valid bound, return appropriate substring
        return String(str).substring(0,n);
    }
}

function right(str, n) {
    if (n  String(str).length) {  // Invalid bound, return
        return str;                     // entire string
    }    
    else { // Valid bound, return appropriate substring
        var iLen = String(str).length;
        return String(str).substring(iLen, iLen - n);
    }
}

Page Navigation

This is really just shorthand for 99% of the popup pages that I would use when I called window.open().

function openPopup(page, width, height) 
{
    window.open(page,'PopupWindow','width='+width+',height='+height+',resizable=no,scrollbars=no');
}

Page/Form Input Helpers

//**************************************************************//
//Makes input control (form control) a highlighted color.  Works
//specifically for textboxes and textareas.
//
//obj = "this" if being triggered by event or if null is passed 
//      or accepts an overload of any document control object.
//
//className = name of css class for active input box.
//--------------------------------------------------------------//

function doActivateInput(obj) {
    if(obj == "[object Event]" || obj == null) {
        obj = this;
    }
    
    if(obj != null) {
        obj.className="input_active";
    }
}

function doDeactivateInput(obj) {
    if(obj == "[object Event]" || obj == null) {
        obj = this;
    }
    
    if(obj != null) {
        obj.className="";
    }
}
//**************************************************************//


//**************************************************************//
//Preloads images for a page to correct wait time when displaying 
//hidden/new images
//
//imgPathArray = string array of img paths to preload 
//--------------------------------------------------------------//
function preloadImages(imgPathArray) {
    for(i=0;i<imgPathArray.length;i++) {
        var img = new Image();
        img.src = imgPathArray[i];
    }
}
//**************************************************************//


//**************************************************************//
//Helper function for adding textbox activate/inactivate event listeners
//
//obj = the object (textbox/input box) to perform action on
//--------------------------------------------------------------//
function doHelperAddTextboxEventListeners(obj) {
    if (obj.addEventListener) {
       obj.addEventListener("focus", function () {doActivateInput(this);}, false);
       obj.addEventListener("blur", function () {doDeactivateInput(this);}, false); 
    } 
    else if (obj.attachEvent) {
       obj.onfocus = function () {doActivateInput(obj);};
       obj.onblur = function () {doDeactivateInput(obj);};
    }
}
//**************************************************************//


//**************************************************************//
//Helper function for adding buttons hover state event listeners
//
//obj = the object (button) to perform action on
//--------------------------------------------------------------//
function doHelperAddButtonEventListeners(obj, activeImgPath, inactiveImgPath) {
    if (obj.addEventListener) {
       obj.addEventListener("mouseover", function () {this.src=activeImgPath;}, false);
       obj.addEventListener("focus", function () {this.src=activeImgPath;}, false);
       obj.addEventListener("mouseout", function () {this.src=inactiveImgPath;}, false);
       obj.addEventListener("blur", function () {this.src=inactiveImgPath;}, false);   
    } 
    else if (obj.attachEvent) {
       obj.onmouseover = function () {this.src=activeImgPath;};
       obj.onfocus = function () {this.src=activeImgPath;};
       obj.onmouseout = function () {this.src=inactiveImgPath;};
       obj.onblur = function () {this.src=inactiveImgPath;};  
    }
}
//**************************************************************//

Check out Script.acul.us!

For a really fun (and useful) Javascript library try out: Script.aculo.us, which does a wide range of client-side effects to really provide a richer UI and better web-applications.