Thursday, July 10, 2008

target="_blank" convention

I've been building websites for a while now, and each time I do it, I run into a couple areas where I sit back in my chair for a second, scratch my head, and ponder conventions. One great thing about Ruby on Rails is the way it enforces convention in many areas, but yet there are still a number of things up for debate. The target="_blank" is one such convention that has yet to be settled it seems.

I guess it's a two sided issue. When do you use target="_blank", and how do you indicate that behavior to the user?

I think the first one is fairly simple. One obvious rule I follow, is whenever you're changing domain's the target should be in a new window. Just because someone want's to read a little background behind a hyperlink, shouldn't mean their done reading the rest of the text on this page. And I usually extend that same principle to other areas, too. For example, I recently built a site that had an editing form, and you could just repeatedly save changes as you went on. I added a 'View' link that targeted a new window so that if you wanted to see the changes you've made, you could, without being taken away from editing. So as far as I'm concerned this issue is pretty straight forward.

This one isn't: giving the user feedback that the link is actually opening in a new window. I can't seem to find anything that is blatantly obvious. I've tried appending '(opens in a new window)', to the link, but that messes up the design. I thought about changing the color of the link, or using a dashed underline, instead of a solid one, but your basic web user isn't going to pick up something that subtle. I was also suggested by a colleague to just put text in the title. But the chances of someone waiting that long before their finger slams the mouse is slim. And using JavaScript to load something more instantly, seems bloated.

The most obvious technique I've found, I saw for the first time with Mantis, a bug tracking system, which was to append a '[^]' to the end of every link. The link, itself would always open in the same window, but if you clicked on that little character, it would open in a new window. But then, why not just right click and let your browser handle it ("Open in a New Window," or "Open in a New Tab", Ctrl + Click, etc.).

Ultimately I think the best solution would be totally default settings that the browser could pick up. Just like a link default is by default blue and underlined. Even then, I suppose it's a browser setting, but we'd be closer to a consistent solution. Or everyone could just agree to something, which I suppose I'd be OK with...

...as long as I'm part of the conversation.

Thursday, June 5, 2008

Deploying a Site via DNS - "That was Easy!"

I launched a site today for Northpoint Horizons (http://www.northpointhorizons.com), and it was seriously one of the simplest deployments I've ever experienced.

We've been working on the site for months on the future (now current) production server. We've used it for the client to review the site, to perform testing, everything you'd do with you traditional development environment. All the meanwhile, the DNS for northpointhorizons.com has been pointing at some sandbox with an "under construction" banner. So after rigorously reviewing the "staged" site with the client and completely approving it for launch, we just flicked a switch pointing the DNS right to our environment and everything just worked.

I can't imagine deploying a website, at least v1.0, any other way.

Tuesday, May 6, 2008

AJAX Form Validation for Rails

Last Saturday at the Chicago Ruby User Group I gave a short presentation on Rails and AJAX. For part of the presentation I decided to solve a problem that's haunted me as a web developer for some time - form validation.

Here's the dilemma:
You start with server side validation, then build your form. To validate the inputs, you have to make a round trip to the server, and re-render the entire page with the validation messages. Not the smoothest process, given the bar set by Web 2.0. But at the same time, if you try to engage the user more, you find yourself writing the same validation in JavaScript for the client - not fun.

Here's the solution:
Again, start with server side validation and a form. Then use JavaScript not to validate the data, but to facilitate an AJAX request to the server, where you there validate the field and send simple feedback to the user.

I started by searching for solutions for this. As it appears, I'm not the only developer in the room who wants AJAX validation. Here's what I found:
I opted, for the sake of practice, to use these as inspiration to my own solution, which goes something like this:


def error_message_for(model, field, options = {})
tag_id = "#{model}_#{field}_validator"

# generate javascript for AJAX request and field observation
js = observe_field "#{model}_#{field}", :function =>
"new Ajax.Request(
'/users/validate?field=#{field}&value=' + value,
{ method: 'get', onSuccess: function(transport) {
element = document.getElementById('#{tag_id}');
var output = transport.responseText;
var css_class = '#{options[:error_css_class]}'
if (output.length == 0) {
output = '#{options[:success]}';
css_class = '#{options[:success_css_class]}';
}
element.innerHTML = output;
element.setAttribute('class', css_class) }
}
);"

# generate html for placing error message
tag = content_tag options[:tag], options[:hint], :id => tag_id, :class => options[:hint_css_class]

#return it
return tag + js
end


I wanted my solution to be equally elegant as Rails' non-Ajax solution, so I created a method error_message_for, which takes the model, field name, and various options. First, it creates the JavaScript I'll need with observe_field, wiring up the Ajax request to the field we're monitoring. Then, using content_tag produces an empty tag which will serve as our feedback placeholder. It returns all that HTML/JS to the browser. But, we haven't done any validation yet. For that we need a validate action that can be called on whatever model you're working with (in this case I'm working with a User):

def validate
field = params[:field]
user = User.new(field => params[:value])
output = ''
user.valid? # trigger the errors hash to be filled
if user.errors[field] != nil
if user.errors[field].class == String
output = "#{field.titleize} #{user.errors[field]}"
else
output = "#{field.titleize} #{user.errors[field].to_sentence}"
end
end
render :text => output
end

Now, we're cooking. As the user moves from field to field, the AJAX request we wrote is created, firing validate. Validate then uses the valid? method to populate the errors collection on our model which in turn allows us to return the same error messages Rails would if we were using error_message_on.

Now we just implement it. Call our new error_message_for method right after the input field like so, and that's a wrap. The HTML and JS is returned to the browser when the page renders the first time. When focus leaves a particular field, it's value is sent down to the server for validation, and the server replies with whatever applicable error messages, which are displayed in the originally empty HTML generated to begin with.


form.text_field :email
error_message_for :user, :email, { :tag => :span, :hint => 'Your email must be formatted properly.', :success => 'Looking good!' }


You may have noticed some code in there referring to :success and :hint. I figure, while we're in there let's add support for a hint to be displayed before any validation occurs, and a success message to display when validation is passed.

The best part of the whole thing, is it's really DRY (Don't Repeat Yourself), and therefore simple. Change your validation rules, and the UI updates dynamically. In addition the same approach can be used on any form that has an underlying model associated with it.

Tuesday, April 15, 2008

Peeling Up

I'm not sure when exactly it happened, but drop shadows and rounded corners struck the web with a vengeance. Then it was the reflections. It seems like those persnickety designers are looking for anyway to make our lives as developers harder. But they have a fairly noble goal, anyway - to give a 2D fairly boring web page depth. I'm a big fan.

But at the same time, I find it very frustrating. Both rounded corners and drop shadows make dynamic widths a nightmare. Then there's the issue of a drop shadow spanning two background colors with full translucency support. Solving any of these problems elegantly is a challenge. So recently I've been looking for simple ways to evoke the same illusion of depth. I think I've found two, but I'll talk about one here.

Every since I signed up for LinkedIn, I've been dying for them to do a redesign. After logging in I felt totally inundated with information, and found it very challenging to navigate. Aside from the fact that a few months back they totally overhauled the design, they added a really slick design paradigm I've never seen before and I was really impressed. I'm referring to this:

Do you see what I'm referring to? It's the peeling up effect below the "Add Connections" button. It doesn't solve all the problems, but it definitely makes it easier than extending a drop shadow all the way up one side of that floating box. They actually call the class on that div "sticky-box" which I think embodies that "peel up" perfectly. Bravo LinkedIn!

Tuesday, March 11, 2008

Skepticism happens {here}

I attended Microsoft's 2008 Product Launch Event, Heroes Happen {Here}, today and I think my suspicions have been officially confirmed. 

My interest in Microsoft products has been waning as of late. Nevertheless, attending a Microsoft launch event is a good reason to get free schwag, and they do a decent job of highlighting what to look for in their new products.

Products? Let's take a minute to dissect what that means.

Stephen D. Levitt in Freakonomics talks about the simple law of incentives. Real estate brokers, he argues, don't stand much to gain by selling your house for a few thousand dollars more. By the time they get their commission, that few grand is only a few hundred dollars. In fact, to that point, they could make far more, by selling another house with the time and effort it might take to "wait it out." Understanding this incentive is the golden key for sifting through potential B.S.

What does that have to do with Microsoft?

Well, Microsoft is selling a product, after all. They make money when you buy Visual Studio 2008, SQL Server 2008, and Windows Server 2008. And that's really only the beginning. Once you're hooked (I walked away with a free copy of each), then they really take you for a wild ride with production licensing.

Now, I'm not saying that is bad. To the contrary. Your business needs paper, staplers, and desks, too. It needs all kinds of tangibles that someone makes money by supplying. It's an awesome system that pretty much drives commerce.

But at the same time, when I see the same UpdatePanel demo in the developer track that I saw last year at the Chicago .NET User Group, I become skeptical. When Split View, one of the most prominent features evangelized at the conference, brings my friend to say "uh, duh... Dreamweaver," I become skeptical. And what about LINQ? Try on ActiveRecord for size - it's free. Silverlight? Ever heard of Flash? And how about instead of banking on the drag and drop AJAX Toolkit, you actually learn JavaScript. You are after all a web developer, right?

But it wasn't all bad. JavaScript debugging and JS IntelliSense are very cool. The load tests also seem cool.

I just want to keep it simple. In one of the presentations the speaker referred to JavaScript as one of the "bane of a web developer's existence;" and you might say an UpdatePanel is the definition of simple. But to who? A dilettante or a developer?

If you want to do anything there's a learning curve. If you embrace that curve you'll find that there are simple, cheap, even free tools that replace the Microsoft suite, backed by hundreds of smart people who did the same. 

And knowing that, it's hard for me to bank on the guy counting all his cash.

Wednesday, March 5, 2008

Best Tool for the Job

The religious wars go on. Microsoft vs. the rest of the world, it seems. On and on, ad infinitum.

But does it ever really matter? Is there definitively a platform of choice? Or more to the point, is that question even valid? Can there be a definite? As Jeff Atwood points out, every technology flexes different strengths and exposes certain weaknesses. Knowing the pros and cons will help you determine the best tool for the job.

I recently started re-reading parts of Marshall Goldsmith's What Got you Here, Won't Get You There. Goldsmith, an organizational psychologist, describes a terribly-negative characteristic common among successful people dubbed as the "need to win." Developers have got a serious case of it.

Looking for a feeding frenzy better than Shark Week on the Discovery Channel? Go into a room of shark, oops, I mean sharp, developers and ask what's the best way to refactor some classes to support an MVC architecture. Before you know it, you've got 100 ways to solve the same problem. How do you pick?

Keep it simple, stupid. You don't need a sledgehammer to hang a picture (although it might be fun). You don't perform brain surgery with a chainsaw (I'm looking at you, Tarantino).

Unfortunately, for software developers. Knowing which tools to keep in that tool belt can be daunting. Each platform presumably exists for some reason or another. They don't just write 300 page, $50.00 software text books for fun. So it's got something going for it (or at least it did), even if it might not be much. Some guy, just as smart as you, probably smarter, was on the other side of your criticism when he built the damn thing. Unlike other industries, where there may be a definitive right way to execute, technologists grapple with hundreds of choices and decisions. So to really be able to know which tool is best for the job takes years of exposure, education, and error.

So take it upon yourself to constantly challenge the risk/reward of a given platform - arm yourself with an arsenal of tools that suits the job you need to accomplish. Picking sides, after all, violates the whole spirit of software development. So let's stop arguing already and build something spectacular.

Tuesday, February 12, 2008

A Look Back at Windows Mobile 6.0 and ActiveSync

While I was walking home from work today, checking my email on my iPhone, something very strange occurred to me. Once upon a time, I was a Windows Mobile junkie. Not just a standard user, but an all out fan boy. I would talk to whoever was willing to listen about how awesome my Treo 750 was, and how awesome of a job ActiveSync did at keeping everything, well, synced. So I started to wonder what happened?

A little background might help here. I made the conversion to Apple (iPhone, iPod, MacBook Pro) about 7 months ago. Before that I was all Windows, all the way. The conversion was sparked by two things. My interest in Ruby on Rails, a very rapid web development framework, which works best on Mac OSX and, the topic of conversation here, my desire to separate work from play. I was blown away.

ActiveSync, which requires an Exchange Server, is awesome. Loose your phone? No problem, your calendar, contacts, email, it's all synced. Out of site, out of mind. It also syncs really fast, with almost no lag from the minute something happens in Outlook to when it hits your phone.

But I wanted to separate work from play, and I couldn't seem to do it. Microsoft sells products, and as a result, no matter how awesome the product is, it's limitations are in MSFT's hands. So I switched to a more "open source" solution.

Now I've got both work and personal email happily IMAPing to my phone, contacts syncing to my Mac, along with the gigs of video and audio I have as well. No, my calendar doesn't sync over the air. No, I can't accept meeting invitations, but, I think I'm OK with that. The things it does do well, it does amazingly. Let alone the interface of the iPhone, it's stable, which is a lot more than any Windows Mobile device can say. Every time a call came through it was like my Treo was having an aneurism. It really tried to keep up, but always seemed a few steps behind. Meanwhile the iPhone "just works." Incoming call during a song? Music fades out, call fades in. It's beautiful.

So all in all, I'm happy I made the switch. More than anything, I'm glad that my personal stuff is out of my corporate account. But hey, the phone's cool too.