Thursday, July 31, 2008

Debugging at APT - Part 2: IE Developer Toolbar

As I said last time, we don't officially support Firefox yet because our clients use it so rarely. So we were relieved when Microsoft finally started to catch up by releasing the IE Developer Toolbar. We're often frustrated by an inexplicable error (either an actual JS error, or just ugly/broken HTML/CSS) that vexes us in IE but works perfectly fine in Firefox. For the JavaScript errors, we've had the Visual Studio Script Debugger available to us for a while (once we jumped through the necessary hoops to enable it), but sometimes the problem is that some of our JS code just isn't being loaded or executed properly. (Never mind that Script Debugger often shows JS exceptions in the middle of completely unrelated HTML markup.) Since we get some of our JS from asynchronous AJAX calls, it's something that View Source wouldn't be able to tell us. Once again, "select element by click" (equivalent to "Inspect" in Firebug) has been a great friend.

I also like the syntax-highlighted View Source, although I usually end up using something like Notepad++ to view source from a browser. But even better, Developer Toolbar's View Source includes the list of CSS declarations that apply to the portion of the page I've selected.



As you can see above and below, I have selected one element buried pretty deep within one of our pages, and I can easily use "Element Source with Style" to see not only its entire innerHTML but also all the CSS declarations, where they came from, and all parent tags' IDs and styles.



Next time I'll talk about Fiddler, also owned by Microsoft, which helps us debug "over the wire."

Friday, July 25, 2008

Javascript Basics: The second and third functions you should write and use all the time

After an embarrassingly long delay, I've decided to put two functions I use all the time in this post to get us somewhat back on track. I also plan on including some other posts about our experimentation with the Yahoo! User Interface (YUI) library and the jQuery library I mentioned last time.

But anyways, back to this post's topic, javascript functions you should write for yourself and be using all the time. This weeks functions are actually pretty simple, but I've talked to and helped a lot of people who weren't using them or had written them so that they're not quite as generic as they should be.

2. show()


One of the main uses of javascript is to interact with the document object model (DOM) created by the browser. At the most basic level, the ability to take static HTML and manipulate not only the properties of those HTML elements, but also remove those elements as well as create new elements really gives javascript a tremendous amount of power.

Quick digression: Of course, this isn't the only thing javascript does for us. Javascript also plays a key role in asynchronous javascript and XML (AJAX), which has revolutionized the way a lot of users interact with web pages. Some would probably argue that AJAX is even more important than the ability to create dynamic HTML (DHTML). I think they're both critical features, and which you think is more important probably will depend a lot on the web site or application you're developing.

Regardless of whether manipulating the DOM is the most important feature of javascript, everyone can admit it's extremely powerful. One of the most frequent manipulations that developers use javascript for is showing and hiding HTML elements. On pretty much every web page there is some extra or more detailed information that you might not want to display to the user immediately, but would like to reveal when they click a link or check a checkbox. Showing the user only the information they need to know at any particular time can greatly increase the usability of a site.

Here is a simple function that will automatically display an element based on its ID:


function show(id) {
$(id).style.display = "";
}


Notice that this function builds off of the $() function from the first post that will get an HTML element based on its ID. It gets a reference to that element, accesses the style attribute of that element, and finally sets the display property of the style attribute to the empty string. At this point you might have a couple questions worth addressing.

First, it's worth pointing out that the style attribute of an element is not a simple value as it is for an element's ID or class. In this case, the style attribute is an object because there are a lot of styles that might apply to a particular element such as the font size, positioning on the page, or background color. All of these style properties could be stored as one big string, but it's pretty easy to see how that would be a nightmare for developers (editing an element's "font-size" wouldn't be very easy).

The other two questions worth answering are why did we choose to change the display property and why did we set it to the empty string? These are both good questions. There are two style properties that control whether an item can be seen or not, display and visibility. The visibility property can have a value of "hidden". It might seem like this would do what we want, but what the visibility property actually does is changes whether an element is visible without removing the space it takes up from the page. This means if a I have a paragraph element whose visibility I set to hidden, I won't be able to see that paragraph element, but I will see a big white space where that element should be. This is rarely what you want, but sometimes it is. Usually what you want is for that element to take up space on the page when it is visible or displayed, but be removed from the flow or layout of the page when it is not being displayed. This is exactly what the display property does. When the display property for an element is set to "none", then that element is completely removed from the flow of the page so there is no unnecessary white space.

So the only question remaining is why did we set the display property to the empty string in order to get our element to appear. If anything, an empty string might indicate that something shouldn't be displayed. In this case, as is the case with a lot of the style properties, it is set to the default value for that property. It just so happens that the default value for the display property is whatever display value for that element will display it properly. This means for block elements like <div> or <p> elements, the display value will be set to "block". For inline elements such as <strong> or <span> elements, it will be "inline". Certain elements, such as elements, even have different display types in different browsers. In Internet Explorer, a <tr> is displayed properly with the value of "block", but needs to be set to "table-row" in Firefox. This is where setting the display value to the empty string and allowing the browser to then apply the default really shines.

So at this point it should be pretty clear why this function was written this way (but if it isn't, let me know in the comments). It's nice to have all of these somewhat complex choices encapsulated in a single easy to understand function that anyone can use, not to mention there's a lot less typing to do.

So what is the other function for this post?

3. hide()



I don't think this one needs much explanation, so here it is:


function hide(id) {
$(id).style.display = "none";
}


I don't think there's anything I need to say about this function. The only slightly interesting thing to note here is that, unlike displaying elements, if you don't want display elements, setting their display value to "none" always does the trick.

Cool, so that's it for this post. Add these functions to wherever you put the $() function -- hopefully an external javascript file that you include on pages you need javascript on. Then use them in your javascript and see how much shorter and easier to understand your javascript becomes!

Monday, July 21, 2008

Debugging at APT - Part 1: Firebug

Like most developers (using any language or platform), folks at APT crave robust and powerful debugging tools. Fortunately, ColdFusion 8 introduced some fantastic new debugging and monitoring tools, on top of the robust logging and request debugging that has been available for a long time. Unfortunately, our architecture seems to prevent us from using most of those tools. (But we'll have plenty of architecture discussions later.) More generally, our system is not "pure" ColdFusion -- we also use Java directly, as well as SQL, JavaScript, CSS, .NET, VBScript, Ant... you name it -- so we often wonder which debugging tools are best for which jobs.

I recently hosted an internal "Wednesday Noon Session" on debugging at APT. (Every three weeks or so, one of our engineers puts together a presentation that focuses on one aspect of development at APT.) I learned a lot by preparing my session, so I'm going to post a series of articles on the tools we use and how we use them. I'll start today with Firebug.

Firebug

For the client side, as well as some server-side debugging, Firebug is one of our best friends. We don’t officially support Firefox for our clients, because their IT departments pretty much all mandate IE6 and prohibit the installation of any other browser. In fact, 95% of our product logins come from IE6, and almost all of the rest are from IE7. Once in a while we even see someone try to use IE6 on Win2K, which typically is missing the past five years worth of bug fixes and security patches. (Yes, even in mid-2008!)

But we’re working toward full Firefox support for a number of reasons, one of which is debugging capability. We have all sorts of complex pages in our software. If you’re not familiar with them, simply finding an element on the page, let alone debugging a script, can be daunting. Thank goodness for the "Inspect" button.


We make heavy use of the Script tab to evaluate JS expressions on-the-fly and step through functions, as well as the Net tab to see what's going on with our AJAX requests (like sorting, searching and pagination within each component). We also used Yahoo!'s YSlow extension to discover that our menus were rendering upwards of 85 iframe tags on each page. (Ouch! Well, it turns out that all of the iframes were there to work around a well-known IE6 bug. But we've since gotten smarter about the "hidden iframe hack" and we've also switched to using YUI menus, which are also smarter about using iframes and about rendering efficiency in general.)

Next time: Firebug's cousin and competitor, the IE Developer Toolbar.