Fri, June 17, 2005
Comments, Login, and Ajax
Man, Ajax really wiped the floor with my ass!
Hey ho, Beesketeers! It's been a while since my last redesign update. Did you think I'd lost my nerve and given up? No way! 15 or 20 minutes with my head in the oven cured me of that notion! Comments, item links, polls, all now work properly in the object-based approach that will run the new site. And all the hard work will definitely be paying off – everything's much more efficient. Not that any of this means much to you, the lowly reader, but nevertheless that's what I've been up to.
The main new feature is the improved process for posting comments on the site. After much deliberation, I've decided to reverse my earlier stance and move forward with comment previewing instead of comment editing. As much as I hate to yield any ground to whiny malcontents, I know when I'm beat. Comment previewing allows everyone a chance to see what they've written before committing, while comment editing would only have worked for users who were logged in. (And, since most comment-based errors happen when someone forgets to login in the first place...) Live it up, whiny malcontents. You got me good.
I learned that previewing comments can be very helpful when your comment is longer than the comment input box. That is, previewing allows you to see your whole comment in one place, without having to scroll – maybe that's something that people have been clamoring for. (Plus, it allows you to notice if you forgot to login.) I also realized that I have already used the comments this way several times, since I have the ability to go into the site's admin section and edit comments after they've been posted. I often read through a comment after I post it and then go back to make small revisions. So, here's to sharing that power with the masses – whiny and malcontent as they may be. I had to jump through some hoops to get it like I wanted (I think it's key that the preview is displayed in the context of the existing comments) and I think the result is a pretty useful solution. The only drawback is that there will be two buttons: commenters must remember to click Preview if they want a preview and Post when they're ready to commit.
Also on the list: streamlining the login process. It has never seemed right that when you need to login, you have to go to a whole other page, login, then return – it ruins the rhythm and breaks your train of thought. So in the future when you click login from the comments area, it will provide a login form right where you are. Even better, due to technical details which I'll outline exhaustively in a moment, you can login after you type your comments into the box (as well as, of course, after you preview them). It's all designed to reduce the nuisance of dealing with the login step as much as possible.
Staying logged in will also be easier. In the past, the login was handled with PHP sessions; in the new onebee, logging in will store a cookie on your computer, which will allow onebee to recognize you if you come back later. The old way, you'd only stay logged in for the current session (i.e., until you closed your web browser), and sometimes you'd be randomly logged out even before that. I never fully understood why, but it happened a lot – and now it won't any more. Thus, finally resolving an ancient demand by one of our most loyal readers. This represents a sizable change in onebee's long-standing policy against persistent cookies, but it seems worth it to me. For one thing, the persistent cookie is set entirely at your discretion when you login. You can choose to set the cookie for just the duration of your session, or you can select from a few other options ranging from one day to forever. So, if you preferred the old session-only cookie approach, you can stick with that. The cookie itself stores only encrypted data so even if some malfeasant were to hack your hard drive and look at your onebee cookie, it wouldn't reveal anything about you.
Now for the technical. (Regular readers may find the remaining part exceedingly dull; feel free to skip it.) One of the new technologies that's available to me during this redesign is something called Ajax. (The silly name, which abbreviates "Asynchronous JavaScript + XML," is somewhat controversial, but it's certainly a lot easier to say.) You can get an in-depth understanding of Ajax from the article at Adaptive Path that coined the phrase, or from countless other resources – but the short version is this: Ajax represents a way for a web page to transmit new information (loading data from the server or sending data to the server) without reloading the page. Google has rolled out some very impressive uses of Ajax, both in GMail and in Google Suggest (which currently doesn't work in the newer versions of Safari because Apple's software goons have a very twisted understanding of what "user-friendly" should mean). As a result of this high profile exposure, the web development world has latched onto Ajax, slapped a goony name onto it, and can't wait to use it for anything and everything.
In my view, that's overkill, but Ajax does serve some very useful purposes, like our new login feature. Ajax allows onebee to login new users without refreshing the page, which means the view doesn't change – you're still looking at your comments in the context of previous comments – and the comment form doesn't have to be submitted – meaning you can login before, during, or after typing your comments into the input box, and it's still seamless. In short, I think Ajax is very powerful, but it's most effective when it's used intelligently. As a designer, I still must work within the confines of users' expectations (for better or worse). All the zowie technology in the world is useless if it doesn't behave the way you expect it to. So, as exciting as Ajax is, I've confined its use to some very specific areas. (Technically, for example, Ajax could be used to load the entire site without ever refreshing the page, pulling in content for new columns as you click the links, etc. But most of us are pretty accustomed to using the "Back" button as we navigate the web.)
Of course, implementing the Ajax solution was not as easy as I'd hoped. Since I was learning a whole new approach from scratch, I figured I'd find some similar examples online and make a few modifications. Like the comments, I soon learned that there were no good examples to fit my needs. It's not as simple as checking the login and returning a status message: the post-login comment form must match the comment form you'd see if you were already logged in when you got to the page. This means displaying name and e-mail information in a custom-formatted way. For tidiness, I wanted that display code to be returned by the server, rather than coding the basic elements into the original page and letting Ajax swap in the proper values after authentication.
I ended up with a script which encodes the password and passes it to the server along with the login. Then, on the server side, a PHP script compares these to the database, and returns an XML-formatted document. If the information is correct, PHP sets a cookie with the user information, and the resulting XML document includes a valid
field set to "true" as well as a chunk of formatted HTML for the name and e-mail display. If not, the valid
field is "false" and another field contains a plain text message describing the error. JavaScript then displays the result, by modifying the innerHTML attribute of a specified portion of the page. (At first I tried using appendChild(), but found it glitchy in some older versions of Windows IE.)
Sending the data to the PHP script and parsing the resulting XML file are the only heavy-lifting portions. Of immense assistance in refining this functionality was the tutorial on the XMLHttpRequest Object from Apple Developer Connection, which includes helpful XML parsing code that works with all browsers. Swapping between the original view, login form, and post-login comment form was accomplished by toggling each object's "display" attribute, which effectively hides/displays that particular object. (This is pretty standard, already in wide use on the web.)
Because logging in is a critical function, it was important that this Ajax feature degrade well. That is, for users with older web browsers which may not support Ajax, the site can still log you in the old way. The login form is coded to submit to a separate login page, so if the browser fails to execute the Ajax version, the user is still logged in. Also, because some browsers will submit data from hidden fields, I had to code my comment-posting code such that a logged-in user will override anything typed into the name or e-mail fields before logging in. (An unlikely scenario, to be sure, but why not be prepared?) Finally, as a general usability improvement, I hid the comment form while displaying the login form. If users were presented with both forms simultaneously, I could foresee them assuming that submitting either form would perform both functions (login and post comments). While possible, that would require handing over to Ajax more work than was really necessary. It was easier to simply hide the comment form until after authentication, then display it again.
I'm very impressed with Ajax; once I familiarized myself with the basics, it was pretty easy to get it to do what I wanted. The hardest part was the cross-browser XML parsing. Other than that, it's just a matter of carefully planning what you want it to do – and what you don't – and preparing the page accordingly. There are a few other minor back-end features that I'd like to enhance with it – it's definitely nice to have in the toolbox.
Brandon — Fri, 6/17/05 9:56pm
Finally, being a whiny malcontent pays off!
Thanks for the additions. They will make help my malcontentery even more whiniferous in the future.
"edgars" — Mon, 7/3/06 11:44am
may I try this form. i didn't find the form.
Comments are now closed.