i am dustin diaz

a JavaScriptr...

boosh.

don't worry about it.

JavaScript searchPlay in Object Notation

One of the most overdone, ill-written, obtrusive snippets I always run into is what I call The JavaScript Search Play. What is the search play you might ask? Well, pardon my lack of naming, but it's when (pay attention now) an input[text] element is prepopulated with a value and when the user clicks into it, it disappears. If the user decides not to type anything and just continue on their way, it is repopulated with the original value. However when the user changes the original value, it then becomes 'sticky', meaning that if they unfocus the input element, it remains what the user last typed. Got it? Ok, if that didn't make any sense to you, we're basically going to make what you see in the top-left hand corner of this website [if you have css enabled[which by the way isn't required for this to work]].

First our fearless [x]HTML

This shouldn't look like anything new, but here I will be purposely populating the input element via the value attribute on the element. Albeit some say it's not a good practice to prepopulate your search terms directly into the element... I say... I don't have an opinion. I personally like it because I tend to have fun with random searches for my visitors to tickle with.

input element search box

<form action='/search.php' method='get'>

  <label for='search'>Search

    <input id='s' name='s' type='text' size='15' value='Yahoo!' />

  </label>

</form>

Function Prerequisites

First you'll need a copy of addEvent. It doesn't have to be the one I put together as there are many other great (and some better) renditions of the original addEvent function. If the function "addEvent" doesn't ring a bell, your best bet is just to copy the reference I provided. If you're going to use your own addEvent(), just be sure that you can reference the keyword this properly with your function. Second you'll need the prototype $() dollar function. That can be found in (of course) the Prototype library, or if you're just looking for a quick copy & paste job, feel free to do that right here:

Prototype dollar function

function $() {

	var elements = new Array();

	for (var i = 0; i < arguments.length; i++) {

		var element = arguments[i];

		if (typeof element == 'string')

			element = document.getElementById(element);

		if (arguments.length == 1)

			return element;

		elements.push(element);

	}

	return elements;

}
If you're wondering why I think this function is so sexy, I talked about it in an article about my top ten list of best JavaScript functions ever.

Now let's dance

For more reasons than one, I generally condone Object Notation when writing JavaScript (I'll save that for another article). So if this is new to you, let yourself become sprinkled into the baptism of programming in objects with JavaScript. Let's take a look at the code in its entirety:

searchPlay Object

var searchPlay = {

	s : Object,

	orig : '',

	init : function() {

		this.s = $('s');

		this.orig = this.s.defaultValue;

		addEvent(this.s,'focus',this.focus,false);

		addEvent(this.s,'blur',this.blur,false);

	},

	focus : function() {

		if ( this.value == searchPlay.orig ) {

			this.value = '';

		}

	},

	blur : function() {

		if ( this.value == '' ) {

			this.value = searchPlay.orig;

		}

	}

};
Notice its simplicity and hierarchial structure. Just straight off the bat I can see that the searchPlay object consists of 5 properties (3 of them being methods [1 public]). Second, notice how we've already avoided five possible globals. Every property within searchPlay is local to its own object (that's a good thing). Okay this is great, but what do I do with it. Well, first we need to run init from the page. Also note that this needs to be run from the page level as a function, and not attached as a listener. Easy enough.

running searchPlay.init() after page 'load'

function pageListen() {

  searchPlay.init();

}

addEvent(window,'load',pageListen);
What I particularly like about this style is that it allows me to always add more to the pageListen function. What I love even more about this method is that it allows the developer to constantly use the method init within their scripts. I say this because init() seems to have become the defacto standard when writing a function that "Initiates" a series of functions. Fine, I can buy that... but here we need not worry about possibly writing two functions with the same name... they're now scoped within the object. Thus init() called from "Object A" is now totally different than init() called from "Object B". For example, we may have a pageListen() function that looks like this:

pageListen revised

function pageListen() {

  searchPlay.init();

  togBar.init();

  getStyles.init();

}

addEvent(window,'load',pageListen);
Gosh isn't that a thing of beauty! Anyway, back to our searchPlay object, you can see now how simple it really is. I'll explain it step by step [see above for reference]:
  1. searchPlay.init() is ran after the page has loaded
  2. this.s is set as an element (object) reference to the input element
  3. this.orig stores a string of the original value of the input element
  4. a 'focus' and 'blur' event is attached to the input element to run the searchPlay's focus and blur methods
  5. searchPlay.focus checks to see if the current value is equal to the original value. If it is, then wipe the value so the user doesn't have to delete it themselves
  6. searchPlay.blur checks to see if the current value is blank. If it is, then it changes the current value to the original value.

Why declare 's' and 'orig'

It's good practice. Declaring your properties (and their 'type') at the top of your object allows developers to clearly see their purpose within the object. In some languages, like PHP [with all errors turned on], failing to declare your properties will produce an error in your application.

Parting words

I suck at conclusions. But straight and to the point: This method of "search play" is unobtrusive which in and of itself, improves maintenance, and allows for better accessibility practices.

Today's contest question and book information

The winner of today's contest question will receive a copy of DHTML Utopia: Modern Web Design using JavaScript and DOM by Stuart Langridge. 50 words or less. Yahoo! versus Google. Who wins? And why [be creative]

[We may have some problems with cross posting as this isn't the ideal platform to A) discuss the article and B) give an answer. So please, put your answer to the question in a <blockquote>]

this is who i am

Hi, my name is Dustin Diaz and I'm an Engineer @ObviousCorp. Previously @Twitter, @Google, and @Yahoo, author of Strobist® Info co-author of JavaScript Design Patterns, co-creator of the Ender JavaScript Framework, a Photographer, and an amateur Mixologist. This is my website. Welcome!

On this site I write about JavaScript. You can also follow along with my open-source work on Github.

This site is optimized and works best in Microsoft Internet Explorer 6.