Want a pony - Google death notification

Google, when I die, could you please send this email/wave to people in my contacts?

From: David Chui
Sent: <Date of death>
To: <Name of recipient>
CC: <Family members>, <Neighbors>
Subject: RIP David Chui 1983 - <Year of death>

Hi <Name of recipient>,

Apparently, I have died (see date in the subject). Obviously, I didn't have the time to write you a personalized message of my death, but depending on your relationship with me, could you please click on one of the actions below?
  • [Mark sender as spammer] - You have always hated me and you don't want to hear from me anymore. However, I doubt I'll be sending you more emails after this.
  • [Update my birthday calendar] - When you click this, my birthday would not recur after the year of death. Optionally, you could create a new recurring event of my death for your annual celebration pleasure.
  • [Tweet about David's death] - When you click this, you'll post a new update on your Twitter that says "w00t! @davidchui is finally dead".
  • [Post a message on David's Facebook wall] - When you click this, you'll post a message on my Facebook wall that says "Let me know if it's hot down there!"
  • [WTF?] - If you don't know what to do, I'll take care of the Rickrolling for you.

Thanks and have a nice life! By the way, how's the dog?

Deciphering the work-speak

It's close to the end of the year. To be specific, it's November now. The year will officially end with the month. Between then and January is a period of time used mostly for reminding ourselves why we could last the 11 months.. and also one of the best times to reflect and think, maybe for a better year ahead.

The year has been full of lingo to me. No, not the terms that people tend to use to sound really smart, but the type of lingo used throughout organizations to get things done. It's work-speak and it's funny when you think about what it could mean. Here's a collection of some of the more memorable ones that I've heard.

  • "Hi" - I've got a problem for you, kiddo.
  • "I'd like to have a catch up with you soon" - I smell you and I will find out where it smells and I'm going to make sure that stench stays until I get hounds on your ass.
  • "So… where are we now?" - Why the fuck are things taking so fucking long?
  • "We need a plan" - I have no idea how to solve this shit. Now it's your problem too.
  • "We need leave planning" - You're not allowed to be away for too long.
  • "We need day planning" - Do let me know how you plan to fuck yourself differently everyday.
  • "I can give you code snippets" - I've got a bunch of useless code pretending to solve a problem in the worst way possible.
  • "The build is green" - The Maven problems are fixed.
  • "This sucks" - Ah, fuck it.
  • "I'm going lunch" - The finger.
  • "X is moving on" - Another one bites the dust.
  • "Would you like to step up" - Would you like a turn in the electric chair?
  • "Great job!" - Finally, you've done something right.
  • "You're the employee of the month" - Congratulations on getting yourself hated by everyone.
  • "Version 1.0 released" - We've finally decided to ship a SNAPSHOT.

Got more?

I won the 'Most elegant use of Javascript' category in Atlassian Codegeist 2009

Codegeist is an annual plugin development competition held by Atlassian to inspire developers worldwide to write fantastic plugins for their products. 2009 is the fourth time around and I've submitted two entries for it. They are:


The plugins were submitted a few weeks ago. Since then, I waited quite anxiously for the results. Today, the wait is over. Atlassian has announced the results publicly in this blog post.

… and I won the 'Most elegant use of Javascript' category! What sweet news to receive!

In this post, I'd also like to congratulate the other winners! You guys rock! Keep the awesome plugins coming!

Simple sign-up forms win

So you've built an amazing web application. You've gone through months of research and development to come up with a formula that you think will win. You got the feedback that gives you the warm feeling that the application is going to be a hit. Everything is ready. You just need to wait for the masses of users.

But then, there's the sign-up.

Sign-up is a problem because it is a hurdle that users need to jump over before they can start benefitting from our applications. Although it is a one-time process, the hassle can be too much. Sometimes, the hassle makes people lose interest… and that's really the worst thing that can happen - lose, lose.

If a big user base is vital for the application's success, sign-up must be as little hassle as possible. One of the biggest hassle with sign-up is the complexity of the sign-up forms. Have you seen sign-up forms that span multiple pages? Or how about sign-up forms that ask too much about you that it becomes uncomfortable?

I think most of us have.

The ideal sign-up form should be smart and asks as little as possible. The objective is to get the user in to experience the key features of the application as quickly and as easy as possible. So, what are the fields that should be there in the sign-up form? I think most sign-up forms can be simplified to only contain these fields:

  • Email address.
  • An optional, non-repeating password field.

How does it work? For the non-imaginative, after the form is submitted, an email will be sent to the user at the email address specified, letting him or her know of the first-time-only-instant-login link. When that link is clicked, the authenticity of the email account is verified and the user is logged in immediately.

The content of the email can be customized to contain helpful hints for the new user. But that's not what this post is about.

If the user did not specify a password in the optional password field, a server-generated password should be included in the email. In this scenario, the application should prompt the user to change the password after he or she logs in the first time.

Sign up forms like this save users some hassle. They include:

  • Choosing a handle/nick that is unique in the system (usually required if such field is present)
  • Type Captcha words.
  • Repeat the password for confirmation.
  • Filling up too much details.

Some may ask, will error handling and application features accessibility be harmed? Well, not really.

The most obvious thing that can go wrong during sign up is when the user forgets the password. But if the application records the user's email address, all it needs to do is to allow the user to ask for the link to reset his/her password. That link will only be sent via email (to the user's inbox).

If there are other parts of the application that need data that is not captured during sign-up, don't worry. The related parts just need to ask for the data when the user wants to use them. This provides context to the user why he or she is providing the details. If the user finds that it is ok to provide those details, he or she will do it. The rule is simple, let them know why the system needs to know so much about them and only ask for the data when there is a need to.

For instance, let's say you're building a social networking site and the application has the ability to find your old school mates. Instead of providing a few text fields during sign-up that ask for education history, it would be better to defer that until the user wants to find his/her old school mates.

Sign-ups should be easy. Features should be discoverable.

Get rid of the clutter

Let's face it. Most of our desks look like they were hit by a tornado. I believe most of us know the disadvantages of messy desks, the reasons (excuses) for them and why it is good to clear the clutter. But how about the "how"?

My workstation consists of only my desk, my chair, my notebook, input devices and my coffee mug/cup. That's all. Despite its simplicity, it does not inhibit good productivity. In fact, it helps me to focus.

So, I thought I'd share some of the things I've thought of and done to clear the clutter.

1. Replace physical tools with virtual ones
  • In tray — With my (gulp) email client and task lists. I use an issue tracker as a helper to this.
  • Calendar — With Google Calendar. It's sharing features, (SMS) reminders, and interoperability (iCalendar) rock.
  • Notes — With Google Notebook. Yes, it's a service that will no longer get maintenance time, but it's one of the best tools I know that allows me to quickly make notes and have them accessible anywhere. It has the advantage of being searchable too.
  • Files/folders — My computer's file system or my company's file storage servers with references to them from my company's wiki. I generally prefer storing information that has a long validity period in file servers, as they get backed up automatically. However, I do keep recent documents in my computer, where they are searchable anywhere (thanks, Spotlight).

Replacing physical tools with virtual ones did require changes in my working style. There's a bit of a learning curve as well. However, after I got used to the virtual tools, reaching to them is really just as easy as with physical ones. It's almost muscle memory. You'd be surprised by the amount of space you'll free up by moving to virtual tools.

2. Put away the things you don't need (frequently)
  • Photo frames — I'm at my work desk to work. Having pictures of my personal life at work is just as awkward as having a picture of my work at home.
  • Complete stationary — I don't use stuff like scissors, knifes, letter openers, erasers, pencils and tapes all that often. So they had to go.
  • Own name cards — I'd expect people who is in the range of giving cards to would either a) have one already or b) know me.
  • Other name cards — Contact details of people I know should either be in a) my brain or b) my virtual address book.
  • Receipts — Bin them or file them (if they are reimbursable).
  • Money — It should be in my wallet or my bank account.
  • Food/snacks — If it can't be finished in the day it was taken, it should go back to the source.
  • Magazines — If I can make use of them there, something is odd. Magazines or other non-work related reading materials should be in the leisure rack.

3. Optimization
  • Reduce the number of cables — Cables make work desks look like snake pits. Invest in wireless networking and input devices (e.g. the mouse and keyboard) to help clear the clutter.
  • Stop using a mouse pad — If you're using a laser based mouse and a non—glossy work desk, you don't need a mouse pad.
  • Reduce the number of devices — If you have two monitors, it's good to think if it would be better to have a big one rather than two smaller ones. Two monitors mean two sets of cables for them. One big one will give you the same virtual space, but with significantly fewer cables.
  • Keep keys in lockers or drawers. If neither is available, ask for one.

And once you've gotten rid of the clutter, remember to keep it that way.

Upload files without refreshing the page with just JavaScript

So you want a simple way to dynamically upload a file? Using JavaScript and nothing more? I may have the solution for you... well no, Google has. But I'll just add some details here.

But first, we need to know our limitations:
  • XHR cannot be used to upload files.
  • Even if it can be (which I'm 99% sure it can't), our code will look like shit.
Next, we need to know what we really mean by "simple".
  • Don't want to use Java Applets.
  • Don't want to use Flash.
  • Simple so that it works with FireFox, Safari and IE.
  • Although desirable, simple means there will be no progress bar. However, the file will get uploaded without the page refreshed.
The best way I know that can do the above is with the iframe hack. There are probably several trillion examples out there. However, those that appeared in the first page of my Google search results are either incomplete, hard to follow or they didn't point out the caveats in an obvious manner.

So, here's my attempt using jQuery.

Typically, file uploads are done with a form and a file input. When the form is submitted, the file gets uploaded and the page refreshes with the results. The iframe hack uses that. Except, there is another component. The iframe, of course.

With the iframe hack, you will have your normal form, but the HTML returned by its submission will be 'sent' to the iframe. The iframe is invisible. So users will not see the page refreshed.

So, let's start with an example:

The form

<form id="topsecretuploadform" method="POST" action="/path/to/file/upload/handler" enctype="multipart/form-data">
<input type="file" name="topsecret">
<input type="submit" value="Let the world see it">
<iframe id="topsecretiframe" name="youcannnotseeme" src="" style="display: none;"></iframe>
</form>

You will need some JavaScript to set the target of the form.

You need to set the target to the name of the iframe. If you do that, the HTML generated by the server after it has processed the upload will be sent to the invisible iframe.

jQuery(function($) {
var iframe = $("#topsecretiframe");

$("#topsecretuploadform").submit(function() {
this.target = iframe.attr("name");
iframe.get(0).processContent = true; // The use of this flag will be explained
});
})

You will need some JavaScript to tell the user that the upload is complete

jQuery(function($) {
$("#topsecretiframe").load(function() {
if (!this.processContent)
return;

var iframeDocument = this.contentWindow || this.contentDocument;
iframeDocument = iframeDocument.document ? iframeDocument.document : iframeDocument;
var iframeBodyElement = iframeDocument.body;
// The 3 lines above is a really easy and cross browser way of getting the body of the document object of the iframe

// Assuming that we know certain elements will be present in the returned HTML after a successful upload,
// the code below shows how you can know from the script.

var someHtml = $(iframeBodyElement);
if (iframeBodyElement.find("div.successfulupload").length > 0)
alert('Upload done successfully.');
else
alert('Oh shit. Upload went fubar. Look at your logs.');
});
});

Caveats

The reason for the processContent flag.

Some browsers will call the iframe onload function the first time it loads (with empty content). Some don't. If that flag didn't exists, using our example, some users will be alerted of something that haven't even started doing.

Iframe names must be set statically.

Don't do this:
jQuery("iframe.thosehackyiframes").each(function(index) {
this.name = "wahooga_" + index;
});
From my testing, that does not work. Set them in a static way.

So

So, you get dynamically uploaded files without XHR. In between the form submission and the iframe load function call, you can insert all the bells and whistles. You may actually want some sort of animated waiting gif. But that's something I'm not going to talk about.

Hope this helps.

Paying the Price of Ignorance

Once upon a time, there lived a community in a small town by a river. There were not many of them. The whole community was about 60 persons. Everyone lived in harmony with each other. There was little to fight about.

As good as it sounds, the town was not without its problems. It had a poor drainage system. Couple that with how close it was to the river, they had major flood problems whenever the rain kept pouring.

For generations, the people were taught that the flood could not be avoided. The only thing they could ever do was to prevent as much water as possible from going into their houses. And so it was, for many generations. And it worked. At least, before it reached the size of 60 persons.

When there were more people, the deficiency of the poor drainage was even more obvious. There were more trash and houses. The drainage system couldn't keep up. Although raised as a problem every now and then by the community, there were never actions taken to address the drainage system problem. To those who ran the town, revamping the drainage system was too much cost. The flood never happened often enough to justify and every time it happened, the people were able to prevent too much damage.

To some of them, the ever growing population was enough to keep the damages low. People just needed to help each other when there was a flood. Also, the post-flood town rebuilding works really kept them too busy to do anything else.

And that remained for many many years. If there was one thing constant about the town, it would be the way they recovered from the floods. The total damages rose higher and higher as the population grew. The recovery time took longer and longer. Year by year, they got busier and busier.

In short, everyone in the town was minimizing the burn, but never took time to take out the flames. In the end, they got incinerated.

I think, things would've turned out better if:

  • The mayor had admitted the deficiency...
  • and invested early on for a better drainage system, before it became a huge undertaking.
  • The people didn't believe that orchestrated water scooping activities as a testaments to their unbelievable team work..
  • and put their efforts to innovative solutions to the root cause of the problem, not its symptoms.

Live and die by decisions

To some of us, making decisions is probably one of the hardest things we have to do. I guess it's fair to say that we often want to make the best decisions, and if possible, to not be accountable for the undesired consequences. But I find it ironic, because I see decisions as creating consequences. When a decision is made, the one who made it is accountable for the consequences, be it good or bad. That's because he asked for a change the moment he decided, and it's his change, really.

Everyone has to make decisions.

I'm not a decision making guru. I have not made half a billion of decisions. But I've been making some and I've been exchanging a lot of thoughts with people who make a lot of decisions. In all honesty, the methods are crap. Not because they don't work. They probably work very well for those who shared with me their techniques. I think they are crap because everyone makes decisions differently.

Some people make decisions based on a thought process. Some make them based on experience. Some based on hunches. There are probably a lot more... but the methods are not what I'm writing about. I'm writing about what happens after decisions are made.

When you're asked to make a decision, know this:

Most of the time, it does not have to be immediate, but when you make it, it has to be firm. The last thing you want to show your people is that you're an indecisive decision maker. When you make a decision, you set the motion. Everything starts to roll based on what you said. It's a terrible thing to do to tell the motion to stop, rollback so your people could be in for another set back. When you feel that your decision is right and you have justifications to yourself why it is right, stick with it.

Don't doubt yourself every 5 minutes and change the decision every 30. The people who need your decision is not a text editor. You don't type, reread, and backspace all you want. When you have decided, stick with it, and make the best out of it. But of course, you should never be...

A stubborn ass (the animal, but feel free to interpret with the other meaning). Decisions can be wrong. I think it's important to keep an open mind when someone challenges your decision. In fact, I think it's awesome when someone challenges your decision.

I can understand how some of us might feel 'mocked' or disrespected when our decisions are challenged. But think about it in another way. After we have made a decision, can we ever be sure that our justifications for it is the only truth? My take: No. Never.

To me, the only way I can be more confident of my justifications is by them surviving challenges.

But of course, you can't always be wrong. Sure, you've probably made some bad ones, but my observation tells me that if you're smart enough that you're asked to decide on certain things, you will never always make the wrong ones. When your decisions are challenged, communicate properly and let them know your justifications. Feel free to let those who challenge you know why you think they are wrong, if you think they are wrong. Like you and I, they need to make mistakes to learn. If they never make any, they are not smarter than the day they are right.

Of course, if you made a bad decision, the best thing you can do is to admit it. Admitting a wrong decision is not about saying you're incompetent of deciding. Admitting a wrong decision allows its corrections. If you're making a decision for your team, it also sends a stark reminder to your team members that anyone can make mistakes. To some teams, it makes the leader more 'human'.. and being human, that means he's more approachable and also someone they can challenge.

Ultimately, that results in better decisions.