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]:
- searchPlay.init() is ran after the page has loaded
- this.s is set as an element (object) reference to the input element
- this.orig stores a string of the original value of the input element
- a ‘focus’ and ‘blur’ event is attached to the input element to run the searchPlay’s focus and blur methods
- 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
- 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>]




December 14th, 2005 at 2:55 am
Sorry dude, just a feeling … like the script. ;)
December 14th, 2005 at 4:06 am
Dustin, the input element in your example has an ID “search”, but in your JS code you reference it with
$('s').December 14th, 2005 at 5:56 am
Excellent article,you always make it so simple :)
December 14th, 2005 at 7:43 am
This one really reminds me of the 24Ways series, you should have saved this for over there. Simple and to the point, the way it should be.
Couple questions…
> (3 of them being methods [1 public])
What exactly, makes a method (function) private in Javascript?
If you’re recommending the usage of functions from the prototype library, why not use the built-in event listener functions (other than the fact that you don’t like libraries)?
December 14th, 2005 at 10:14 am
wow. that’s exactly 50 words…you have no idea how long it took for me to get it that low.
December 14th, 2005 at 10:15 am
Oh btw, who won the last one?
December 14th, 2005 at 11:25 am
Thanks Igor for pointing that out. My mistake.
Great responses guys! I currently haven’t decided a winner for yesterday’s article.
Hopefully today’s example was simple.
Justin,
Although not as strict as some server side languages, a public method is really just a method that is called from outside the object. The two private ones are methods that other methods within the object can call itself. Kind of like tools for itself.
I suppose technically there’s nothing stopping you from actually calling those methods outside the object, but declaring them as such in your code will help other developers [and yourself] not to accidently call it.
The Y! vs G answers are looking good as well! I’m expecting 50/50. And no need to suck up. This requires your complete honesty. :)
December 14th, 2005 at 12:18 pm
I’ve heard of private function in Javascript, but have never actually seen them in use. The best tutorial on the subject I found would be this:
http://www.crockford.com/javascript/private.html
I was able to get a little private/public sample running using the samples in the tutorial above. Pretty cool stuff, I had no idea you could do such a thing.
December 14th, 2005 at 2:56 pm
A trick question, imo, as it appears that the two companies are heading in different directions, having started from different starting points in the first place! But I’ll focus on search :-)
December 14th, 2005 at 3:00 pm
December 14th, 2005 at 6:00 pm
Nice script … Like the use of Objects.
I’m not quite sure if I like the term “search play” but I can’t think of anything better.
December 14th, 2005 at 10:24 pm
In this Google vs Yahoo! fight, Yahoo! Wins. Why you ask? Because my dad uses Y!, and He’s the biggest player in this game. He’s the average online user. He wants stock quotes, movie times, maps, news, and he gets. He gets it all from Yahoo!
December 15th, 2005 at 2:35 am
December 15th, 2005 at 11:50 am
December 15th, 2005 at 9:57 pm
I think Tony’s comment is actually a reason why Yahoo! has an edge. When you say “Google”–people think search. The fact that their brand has become synonymous with search is a limiter. You “google” someone to get info and then you bounce–off to the site/answer/info you wanted to find.
You can’t Yahoo! someone–correct. That is because Yahoo! is many things to many people. For some just communication (mail, messenger). For others, a place to meet and share (360, groups, Flickr, del.ico.us, etc). You come to do one thing, become a loyal user and adopt that and other services–all the while spending more time and viewing more ads$$$$.
In conclusion, (and though I’m over 50 words), Google Schmoogle.
December 21st, 2005 at 12:18 am
This is a double post from a previous day, but this one fits the blockquote rule. Very sorry for the 2x post.
December 21st, 2005 at 2:31 am
Yahoo wins. Y? Flickr. Del.icio.us. Next generation web. Social theory is bar-none. Need I say more?
-Derek
December 21st, 2005 at 3:26 am
Nice way of tackling this problem.
Do you know you could go about tackling this to handle more than one field in a form? For example, name and email address?
I’ve racked my brains trying to find a way to adapt your function but am getting nowhere.
December 21st, 2005 at 11:20 am
@Mike:
Abstration. By pulling out the object you’re ‘playing’ from the object literal, then passing it in as an argument into the
initmethod, you could, perhaps, apply this to as many input elements as you’d like.Eg, init would look like this:
function pageListen() {searchPlay.init('s1','s2','s3');
}
Then figure it out from there…
*Hey, I gotta give you ’some’ work to do.*
December 21st, 2005 at 4:29 pm
Thanks for the reply Dustin, I’ll have a think about tackling it in the manner you’ve suggested above. Will be sure to let you know how I get on.
December 22nd, 2005 at 10:23 am
Ok, I’ve tackled the problem now and have got this working with multiple input elements.
There’s a little write up at:
http://www.mikerumble.co.uk/examples/javascript/toggle-input-text.html.
January 13th, 2006 at 12:26 am
[...] Tips ever. Sarven Capadisli http://www.csarven.ca/ Sarven just had some solid answers. 2) JavaScript Search Play in Object Notation Yahoo vs Google i [...]
August 11th, 2006 at 1:40 am
you might put an exaple in the start so it’s be easier to get what the code is supposed to do.