Design Lesson

May 7th, 2008

The more I design, the more I notice design. Good design, mediocre design, bad design… you get the idea. The design does not have to be on the web, either. Car instrument ergonomics, kitchen appliance design, print advertising, architecture - nothing is safe from the critical eye.

Up until recently, I had been driving past this store in a little strip mall every day on my way to work. And every day it got a chuckle from me.

mmm - yummy

Teriyaki Smoothies? Ick. How could anyone think that a Teriyaki Smoothie would taste good? Is it sweet and sour? Kinda thick…

What? That is Teriyaki + Smoothies? Oh, I see it now. Well, I guess that is different.

But the point is that people don’t always read - they scan. In a car whizzing by at 30 mph, you just get a moment to process what you see. As new media designers (do they still call it that?) we are designing for an audience moving as fast as cars past that smoothie joint. We have but a moment to communicate to our users. Clarity should be our mantra. Organization is key.

Layout is just a small part of design. Content plays a larger part in a successful design than most of us give it credit. In fact, design without content is just decoration.

In my opinion, the sign designer here failed. They did not make it obvious what the spirit of what this store is about. That sign is not down low, where people leisurely walking by can browse the subtleties of font and leading and ponder the odd combination of edibles offered here, it is up high, facing a boulevard just yards from the freeway onramp.

In fact, I wonder if they are doing any business. What do you think?

Form Robot

April 9th, 2008

We’ve all thought it would be cool to have a robot, right? Something that just exists to make our life easier, quietly performing redundant tasks that if we were to do, just take up a lot of our time. One of the most redundant tasks a front-end UI designer faces is creating form validation.

Most websites have forms of one sort or another. After all, that is how users communicate back to the app. It is the active part of interactive. Nobody really wants to fill out these forms on the anonymous web and most will skip any field they feel is too personal or not needed. They’ll press the submit button and wait a few moments, only to have the original form reload with a vague error message posted across the top or bottom of the page suggesting they need to do something.

So, that’s where validation comes in. If we can help the form-filler-outer (that is the technical term) complete the input with the least amount of frustration, that would be a good thing. So what are the steps involved in creating sensible form validation?

First, we want to make sure that the user knows what we expect of them. Most of us have see the little asterisk (*) next to a form field or label and have learned that means “This field is required”. So if I skip over that field, I can expect to be looking at an error message when I submit.

In reality, shouldn’t every field be required? After all, why would we want to ask the user for information that was not needed? So now that we have decided that every field in our form will be required and we will only ask what is absolutely necessary to complete whatever operation we’re doing, we need a simple way to ensure those fields have been completed. I’ve found that a somewhat generic method can handle about 85% of my validation needs. It is a mixture of javascript and cascading style sheets. Here’s how it works:

I assign a style class to each field that I want to be required. We’ll call it “required”. Depending on the type of validation we need, we’ll assign another class as well. A partial list of these types is “text”, “numeric”, “email”, “list”. Here’s how a text field that we want to make sure contains a simple alpha-numeric value might look:

<input id="fName" name="fName" class="required text" type="text" value="" />

My submit will trigger an onSubmit event which I’ll set up to run my validation method. Now here is where the automation comes in. My method will grab a collection of all of the document elements with the class of “required” which I can then iterate through and perform some validation. I does not matter how many fields there are, and I can add or remove fields at a later date without touching my validation script. That, my friends, is gold.

I prefer mootools to help simplify my javascript creation and this validation script is no different. My sample will be using v1.11. You can grab a copy at mootools.net. Place your script tag to include the mootools.js file in the head of your document and you’re all set. Check the source of some of their demo sample pages if you are not sure how to do that.

So let’s take a look under the hood of our method:

validate = {
// global variable - assume all good until we hit an error
var goFlag = true;
var msgText = "";
getFields: function(){
$$('.required').each(function(itm){
if(itm.hasClass('text') validate.checkText(itm);
// checks for other data types will go here
}
// validation complete - now return the results
validate.complete();
},
checkText : function(itm){
if(itm.getValue().length < 1){
itm.addClass('error');
validate.goFlag = false;
}else{
itm.removeClass('error');
}
},
complete : function(){
if(!validate.goFlag){
$('msg').setText('Sorry, we need a few more items completed!').addClass('error');
}
// goFlag is either true or false
return validate.goFlag;
}
}

What this is doing is creating a javascript object named validate. It contains different methods, getFields and checkText. getFields grabs all of the required class elements and iterates through them using each. This does the same thing as a for/next loop. Inside the iteration, we check to see if the element has an additional class, in this case “text”. If we find that, then we fire off a call to another method checkText. checkText takes the element passed to it and performs a simple length test of the value. If this is less than 1 character in length, then the field must be empty. Add another class to the element (there are three classes now) and set our goFlag variable to false.

If the value returns a length, we know the field was filled out. In that case, run the removeClass method on the element - it won’t error if the class is not there.

Notice that the proper way to reference the internal method is validate.checkText(itm) . We must include the name of the javascript object. This is a good thing as we can have many different scripts running and the name space helps keep the different scripts playing nicely together.

We’ll need a style defined to differentiate the required fields and to highlight any errors. In our CSS, create the following:

.required{
background-color: #FFF3DF;
}
.error{
background-color: #FFB93F;
}

This will color the text field background for a required field a light shade of orange. This will differentiate the required fields from any optional ones. Any field with an error will be a darker orange. That let’s our user know exactly which field the problem was in.

So the last piece is setting up our form:


<form name="theForm" id="theForm" action="index.php" onSubmit="return validate.getFields()" method="post" >
<span id="msg"></span>
<label>Enter your name</label>
<input id="fName" name="fName" class="required text" type="text" />
<input type="submit" value="send" />

OK, so there you have it. The elementary start of what can be flushed out into a full-blown automating, validating robot that will labor tirelessly to help your site visitors interact with your application.

Bartleby the RSS Feed Reader

February 25th, 2008

Recently, I was reminded about a short story I read in literature class when in college at the University of Redlands. It was called Bartleby the Scrivner, by Herman Melville. A strange little story, about a scribe in a legal office who copies text all day long, longhand, ultimately becoming an apathetic soul who “prefers not to” participate in life.

What got me thinking recently about old Bartleby is the rise of RSS (Really Simple Syndication) of content. For those who don’t know, many websites provide a “feed” of content that originally was intended for individuals to receive notification of when new content was available for viewing. That evolved to websites consuming these feeds, receiving and regurgitating the content themselves. Not adding value, just repeating. Copying. Replicating. Xeroxing. Duplicating.

Do a search on Google for [whatever] and you’ll see what I mean. Dozens of different sites that are displaying the same exact quote in the content preview.  A strange coincidence where dozens of individuals just happened to pluck the same idea from the universe simultaneously?

Sadly, no. It is a case of SCM: “Slacker Content Management”. For every original there are dozens of content repeaters, more than happy to benefit from the content they feel is “free for the taking”. But you say, “artists have always borrowed from the past”…

Many great masters of art were directly inspired by an existing work to create their own vision. Much architecture has it’s roots in previously created buildings, yet manages to exist on it’s own merit. Music is made up of notes, all of which have been used before, and many compositions will contain a recognizable phrase or snippet of another song, but with a few exceptions, most are created with the reference to the original as more of a tribute or hat-tip than a rip-off.

Ah, but this seems not to be the case with web-based content. Blatant borrowing, quoting without reference, and lots of “that’s cool - I want that on my site” has resulted in a bloating of the volume of web content, but a reduction in originality and quality. The new phenomenon of the parody site or video - those that intentionally mock the original in a karaoke-like manner - is especially annoying.

So, before you control-V that gem of a quote, save as that image file, or simply output a direct RSS feed as your own, ask yourself, “Am I taking inspiration from this source, or am I just taking this source?” Let those creative works that move you, inspire you. And let yourself take the freedoms to build on those inspirations to make your own contributions to the Internet.

More on using the JSON.cfc

February 19th, 2008

I thought it may be helpful to provide a little more detail on the edits I made to JSON.cfc, a coldFusion component used to serialize data.

To serialize data, a string is constructed with each member of a structure or array being added to the string. In essence, this is a situation of:

strVariable = strVariable & newData

Where strVariable ands up being a representation of the original data, but in a different format, usually comma delimited. so, if you had an array that looked like this:


list[1] = "apple"
list[2] = "bananna"
list[3] = "kiwi"
list[4] = "pineapple"

The value of strVariable would increment like this:


<cfscript>
strVariable = "";
strVariable = strVariable & "apple";
strVariable = strVariable &"," & "bananna" ;
strVariable = strVariable & "," & "kiwi";
strVariable = strVariable & "," "pineapple";
</cfscript>

The problem here is that coldFusion created 5 string objects to create that list. Granted, for this example, it wouldn’t matter, but what if you were serializing substantially more data? That could result in hundreds of string objects, each of which would contain all of the previous object’s contents, and adding just one more item to the list.

I read about using the java language string buffer object, and decided to try to implement it on the cfc. Here is a code snippet of the CF array to JSON code to show how it works:


<cfset s = createObject('java','java.lang.StringBuffer').init()/>
<cfloop from="1" to="#ArrayLen(_data)#" index="i">
<cfif i GT 1><cfset s.append(',') /></cfif>
<cfset tempVal = encode( _data[i], arguments.queryFormat, arguments.queryKeyCase, arguments.stringNumbers, arguments.formatDates ) />
</cfloop>
<cfreturn "[" & s & "]" />

You’ll notice a key difference. Instead of the familiar “strVariable = strVariable & newData” we create a reference to the java string buffer object:


<cfset s = createObject('java','java.lang.StringBuffer').init() />

Now, to add more data, all we need to do is to write:


<cfset s.append("newData") />

Where this really benefits the performance of our operation is that this is a single object, that our concatenations get applied to, instead of a new one for each concatenation.

Alternately, you can serialized in a block of cfscript:

<cfscript>
strVariable = createObject('java','java.lang.StringBuffer').init();
strVariable.append("apple");
strVariable.append(",");
strVariable.append("bananna");
strVariable.append(",");
strVariable.append("kiwi");
strVariable.append(",");
strVariable.append("pineapple");
</cfscript>

JSON and ColdFusion

February 7th, 2008

I’ve been working on a project that has required a boatload of data getting passed to the client - something like 22 arrays of 2000 records each! This project, which I inherited, used WDDX to serialize the data. Well, it appears that Internet Exploder 7 started throwing errors when loading this massive data set, and I needed to fix it.

I’ve been doing more with XHR requests and using JSON for modeling objects, so it seemed natural to leverage JSON as a forwards-compatible solution for this predicament. JSON is cool because Javascript can evaluate it directly without parsing as required with XML.

JSON, which stands for JavaScript ObjectNotation is a method for serializing a complex data type, such as an array or structure in a string which can be passed from server to client for processing by client-side JavaScript. I happened by a coldFusion cfc called JSON.cfc which encoded and decoded queries, structures, and arrays to JSON objects. The problem was, that my data set was so ginormous that the server was timing out on the request. So I started to look for ways to optimize the process.

Serializing data requires much string concatenation, basically adding on more pieces of text to a single string. To do this, ColdFusion has to create a new string object each and every time you add more data to it. Wow. That adds up.

We’re using ColdFusion 7, so we can access some of the Java methods directly. I modified JSON.cfc to use the Java StringBuffer object, which can persist through the iterations and results in substantial performance improvements.

While I was at it, I changed some of the logic behind adding the commas into the object, so that that last name/value pair would not have a comma training it. IE barks at those (and rightly so) .

My original WDDX packets were weighing in at 1.4 MB, 240K on CF7 (thanks in part to gzip), and after converting to JSON on CF7, 84K .

So without further ado, here is the modified JSON coldFusion component for your serialization pleasure… I uploaded the file as a .TXT file - you’ll want to rename it as .CFC for use.

SciFi: it really could explain a few things

January 30th, 2008

I’ve been amazed at how much there is to do and how little time there is to do it. I don’t remember it used to be that way when I was younger. And whenever you talk to older folks and you say “Wow, that year went by fast” they always reply “Oh, you ain’t seen nothing! Wait until you get to be my age”.

So what if there was a reason for this? I mean, besides insanity.

Maybe, just maybe, the earth is actually spinning faster, completing it’s daily rotation a little bit quicker. maybe there actually is less time.

Yeah, maybe all of those atomic blasts 50 years ago, which expelled massive amounts of energy, somehow boosted the spinning of the earth on its axis. Like a basketball spinning on a finger gets sped up with a glancing impact. Given the mass of the earth, several of these boosts could have a compound effect that could take years to see the resulting action. It wouldn’t take much. We’ve learned from global warming data that 1 degree can have huge consequences.

And speaking of global warming, maybe that is contributing to our lack of leisure time, too. The atmosphere is a gas and warming it would thin it slightly. A thinner viscosity would let the obstructions of the earth’s surface slip through it with less resistance. Less friction, in effect.

This reduction in the length of a day would have happened so gradually, we’d all just never notice it. The sun comes up. The sun goes down. It’s tomorrow already.

Except for the clock thing. How could the operation of clocks, many of which are purely mechanical, not notice the extra time at the end of a month or year? Well, the good folks that control things like resetting the atomic clock (ironic, huh) maybe came up with a solution - Daylight Savings Time.

How perfect! Twice a year, everyone has to manually change their timepieces. You could lose 60 seconds twice a year and not even know it. I don’t know about you, but I sometimes have to “adjust” my clock a week or so after a scheduled time change.

So, now that we know the reason*, what do we do? Accept that we may not accomplish all that we hope to? Organize better to be more productive? Delegate more?

I’ll let you know when I figure it out.

*Of course, the scenario described is science fiction… or is it?

Sortable list - the remix

July 18th, 2007

Last time I showed you how to create a sortable list using a couple of lines of javaScript. but that example was lacking something… design. It was what it was - an unordered list. Just like this:

  • wind farms
  • hybrid vehicles
  • renewable fuel sources
  • recycled products
  • solar energy
  • non-incandescent light bulbs

To look at the list, it is not apparent that you could manipulate it in any way. The cursor did not change to give you a hint, the items did not look compelling, nothing guided you to the conversion point - which would be to re-order and save your sorted list.

Well, we’re going to try to fix that, but not using javascript. Instead, let’s work with the presentation layer using just some CSS. Cascading Style Sheets allow us to define display properties to our HTML elements in a separate document. Why is that good? Because it removes all of the display logic from the document, leaving it uncluttered and accessible. It lets us code our content with semantically-correct structure, instead of a hodgepodge of shims, spacer images, and nested table elements.

So, let’s start by modifying the list elements to appear more interesting. Here is our first rule:



ul.sortable {
	list-style-type: none;
}

Notice we’re specifying “ul.sortable”. This means, an unordered list with a class of “sortable”. Our rule will not apply to all of the lists in the document, just the ones we want to be sortable.

Here is how the list will appear with our new rule applied:

  • wind farms
  • hybrid vehicles
  • renewable fuel sources
  • recycled products
  • solar energy
  • non-incandescent light bulbs

So, that got rid of the bullets (except WordPress is adding them back in - check my html example page if you want to view source), but we have a long way to go to make this look sortable. Let’s add a border around each of the items to give them more of a button feel.



ul.sortable li{
	border: 1px solid #cccccc;
	width: 260px;
	padding: 6pc 12px;
	margin: 2px;
	cursor: move;
}

And here is our list:

  • wind farms
  • hybrid vehicles
  • renewable fuel sources
  • recycled products
  • solar energy
  • non-incandescent light bulbs

Our drag script will use a cool alpha transparency effect on the dragged item, so let’s add a background-color to accentuate that.



ul.sortable li{
	border: 1px solid #36668E;
	width: 260px;
	background-color: #8FC0E9;
	padding: 6px 12px;
}

I also changed the border-color to work better with my background. I sampled colors from my banner using colorzilla, an extension for the FireFox web browser.

Now let’s modify the cursor property to change to a ‘move’ style. That will be a great visual cue that we can do something on the element we’re hovering over.



ul.sortable li{
	border: 1px solid #36668E;
	background-color: #8FC0E9;
	padding: 6px 12px;
	margin: 2px;
	cursor: move;
}

That brings us here. As you can see, our list is certainly more interesting now:

  • wind farms
  • hybrid vehicles
  • renewable fuel sources
  • recycled products
  • solar energy
  • non-incandescent light bulbs

For the full effect, complete with the working sortable functionality, check out the sample page.

Frameworks - worth the download hit?

July 12th, 2007

We’ve all been enamored with the new javascript libraries lately. Some of the more popular ones are (in order of my preference) mootools, jQuery, YUI, and prototype/scriptaculous. All of the libraries are quite good, and you can learn from all of them. I ended up preferring mootools because of it had the smallest download at the time. jQuery’s brand new version has lightened up to be some real competition for mootools in size. YUI (Yahoo’s User Interface library) is totally awesome, but it does soooo much. I was looking for something a little simpler.

That may be the biggest drawback of having a framework. It is easy to get caught up in the “what a great feature - let’s add it to the framework” cycle. Soon, the bulk of features slows the client-side processing to a grind and adds 400k to the download of a first-time visitor.

There is a saying out there that “Mootools is the coffee - you add the sugar”. Corny as that sounds, it is true. The library stays out of your way and lets you still have good access to the elements, objects, and callbacks. It doesn’t try to do it all for you, and as such, becomes more usable for those exceptions where you need to bend from the simple solution.

Since an example is a much more effective way to demonstrate, let’s get right to one, shall we?

Let’s say we want to create an interface where the user is presented a list and that they may reorder that list. They need to be able to save that change as well. In the old days, we would have created a table with the list items accompanied with a “move up/move down” set of buttons along each one. It woks, but is not a real satisfying experience for the user - especially if they need to move an item all the way up or down the list. (click, click, click, click…).

OK, well, then, a sortable list where you can drag and rearrange the items is a much more intuitive way to accomplish that task - and more fun too.

The first item of business is to forget using a table and select the semantically correct element for the task - a list. We’ll be using an unordered list:

  • wind farms
  • hybrid vehicles
  • renewable fuel sources
  • recycled products
  • solar energy
  • non-incandescent light bulbs

Next, let’s add the appropriate javascript library into our document - in this case I’ll be using mootools.

I’ll create another script file to manage the page-specific code: I’ll call it “sortable.js”.



<script src="mootools.v1.1.js" language="javascript"></script>

<script src="sortable.js" language="javascript"></script>

The first step is to load a method that will automatically convert this list to into a sortable list. For that, we’ll use the window.event() method.


// fire the function when the DOM loads
window.addEvent('domready', function() {
new Sortables($('mySortList'));});

Sorting the list is easy, as you can see… really easy. But sorting a list on the client side can only be so useful. We need to be able to do something with the sorted list, or it is just a useless exercise.

So we’ll add a link or button that fires off another method - one that will loop through the list and build a variable with the sorted order. Then, we could submit that sorted order up the server using an asynchronous method (we’ll cover those in another post). But to keep things simple, we will just serve up an alert with our newly sorted list.

Here’s the reporting method:

sorted = {
display : function(){
var theList = $$('li');
var text = "";
theList.each(function(itm, idx){
text += itm.getText();
if(idx < theList.length - 1) text += ", ";
});

alert(text);
}
}

And the link to call it:


<a href="javascript: sorted.display()">save this order</a>

Here is a link to a working sample page that demos the script.

So, there you have it. You have created some pretty complicated functionality with just a couple of lines of script. The javascript library weighs in at 40k, which if used throughout a site averages out to next to nothing per page. Not only is it worth the download, but will save you hours of repetitive coding as well.

Digital Compost

June 27th, 2007

We work in a temporary world.

The reality of designing for new media is that what we create today will most likely become overwritten or become obsolete in a matter of years… The masterpiece of layout and composition that was so carefully crafted starts displaying all wonky because browsers (or whatever replaces browsers) just don’t render the same way they did.

Don’t get me wrong - that is a good thing. I don’t miss writing all of those code forks:

var is_nav = ((agt.indexOf('mozilla')!=-1) && (agt.indexOf('spoofer')==-1)
&& (agt.indexOf('compatible') == -1) && (agt.indexOf('opera')==-1)
&& (agt.indexOf('webtv')==-1) && (agt.indexOf('hotjava')==-1));

BTW, one version of browser sniffing script is about 100 lines loooong (not counting comments).

Of course, we all got wise and discovered object detection - testing for a browser’s ability to recognize an object, instead of looking for the browser’s name and version:

if(document.layers){
// do something for Netscape
}
if(document.all){
// do something for IE
}

This was a huge improvement, as it was the beginning of forward-compatible thinking. Chances are, if a browser version can detect a certain object, it’s next version will be able to as well. After all, there are not too many products that lose features with a new release.

Then came the Web Standards movement, thank goodness, and the smart folks started to change their ways. Heroic grass-roots coders that were going to change the web-world one page at a time. Suddenly, code became simpler again and best of all, started to look OK on most of the browser flavors. I still remember having heated discussions with a content editor about the fact that NN47 had 3px more padding than IE5.0 on a list item, and that maybe, that was OK… Alright, we still have those debates sometimes, but the names have changed.

There are still folks out there that like to serve up different branches of their pages for various browsers, but my opinion is: If you need more than one version of the code, rethink your code.

Besides, I don’t want to doing sniffing on Safari…

Hello World

June 22nd, 2007

garouttecom.pngWell, it has been six years since I put the catchy “There’s nothing to see right now” on the front page of garoutte.com. I think that is long enough. In fact it may be some Internet record for the longest un-updated page around.

Actually, looking at it now, it kinda fits in with the new web2.0 minimalism. Tiling textured pattern background, muted colors and lots of neutral color. And the block of orange - the web2.0 power color. It just makes you want to click it, doesn’t it?

Well, that little orange box doesn’t want to be clicked - thanks to a line or two of javaScript, it dances away from your mouse in a game of keep-away. In case you’re curious, here’s the method:

function movit(){
if(document.getElementById){
var x = document.getElementById('accent');
x.style.display="none"; x.style.top = Math.floor(Math.random() * 400); x.style.left = Math.floor(Math.random() * 600); x.style.display="";
}
}

Now, keep in mind, this was scripted well before the advent of the fabulous javaScript libraries and object oriented styles of scripting, so I might change a few things if I were to write this today.

The second part of this feature is the little orange accent. I didn’t want to use an image, so I created a small div. The div has an event attached to it to fire the movit method on mouseover.

<div id="accent" onmouseover="movit()"> </p>

So here is how the effect works: An unsuspecting user comes to the web page and places their mouse on the accent div to click it. The method fires, hides the div, gets a random point for the top and left position (within a 400 x 600 pixel area) and displays the div at that new, random location.

It does it over and over again. I just wish I had coded a log of how many times the div got repositioned…