How well do you know prototype

or taking advantage of those extra 100 KB in your page

Let's be honest - I'm tired of answering same questions over and over again. Prototype.js is a widely used javascript library with somewhat confusing online documentation. I personally find API reference to be a great resourse overall (with few glithes of course), but it's far from being newbie-friendly. I've been developing with prototype for almost a year now and have been spending a lot of time on the IRC channel. It's hard to explain what kind of nonsense people are asking sometimes. It seems to me that most of the time prototype is used at 15%, not more. I'm not surprised anymore to see Ajax.Request used with document.getElementById on one line

Update: How well do you know prototype :: part II

Here, I've collected most common use cases that do NOT use all of prototype's capabilities and their simple solutions. I hope this will be a basic checklist to go through when developing for your next project. So... Here we go:

1
The wrong way:
document.getElementById('foo')
The right way:
$('foo')

Surprisingly some people actually don't know about this one ( including ~100KB file just to use Ajax.Request family )

2
The wrong way:
var woot = document.getElementById('bar').value
var woot = $('bar').value
The right way:
var woot = $F('bar')

Handy shortcut for reading a value of a form control

3
The wrong way:
$('footer').style.height = '100px';
$('footer').style.background = '#ffc';	
The right way:
$('footer').setStyle({
	height: '100px',
	background: '#ffc'
})

Dreaming about IE behaving W3C way? Not happenning! (but second construct will make you forget about cross-browser glitches)

4
The wrong way:
$('coolestWidgetEver').innerHTML = 'some nifty content'
The right way:
$('coolestWidgetEver').update('some nifty content')

One of those simple ones yet quite often forgotten. Yes, I know they are almost the same but I want to see you doing THIS with the first one
(isn't chaining just cool?)

$('coolestWidgetEver').update('some nifty content').addClassName('highlight').next().hide()

5
The wrong way:
new Ajax.Request('ninja.php?weapon1=foo&weapon2=bar')
The right way:
new Ajax.Request('ninja.php', {
	parameters: {
		weapon1: 'foo',
		weapon2: 'bar'
	}
})

Cleaner and better structured parameters definition

6
The wrong way:
new Ajax.Request('blah.php', {
	method: 'POST',
	asynchronous: true,
	contentType: 'application/x-www-form-urlencoded',
	encoding: 'UTF-8',
})
The right way:
new Ajax.Request('blah.php')

All of these options are in Ajax.Request by default! "method: 'POST'" happens to be on every second pastie page I've seen
(Still don't believe in JS inheritance? You don't have to. Just take advantage of it)

7
The wrong way:
Event.observe('myContainer', 'click', doSomeMagic)
The right way:
$('myContainer').observe('click', doSomeMagic)

This one is debatable but second way is more Object Oriented (well... sort of) and easier to chain (So decide for yourself)

8
The wrong way:
$$('div.hidden').each(function(el){
	el.show();
})
The right way:
$$('div.hidden').invoke('show')

Here's a typical "each overuse". We have invoke for such things, folks! Sadly not many people know about it.

9
The wrong way:
$$('div.collapsed').each(function(el){
	el.observe('click', expand);
})
The right way:
$$('div.collapsed').invoke('observe', 'click', expand)

Ha! Take this! Invoke can also be used for event handling when iterating over a collection of elements. It's really easy, isn't it?

10
The wrong way:
$$('input.date').invoke('observe', 'focus', onFocus);
$$('input.date').invoke('observe', 'blur', onBlur);
The right way:
$$('input.date')
	.invoke('observe', 'focus', onFocus)
		.invoke('observe', 'blur', onBlur)

Somehow people tend to forget about "chaining nirvana". Don't like the way it looks? Think about saving some time by NOT invoking $$ twice!

11
The wrong way:
$('productTable').innerHTML = 
	$('productTable').innerHTML + 
	'<tr><td>' + productId + ' '
	+ productName + '</td></tr><tr><td>' 
	+ productId + ' ' + productPrice + 
	'</td></tr>'
The right way:
var rowTemplate = new Template('<tr><td>#{id} #{name}</td></tr><tr><td>#{id} #{price}</td></tr>');
$('productTable').insert(
	rowTemplate.evaluate({
		id: productId,
		name: productName,
		price: productPrice
	}))
)

No I'm not kidding. This has been posted to #prototype and something was wrong with it (hmm... I wonder what)
Templates are great for those nasty HTML strings. Those humongous concatenated constructs make me feel slightly nauseous
evaluate takes care of all the parsing in a nice structured way

That's all for now. Stay tuned as there is always a room for improvement!

Created by kangax
Questions? Suggestions? Find me in #prototype [kangax] or shoot me an email [ kangax@gmail.com ]