September 5th, 2006

The Flurry Continues: More Prototype Updates

14 comments on 1028 words

The last Prototype update was nice, but it doesn’t compare to this update in terms of overall awesomeness. I think Sam worked on labor day or something, because we’ve got a host of new additions and fixes to play with now.

Before we get started, I’m gonna be using this chunk of html for the examples:


  <div id="sidebar">
    <ul id="menu">
      <li><a id="cool" href="#" title="Cool">Cool</a></li>
      <li><a href="#" title="This Rocks">This Rocks</a></li>
      <li id="selected"><a href="#">I am selected</a></li>
    </ul>

    <ul id="actions">
      <li><a href="#" title="Delete this">Delete</a></li>
      <li><a href="#" title="Edit">Edit this</a></li>
    </ul>
  </div>

Events with a side of arguments

In days past bind was great at accepting additional arguments, however, bindAsEventListener didn’t get this love until now. We can pass those additional arguments to bindAsEventListener with ease:


  var Clicker = Class.create();
  Clicker.prototype = {
    initialize: function(link) {
      Event.observe(link, 'click', this.onClick.bindAsEventListener(this, 'red'));
    },

    onClick: function(event, color) {
      Event.element(event).setStyle({color: color});
      Event.stop(event);
    }
  }

  new Clicker('cool');

Notice how I passed red to the onClick callback? This little class observes the element with the id of cool, and when clicked set’s it’s color to whatever value we pass as the color. If we wanted to add additional arguments we could.

Traversing the DOM

What a pain eh? Not anymore! We now have some really cool methods for Element to help us traverse the DOM: up, down, previous, and next. Let’s fire up Firebug and test:


   console.log($('menu').up()); //<div id="sidebar">
   console.log($('menu').down()); //<li> (First child li element of menu)
   console.log($('menu').next()); //<ul id="actions">
   console.log($('menu').previous()); //undefined because menu has no previous siblings

You can also pass tag names and integer indexes (or both) to these methods making them super powerful:


   console.log($('menu').down(2)); //Grabs second li element (index starts at 1)
   console.log($('menu').down('li', 0)); //Grabs first li element(index starts at 0)

After testing this, it seems there might be a bug or just an inconsistency with this. When you don’t supply a tag name, the index starts at 1, if you do supply a tag name, the index starts at 0.

Siblings, Descendants, and Ancestors

There is even more DOM goodness now with these additional methods to Element: ancestors, descendants, previousSiblings, nextSiblings, and siblings. I’m sure most of you can guess what they do, but here it is:


   console.log($('sidebar').descendants()); //Every descendant, even nested descendants
   console.log($('selected').previousSiblings()); //<li><li>  (Both li's before #selected)
   console.log($('actions').ancestors()); //sidebar, <body>, <html>
   console.log($('actions').siblings()); //menu

On the Horizon

There is much more that went into this update, so be sure to checkout the source and give it a run.

While I’ve got your attention I also want to say there is some internal changes happening at camp Prototype. There is a Prototype Core team in the works and we are laying out our ideas for the upcoming versions of Prototype, documentation efforts, and many other things. The paint still isn’t quite dry on this yet so I’ll wait before I talk more on this.

On the documentation front: We have something in the works. We have the API about 80% documented and will have this up for public consumption as soon as we can. This will start off as very basic API docs, but we plan on putting a lot of effort in this as time goes by. On that note, you can send your thanks to Andrew Dupont considering he has worked very hard on the docs.

Until next time!

Discussion

  1. Jack Sleight Jack Sleight said on September 5th

    Hey, that all looks excellent. Something Prototype needs is official documentation, so that’s great news. But it would also be good to have a website where Sam (and any other developers) can give us the progress of the project and development. I’ve been wondering when 1.5.0 would be released and exactly what it would include for ages, but there’s currently no official place where you can find such information out.

  2. Cory Hudson Cory Hudson said on September 5th

    Is there any way to volunteer to help out and join the Prototype Core team?

  3. Thomas Messier Thomas Messier said on September 5th

    Thanks for posting this, good stuff. I’m currently working on extending the Prototype event model to make it easier to add events for right mouse clicking. The subtleties of it are a pain in the ass, but I’m hoping to have something done soon. When I’m done I’ll post it on my blog and see if I actually did something worth a damn…

  4. Cory Lievers Cory Lievers said on September 5th

    Great article. I love this idea.

    Thomas, excellent idea. For a web-application, utilizing the right-click can be very handy. It would be great to have an easy[ier] way to handle it.

    What about browser bookmarking? Would that be something to add into the framework?

  5. Jon Jon said on September 5th

    Great changes. It’s great that prototype is getting a core team as well—that model seems to be the best one for open source projects.

  6. David Zülke David Zülke said on September 5th

    console.log($(‘menu’).down(2)); //Grabs second li element (index starts at 1)

    this seems odd. I’d expect that to grab the child of the first li element. .down().next() should grab the second li.

  7. Justin Palmer Justin Palmer said on September 6th

    Cory: You can volunteer by donating your time to the documentation effort if you’d like.

    David: ‘down’ doesn’t traverse nested elements. It just traverses the immediate siblings of a parent node.

  8. Nicolas Sanguinetti Nicolas Sanguinetti said on September 6th

    Wow, that’s great stuff!

    The work done on prototype 1.5 is pretty impressive, and I can’t wait to get my hands on an official release (of course svn checkouts will do for now ;))

    I completely agree with Jack about an official prototype blog or something to get a little more information on it’s status :)

  9. Scott Durnell Scott Durnell said on September 6th

    Justin,

    Who would we need to contact to get involved in assisting in the documentation effort?

    I have been using prototype for the last 9 months, (after I saw the error in my ways of web programming), and have learned SO much about Javascript programming from examining the code. I would love to return the favor by helping out on such a great framework.

  10. Thomas Messier Thomas Messier said on September 6th

    @Cory: I’ve just put up my patched version of prototype that allows for right mouse click handling up. You can check it out at http://www.epiphantastic.com/index.php/enhanced-prototype-event-model/ . Feeback and constructive criticism is welcome.

    Turns out this new bindAsEventListener enhancement made my life much easier! My code suddenly got much simpler.

  11. Alex Alex said on September 6th

    Is it only me that is bothered by the fact that the code blocks line height and the background image dont line up??? (Silly thing I know, but it bugs me…

    Any how. This CSS fixes it…

    pre { background: #fff url(http://encytemedia.com/blog//images/theme/cdots.gif) 0 2% repeat-y; font-size: 110%; line-height: 189%; color: red overflow: auto; padding: 5px; margin: 0; }

  12. Dustin Diaz Dustin Diaz said on September 6th

    Those are handy methods. It beats using the cleanWhitespace function yourself to make walking the dom easier even with native js methods.

  13. Arrix Arrix said on September 6th

    Justin, “After testing this, it seems there might be a bug or just an inconsistency with this. When you don’t supply a tag name, the index starts at 1, if you do supply a tag name, the index starts at 0.” I think the index start at 0 in both cases. When a tag name is specified, all child elements fall into the result set. $(‘menu’).down(1) would return a#cool.

  14. Alex Alex said on October 5th
    I have started to put together a wiki about Prototype. Sergio Pereira's documentation is wonderful, but this way everyone can contribute to the documentation. It would be much like the annotated PHP help downloadable from php.net. Have a look at http://www.formar.se/prototype

Sorry, comments are closed for this article.