Archive for November, 2008

The Reddit crowd weighs in on the JavaScript WTF

November 22nd, 2008 by Aaron N.

So my traffic went kaboom yesterday (most traffic I’ve ever gotten – period) because my post made the home page of reddit apparently. This is novel and I welcome all those viewers to my little corner of the tubes. What’s interesting though is the conversation going on over there.

I’ll point out that the code in question (on a Function.apply method for IE5) that I understand why Microsoft would write such a hack, as IE5 doesn’t have a suitable method for deferment and they can’t just ignore those users. It’s easy for me and others to be entertained by such a hack, but it’s not like I suggested an alternative.

To be frank, I simply wouldn’t even try to. IE5 is 9 and a half years old and I don’t envy anyone who has to support it. I was amused by the method I posted, but hey, it works, and that’s about all that really matters.

Still, that said, it is possible to implement a more elegant apply method for IE5. Here’s an example from google’s code base:

if (!Function.prototype.apply) {
  Function.prototype.apply = function(oScope, args) {
    var sarg = [];
    var rtrn, call;

    if (!oScope) oScope = goog.global;
    if (!args) args = [];

    for (var i = 0; i < args.length; i++) {
      sarg[i] = 'args[' + i + ']';
    }

    call = 'oScope.__applyTemp__.peek().(' + sarg.join(',') + ');';

    if (!oScope['__applyTemp__']) {
      oScope['__applyTemp__'] = [];
    }

    oScope['__applyTemp__'].push(this);
    rtrn = eval(call);
    oScope['__applyTemp__'].pop();

    return rtrn;
  };
}

Now, one could argue that this is an ugly hack too. Using eval and whatnot. But there are two things about it that make it a better solution in my book (and to be clear, there are no doubt even better ones out there – I haven’t searched that hard). Those two things are:

  1. The function isn’t limited by the number of arguments you can pass it. In the MSFT version, if you passed in more than 10 arguments, you just got a ridiculous error.
  2. More importantly, it defines apply only if it doesn’t already exist. The MSFT code defines its method for everyone and it’s not even on the Function prototype. Rather than testing to see if the method they needed exists, they opt to just use a non-native hack that uses eval.

It’s easy to call this one from the sidelines as being a ridiculous hack, but I genuinely sympathize with someone who has to support JavaScript on IE5. That said, acting like every browser is IE5 is just inflicting pain one’s self for no good reason.

Element shortcuts for Waiter

November 21st, 2008 by Aaron N.

For those of you who haven’t seen my Waiter class, it basically automates the creating of an ajax spinner on a DOM element that’s being updated by an ajax request (or some other process). It’s integrated into Request.HTML so you can enable it with a simple option (useWaiter:true), but occasionally I want to use it outside of an ajax request. I just added two shortcuts to the Element class: wait and release. These basically let you do myElement.wait() to put a waiter over a DOM element. Just a little Friday love.

Here’s a demo in the wikitorial.

Ask Clientcide: How do you randomize your header?

November 21st, 2008 by Aaron N.

I get a lot of emails from people. Sometimes it’s a charitable soul sending me a bug report (via google code) and, sometimes, an even more charitable soul sending me bug fixes (these are my favorite types of people). Then there’s the Clientcide google group, which is where I prefer questions about my code go so that future readers can see the answers, too.

But today I got this email:

Can you write a blog about how you change the images in your
header.

I like your new design so much.

-shin

Awww shucks. Why thank you shin, I like it, too.

So I added a new contact page specifically for suggesting topics you’d like to see me write about (Post a Question / Suggest a Post Topic). And, for starters, I’ll answer this question from shin.
Read the rest of this entry »

Preventing Ajax Request Caching in MooTools – introducing Request.NoCache

November 20th, 2008 by Aaron N.

Ajax requests are, generally speaking, used to update the document or meant to send and fetch new data to and from the server. In Ajax heavy apps, you might end up sending the same request on numerous occasions and not always expect the server to respond with the same results.

This can cause problems with caching. Internet Explorer in particular will see an ajax request with the same parameters and just return the results it got last time, which, well, sucks.

I have this trick that I’ve been using for a while now and I figured I’d release it. The solution is to include a value in your request that’s always different. My solution has been to add a “noCache” value set to the current time. So long as I’m not sending the same request more than once in a millisecond, this solves my problems.

Hot on the heals of yesterday’s plugin (Class.refactor), I’m releasing this tweak on the Request classes that introduces the ‘noCache’ option that will automate this for you. Simply set the ‘noCache’ option to true and you’re all set.

new Request({
    url: '/foo.php',
    data: {...some data...},
    noCache: true
}).send()

Don’t want to set it every time? No problem, just switch the default for the option to true with Class.refactor:

(function(){ //let's not pollute the global namespace
    var setNoCache = function(cls) {
        return Class.refactor(cls, options: {
            noCache: true
        });
    };
    Request = setNoCache(Request);
    Request.HTML = setNoCache(Request.HTML);
})();
//all future instances of Request and Request.HTML
//default to using the noCache functionalty

Man. I’m on a roll this week. You can download this script on the download page and view the docs.

New plugin: Class.Refactor

November 19th, 2008 by Aaron N.

Whenever I start a new project (like Iminta.com) one of the first things I find myself doing is redefining how I want my classes to work in that specific environment. Maybe I want all my Request.HTML instances to change the document body’s cursor property (in css) to the hour glass (I do this in ajax heavy apps – I want the user to know that the browser is working on something). Or maybe I want all my popup divs to be at a specific zIndex, or all my effects to default to 100ms instead of 500. Read the rest of this entry »

Embiggening the MooTools Book

November 18th, 2008 by Aaron N.

So Apress, publisher of my book on MooTools, has kindly asked me to consider upgrading it from their “firstPress” imprint to their main Apress book line. This would involve adding more content to it among other things.

So I’m curious. To those of you out there who have read the book, what do you wish were different about it? What do you wish there were more of? When you finished it, what lingering questions were still on your mind?

Do tell.

Today’s JavaScript WTF

November 17th, 2008 by Aaron N.

MooTools cohort Jim Wilson sends me this wonderful little nugget of entertainment today. Microsoft’s SharePoint app has in it’s web app code this lovely little bit of JavaScript:

function DeferCall() {
	if (arguments.length == 0) {
		return null;
	}
	var args = arguments;
	var fn = null;
	if (browseris.ie5up || browseris.nav6up) {
		eval("if (typeof(" + args[0] + ")=='function') { fn=" + args[0] + "; }");
	}
	if (fn == null) { return null; }
	if (args.length == 1) {
	 return fn();
	} else if (args.length == 2) {
		return fn(args[1]);
	} else if (args.length == 3) {
		return fn(args[1], args[2]);
	} else if (args.length == 4) {
		return fn(args[1], args[2], args[3]);
	} else if (args.length == 5) {
		return fn(args[1], args[2], args[3], args[4]);
	} else if (args.length == 6) {
		return fn(args[1], args[2], args[3], args[4], args[5]);
	} else if (args.length == 7) {
		return fn(args[1], args[2], args[3], args[4], args[5], args[6]);
	} else if (args.length == 8) {
		return fn(args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
	} else if (args.length == 9) {
		return fn(args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]);
	} else if (args.length == 10) {
		return fn(args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9]);
	} else {
		var L_TooManyDefers_Text = "Too many arguments passed to DeferCall"
		alert(L_TooManyDefers_Text);
	}
	return null;
}

As Jim put it, “and we wonder why windows has 40 million lines of code.”

Update: This article got featured on Reddit and I have another post about my actual thoughts on this chunk of code above: The Reddit crowd weighs in on the JavaScript WTF

New form validators, beta code is now documented

November 14th, 2008 by Aaron N.

Just a quick end of the day friday note: I’ve released all the beta code that I blogged about a little while ago and you’ll find all these files are now documented (not in the wikitorials yet, but I’ll get to that this weekend if I can). Also, thanks to contributor Chafik Barbar we now have about a dozen new validators for the FormValidator. These can be found in FormValidator.Extras.

Other new things include Date.getDiffInWords which improves on the old Date.timeAgoInWords in that it will now give future time (“about an hour from now”) as well as the past (“about an hour ago”).

As always, you can keep track of what’s new by following the svn log on google code.

Domo arigato

November 3rd, 2008 by Aaron N.

Anyone need the MooTools docs in Japanese?