Archive for the ‘Behaviour’ Category

Predictive Text

Anyone who likes to text is probably familiar with “predicative text”—you start typing a word and the phone guesses what you’re trying to say so you don’t have to type the whole thing and you can go on to the next word. Saves my thumbs some effort on my blackberry. Pretty neat. I’ve always wondered how it worked as it seems to always know the word I want to type but on second thought, maybe it’s really influencing what and how I am saying and I would have said something different had it not suggested that word. Hrmmm… Here’s an example:

“T” is for technology!

Sometimes we take technology for granted and something small make us sit back and think “Wow!” That just happend to me. Tonight I was sitting at the kitchen table working on a technical review for an upcoming PHP book while my wife was playing with my giggling daughter, singing songs and reading books. While singing, my wife turned to me and asked:

“What are all the words to the Cookie Monster’s “C” is for cookie song?”

I started singing “C is for cookie, that’s good enough for me…” but then we realized that was the only verse we remembered. I instantly popped up a browser window, “googled” for “C is for cookie”, clicked the first hit which was a link to a YouTube video and about 10 seconds after the question was posed, my daughter was giggling to the original Sesame Street recording…

That’s just cool. Instance access to almost any information, available on demand, whenever you need it. It sounds like a tale of science-fiction but it’s something I take for granted all the time. Need a recipe? info on a movie or a trailer? phone number? driving directions? Those and many more things are at our fingertips whenever we want them. I can only imagine what will be available tomorrow!

Now, I wonder what I would “google” to find a good place to hide for hide-and-seek?

Is it true? A decent JavaScript editor?

Of all the software I have on my Mac, I’ve always been missing a decent JavaScript editor. I do have editors that support JavaScript syntax highlighting and such but they lack those extra features. For other languages such as:

  • CSS I have CSSEdit and StyleMaster,
  • PHP I have Zend Studio and it’s wonderful developing environment,
  • HTML, JavaScript and general code editing I have the awsome BBedit,
  • and for general subversion access there’s svnX.

(note the lack of a WYSIWYG editor! Everything by hand!)

But I really want a good JavaScript IDE. And I may have found one. A colleague pointed me at Aptana, I just downloaded it and gave it a quick try and looks very promising:

aptana_test.jpg

My only complaint is that it’s written in Java so it doesn’t use the standard windowing methods on my Mac but I can look past that if it’s good enough. Hopefully this will now complete my tool set.

Disabled? No Pizza For You!

This past weekend my wife and I decided to check out the new Boston Pizza that was recently built near our house. It’s one of only a few new popular restaurants in town so we were told the line has been crazy long with more than an hour wait at times. We decided that before we went, we would check out the on-line menu too see what they had. That way, if the line was too long we could just order takeout and go home to enjoy our meal. The domain name BostonPizza.com wasn’t hard to guess so I pulled up the site and we proceeded to peruse the menu (I decided on a small hawaiian and my wife chose the Ultimate Pepperoni pizza). While browsing the menu I also noticed that the main navigation used a ‘drop-down’ effect:

BostonPizza.com Dropdown Navigation

Being the curios web developer I am, I decided to investigate a little further to see how it was done and if it was a semantic list a la suckerfish (though I had to work quickly as my wife was getting hungry after looking at the photos of pizza).

(more…)

Doing it Asynchronously

Regardless of what you’ve heard about Web 2.0, why it’s cool, why it’s not really 2.0, or why the term Web 2.0 may actually be important, one thing is certain. It’s very shagadellic and it’s all about asyncronicity baby!

Yes that’s right, everyone is doing it asynchronous now, newbies and hackers alike. And why not? It’s all the rage! I mean, how boring was the way your grandparents did it? So mundane, always following the same routine:

  1. Load
  2. Wait for a response
  3. Click
  4. Repeat

Are you really happy with the result of a simple load, wait, click, repeat? Maybe you enjoy the repetitiveness since you’re web site ’seems’ to enjoy it equally, but what if there’s more?. To enjoy the best experience of asyncronicity, all you need are the Ajax twins: XmlHttpRequest and ActiveXObject(”Microsoft.XMLHTTP”) — but that’s where it begins to get a little complicated. It seems these two have been taking over the minds of many a young web developer, corrupting their thoughts with wild imaginative fantasies. Now, day-in and day-out, 24/7, all the web developers can think about is:

  1. Load
  2. Wait for a response
  3. Click
  4. Click
  5. Click
  6. Click
  7. Click
  8. Click
  9. Click

Going with the flow

All these asynchronous communications change the very nature of your application’s flow. You can’t rely on that mundane load, wait, click, repeat cycle because the page never fully loads again, only little pieces of it do. For instance, take this common simple administration tool for a news item list on a website:

Common News Tool

The ‘check mark’ and ‘x’ symbols represent the ‘active’ state of the items in the list.

To ‘activate’ an item, the user would simply click the check box or the x and several things may happen. If you’re using the traditional workflow, your web application will probably do something like this where the page is forced to reload:

Traditional Application Flow

This is a typical “Web 1.0″ application flow. You click, a request is sent to the server, it responds, and the entire page is reloaded to reveal the new change. Often, you’re left sitting at the top of the page and forced to scroll down to even see the change. What fun.

Alternatively, if you’re going asynchronous with Ajax, you’ll end up with something that looks a little more like this, where only small protions of the page change using the appropriate DOM scripting:

Ajax Application Flow

No reloading except for the manipulation of the page with your favorite DOM methods. So where’s the problem? We’ll it’s not really a problem — if you know what you’re doing. The thing you have to remember is that you’re doing things asynchronously now. Requests are going out every time you click the buttons, but they don’t necessarily come back in the same order. Huh? Let me explain with an example. Click this button several times quickly in succession:

Requests

    Notice the order of the requests coming back? The request number represent the order you clicked the button but the order of the list represents the order they were completed by the server. When you click the button, a request is sent to the server and in this case all I’m doing is simulating some server traffic by sleeping the PHP script for a random time:

    <?
    header("Cache-Control: no-cache, must-revalidate");
    sleep( $time = (2/rand(1,8)) );
    echo "$time";
    die();
    ?>
    

    and then sending back the $time before completing the request. If you wait at least 2 seconds between each button click, it’ll probably return requests in the same order because the initial request will complete before the following request. But, if you click it quickly several times quickly in succession, in this case less than 2 seconds apart, you may have a request of 1.5 seconds followed by a request of 0.5 seconds. When that occurs, the second request will finish and complete before the earlier request! This demonstrates asynronous in action - it’s out of sync and out of order, running at the same time as other requests.

    Handling Asynchronous Requests

    If you check out the JavaScript I’m using to do the request it looks something like this:

    var counter=0;
    function doRequest(e){
        var num = ++counter;
        new Ajax.Request("http://jeffreysambells.com/openprojects/PHP/sleeper.php",
        {
            onComplete:function(t){
                e.innerHTML += "<li>Request <strong>" + num + "</strong> <em>(took " + t.responseText + " seconds)</em></li>";
            }
        });
    }
    

    All it does is make an Ajax request (using the Prototype library Ajax object, since it’s already loaded in my blog) and then processes the result when complete. The key thing to remember is that the action you want to take as a result of the request must be placed on the onComplete handler of the Ajax object (or onSuccess in the case of prototype if you’re doing error handling). I often see Ajax rookies doing something similar to:

    var counter=0;
    function doRequest(e){
        var num = ++counter;
        new Ajax.Request("http://jeffreysambells.com/openprojects/PHP/sleeper.php");
        e.innerHTML += "<li>Request <strong>" + num + "</strong> <em>(took " + t.responseText + " seconds)</em></li>";
    }
    

    which is just plain wrong. As I demonstrated earlier, The XmlHttpRequest object is asynchronous, this means that the

    new Ajax.Request("http://jeffreysambells.com/openprojects/PHP/sleeper.php");
    

    line will execute, but may not return before the

    e.innerHTML += "<li>Request <strong>" + num + "</strong> <em>(took " + t.responseText + " seconds)</em></li>";
    

    line executes. If you want your script to wait until the request is complete, you must handle the remaining script from within the onComplete handler by splitting your JavaScript code into objects and methods, then calling the appropriate one when each request is complete.

    In the ‘wrong’ way above, there’s the additional problem of using t.responseText, which isn’t in the scope of the doRequest() function, but we’ll discuss that mistake another time.

    It’s that simple. Nothing too complicated just a complete shift in the ‘top down execution’ approach you’re probably more familiar with. All you have to do is remember that the A in Ajax means Asynchronous. That’s the key.

    If you’d like to learn more about Ajax, I’d suggest first reading the original Ajax article by Jesse James Garrett at Adaptive Path “Ajax: A New Approach to Web Applications” and the many excellent resources over on ajaxian.com but in the mean time have fun with Ajax — the more you do it the better you’ll get.

    Relativity and Your Web Site

    Caution: Paths may explode.I bet, at some point, you’ve come across a broken link or maybe an image that just wasn’t loading properly into your web site. When it comes to linking files, or more specifically, file paths in your web site, everything is relative. But relative to what? The problems associated with relativity become especially apparent when working with dynamically created pages. (more…)

    Play Nice With Others: JavaScript Namespace

    Good Job!Ever had a friend with the same first name? I did. Growing up, through elementary school, I had a good friend named Jeff Shaddock. This posed a problem for most of our teachers as the typical “first name, last initial” solution for children with the same name didn’t work. On assignments and tests, I was usually forced to be Jeff Sa. and likewise, my friend Jeff was forced to be Jeff Sh. so people knew which one of use was which.

    Similar situations often crop up when dealing with web applications and JavaScript. Since JavaScript doesn’t complain when you declare a function multiple times and it simply uses the last declared version, if you have a few different libraries, each doing their thing, you need to make sure they don’t conflict. If you’re planning on writing a new library, or improving an existing one, you can avoid frustration by keeping two simple things in mind: be unique and don’t share. (more…)

    Yet another JavaScript logger

    While writing Beginning Google Maps Applications, I grew accustomed to using GLog.write() while debugging any JavaScript I was working on. It was a wonderful alternative to alert(). That was great while I was working on map related projects but without the Google Maps API, it wasn’t there. Finally the other day, frustrated the 100th time I accidentally put my browser into an infinite alert loop, I decided to write up a quick logger myself. Afterwards, I realized there were already a bunch on the net but I had fun writing my own and even learned a few DOM tricks. For any of you out there who want to use it, go nutz. I’ve called it JSLog and the primary methods are JSLog.write(); which outputs escaped angle brackets while JSLog.writeHTML() outputs the raw input.

    JSLog Window

    The best part is now when debugging things like Prototype AJAX calls, you can easily log and see all the exceptions!

    new Ajax.Request( 'example.php', {
        onComplete:function(request){
            try {
                //do whatever you need to an errors will be logged!
            } catch (e) {
                if(JSLog) JSLog.write(e);
            }
        }
    });
    

    No more errors floating into dream land!

    To use it, just download the source or add

    <script type="text/javascript" src=http://jeffreysambells.com/openprojects/JavaScript/JSLog.js"></script>
    

    to the head of your document.

    Lert: the multi-button JavaScript alert/confirm box

    The other day a co-worker was asking if it was possible to add additional buttons to the JavaScript confirm box. As far as I knew it wasn’t possible, but there was another option, and probably one that’s a lot cooler and more useful: make our own alert/confirm box. I planned it all out in my head the next morning while cutting greens at the golf course, and hacked a working version together while I was eating my dinner later that day.

    So here’s the quick and dirty script. Use it as you please.

    The quick features list is:

    1. Floating ‘window’ with darkened background a la lightbox.js.
    2. Specifying a defaultButton will execute that button event when the ‘enter/return’ key is pressed.
    3. Styled using CSS so you can edit it as necessary.
    4. Asynchronous event triggering similar to an AJAX call. Events are specified using anonymous functions passed into the LertButton() object and triggered when then associated button is clicked.

    Remember, I wrote this quickly while I was eating so it’s not a perfect OO solution and is a little hacky. I’ll improve upon it when I get a chance.

    Lightbox 2 mods

    I’ve been using the awesome Lightbox 2 JavaScript by Lokesh Dhakar to build a quick photo viewer but was running into a problem. There are two configuration options:

    var fileLoadingImage = "/path/to/loading.gif"; var fileBottomNavCloseImage = "/path/to/closelabel.gif";

    that are required to specify the location of the loading and close images respectively. My problem is that I want to use fancy URLS for the links with an ‘unknown’ depth, and I don’t want to reference the path from the web root so that I can install it multiple times, wherever I want, and have it just work. Digging into the code a little further, I make a few modifications to allow you two set the images using CSS only, rather than edits to the JavaScript. If you want to do the same, around line 270 just comment out:

    //var objLoadingImage = document.createElement("img"); //objLoadingImage.setAttribute('src', fileLoadingImage); //objLoadingLink.appendChild(objLoadingImage);

    and around line 306 comment out:

    //var objBottomNavCloseImage = document.createElement("img"); //objBottomNavCloseImage.setAttribute('src', fileBottomNavCloseImage); //objBottomNavCloseLink.appendChild(objBottomNavCloseImage);

    then in the CSS file add:

    #bottomNavClose { display:block; background: url(i/closelabel.gif) no-repeat; width:66px; height:22px; }

    loadingLink {

    display:block; background: url(i/loading.gif) no-repeat; width:32px; height:32px; }

    Make sure the url()s are relative to your stylesheet. In my case all the images are located in an ‘i’ directory along with the style sheet.

    Now the images are specified with the CSS and you need not edit the JavaScript. I’m sure this will be done in an upcoming version as the Next and Previous buttons are already set up this way.

    Content & imagery © Copyright 2007 by Jeffrey Sambells as appropriate.