Generic-user-small Jason Pecor 6 posts

I just purchased/downloaded the PDF of this book yesterday, excited to start building slick UI’s for my projects. I wanted to give my first impressions of the book, and some recommendations for making Prototype more accessible to “the rest of us.”

I’m a so-called “Hybrid Designer” meaning I’m from a graphic design background, and slowly migrated into programming as the industry began to demand it. My programming background consists almost entirely of PHP, and my only real exposure to Object-Oriented programming is to the extent that it is implemented in PHP 5. I write standards-compliant markup, CSS, and unobtrusive JavaScript; I’ve used AJAX on a very small scale; And, I’ve manipulated the DOM using the standard browser-supported methods.

As of yesterday, I thought I was doing well. I thought I had a pretty good handle on things. Then I was served an extra large helping of humble pie! You can pass a function as a parameter? Who knew?! But that’s okay. I pressed on, eager to get to chapter 7, where the DOM would become fun, and the magical powers of Prototype would be layed at my feet.

The chapter started off being very promising. Then, at the bottom of page 132, when you’re itching to get your feet wet with some simple exercises, you’re hit with a bold heading to the effect of “Now, Let’s Rebuild Google Maps From Scratch”...”Building a Staff Manager.” ARGH! How about starting with something simple? Every DOM book I’ve read starts with the most generic exercise there is… attaching an alert() call to the ‘click’ event of an <a> anchor tag, starting with “document.onload” ( or document.observe(‘dom:loaded’, [listener]) in this case ). It reminds of my first time behind the wheel when my driving instructor casually instructed me to “take the interstate; it’s faster.” Again, ARGH!

For people such as myself, I think a little more hand-holding would be much appreciated in Chapter 7. This way knowledge of the syntax builds gradually through use. Perhaps such hand-holding could be relegated to an appendix, but I definitely see a need for this.

All said, I am really enjoying the book. It’s eye-opening, entertaining, and (as I mentioned earlier) humbling!

 
Generic-user-small Jason Pecor 6 posts

I thought, rather than just complaining, maybe I could provide some simple examples myself as I learn Prototype from the book. Here is the simple “Hello, World!” alert exercise I mentioned above:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script type="text/javascript" src="prototype.js"></script>

    <script type="text/javascript">

    // document.onload

    document.observe( 'dom:loaded', function()
    { 
        $( 'helloWorld' ).observe( 'click', sayIt );
    } );

    // custom functions

    function sayIt( event )
    {
        alert( 'Hello, World!' );
        event.stop();
        return true;
    }

    </script>

    <title>PrototypeTest</title>
</head>

<body>
    <a href="ignored.html" id="helloWorld">Click Me</a>
</body>

</html>
 
Generic-user-small Jason Pecor 6 posts

Here is another example, this time using the $$() magic search, and the incredible .each() method to attach the “Hello, World!” alert to all <a> anchors with a class of “helloWorld”.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script type="text/javascript" src="lib/prototype.js"></script>

    <script type="text/javascript">

    // document.onload

    document.observe( 'dom:loaded', function()
    { 
        $$( 'a.helloWorld' ).each( function( instance, i ) { instance.observe( 'click', sayIt ) } );
    } );

    // custom functions

    function sayIt( event )
    {
        alert( 'Hello, World!' );
        event.stop();
        return true;
    }

    </script>

    <title>PrototypeTest</title>
</head>

<body>
    <a href="ignored.html" class='helloWorld'>Link 1</a>
    <a href="ignored.html" class='helloWorld'>Link 2</a>
    <a href="ignored.html" class='helloWorld'>Link 3</a>
    <a href="ignored.html" class='helloWorld'>Link 4</a>
</body>

</html>

For more examples of using $$(), see pages 45 – 47. Examples of .each() are sprinkled throughout the book, so check the Index.

 
Generic-user-small Jason Pecor 6 posts

Here is an example of using toggle() to show/hide a <div> element.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script type="text/javascript" src="lib/prototype.js"></script>

    <script type="text/javascript">

    // document.onload

    document.observe( 'dom:loaded', function()
    {
        $( 'showHide' ).observe( 'click', makeToggle );
    } );

    // global functions

    function makeToggle( event )
    {
        // Change <a> nodeValue     NOTE: event.element().firstDescendant().nodeValue will not work (why?)

        event.element().childNodes[0].nodeValue    = ( event.element().childNodes[0].nodeValue == 'Hide' ? 'Show' : 'Hide' );

        // Show / Hide <div>

        $( 'togglable' ).toggle();

        event.stop();
    }

    </script>

    <style>
        *            { font-family:Arial, Helvetica, sans-serif; color:#036; margin:5px; }
        #showHide    { display:block; float:left; padding:5px; border:1px solid #aaa; }
        #togglable    { display:block; float:left; padding:5px; background-color:#036; color:#fff; }
    </style>

    <title>PrototypeTest</title>
</head>

<body>
    <a href id='showHide'>Hide</a>
    <div id="togglable">I am visible!</div>
</body>

</html>
 
Headshot_120px_small Christophe P... 28 posts

Hey Jason!

Thanks for the feedback. I’m delighted you do find the book helpful, although perhaps not as hand-holding as you were hoping.

The book’s idea is, indeed, not to explain JavaScript itself (other books do that wonderfully well), although I sometimes pause for a moment to quickly describe a language feature or another. The book is about the libs, so we dive into these. However, I agree that lowering the barrier to entry sometimes would be good (although this makes the book bigger and bigger, to the point where it might scare off quite a few people!).

Allow me to thank you for your examples and the desire to help out that drove them, and let me comment on those to help you out in turn:

First one: just fine, although I would personally recommend, most times, to start the handler with a event.stop() call (it lets me abbreviate code by returning instead of using (potentially nested) if/else and stuff).

The $$ example: ah, a prime case of over-using each and under-using invoke. Here’s the culprit:

$$( 'a.helloWorld' ).each( function( instance, i ) { instance.observe( 'click', sayIt ) } );

You see, the anonymous function is unnecessary overhead here, because all it does is invoke the same method on each element, with the same arguments. That’s a prime case for invoke:

$$('a.helloWorld').invoke('observe', 'click', sayIt);

Isn’t it sweet? Plus, it does not use an anonymous function internally, so it’s faster, too!

In the same manner, pluck and map optimize common iteration patterns; see the book’s dedicated sidebar and the online API docs for details and cross references between all those.

Third example: the toggling thing. First off, the markup:

<a href id='showHide'>Hide</a>

Is not valid XHTML. The href attribute is here pretty useless, as you don’t have an accessible (i.e. non-JS) alternative. On the other hand, stripping it entirely will make the link not react to click, and even sometimes not render as a link, on a few browsers. So you should just provide the classic href="#" tweak. Also, inline elements such as a are not allowed directly within body, according to the XHTML 1 Strict DTD. Just wrap it inside a paragraph to be fully compliant ;-)

Now, the code you’re using to change the contents:

event.element().childNodes[0].nodeValue    = ( event.element().childNodes[0].nodeValue == 'Hide' ? 'Show' : 'Hide' );

This is typical half-Prototype code, e.g. half old-school-doing-it-all-myself, way-too-much-DOM-intimacy way, and half Prototypish way. You shouldn’t care about childNodes: that’s raw DOM stuff. Incidentally, this (only) child node is a text node, which makes it outside the scope of firstDescendant(): the DOM traversal methods in Prototype only care about element nodes (as well they should).

What you’re trying to do here is change the contents of your toggler, toggling between two states. First, you should avoid multiple traversals for no reason. Second, you can either go with innerHTML (which is reasonably well supported for such simple purposes) and update, or still go DOMish.

The Proto way:

var contents = event.element().innerHTML;
event.element().update('Hide' == contents ? 'Show' : 'Hide');

The DOMish way:

var contents = event.elements().firstChild;
contents.nodeValue = ('Hide' == contents.nodeValue ? 'Show' : 'Hide');

There, I hope this helps.

In addition to this forum, I suggest you keep an eye on the book’s blog for upcoming tips and tricks, answers to the “Neuron Workout” sections, announcements, challenges, quizzes, and more!

 
Generic-user-small Jason Pecor 6 posts

Christophe,

Thanks so much for your reply. As you can see, I’ve only ever worked with the DOM, so the “Ways of the Proto” are totally new to me. I just received my paperback copy of your book in the mail, and I’m excited to begin rewiring my brain to do things the efficient, Prototype way. I’ve been charged with training our development team in Prototype, so your book and blog should be excellent resources.

Thanks again… Merry Christmas.

 
Generic-user-small Jason Pecor 6 posts

Oh yeah, you’re absolutely right about the <a> tag not being allowed directly under the <body> tag in xHTML 1.0 Strict. I believed you, but wanted to try it out for myself… my validator yelled at me.

The missing ‘href’ was a case of coding in a hurry :).

7 posts, 2 voices