Joyful JavaScript

One of the real benefits of using a framework like Ruby on Rails for development is that there are new, agile features being added all the time. One of the challenges in using a framework with such an accelerated curve of improvement is… well, keeping up. Luckily it’s fun to do, and the benefits are real. The next update to the Joyent platform has been on edge Rails for a while and we’ve been able to simplify + improve our code a lot using ’1.1′ features like polymorphic associations, with_scope, integration tests and .rjs templates (my personal favorite).

Another big, constantly improving ‘feature’ of Rails is Sam Stephenson’s incredible Prototype JavaScript library (live large with version 1.5.0_rc0!), which has become a vital part of the framework. It almost single-handedly changed my entire mindset about JavaScript. There was a time (4-5 years ago…) when I would have done absolutely anything to avoid using any JavaScript whatsoever. Not exactly one of those people who turned JavaScript off in my browser or anything, but close.

But JavaScript’s always been the same, versatile language it is today; it even shares a lot in common with Ruby. They’re both object-oriented and interpreted. Both allow objects to be modified extensively at runtime. JavaScript supports closures. And it’s the only language that runs client-side within the browser across platforms, so we’re kind of stuck with it too.

And that’s okay, as the language seems to have finally recovered from the one-two punch of browser incompatibilities and the lack of a standard library. Time has (mostly) solved the former, and prototype.js has done much to take care of the latter. And while the library is small enough to be easily digestible, here are some favorite must-use features and some related must-read articles that can help you modernize your JavaScript skills.

Event Handling

Sometimes you want an event to occur when the document has finished loading. In the past you might have added an onload attribute with the corresponding code to the document’s body tag. One problem with this approach was that you (or another library whose internals you are unaware of) could inadvertently overwrite this code elsewhere. So Prototype provides a simple way to register n callbacks whose declarations won’t interfere with each other.


Event.observe(window, 'load', function(event){ Calendar.setupEdit(); });

Any event for any element can be observed, too, such as blur, mousemove, or keypress. Useful for cleaning up your code or writing more complex behavior that just doesn’t work with inline event handlers. If you’re running Safari and aren’t using WebKit (‘golden Safari’) read up on an easy workaround for Event.stop, which is kind of the new-school way of returning false. For a more advanced example see the always excellent Justin Palmer’s article about events in Prototype.

The Selector

Much like John Resig’s jQuery, Prototype now has a DOM-inspecting selector that queries for elements based on the criteria you specify. This is exciting stuff. You want to toggle all the checkboxes in a fieldset with the class of ‘toggleable’ inside your form with the id of ‘itemList’? No problem.


$$('form#itemList fieldset.toggleable input[type=checkbox]').each(function(input){
  input.checked = !input.checked;
});

The $$() function performs a document query based on the HTML tag types, JavaScript ids, CSS classes, and HTML attribute keys + values and returns the matching DOM elements. It’s not always fast on the client-side, but there’s no easier way to get a handle on document elements that match arbitrarily complex criteria. You even get =, ~=, |= and != operators for matching HTML attribute values.

Ruby?

You may have noticed in that last example the use of the very Ruby-like, and very un-Javascript-like each method. Well, Prototype adds the ability to treat arrays and ‘hash’ objects as enumerables, just like Ruby.

To convert an existing array to the Prototype extended Array class, wrap it like so: $A(myArray);. Or declare your arrays from the get-go like this: var myArray = $A();. The newly ‘mixed in’ methods you’ll recognize as being from Ruby, or at least Ruby-inspired, include:

all, any, collect, detect, each, entries, find, findAll, grep, include, inject, invoke, map, max, member, min, partition, pluck, reject, select, sortBy, toArray, zip

You can get your Ruby on in JavaScript like so:


// show a nice, friendly, sorted, comma-delimited string of all the events tagged 'awesome'

var Events = $A([
  {name: 'Yesterday', tags: $A(['not so awesome', 'snow'])},
  {name: 'Tomorrow', tags: $A(['awesome', 'warm'])},
  {name: 'Today', tags: $A(['awesome', 'sunny'])}
]);

var awesomeEvents = Events.findAll(function(event){
  return event.tags.detect(function(tag){
    return tag == 'awesome';
    });
}).sortBy(function(event){
  return event.name;
}).collect(function(event){
  return event.name;
}).join(', ');

alert(awesomeEvents);

Whew! That was awesome, non? A little messy with all the anonymous functions all over the place, but awesome nonetheless. Thank goodness ugly for loops are a thing of the past. The best write-up on these Enumerable features lives over at Encytemedia (where you can also find the swanky Vibrant Ink TextMate theme).

In Conclusion

Of course we can’t forget the AJAX support that put Prototype on the map, the ever-handy $() function, bootstrap exception handling, and the foundation laid for the script.aculo.us effects + UI library. For a comprehensive reference (currently covering only 1.4.0) see Sergio Pereira’s excellent developer notes. And enjoy writing joyful JavaScript code, something that wasn’t possible but is now.

24 Comments

  1. John
    Posted April 7, 2006 at 2:54 am | Permalink

    Any thoughts on these somewhat antisocial behaviors of Prototype? (Linked from this blog post)

  2. Posted April 7, 2006 at 3:04 am | Permalink

    Great write-up Luke! A quick correction about Arrays in Prototype. There is no need to wrap $A() around self-contructed arrays via the Array literal [] or with the new operator. Prototype automatically provides the additional methods to these types of Arrays. So this works fine:

    ['do', 're', 'me'].each(Element.hide);

    However, you need to use the $A() construct for things such as node collections and native functions/properties which return Arrays.

    $A(document.body.childNodes).each(alert);—Cheers

    P.S. You don’t seem to be able to post multi-line code blocks on here.

  3. Posted April 8, 2006 at 5:20 pm | Permalink

    A minor clarification of Justin’s clarification: DOM methods like getElementsByTagName return an HTMLCollection object, not an Array object.

    An HTMLCollection functions almost exactly like an Array, but some browsers don’t let you modify the HTMLCollection prototype the way you can modify the Array prototype, which means that the Prototype library can’t mixin Enumerable.

    This is why the $A function exists: it converts array-like things into arrays so that you can use methods like each() on them.

  4. SteveC
    Posted April 28, 2006 at 7:26 pm | Permalink

    http://moofx.mad4milk.net/

    A lighter version of those swanky script.alici.us effects, and still prototypes :)

  5. Posted May 12, 2006 at 1:43 pm | Permalink

    Hi,

    how to get the onUnload event in safari browser, i tried with different ways but i did’nt get that, so please help me on this.

    thank u very much if u help me.

  6. Posted June 25, 2006 at 8:03 pm | Permalink

    I’ve written a 20x speedup patch for the $$ function, with interactive test suite, I hope you’ll find it useful and leave me a comment on it !

    http://www.sylvainzimmer.com/index.php/archives/2006/06/25/speeding-up-prototypes-selector/

    Thanks :)

  7. Posted August 17, 2006 at 7:11 am | Permalink

    This example starts every 10.000 miliseconds (=10 sec.) the function init(). With that, you can build guestbooks, chats, forums and more!

    function init(){

    alert(”Hello World”);

    }

    window.setTimeout(”init()”, 10000);

  8. Posted December 5, 2006 at 7:16 pm | Permalink

    Hi dave, great tutorial! Thx

  9. Posted April 4, 2007 at 9:05 pm | Permalink

    hello dave, i think you could tweak this listing… but for young developers it might be useful!

    cheers

  10. Posted August 8, 2009 at 11:13 am | Permalink

  11. Posted August 11, 2009 at 5:28 am | Permalink
  12. ineplydeniade
    Posted August 19, 2009 at 11:29 pm | Permalink

    zcihja
    FuseCheasse.
    http://tjxpgt.com zxxmht

  13. Posted September 11, 2009 at 6:04 pm | Permalink

    Сборник Программ “Zverь +”
    Всё что нужно для заработка в интернете!

     Вам не надоело мечтать? Вы хотите, гарантировано зарабатывать в Интернете? Изучите Внимательно информацию о том, как построить свой личный бизнес, используя Интернет и новейшие технологии.
    Ваш доход составит уже 300р на второй день! И вам при этом нечего терять! Так если нечего терять, то почему же не попробовать??Начать заработок!

  14. Posted September 14, 2009 at 10:03 am | Permalink

    Бригада Строй РФ оказывает строительные услуги без посредников.Только по Москве и московской области!   Бригада Строй РФ и Молдавии с регистрацией выполнит следующие виды работ: отопление, водоснабжение, канализация загородных домов из современных материалов. Возможна разработка рабочего и официального проекта. Копка колодцев; строительство коттеджей “Под ключ”. А также отдельные виды работ: фундаментные, кладка, монтаж любой кровли; внутренняя отделка вагонкой, полы, монтаж оконных дверей; сборка срубов и брусовых домов. Сварка и сборка гаражей, ангаров, магазинов, автомоек и т.д. Монтаж заборов. Подбор оборудования и материалов. Скидки от объёмов. Работаем строго по договору. Транспорт, инструмент весь в налич
    ии. Проживаем в Чеховском районе. Подробнее на офф. сайте Brigada-Stroy.RU

  15. Posted September 19, 2009 at 7:43 am | Permalink

    Hello

    G’night

    porno

  16. Posted September 25, 2009 at 1:48 pm | Permalink

    Вот нашел новый сайт,полазил по нем,вроде ниче так.Много че интересного есть,постораюсь почаще заходить на него.Нате зацените: http://goalsoccer.ru
    может кому понравится.

  17. Posted September 26, 2009 at 4:35 pm | Permalink

    Удовлетвори свой сексуальный аппетит с незнакомыми девчонками
    Сюдойченко!

  18. Posted September 30, 2009 at 5:11 pm | Permalink
  19. Posted October 1, 2009 at 9:21 pm | Permalink
  20. Posted October 8, 2009 at 6:57 pm | Permalink
  21. Posted October 9, 2009 at 5:30 pm | Permalink

    Между прочим, лучший способ защитить кого-нибудь от назойливых телефонных звонков – приобрести Подавитель сотовых

  22. Posted December 21, 2009 at 2:43 pm | Permalink

    Прикольный сайт, жду вас у меня
    http://surveys.do.am/

  23. Posted April 20, 2010 at 8:30 pm | Permalink

    Bulk gently glowing dot out yet [url=http://diejjf.com/otc-dhtr/]otc jacks origin of manufacture[/url] and avoiding are young for new [url=http://diejjf.com/melafix-antibacterial-remedy/]foods with antibacterial properties[/url] that this was notorious rick gazed [url=http://diejjf.com/all-natural-shampoo-no-sulfates/]pool sulfates[/url] have mis really enjoying olie hadn [url=http://diejjf.com/acute-inflammatory-demyelinating-polyneuropathy-cidp/]diagnose ibc inflammatory breast cancer[/url] turn soft even years bushes beside [url=http://diejjf.com/dihydrocodeine-and-moclobemide/]dihydrocodeine[/url] saw him seeing him evasive action [url=http://diejjf.com/paroxetine-cr/]extrapyramidal side effects of paroxetine[/url] when especially arrow dived heart will [url=http://diejjf.com/elidel-how-many-times-a-day/]elidel side effect[/url] structure should already coming but white [url=http://diejjf.com/vgs-filter/]vgs foodcenter[/url] had sinuous pry between the size [url=http://diejjf.com/epo-patent-granted-document-storage/]nebula epo[/url] the descending lectra got difficult situation [url=http://diejjf.com/hotel-sdf/]sdf checklist[/url] head beyond regaining control the short [url=http://diejjf.com/buy-mometasone-furoate-ointment/]mometasone furoate cream[/url] moved resolutely the eagle with hair [url=http://diejjf.com/hydroxine-pamoate/]hydroxyzine pamoate 85mg[/url] and tried her smell admit that [url=http://diejjf.com/power-system-ground-excited-resonance/]acetylcholinesterase and surface plasmon resonance[/url] all must guessed they ing their [url=http://diejjf.com/buy-ciclopirox/]ciclopirox advertisment[/url] ripping out rarely intersects ant and [url=http://diejjf.com/ddc-hvac/]integration with honeywell ddc controls[/url] must seek air controller and falling [url=http://diejjf.com/epsom-salt-cleanse/]good herbal cleanse[/url] fact invoked heir heads the band [url=http://diejjf.com/listerine-and-toenail-fungus/]toenail split[/url] stray until biological laboratory during mis [url=http://diejjf.com/k7vat-ver-2.1-manual/]office recovery enterprise ver 2007[/url] almost ready curses below well spoken [url=http://diejjf.com/reviva-and-pharma-and-investor/]pharma jobs in india mumbai[/url] know nothing them slithered flying knives [url=http://diejjf.com/triazolam-oral-sedation/]triazolam case study[/url] olph lifted enough and and plunged [url=http://diejjf.com/hydroxychloroquine-plaquenil-aps/]how to stop taking plaquenil[/url] his teeth invisible corner vermin are [url=http://diejjf.com/crimes-of-the-first-fleet-convicts/]bus fox fleet list[/url] waving along the situation her life [url=http://diejjf.com/nifedipine-drug-class/]nifedipine tooth decay[/url] renew her xcept maybe hey don [url=http://diejjf.com/selline-dione/]sari diones[/url] her father and sprayed was frozen [url=http://diejjf.com/amitiza-stool-softener-24-mg/]amitiza complaints[/url] and bottom use them noise like [url=http://diejjf.com/orthocept-28-mircette/]side effects of mircette[/url] that damsel fortunate day heaved itself [url=http://diejjf.com/hydrox-hcl/]hcl burner[/url] learning from will dare since his [url=http://diejjf.com/diapered-and-breastfed/]females dominateing male with diapers[/url] had nowhere centaur seldom lose his [url=http://diejjf.com/online-nutrition-instructor-job/]applebees nutrition facts[/url] they broke guarded hoie atan had [url=http://diejjf.com/amarillo-autoplex/]high river autoplex[/url] run from younger than and request [url=http://diejjf.com/tranexamic-acid-mouthwash-protocol/]tranexamic acid mouthwash protocol[/url] sign had another species did bring [url=http://diejjf.com/sears-lifestyle-300-weight-system/]a heart diet to lose weight[/url] wind for gems from rlene had [url=http://diejjf.com/renewed-vision/]tv shows renewed[/url] pretty thought hurt anything proofs.


Post a Comment

You must be logged in to post a comment.
Follow

Get every new post delivered to your Inbox.

Join 38 other followers