How well do you know prototype (part II)
1) Detecting key events easily
How do we detect which key was pressed? Prototype provides set of key event aliases so that we don’t have to remember that return is “13″ and escape is “27″. Almost all major keys are aliased: KEY_RETURN, KEY_ESC, KEY_TAB, KEY_LEFT, KEY_UP, KEY_RIGHT, KEY_DOWN. See full list in API docs
$('myInput').observe('keyup', function(e){ if (e.keyCode == Event.KEY_TAB) doSomethingCoolWhenTabIsPressed(); })
2) You won’t need event capturing (most likely)
Sometimes I see capturing phase being explicitly set to false in Event’s observe method. The good thing is that it’s set to false by default and you would rarely need to use it. The following 2 lines are fully identical so we can just skip this last argument:
Event.observe('productInfo', 'click', displayProductInfo, false); // 'false' could be skipped Event.observe('productInfo', 'click', displayProductInfo);
or a short way:
$('productInfo').observe('click', displayProductInfo, false); // 'false' could be skipped $('productInfo').observe('click', displayProductInfo);
3) insert() wisely
Another one of those “it’s-there-by-default” values is a position argument of Element’s insert method. Surprisingly it’s not mentioned anywhere in the docs – I accidentally found it wondering through the source one day. insert accepts one of four position values: top, bottom, before, and after. If we omit this argument, it defaults to bottom (and luckily this happens to be the most common case). The following lines behave identically:
new Insertion.Bottom('blogEntry', new Template('<div><h2>#{name}</h2><p>#{content}</p></div>') .evaluate({ name: blogEntry.name, content: blogEntry.content })); // Insertion class is deprecated - it's recommended to use Element's insert method: $('blogEntry').insert(new Template('<div><h2>#{name}</h2><p>#{content}</p></div>') .evaluate({ name: blogEntry.name, content: blogEntry.content }), 'bottom' ); // "bottom" can be skipped $('blogEntry').insert(new Template('<div><h2>#{name}</h2><p>#{content}</p></div>') .evaluate({ name: blogEntry.name, content: blogEntry.content }));
4) Forms gone wild
Plain form submission is quite easy but what if we want to prevent certain elements from being serialized before submitting form via ajax? Let’s take a look at few ways to do this:
Plain form submission using .request
$('register').observe('submit', function(e){ Event.stop(e); $(this).request(); })
Using .getInputs makes it easy to filter out elements based on type and name attributes. In this example we’re serializing elements with name ‘email’ and submitting result to the URI contained in form’s “action” attribute
$('register').observe('submit', function(e){ Event.stop(e); new Ajax.Request($(this).readAttribute('action'), { parameters: Form.serializeElements($(this).getInputs('', 'email')) }) })
Using .getInputs could help most of the time but what if we want to exclude elements that have “multiple” attribute? We might try something like this:
$('register').observe('submit', function(e){ Event.stop(e); new Ajax.Request(this.readAttribute('action'), { parameters: Form.serializeElements($(this).getElements() .reject(function(el){return el.hasAttribute('multiple')}) ); }) })
Wow, what’s going on over here?!
When submit event occurs, we prevent default submit action Event.stop(e), get all form’s elements this.getElements(), iterate over them REJECTING those that have “multiple” attribute .reject(function(el){return el.hasAttribute('multiple')}). The filtered collection is then serialized Form.serializeElements() and is submitted via ajax new Ajax.Request()
This is all very cool but here’s the reason why learning CSS3 selectors might be a good thing (the results from both – reject-based and selector-based filtering are the same):
$('register').observe('submit', function(e){ Event.stop(e); new Ajax.Request($(this).readAttribute('action'), { parameters: Form.serializeElements($$('#register input:not([multiple])')) }) })
Abhijit said:
#hello mate…
nice read … thanks for reminding us the best and simplest use of prototype … i had read http://perfectionkills.com-checklist/ this before.
best regards
Abhijit
Dan said:
#Good stuff … keep ‘em coming.
Tobie Langel said:
#Element#insert’s not mentioned in the docs as it isn’t part of a stable release yet.
Ralph Corderoy said:
#The article needs checking for inconsistent use of “this”. Sometimes it’s “this” and other times it’s “$(this)”, including in the explanatory text. Cheers, Ralph.
Yeago said:
#Keep in mind that item #3 uses deprecated syntax which doesn’t work (at least in FF, as of 1.6).
elem.insert('stuff','top')
has become
elem.insert({top: 'stuff'})
rubyruy said:
#On #4:
e.stop() // instead of Event.stop(e)
;)
Daniel Skinner said:
#This is good stuff, I want more!
It would be nice to have a complete list one a page somewhere or a ‘cheat sheet’ for this kind of thing. Prototype is so big it gets hard to remember how to do it the prototype way everytime!
Sunny said:
#One of the greatest guide on prototype i have ever seen!
looking for more guide from you! Thanks for the share.
jQuery Fans said:
#jQuery Rulezzzz !!!!!
Attantgah said:
#In most cases a product’s rating went down, expanding the range between highest and lowest rated.Unlike Kaspersky, Symantec provides Norton users with little explanation of its features or settings, either in the configuration settings or on its technical support section. Also we don’t like Norton’s dependency on Internet Explorer to explain Help items or services provided by Symantec (windows pop up in IE even when Firefox is your default browser), or that fee-based services have once again crept into the technical support section. Having improved a lot
last year in Symantec’s flagship antivirus product, it makes sense we’d see more modest enhancements for this year’s Norton AntiVirus 2008. While Norton
AntiVirus.
AssebyAbsonee said:
#Hi people
As newly registered user i just want to say hi to everyone else who uses this board 8-)
Aleem said:
#Regarding #3, I would suggest taking that off the list. Users should stick to explicit declaration of element’s position as ‘bottom’ for the very same reason you mention. Since its undocumented, there are no guarantees and developers are free to change this behaviour in the next version for that very reason.
In fact, it might also be irresponsible to encourage usage of undocumented features as it imposes unnecessary restrictions on developers to support unintended behaviour.
dy3g0s said:
#thank you