Saturday, August 9, 2008

Shrinking the Web

Although consolidation of information is not really the main focus of this particular blog, it seems to be a recurring theme, and one that I'd like to expand in this entry.

If you're anything like me, you're a well-connected individual. Perhaps you're over-connected, if such a state exists. You have accounts on social networking sites like MySpace, Facebook, Yahoo 360, and Classmates, you have a photo account on flickr, you have an MSN Live account, your XBox Live account, your Twitter account, about a dozen blogs that you like to read, you have six or seven different e-mail accounts (one for work, one for personal use, one that you use to collect all your spam, one that you got for free from your new ISP, a couple older ones that you still check from time to time, and another one that you thought you might use but never really do), your current eBay auctions, and who knows what else.

If you go to each site to read all your mail and check up on what's going on with all your friends, you don't have any time left in the day to actually live your own life.

Something I recently discovered was a nifty little website called Netvibes. The Netvibes site has a vast number of widgets that you can install, and these widgets go out and scrape all the important information from all your favorite websites for you. A couple years ago, I started work on a project to accomplish this very same task, but the job that the folks at Netvibes have done is far superior to anything I had imagined, so I will scratch that development item off my rainy day list.

I'm really not doing the site justice in this little review, but I can tell you that it's quickly earning its place in my daily top 10 page views, and may possibly become my new default home page. (This is a huge thing for me.... iGoogle has been my home page for as long as I can remember.)

With all my e-mail going straight to my phone, and this awesome web service, I'm quickly finding that I spend far less time surfing, and have more time to do other things. Maybe sleep will be one of them soon.

Tuesday, July 15, 2008

Beginning at the Beginning

I've been discussing the topic of beginning coders with a couple other developers recently, and we seem to be at odds as to the best way to learn how to write code when you've never really done it before. I've been tutoring a couple co-workers with a few items, some purely elementary, and yet others are dangerously close to intermediate. However, my daughter is showing more and more interest in understanding exactly what it is that Dad does, and that's part of what creates the issue.

When the computer is a magical box that does things because the invisible gnomes tell it to do them, it's difficult to even begin to begin, if you catch what I'm saying. Elementary syntax, keywords, comments: these are all foreign words, and must be explained as if to a child (especially if you're really talking to a child).

But how do you take this person who is chomping at the bit with wild ideas for massive projects and teach them the most basic steps of the process, getting them to understand the complexity of what we do without inhibiting their desire?

A lot of my colleagues maintain that the "textbook" approach is best. As I've seen so often, "there's nothing that can't be built from a 'Hello world!' foundation." This seems to be the widely accepted view. Start with simple screen output, formatting, structure, and build from there.

I understand the premise here. It's the same as learning to talk. You start with simple words until you understand the reference to the objects and actions behind the ideas being conveyed, then you build up into phrases and eventually sentences.

But I disagree with the overall view. If I had spent my first few months "building upon a solid foundation of 'Hello world!' material," there's no way I would be a developer now. What a slow, boring, tedious process! Most of the people I know who are passionate about what they do started with a complete idea or a finished product, and began to disassemble the components to see how they all fit together. This applies to anything, not just software development.

My first programs were copied verbatim from the back of old "Compute!" magazines, which were, at that time, geared toward my beloved Commodore C-64. A half dozen hours of copying BASIC language code and a six pack of soda later, there was a crude sprite floating across the television screen that would seem to make anything it touched explode. When we got bored of playing the game (usually 15 minutes later), I could look at the code in more detail and see how to change the things I didn't like or try to understand some of the unfamiliar sections of the program.

Software development is all about the assembly of specific components and, of course, logic. If I show you seventy-five cents and an empty soda bottle, how in the world are you supposed to make anything out of that? You're missing the fact that I started with two dollars, purchased the soda from a vending machine, drank it, and had change left to spare. There's a lot of the story that gets left out if you only include the bare minimum components. You don't need to know how the vending machine works, or even understand the engineering behind the bottle cap. But you do need to know that they exist (and that you can study them later) in order to understand why you have the pieces remaining that you do.

Otherwise, you're still left with invisible gnomes doing magical things.

Sunday, June 1, 2008

this: i.e. frustration

Pardon my play on words.

Internet Exploiter continues to frustrate me.  In this installment, I've been arguing with the "this" keyword for longer than I ever dreamed I could suffer.

The W3C standard for "this" as it applies to error trapping is that it references the object that trapped the event -- the one with the event handle applied.  So if I attach an onclick event to a table row element, and that event invokes a function that pops up an alert dialog containing "this.id", I would expect to see an alert box with the id tag of the table row.

Of course, this works flawlessly in Firefox, as one would rightfully assume.

However, in IE, we see: "undefined"

Why?

Because IE apparently assigns "this" the value of the topmost element, which in this case would be "window."  So if I set the window.id to "something," I do in fact see the window.id value of "something" in my alert box when I click my table row with the onclick event handler attached.

This, as you might expect, isn't the most useful feature in the world.  In fact, it's one of the most inane of Microsoft's convoluted implementation of javascript I've seen to date.

The workaround for this is the most un-sexy bit of code I've seen in a long while.  Here it is, for your giggling pleasure:

var onClick = function(e) {
    if (!e) e = event;
    var src = e.target || e.srcElement;
    while(src.nodeName != 'TABLE') {
        if(src.nodeName == 'TR') {
            alert(src.id);
        }
        src = src.parentNode;
    }
};

Now, the point here is to trap the source object that triggered the event, so long as it matches the object type we're truly interested in -- in this case, the table row.  So we have to iterate up through all the elements in the tree to get to the table row, then -- finally -- grab it's id tag.

We can then send this to a custom "addEvent()" method that will append this function to the onclick event as we populate the table, a la:

addEvent(objectTableRow, onClick);

The addEvent() method is outside the scope of this blog, and honestly, there are thousands of pages dealing with this all over the web, so I'm not going to cover it here.  My particular problem above isn't as popular, which is why I chose to complain about it.

It's a long way to go to get to something as simple as a "this.id" but at least it's possible, and, fortunately for us, works in both IE and Firefox.

Sunday, May 25, 2008

A simple .toJSON() method

Here's an interesting situation we've stumbled across in recent development. Now, bear in mind, I'm not the world's greatest Javascript developer -- not by a longshot -- but I seem to get the job done, so if there's a way to improve upon this, I'm definitely interested.

The simple AJAX function we're using has a an event handler that we use to deal with intermittent network problems. Instead of having the script bomb out when the server is busy, we want it to wait a few moments, then try the call again.

Part of the problem with this is that by the time our script has picked up the error, it has already moved on to other things, so the object that we used to set the server request variables is no longer available. How do you pass these "retry" parameters to an onError event handler that is called from a setTimeout() function?

The method I came up with is quite the eclectic mix of code. What we need to do is take the object that contains all our parameters and convert it to a string so that we can pass it back to the AJAX function as a regular parameter. This is how I've done it:


// Function converts a JSON object to string literal for passing
// into externally referenced callbacks (a la on AJAX failure retries)
Object.prototype.toJSON = function () {
// We first need to declare an array to hold each propertyName/value pair
var result = [];

// Now iterate through each property and assign them to the array
for(var element in this){
var key;
var val;

// Prepare the object property names...
// encapsulate strings in quotes,
// let numbers go unscathed,
// recurse if it's an embedded object,
// skip everything else
if (typeof element == "string") {
key = "'" + element + "'";
} else if (typeof element == "number") {
key = element;
} else if (typeof element == "object") {
key = element.toJSON();
} else {
continue;
}
// Do the same for the object values
if(typeof this[element] == "string"){
val = "'" + this[element] + "'";
} else if (typeof this[element] == "number") {
val = this[element];
} else if (typeof this[element] == "object") {
val = this[element].toJSON();
} else {
continue;
}
// Add the most recent name/value pair to the result array
result.push(key + ":" + val);
}
// Send the properly formatted string back to the script
// We do this by concatenating the elements together into a string
result = "{ " + result.join(", ") + " }";
return(result);
};

For the uninitiated, this is a method prototype extension. It works just like a .toString() call would. For example:


var testObj = { 'var1':0, 'var2':'sampleText', 'var3':12345 };
var testStr = testObj.toJSON();


The testStr variable now holds the contents of testObj, but as a string literal, so that we can pass it around wherever (or, more accurately, whenever) we want.

Again, I'm sure there's a lot of room for improvement here, but it serves the purpose we need, so I'm not going to beat myself up if someone shows me a cleaner way.

I have seen a couple alternatives that rely on a completely different approach, but I have yet to try them (partly because it appears that using them would require a significant review of our AJAX functions).

What I like most about this little method is that it's smart enough to handle nested objects. What I don't like is that it's long, and easily bombs out if the object being referenced is not a true object (but instead, say, a string variable). This is something I could fix in the future, but I would instead just say, "Don't do that!" (Because it means less work for me.) :)

(Note: the tabs for indentation don't turn out real well here. I'll have to find a fix for that.)

Saturday, May 24, 2008

The Search for Unity (Updated)

First, let me say that busy is an understatement, so it's (obviously) been quite a while since my last update. This is a short but sweet segue into an entry of mine from last summer about being able to access everything digital from one central device and location.

The quick answer is that applications for Windows Mobile 6 have been the answer to most of my prayers.

First and foremost, you may recall that our corporate solution for groupware is Lotus Notes. This makes us a little unconventional and finding helper applications becomes a little more difficult, but alas, it's what we're stuck with. For this, I've found a perfect solution: Commontime mNotes. It seamlessly synchronizes my e-mail, contacts, calendar, and to-do list with the built-in WM6 counterparts. I even get the little buzzes and chimes for meeting alerts. (Without them, I'd be late to every meeting I'm supposed to attend -- if I even remembered them at all.)

The downfall of Commontime mNotes is the $15.00 monthly service fee, but it's a small price to pay to free yourself from the shackles of your desktop PC.

Next on my list of groovy things is an old stand-by: IMAP e-mail. Thankfully, most e-mail services now have an IMAP option, and all of the ones I use are free. Yahoo, MSN, and Google Mail all have direct IMAP mail access for free, so I can access all three services from the messaging application on my WM6 device. I set each one up to check my e-mail at varying intervals (my Yahoo and gmail accounts are for personal use, for example, so I only have my phone set up to check those a few times per day). I realize this is nothing new, but it's something that a lot of people forget to do. Why bother logging into a desktop PC when all you want to do is read your joke of the day or send a quick note to Aunt Bunny telling her she has a mustache?

These two simple things have shortened the amount of time I spend at my desk more than I could have imagined. More convenient is the fact that my phone has a full qwerty keyboard, so composing e-mail is not much of an issue. I also happen to spend nearly 3 hours per day commuting, which gives me ample time to check my schedule and fire off a couple quick e-mails. (Yes, I'm "that guy," but I'm responsible about it -- I wait until I'm on the limited access highway and I'm not in a group of other vehicles before pulling out my PocketPC.)

Now, bear in mind that without a data plan, all of this stuff is pretty much worthless unless you're in a Wi-Fi area -- which doesn't happen for us normal folks very often.

All of that said, I still have a long way to go to restore my sanity, but things are definitely looking better, and I'm hoping to pass along another update in short order with some other tips for simplifying your connected presence.