Monday, February 28, 2011

The Zen of jQuery

A few months ago I decided to research jQuery. I had heard about it from time to time, and had often seen it as a job qualification, but didn't really know what it was. I am still somewhat new to it, but I can honestly say that it has done more for me as a web developer over the past few months than several years of writing JavaScript by hand.

jQuery is a JavaScript library that has predefined methods for document traversal, event handling, animating, and ajax handling. Code that would otherwise have taken hours to write, can now be done in a few minutes. In this post I want to give a brief introduction to jQuery and some of it's features. This is not meant to be comprehensive, nor in depth. It's intended to be just enough to jump in and get started.

Although it is good to be able to write the code by hand and to have an understanding of what is going on under the hood, in the end we want to write better applications faster and with more ease, and that is just what jQuery promises: "Write less, do more."

Getting Started

The first thing to do is include the library in the page, it can be anywhere in your html document, as long is it's before you use jQuery. It is just one big javascript file. You can download it from jquery.com, or use the one hosted by google:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>


Selectors

The beginning of almost all jQuery is selectors. jQuery uses a shortcut called $ to make the code more concise. Selectors return an object or an array of DOM elements based on the string or object passed in. There are two main types of selectors, DOM elements and css. Using these we can attach events, animate, remove, or do any number of things with elements of the page.


Here is an example of a few selectors. There is one to select all div tags, one to select all with the class 'bar', another to select the div with id 'foo', and selectors for even, odd, first and last elements. Obviously there is more code at work here, this is just to show you how they work.







<div>content 0</div>
<div>content 1</div>
<div id="foo">content 2</div>
<div class="bar">content 3</div>
<div>content 4</div>
<div class="bar">content 5</div>
<div class="bar">content 6</div>
<div class="bar">content 7</div>
<div>content 8</div>

With the exception of the id and class selectors, those shown on the buttons won't work as they are. The odd selector, for example, would select every odd element in the entire document, starting with the body.  You would want to wrap the items you are wanting to select in a div with an id, and use the knowledge of css you already have: $("#id-of-div div:odd")



Events

Once we have used a jQuery selector to get one or more items we have to do something with it. We can perform an action on it right away, or we can bind events to the selected elements, such as click or hover. In the example above I just showed the selector, but now lets attach an event to it. Let's say we have a list of items that we want to delete as they are clicked on. This turns out to be a trivial task. Let's take the following html code:


      <ol id="odds">
         <li>Mountain Dew</li>
         <li>Dr. Pepper</li>
         <li>Root Beer</li>
         <li>Sprite</li>
         <li>Sunkist</li>
         <li>Pepsi</li>
         <li>Coke</li>
      </ol>
 And now we want to delete each item as it is clicked on. All we need to do is add this javascript:

$("#odds li").click(function() {
   $(this).remove();
});

So let's go over this little script. The $("#odds li") selects all li elements within the element with id "odds".
The .click() function attaches an event to all elements retrieved that is fired whenever they are clicked on. It will attach a separate event for each distinct element. Remember that if this is called multiple times it will attach multiple events instead of replacing any previous events.
An anonymous function is passed into click(), this is the callback that the event fires. You can also pass in a function name.
Inside of the function is $(this) which refers to the object that triggered the event. We simply call the .remove() method and the element is deleted from the DOM.
Three lines of code and we are done.


Here it is in action:
  1. Mountain Dew
  2. Dr. Pepper
  3. Root Beer
  4. Sprite
  5. Sunkist
  6. Pepsi
  7. Coke

Now let's use some of the selectors we learned earlier, and make it a bit more fun. We can color the even rows one color, and the odd rows another. The problem that arises is that if we delete a row, then the even odd color scheme is broken, so we need to fix it after every delete. Let's update our script to look like this:


$(document).ready({
   function colorize() {
      $("#odds li:even").css({backgroundColor:"#bbf"});
      $("#odds li:odd").css({backgroundColor:"#fbb"});
   }


   colorize();
   $("#odds li").click(function() {
      $(this).remove();
      colorize();
   });
});


Remember that jQuery is javascript, so we can use any javascript we want with it. Notice that I wrapped everything in the (document).ready function, this prevents anything from being executed until the page is loaded, if we didn't do this then the script would fail if called prior to where the html was placed. If we run this code we get the following effect:
  1. Mountain Dew
  2. Dr. Pepper
  3. Root Beer
  4. Sprite
  5. Sunkist
  6. Pepsi
  7. Coke


There are a number of other predefined events, such as hover, double click, change, focus, keyup, keydown, and dozens more. You can also define your own. They are all bound in the same way as you have just seen the click event bound with jQuery.

Effects

One of the best parts of jQuery is the effects that are built in. Here is an example of one of my favorites, the fade effect:

Click Me!


All that is needed to accomplish this is the following line of code:

$("#fade").click(function() { $(this).fadeOut() });

Another one of my favorite effects is the slide. To demonstrate this effect I created an expandable/collapsible tree structure. To build the tree, which represents a small file system, I used nested unordered lists. I set an event to toggle the children of an element when it is clicked on. Check it out:

  • /
    • /home
      • /root
      • /adam
      • /john
    • /etc
      • /init.d
        • apache
        • mail
        • mysql
        • postgresql
      • /apache
        • httpd.conf
      • /php5
        • php.ini
    • /var
      • /www
      • /log
      • /spool


It is noteworthy that I was able to accomplish that effect with only 4 lines of code. Seriously, it was exactly 4 lines. You can barely write a hello world program with 4 lines in most languages. I admit that I had a bug to work out, but jQuery's documentation is so complete that it took only a few minutes of research to get it working properly. I suspect that doing this with regular javascript would have taken a few hours to get the same effect, and a few more hours to get it working properly in internet explorer.

Ajax


One of the best parts of jQuery is the cross-browser compliant, and very easy to use ajax library.

Because of security restrictions I can't demonstrate ajax within this blog post, but there isn't much visually to show, so I feel an explanation and some example code will be sufficient.
jQuery makes ajax trivially easy to do. Let's say I wanted to load the contents of a file hello.html into a div with the id load. It only takes one line of code to do this:

$("#load").load("/hello.html");

And that's it.


In spite of the convenience and simplicity of this method we usual want to do a bit more than this. There are several predefined ajax methods, but I usually just use the $.ajax() method. All of the other methods are built from this and it is very powerful and customizable. Let's start with a simple example, if we recreate the above example manually, it would looke something like this:


$.ajax({url:"/hello.html",
        type:"GET",
        dataType:"text/html",
        success:function(data) {
           $("#load").html(data);
        },
        error:function(xhr, status) {
           $("#load").html("Error: " + status);
        }
});

Generally for ajax interactions, as we do here, we call the ajax function and pass in a JSON object of the properties of the request. The above function call is a typical vanilla ajax request, but let's take a slightly more complex example. A while ago I wrote a function to retrieve a news feed for a webpage. It retrieves a JSON object and iterates through each item, adding them to the news feed.


function getNews(isFirst) {
   // retrive the news
   $.ajax({url:"/apps/news/news.php",
           data:{"update" : (isFirst ? "0" : "1")},
           dataType: "json",
           success:function(data) {
                      news = data.news;
                      for (var i = 0; i < news.length; ++i) {
                         addNews("<b>" + news[i].user + "</b><br />" +
news[i].news, isFirst);
                      }
                     $(".news-item:last").addClass("news-last");
                   },
           error:function(xmr, type, e) {
              addNews("ERROR: Could not retrive news: " + e, false);
           }
    });
}

It retrives the following json:

{
    "news" : [
        {
            "news": "testing eaccelerator",
            "user": "adamb",
            "news_time": "2011-02-14 00:57:06.846938" 
        } ,
        {
            "news": "apache up to almost 2000 rps!",
            "user": "adamb",
            "news_time": "2011-01-19 15:17:11.903671" 
        }
    ]
}

In this example we used the data parameter to pass parameters in the url. We also specify that we are going to receive a JSON object. Usually this is difficult because we have to parse the JSON ourselves, which will require a lot of code and can present security hazards. jQuery does all of this for us, and parses the object for us. jQuery will also handle xml, jsonp, html, javascript, and text.

Go and Code

I hope that this brief introduction has been helpful. My intent was to give you just enough to jump right in and write some code. You will probably want to spend some time on jquery.com, and read a few manuals.  Another exceptional tool that is built on jquery, is jquery UI, found at jqueryui.com. It has predefined methods for windows, date pickers, accordians, auto-completes, visual effects, and more.

Go now, and write some code. Become a jquery ninja, write less, do more.

2 comments:

  1. still over my head, I'll let you do any programing I need! With that said, very nice write up. love ya, mom

    ReplyDelete
  2. Wow, thx for this code.
    I will use it in my dissertation work, if y don't mind.

    Best regards
    Toby, data room m&a

    ReplyDelete