Topics:
apps
css
games
javascript
mobile
node
php
speaking
tehcl
textmate
tools
video
webgl

jQuery Syntax for Easy Portability?

published:
2009.06.03
topics:
javascript

I have to say, I find the syntax of the jQuery JavaScript library to be very logical, efficient, and readable. I realized today that jQuery code also has the very interesting property of being relatively easy to port to any other JavaScript library. And jQuery, or a jQuery-like syntax, seems to be a reasonable starting point for creating JavaScript-library-agnostic code — that is, JavaScript code that depends on a JavaScript library to function, but can be easily made to work with any library.

As an example, lets consider the following jQuery call:

$('#foo,#bar').addClass('test').css('color', 'blue');
Now lets look at code that does the same thing written for YUI and Dojo:

// YUI
YAHOO.util.Dom.addClass(['foo', 'bar'], 'test');
YAHOO.util.Dom.setStyle(['foo', 'bar'], 'color', 'blue');

// Dojo
dojo.query('#foo,#bar').addClass('test').style('color', 'blue');

Lets say we wanted to keep the jQuery syntax shown in the very first example above, but instead of including jquery.js and all of the jQuery code, we wanted to use the YUI JavaScript library. How could we make the jQuery style call use YUI? Here's some code that maps those calls to the YUI library:

function UseYUI(selector) {
    this.nodes = YAHOO.util.Selector.query(selector);

    this.addClass = function (className) {
        YAHOO.util.Dom.addClass(this.nodes, className);

        return this;
    }

    this.css = function (property, value) {
        if (typeof value == 'undefined') {
            return YAHOO.util.Dom.getStyle(this.nodes, property);

        } else {
            YAHOO.util.Dom.setStyle(this.nodes, property, value);

            return this;
        }
    }
}

function $(selector) {
    return new UseYUI(selector);
}

After adding the above code to your page you could keep the jQuery syntax — i.e. $('#foo,#bar').addClass(… — but include the YUI library code and files instead of the code and files for jQuery.

And actually, if we had many methods like addClass where they are the same in jQuery and YUI except for the first argument, we could create a helper function to generate the mapped functions for us:

function UseYUI(selector) {
    this.nodes = YAHOO.util.Selector.query(selector);
    
    this.mapMethodToYUIDom = function(method) {
        this[method] = function () {
            var args = new Array();
            args.push(this.nodes);
            for (var i = 0; i < arguments.length; i++) {
                args.push(arguments[i]);
            }
        
            YAHOO.util.Dom[method].apply(null, args)
        
            return this;
        }
    }

    this.mapMethodToYUIDom('addClass');
    this.mapMethodToYUIDom('removeClass');
}

Mapping the jQuery style calls to Dojo in this case is even easier than YUI. Much easier:

function $(selector) {
    var nodes = dojo.query(selector);

    nodes.css = nodes.style;

    return nodes;
}

It would be a fair amount of work, and a decent bulk of code, to completely map all jQuery style calls to either YUI or Dojo, or any other JavaScript library for that matter. Obviously, when porting from one JavaScript library to another, going through line by line and replacing each call would result in slightly faster and more file-size efficient code. But that's no walk in the park either.

With the method I've described in this post, you could actually put in the one-time effort towards creating the code to dynamically map from jQuery syntax to any other framework thereby making any and all projects you build and distribute library-agnostic. What do you think? It seems like such mappings would come in useful.


Pixel Art Story: The Eagle Has [Crash] Landed, Pt. 1

published:
2009.05.27
topics:
tehcl

Foreword: I tend to spend most of my time wearing my coding hat, but one of the things I really enjoyed about creating this site was the design process with all of the pixel art. Well, actually it wasn't that much pixel art really, and I wanted an excuse to push more pixels.

As soon as I came up with the idea of having the rocket take off from Earth, I knew that it was going to have to land on the Moon. And it turns out that therein lay the perfect opportunity to don my creativity cap.

The idea I came up with was for Zachstronaut, a pixel character representation of myself, to crash land the rocket on the Moon. This would then let me slowly reveal the adventures of a marooned traveler by adding more pixel art to the footer of my site over time.

And with that said, I give you a briefly animated first installment, "The Eagle Has [Crash] Landed" (TEHCL), Part 1. Read the story if you'd like, and then scroll to the Moon and wait for the magic to happen.

Zachstronaut: Houston, I have a problem.

Houston: Roger that, Zachstronaut. What is your situation?

Zachstronaut: You know how you said I'd run out of fuel if I did some full thruster joy riding around Earth…

Houston: God damnit, we told you that you needed that extra fuel to do a controlled burn down to the surface of the Moon!

Zachstronaut: Look, now is not the time for–

Houston: Oh really? When exactly would be the best time to let you know how much of an idiot you are?

Zachstronaut: My engines have sputtered out, and judging by how big the Moon craters are getting in my window I'd say you've got about 5 seconds. 4. 3. 2. 1. [KRRKKKSSSHHHHHHHHHZZZZZZTTTTTTTTT]

Houston: My god. Zachstronaut? Zachstronaut, do you read?

Zachstronaut: . . . [static]


Patch jQuery fadeTo() to Bring Back the Dead

published:
2009.05.14
topics:
javascript

Well, maybe not bringing back the dead exactly, but I did patch the jQuery function fadeTo() to bring back elements after hide() or fadeOut() were called on them.

Just paste this in your JavaScript after you load jQuery:

/**
 * Fix jQuery fadeTo() so it can bring back something after hide() or fadeOut()
 */
(function ($) {
    var proxied = $.fn.fadeTo;
    $.fn.fadeTo = function() {
        if ($(this).is(':hidden')) {
            $(this).css('opacity', 0).show();
        }
        
        return proxied.apply(this, arguments);
    }
})(jQuery);

I'd like to just see them fix this in the library itself, so I submitted a ticket.


Pattern for JavaScript Options with Defaults

published:
2009.05.14
topics:
javascript

Maybe this is obvious, but here's a really handy pattern for passing an object of options into your JavaScript functions when you also want there to be a set of default options for that function. I'm using jQuery's $.extend function to handle the objects, but most JavaScript libraries provide this functionality.

function myFunction(arg1, options) {
	var defaultOptions = {
		foo: 'foo-default',
		bar: 'bar-default'
	}
	
	if (typeof options == 'object') {
		options = $.extend(defaultOptions, options);
	} else {
		options = defaultOptions;
	}
	
	// rest of your code here...
	
	// for demonstration purposes
	alert(options.foo + ' and ' + options.bar);
}

Try running some demonstration code by clicking these buttons:

I hope somebody found that interesting/helpful.


Presenting ShortJournal at MinneDemo

published:
2009.05.13
topics:
php
speaking
tools

Last week Thursday, May 7 I had the pleasure of presenting a piece of software I've been working on called ShortJournal at MinneDemo. MinneDemo is the "Twin Cities' premier technology demo and networking event," and I "came for the demo" but "stayed for the beer." It's true, I did. I'm quoting the site, not being sarcastic. I met a lot of interesting people and had a great time. In the beginning of this video you'll find me briefly blathering on about what ShortJournal is (right after Extendr):

Right, so anyway… ShortJournal is a tool I made for myself to solve a specific problem I was having: I had umpteen million notes and ideas that I was either putting into text files or emailing to myself or writing on scraps of paper. Searching for a specific note or idea was totally brutal, and that's if I even had the right file with me on the particular computer that I was on. It sucked.

So I made ShortJournal for storing and organizing my notes — any little bits of text. It's a development journal and an everything bucket, and I use it to store code snippets, how-to's, bookmarks, project ideas, notes to self, to-do lists, and anything else I want to remember. Any bit of text can be tagged and stored away in ShortJournal, and then retrieved from anywhere on any computer or phone with web access.

Other products that solve this problem such as EverNote or BackPack certainly have a lot going for them, and I know ShortJournal won't be for everyone. Really, personally, it just came down to me not being comfortable with the idea of a third party having access to all of my notes and ideas, and then also being dependent on that service and their uptime to access my data.

That's the key way that ShortJournal is different. It is a simple service that you can run on any machine with Apache-MySQL-PHP. From that machine you can access your notes anywhere via the web, and then ShortJournal itself also has a [currently very rough] REST API so that you can write any kind of client (in any language) for ShortJournal that you'd want. I made a nice simple little command line client for those shell users like me out there. I've got it plugged into my TextMate. Somebody could certainly make a desktop app, a native iphone app, or a better web client with the API... at least that's the concept.

I'm already using ShortJournal heavily on a daily basis with great success. It solved the problem that I had. I've got a couple other people testing it out for their own needs. Right now I'm looking for more alpha testers. If you want to try out ShortJournal, you just need to get ahold of me via email or my contact form, or Twitter is fine, too.

Eventually I think this project is bound to end up as open source so that people can extend it as they need. I wouldn't hold your breath for a glossy boxed product. ShortJournal really is targeted for developers, not casual computer users. It is the first in a line up of several other tools and libraries I've been using over the years to optimize my development environment, all of which I intend to share the source of "some day soon." More information can be found on shortsix.com.

Oh, and speaking of the target audience here being developers, you may enjoy this wildly inaccurate review of ShortJournal from one of the MinneDemo attendees.