with Imagination: by Dustin Diaz

./with Imagination

A JavaScript, CSS, XHTML web log focusing on usability and accessibility by Dustin Diaz

JavaScript Chaining

Friday, March 9th, 2007

AKA: Proof that JavaScript is an Object Oriented language. AKA: Why JavaScript is a totally kick ass language. Yeah. Anyway. It’s 3am and I’m in Austin Texas writing JavaScript for work at the Hotel and I ran into particular problem that involved something that looked extremely wicked and totally awesome from which immediately afterward I couldn’t believe my fingers just whiddled it onto the keyboard as if sprinkling fairy dust unto the children (I have no idea where that image just came from (nor is whiddled a word)).

Ok so here was my situation. I needed all the values of each “checked” checkbox in a particular form to be concatenated into a comma-delimited string list. That’s it. The purpose was to send these values to a web service where I could perform a batch query on them… and yada yada yada. Anyway, here was the code that came out of this.

JavaScript Chaining

var guids = function() {
    return Dom.query('#product-list input[type="checkbox"]').filter(
         function(el) {
             if ( el.checked == true ) {
                 return el;
             }
         }
    );
}().map(
    function(el) {
        return el.value;
    }
).toString();
console.info('my guids are:', guids);

Pretty cool, huh? Now this need not be an exercise of how to turn this into a one line function or what library can do it better, bla bla bla. But more or less an admiration of the expressive nature you can do with JavaScript. You’ll notice that guid is defined only once, and through chaining, self-invocation, method inheritance, and a sweet querying utility, we’ve essentially assigned the correct value to guid in the end.

To briefly explain what’s going on, you’ll see that I’m using two of the JavaScript 1.6 Array extras called filter and map which allow me to essentially weed out the non-checked checkboxes, and then map those elements with their values. For cross-browser compatibility I used my own sugar arrays.

Starting from the top I’ve assigned guid to an anonymous function which is (immediately) self-invoked and assigned a return value. That return value is an array of elements which is returned by Dom.query (aka Ext.query). Once we have those elements, we filter through the ones that have been checked by validating against the ‘checked’ property. If so, we return it. Once that loop is finished, it returns the filtered array which moves right on to the map method. The mapping will take the value property from each, and return those. Once all the loops have finished, we call the Array object’s toString method (which is inherited from Object’s toString method).

And that my friends, is why JavaScript is sexy.

22 Responses to “JavaScript Chaining”

  1. Dean Edwards

    I’m releasing a library pretty soon which allow you to achieve the same thing with the following code:

    var guids = body.matchAll("#product-list input:checked").pluck("value");

    You’re right. JavaScript is sexy. ;-)

  2. Dustin Diaz

    Dean, that’s very sweet. Looking forward to it. Here here, JavaScript is Sexy :)

  3. Aristotle Pagaltzis

    Hmm, am I missing something? What’s the point of the first anonymous function? Can’t this be written like so?

    var guids = Dom.
    	query('#product-list input[type="checkbox"]').
    	filter( function(el) { return el if el.checked } ).
    	map( function(el) { return el.value } ).
    	toString();
  4. Simon Proctor

    Very nice, it’s a bit like a piece of modern art. The first time you look at it you wonder what’s going on but then it all comes together and you realise that it’s beautiful.

    I’m with you. Javascript is Sexy.

  5. JavaScript Chaining « [REF]

    [...] JavaScript Chaining [...]

  6. Edwin Martin

    Aristotle, I think you’re right.

    But remember it was 3:00 in the night and he was hallucinating ;-)

  7. Binny V A

    I would prefer using .join(","); over using .toString(); - just in case you want to use ‘;’ or something as a delimiter. And by the way, I agree with your conclusion. Javascript is sexy.

  8. Dustin Diaz

    @Aristotle: It can indeed be done that way, and is just as pretty. To speak to Edwin’s remarks, although I may have been hallucinating in the early hours of the day, it came from my second hand nature of using anonymous functions as a pattern that allows possible extensibility to whatever I’m doing since I never know what I’m going to stick in that scope at a later point… An easy parallel example would be like how a designer uses photoshop, but leaves open hidden layers that they could always come back to and enable, duplicate, and mess a bit more around with.

    Another point is that I was seeing this code through the lens of development and rapidness, and not a lens of correction and optimization (I had literally just written a hundred lines before it, and probably another hundred lines after). When I realized I had just written a giant chain without my brain even thinking so, I knew it was worth writing about on the website… even at 3am ;)

    @Binny: Excellent enhancement. That too would add to its portability. But keep in mind there is no function call around this where a delimiter is passed in - eg: The lines above are already passed the point of no return. If I wanted to change it to another delimiter, I would simply remove toString(), and replace with join(';'). The point was more or less the chaining :) - that of which everyone so far, agrees has sex appeal.

  9. MrMunkey

    I’ve been a PHP developer for some time now, and things like this are why I’m using JavaScript for more and more things. Using JavaScript allows you to completely seperate your UI code from your logic. Nice work, I’ll have to throw that in my little bag of tricks :)

  10. Tobie Langel

    Dean… not yet another library! ;-)

  11. Brian Moeskau

    Fyi, if you’re using Ext DomQuery, it supports pseduos like ‘input:checked’ so that you should not need the first anonymous function.

  12. Riddle

    I rediscovered JS beacuse of chaining, and the best available library which helps you do this stuff is jQuery. I know, everyone now advertises different libraries, but if you love simplicity and naturalness of snippet from this post - you’ll love jQuery.

    Let me be more vivid. Here’s how you invert checkbox selection in jQuery:

    $('input[@type="checkbox"]')
    	.not('[@checked]').attr('checked','checked').addClass('modified').end()
    	.filter('[@checked]').not('.modified').removeAttr('checked').end()
    .removeClass('modified');

    Isn’t this AWESOME? :D!

  13. Dustin Diaz

    Brian: I should have known it did. I only briefly looked at the spec on Jack’s blog. It’s safe to say that if input[type="checked"] is supported, then most definitely there should be input[type="checked"]:checked. All very cool stuff as should any js quering library should do :)

  14. Jim

    Dustin,

    I love the fairy dust comment! (Does that say something about me…!?)

    Anyway, you’re right! JS is so elegant and slick. I find myself called to it like the mythical Sirens–though there hasn’t been a shipwreck among the rocks yet! I do get funny looks from other developers when I proclaim the greatness that is JavaScript. But I am never swayed in my love. ;)

    Chaining is extremely cool, as is the smoothness that the tertiary operator (I know this is not unique to JS) brings to the table. The more I use all these shorter-hand methods of coding the slicker it all gets–chaining, tertiary, JSON–it’s all so beautiful.

    –Jim

  15. Jim

    OH yeah…I forgot…closures are also another beautiful elegant shorter-hand method of coding which make JS so awesome.

  16. splintor

    JavaScript is indeed sexy, but not because of function chaining - almost every OO language I know supports chaining - Java, C++, even VB - every language that has objects with methods that can return objects support chaining.

    JavaScript is sexy because of lambda calculations and closures.

  17. splintor

    BTW, Dustin, I just found the change layout buttons on the top-right of the post and they are really cool, but my favorite, the right-most one that change the background color to white changes the color of your comments but not their background color, which render them illegible.

  18. Remy Sharp

    Sorry - coming from the jQuery corner, I couldn’t resist:

    @dean, isn’t your pluck method actually quite simple:

    (in jQuery - and using Firefox to debug)

    jQuery.fn.pluck = function(key) {
        var plucked = [];
        this.each(function() {
            plucked.push(this[key])
        })
        return plucked;
    }
    
    console.log($('input:checked').pluck('name'))

    Maybe I’m over simplifying..? +1 vote for sexy JS.

  19. Pete

    I concur, Javascipt is exciting, but sexy? It cannot tease us in that way

  20. A few more jQuery plugins: crop, labelOver and pluck at remy sharp’s b:log

    [...] Finally, pluck is a plugin inspired by a comment on Dustin Diaz’s web site by Dean Edwards that I found I needed in a project I was working on lately. [...]

  21. Duncan Green

    I agree with most of above comments. However, if you want Javascript to rock, you should consider writing automated unit tests for ALL your js code. This is the only way to make code solid. Check out http://www.jsunit.net/. Not pretty but fundamental shift in thinking.

  22. marios

    Excellent example to learn from.

    Not that it matters much, but shouldn’t it be an identity operator instead of equality on line 4 in the if statement?

    regards

Get "JavaScript Design Patterns"

"As a web developer, you'll already know that JavaScript™ is a powerful language, allowing you to add an impressive array of dynamic functionality to otherwise static web sites. But there is more power waiting to be unlocked--JavaScript is capable of full object-oriented capabilities, and by applying OOP principles, best practices, and design patterns to your code, you can make it more powerful, more efficient, and easier to work with alone or as part of a team."

Buy JS Design Patterns from Amazon.com Buy JS Design Patterns from Apress

Submit a Prototype

All content copyright © 2003 - 2007 under the Creative Commons License. Wanna know something? Just ask.

About | Archives | Blog Search

[x] close

Loading...

Submit a prototype

By checking this prototype I agree that I am not submitting false credentials, pornography, or a hate crime website. I also understand that by submitting my entry I may or may not be accepted, and if accepted, my entry may be taken down at any given time if I violate these terms.