Archive for the 'javascript' Category

Stages in Life of a Web Developer

Monday, September 1st, 2008

After experiencing this interesting development in my own life, I keep seeing others go through the same 3 stages:

  1. Stage 1: TOTAL HAET!
  2. Stage 2: Careful, reserved acceptance…
  3. Stage 3: TOTAL LOVE!

People in Stage 1, almost unanimously think that Javascript is “totally ghay”. They use phrases such as “a silly toy language” and generally consider it to be just a step above Visual Basic. Let me explain this for those readers who don’t hang out with programmers all day and they don’t get to learn our lovely stereotypes, and for Visual Basic folks who are probably not aware of this. In the world of software engineering, being a VB guy is a bit like wearing a mullet. In other words, it implies lack of style and sophistication and underlines the fact that you are just not keeping up with current trends. Not that there are no talented VB programmers - there are exception to every rule after all, and all stereotypes are mostly false except when they are true. )

Stage 1 people look at Javascript hackers, and scoff at them confident of their own superiority. They view client side scripting as a thankless, tedious job for masochists. After all, coding in Javascript is a a chore, right? You set something up and test it in Firefox, only to find out it doesn’t work in IE. Then you fix it for IE6 but it doesn’t work in IE7. Then you find out it doesn’t work in Opera. Finally you covered most of your bases and someone tells you that you need to support IE5 as well. Then IE8 comes along, and breaks your code once more. So your code branches into a tangled forest of exceptions, workarounds, hacks and mostly undocumented syntax acrobatics. This must be what programmer’s hell is like.

Most people who go through this once or twice in their career, wash their hands from client side development and declare themselves as server side dudes. Some of us however, end up working more and more with the infernal language, and eventually we end up researching ways to make the language it less painful and more powerful. And then something happens.

We discover one of the many Javascript frameworks such as JQuery, Prototype, YUI and etc. All of a sudden you have this tool - this API which gives you a comprehensive list of cross-browser functions, objects and widgets to play around. Someone already went through the browser compatibility hell and built a layer on top of it. You talk to the framework, and the framework deals with the browser bullshit that made your life so difficult initially. All of a sudden you realize that, hey - Javascript ain’t that bad actually. The language is flexible, dynamic and very expressive. It doesn’t get in your way, it doesn’t require you to write boilerplate essays, and it allows you to be as brief and cryptic or as verbose as you like. Wow…

Welcome to Stage 2. At this point many people still have their reservations. They are sure that sooner or later they will to fall back onto their old Javascript tricks and deal with the browser hell. They are convinced that there will always be exceptions and outlying cases that will make the framework a liability. They thing that at some point they are bound to run into a problem which is only compounded by the framework and will have to work around it, and around browser bullshit to fix it. So they remain cautious and vigilant. They promise themselves that they will never get roped into doing client side stuff again. They will be strictly server side from now on. They view Javascript as necessary, but manageable evil and purposefully make their trips to client-side land brief and limited in scope.

But then as they work on their JS related projects they grow to like the language. The realization that this language can do almost everything that Ruby and Python are being praised for if not more while maintaining a conservative and familiar syntax slowly starts sinking in. You can do crazy dynamic Ruby/Python like stuff without actually running yet another interpreter of VM. Javascript runs in your browser, and can run on the JVM with Rhino. If you wanted to, you could even use it on the server side with full access to Java API and leveraging the full potential of JSP without the burned of verbose, statically typed Java syntax.

A whole new world opens before you. Javascript is popular. Everyone knows a little bit of it. Everyone has a collection of hacks posted somewhere. There are volumes upon volumes written about the language. There are dozens of frameworks, millions of libraries and code snippets waiting for you to exploit them. Whatever problem you are having, there is probably an easily googlable solution for it. If the solution seems complex there is probably a framework out there which reduces it to a single function call. And if you happen to be working with Rhino you can always just call one of the countless Java API methods instead.

You just entered Stage 3. Stage 3 folks can be recognized by the smug smile glued to their face when they code in Javascript. They know that you know that they know something that you don’t. They have this inner glow, and supernatural powers - they can solve a complex issue in 3-4 lines of code. They take this silly toy language and build incredibly awesome, rich client side applications. Stage 1 person may think that Javascript is pretty much only good for sending asynchronous request to the server and making things fade in and out on the screen. Stage 4 people create impressive stuff ranging from Rhino on Rails, to a 14KB Super Mario Clone or DHTML Lemmings.

Personally I think Javascript has a bright future. It’s just that a lot of people are still stuck at Stage 1 and the stigma of toy language keeps them there indefinitely. Stage 2 is transitory and brief, and almost always results in a transition to Stage 3.

Which stage are you? Are you hating Javascript, begrudgingly accepting it or loving it? Have you experienced a similar transition, or were you one of the few people who instantly fell in love with the language? Do you think you will ever transition beyond your current stage?

Making Websites Without Serverside Scripting

Monday, May 19th, 2008

Here is an interesting task: make a semi decent website, which is pretty, and maintainable without using any server side scripting or server side includes. In other words, we want a website that has a header, footer, a navigation sidebar and layout modeled via css without doing any copying and pasting. The above mentioned layout elements should only appear in a single place for ease of maintenance. Why would someone need something like that?

Well, the Novel Netdrive service my school uses has weird issues with php. At one point it was allowing me to use it, then it stopped, then it was working again. Needless to say, I couldn’t rely on it. What I needed was a set of fairly static pages where I could post some resources and tools for my students.

Naturally I wanted the site to look presentable and I hated the idea of copying and pasting the header, footer and the navigation sidebar all over the place. So I opted for some clever client side scripting. I started with something like this:

<!DOCTYPE HTML PUBLIC 
  "-//W3C//DTD HTML 4.01 Transitional//EN"
  "http://www.w3.org/TR/html4/loose.dtd">
 
<html>
   <head>
      <title>Luke's CMPT 109 Page</title>
      <link rel="stylesheet" href="layout.css" type="text/css" media="screen" />
      <link rel="shortcut icon" href="favicon.ico">
      <script type="text/javascript" src="jquery.min.js"></script>
      <script type="text/javascript" src="funcm.js"></script>
   </head>
   <body>
      <div id="header">
         <!-- header stuff -->
      </div>
      <div id="sidebar">
         <h2>NAVIGATION</h2>
         <ol>
            <li><a href="/">Home Page</a></li>
            <li><a href="foo.html" class="aj">Foo</a></li>
            <li><a href="bar.html" class="aj">Bar</a></li>
            <li><a href="baz.html" class="aj">Baz</a></li>
         </ol>
      </div>
      <div id="content">
         <!-- Content goes here -->
      </div>
      <div id="footer">
         <!-- footer stuff -->
      </div>
   </body>
</html>

Note that the above page is completely static, and the links are fully functional. This is intended, because I wanted it to degrade gracefully. If someone visited the site using one of the many text based browsers they would be able to navigate it without any problems. Not that my students would ever use one of these, but I don’t like the idea of depending on Javascript for crucial navigation without providing this sort of fall back.

What I could do next was to add a click event to every links with the class of “aj” and use an asynchronous call to load an external HTML page into the “content” div. Unfortunately, that would mean that all the pages would have the same URL. Any attempt to link to pages foo, bar or baz would fail miserably. Furthermore, the back and forward button functionality would be broken.

Naturally, loading pages into “content” div is what I really wanted in the end, but I also needed a unique URL for each of them and a working back button. That meant I needed to approach the problem a bit differently.

I decided to rewrite all the relevant links at runtime so that they would point back at our index.html page:

$("a.aj").each( function() {
    h = $(this).attr("href");
    $(this).attr("href", "/?p=" + h.substr(0, h.indexOf(".")));
});

I used JQuery because it makes stuff like modifying certain selection of links incredibly easy. If the page loaded and Javascript was enabled the links would get quietly changed to this:

<a href="/?p=foo" class="aj">Foo</a>
<a href="/?p=bar" class="aj">Bar</a>
<a href="/?p=baz" class="aj">Baz</a>

Note that I could have used foo.html in the query string but I didn’t want to. The URL’s were ugly as it was, so I decided to keep them short and as simple as possible. So the .html suffix was dropped for the sake of clarity. Next step was evaluating the query string and actually loading the pages:

 $(document).ready(function() {
   page = getQueryVariable("p");
   if(page)
      $("#content").load(page + ".html");
});

I skipped the link rewriting code in the above for clarity but it should theoretically be somewhere in that anonymous function block. The function getQueryVariable can be defined as follows:

function getQueryVariable(variable) 
{
   vars = window.location.search.substring(1).split("&");
   for (i in vars) 
   {
      pair = vars[i].split("=");
      if (pair[0] == variable) 
         return pair[1];
   }
   return false;
}

It should be self explanatory. Grab the query string, split it on the & character, iterate through the list and return the value of matching attribute, or false if none is found.

With that framework in place, I created foo.html, bar.html and baz.html files as plain HTML documents without a defined stylesheet. Loading it into the “content” div in index.html would force the styles defined on that page to be used on the imported content as well. Visiting the pages directly might be a bit jarring because they would be very plain but it shouldn’t be a huge issue.

Anyone visiting the page with Javascript enabled browser would see the “fixed” links that would cause the page to reload and import the desired content from the external file. Browsing without Javascript would yield links leading directly to the pages.

The only time the site wouldn’t work properly was if someone followed a link or a bookmark which in the /?p= format but with Javascript disabled. They would end up on the homepage without any indication of what happened. That sort of behavior could be a bit annoying but I’m not sure how to fix it at this point.

Other than that, the few lines of Javascript should save you tons of copy-pasting, and shave many hours from future maintenance. There is of course possibility that this method could be exploited and. I tested few obvious things and I couldn’t get it to load any remote web pages in any way. It doesn’t mean it is not possible so be aware that someone could potentially cause your page load external content with a GET request formated just the right way. It’s nowhere near as bad as that silly ny.com page.

Javascript will be the Next Big Language

Wednesday, April 23rd, 2008

I’m on JavaScript kick lately. Or rather, I have been rediscovering it ever since I read the series of Steve Yegge’s blog posts on JS and Rhino and his predictions for the next big language. I really think he is right - JS will be the next big thing that will trump Ruby from it’s pedestal or at least become its viable competitor as the next big dynamic scripting behemoth. Why? I think a better question is: why not? It almost seems like this language is destined for greatness.

For one, JavaScript or rather ECMAScript is really a kick-ass language if you look at it objectively. When I say JavaScript most people automatically think about the client-side, browser dependent, inconsistent scripting language which only works half of the time. But this is not really the fault of the language but inconsistent implementation of the DOM model across different browsers.

Internally the language is really consistent, flexible, readable and fun to use. Not only does it have most of the cool features that are all the rage now (ducktyping, closures, variadic functions, prototypes, metaprogramming end etc..) but reads a lot like C. The syntax is full of the familiar and lovely brackets and semicolons that we all know and love (or hate) and all the control sequences and language constructs follow the familiar C patterns. Coding in JavaScript is really a lot like coding in Java only 5 times less verbose which is a good thing.

And when it comes to shuffling around HTML or XML data there is no other language that is both so good at it, and so well documented. We have been using it for that purpose decades now and nothing else compares. No other language can be used int the online so effectively and seamlessly.

Also, Javascrip has something that neither Python nor Ruby possess - a real spec. So it is really a good language - a Language with capital L. It is just burdened with a bad stigma of being a browser specific toy language.

This stigma is slowly dissipating as the Web 2.0 craze is raging on. I don’t care who you are right now - if you are doing any web development right now, you have to deal with Javascript whether you want it or not. You can avoid it, you can claim you are server side guy but if you want to be competitive right now your web app needs to use AJAX and if it is, then Javascript is becoming a big internal part of your code base. You can hide behind a framework, and have it generate AJAX code for you the way RoR does, but sooner or later you will have to do something complex and will end up hacking on js files. Whether you love it or hate it - you will be exposed to it at some point.

So your code is now roughly half Javascript and Half something else which is a bit messy, but that’s Web 2.0 for you. Does it have to be that way though? Of course not. You don’t need a dedicated client side language ad another dedicated server side language. You could really do all your scripting on both sides with Javascript. Yes, Server Side Javascript is not a joke or some pipe dream - it is reality. Believe it or not, but there is a lot of development going on in this area - there are tons of projects out there which use JS on the server side.

These projects range from very simple to very complex full featured solutions. For example, mod_js is an Apache module loosely based on Perl’s CGI.pm which implements ECMAScript on the server side. It is astonishingly simple, and compact but also very immature project.

If you want something more robust and mature there is Jaxer - a self contained Java based server which supports server side scripting in Javascript. The whole idea behind this environment is unifying your code base. With Jaxer you can use the very same language to query the database, dynamically rearrange the HTML output, and make asynchronous calls back to the server. Added bonus is that it is bundled with the very popular Aptana IDE (aka. the Eclipse for web designers) which means it is already near ubiquitous.

If you are allergic to Eclipse and it’s forks and you like NetBeans then Phobos is probably what you will want to sink your teeth into. It uses Glassfish server and uses Javascript as it’s default server side language. Same concept, different approach. The project seems to be mature, well supported and have a big community.

Want more? Theres Helma which is a Rails like framework which leverages server side Javascript and Rhino. The whole thing runs in the JVM and uses Jetty as the default, self contained web server - but you can also put it behind Apache or IIS if you want. How come you can go wrong with a combination like that? You get a MVC framework with a self contained server and set of useful tools and utilities that only requires you to have a basic JVM installed. You get to script it with the dynamic and flexible language that requires no compilation, and no SDK. You get the entirety of the Java API at your disposal courtesy of Rhino. Not only that, but you can simply drop in your custom precompiled Java libraries and classes and seamlessly integrate them into your project.

But there is more - recently I spotted another interesting project called Junction. Like Helma it is a Rails like MVC framework that uses Rhino but in addition, it also has a built in support for Google Gears. This means that apps built on the Junction framework get to benefit from the offline persistence features offered by the Google technology.

There is all this development going on out there. It’s not very visible yet - most of it is somewhat behind the scenes. But it’s like that distant rumbling before the storm. You know something big is coming. Just look around.

You want to develop rich client interfaces? There’s XUL and Adobe Air for you - both using Javascript at their core.

You want dynamic web UI framework? There is JQuery, Prototype, Dojo, Google Web Toolkit and YUI just to name few.

Want to use Java API? Use Rhino. Want to tap into the richness of Microsoft CLR and interact with the rest of .NET ecosystem? Theres JScript.NET. You want to do some native scripting on MacOS? There is Javascript OSA.

You want to add oflline persistence to your web applications? You need Google Gears which is also using Javascript.

The language is everywhere. Everything that is new, that is hot and that relates to the web is at least touching or benefiting from it. Every developer will see it, and work with or alongside it sooner or later. It’s ubiquitous.

The pieces are slowly falling in place and setting up the stage for the upcoming explosion. It’s no longer question of whether we will reach that critical mass, but when will it happen. We have the tools, we have the technology, we have the hook and the need (unifying the client and server side under one language) - now we just need to wait for the hype. And for that, we need branding. Steve Yegge talked about this during his Ted talk - we need to re-brand the language to make it more sexy. Everyone thingks that Javascript is a toy language, and ECMA sounds like a some sort of acne prescription so we need a new, cool name. We also have a good reason for re branding - the upcoming release of Javascrip2 standard which brings about many new features to the language such as classes, interfaces, namespaces, packages, destructuring assignments, structs, type declarations and more.

It is a bucket load of new features so why not start fresh, with a new sexy name and identity. I mean look at AJAX - the acronym really means “using the asynchronous calls in Javascript” but if you say it like that, people immediately fall asleep and run away. But AJAX is cool and sexy. Javascript can be to - and I predict it will be, sooner or later.

3 Value Checkbox with JQuery

Monday, March 24th, 2008

Few days ago I did that whole 3-value checkbox thing basing it on some script I found online. I went back and I re-implemented it using some JQuery magic. I’m not going to reiterate the whole setup here. I recommend that you check the linked post for details. You can find the JQuery-fied code below:

$(document).ready(function() 
{
   checked = '/path/to/checked.jpg';
   unchecked = '/path/to/unchecked.jpg';
   na = '/path/to/na.jpg';
   i = 0;
 
   // replace the checkboxes with images    
   $("form.funky_form > fieldset.funky_set :checkbox.funky_box").hide().each(function() {
 
      img = document.createElement('img');
      img.className = "funky_image";
 
      switch($(this).val())
      {
         case "0":
            img.src = unchecked;
            $(this).attr("checked", "false");
            break;
         case "1":
            img.src = checked;
            $(this).attr("checked", "true");
            break;
         case "2":
            img.src = na;
            $(this).attr("checked", "true");
      }
 
      // these will let us identify which image was clicked
      // and which checkbox does it belong to
      $(this).attr("id", "input" + i + "image" + i);
      $(img).attr("id", "" + i + "image" + i);
 
      i++;
 
      $(this).before(img);
   });
 
   // add onClick functionality to the new images
   $(".funky_image").click(function() {
 
      // select the checkbox corresponding to the clicked img
      t = $("#input" + $(this).attr("id"));
 
      switch(t.val())
      {
         case "0":
            $(this).attr("src", na);
            t.val(2).attr("checked", "true");
            break;
         case "1":
            $(this).attr("src", unchecked);
            t.val(0).removeAttr("checked");
            break;
         case "2":
            $(this).attr("src", checked);
            t.val(1).removeAttr("chekced");
      }             
   });
});

The major difference from the other version is that I’m much more discerning in which checkboxes get converted. The code will select only a box that is of the class funky_box and is inside a fieldset with a class of funky_set and inside a form with a class of funky_form. I’m mostly doing that to show power of JQuery - this is all specified in that very first select statement. I was trying to do something similar in the old code, but I was getting hung up on the silly DOM gotchas. JQuery makes this easy.

Also note the chaining functions. The first line after I declere i both hides all the selected check-boxes and begins the each block. Similarly, check out the second switch statement. In several places I set the value of t and change the checked attribute on the same time. It’s very expressive, and lends itself toward very compact and concise code.

Here is the HTML for the form to go with the code above (note the inclusion of the fieldset tag):

<form name="funky_form" method="POST">
      <fieldset class='funky_set'>
         <label for="c1">
            <input type="checkbox" name="c1" value="1" class="funky_box" checked>
            Some Important Task
         </label><br>
 
         <label for="c2">
            <input type="checkbox" name="c2" value="1" class="funky_box" checked>
            Some Important Task #2
         </label>
      </fieldset>
 
      <label for="c3">
         <input type="checkbox" name="c3" value="1" class="funky_box" checked>
         This is a checkbox with the funky_box class outside the funky_set
      </label><br><br>
 
   <input type="submit" value="Submit">
</form>

How readable is this version? To me it is actually better because it’s smaller, and more compact. To someone who never worked with JQuery it might be a bit confusing at first but I think you get used to the weirdness pretty quickly. I find the selection statements much more elegant than nested loops for example, even if they might The more code I can see on my screen the better. I’m not golfing though - all the methods and most variables have meaningful names (well, except stuff like t and i but you know how it goes).

Which version do you like better?

JQuery Quirks

Friday, March 21st, 2008

Here are two interesting quirks in the way JQuery works. Let’s say you want to check all the check-boxes on the page - how do you do it? It’s trivial:

$(":checkbox").attr("checked", "true");

Now quickly, how do you un-check all the check boxes on the page? If you said:

$(":checkbox").attr("checked", "false");

You are wrong. Despite the fact that if you use a more standard notation and say for example:

document.myform.mycheckbox.checked = false;

it will give you the desired result. The JQuery call however does not work. In fact, it does the exact opposite - it will set all the check-boxes on the page to their checked state. Apparently for the few funky attributes like “checked” and “selected” the second argument of the attr() method call can be any non-empty string. It makes sense because you actually don’t have to give these attributes an explicit value in your HTML code for them to work. So how do you un-check a box in JQuery? There are two ways. First one, and the more sure-fire one is to remove the checked attribute altogether:

$(":checkbox").removeAttr("checked");

Second one which has worked for me for some reason was to set the attribute to the empty string:

$(":checkbox").attr("checked", "");

Same goes for select attributes in combo boxes and list boxes. You need to remove them or set them to an empty string, or they won’t go away.

Quirk number two: axjax weirdness. Look at the code below:

$("a").hover(function() {// do something});
$("#sometrigger").click(function() { 
   $("#container").load("/some/page.html #links"); });

What am I doing here? I’m adding some hover functionality to all the links on the page. Then I add an on-click even to #sometrigger element. When it is clicked I want to load the contents of #links from /some/page.html into #container asynchronously. Where is the quirk? The hover functionality will not apply to the dynamically loaded links. It’s weird, but that’s just how it works. So if you want this functionality on all your links you will need to reapply them:

$("a").hover(function() {// do something});
$("#sometrigger").click(function() { 
   $("#container").load("/some/page.html #links", 
      $("#container > a").hover(function() {// do something});
         });
   );

It’s a little bit silly, but it kinda makes sense. You may not always want to apply the same events and formating to newly loaded html. But if you don’t expect it, it may throw you off. One you know about it however you learn to compensate for it. I’m being told that folks coming from the Prototype community are hitting this little quirk like a brick wall because their framework behaves in the opposite way (ie. the effects and behaviors are applied to the ajax loaded html).