Wednesday, December 24, 2008

Debugging Javascript

Debugging is a very important aspect of programming, and odds are you will spend much more time debugging your code than you will writing your code. It is important than, to have tools and procedures to make that process go as fast as possible.

Here is a working demo, and we will show how to resolve particular issues with it.

Syntax Issues

Whenever you are learning a new language, you have to deal with not knowing the particulars of the syntax. This is where a good IDE is useful. Unfortunately, there don't seem to be any great options for JavaScript IDEs. Eclipse is an option, but that takes a good amount of configuring. Previously we mentioned Notepad++, which has good syntax coloring but will not tell you outright if something is wrong. If you open the javascript in firefox, and the syntax is wrong, firefox will tell you (It is in the error log -- Tools->Error Log) so as long as it has to run the code -- ie, the function that the incorrect code in is called.

So syntax support is not the best. It certainly isn't as good as .Net for C# or Eclipse for Java; which will underline every syntax error for you and tell you why it is wrong. However, syntax errors will occur less and less as you learn the language.

Look at this example of a syntax error in a program. For this you'll need to have firebug installed in firefox, and open up this page.

First, you should notice that the page doesn't do what it is supposed to. We will see what it is supposed to do in a second. If you look at the firebug (open up firebug by Tools->Firebug->Open Firebug) console, you'll notice that it says this:


missing ; before statement
[Break on this error] This is not a syntaxically correct javascript statement\n


If you click on the 'This is not a syntaxically correct javascript statement' it will bring you to the firebug script viewer, highlighting the offending line. And of course, this is not a syntaxically correct line. So we take it out like we did here, and try again.

Now this time, you'll observe nothing appears in the console until you mouse over the image. This is because the syntax error is in the mouse over function, so it doesn't know it has an error until it is called. The error is this:

thisdoesnotbelonghere is not defined
[Break on this error] thisdoesnotbelonghere


And of course, the error is simply that meaningless block of text.

Runtime Exceptions

Runtime exceptions happen when you are running a program, and you do something that the processor can't do. For instance, dividing by zero will usually cause one. Or accessing an attribute on a object that is null. These are usually pretty easy to see happen because the code will just stop and firebug will show the exception in its log.

Lets look at an example of such an exception.

If you run this page, you'll notice right off the bat, only the X direction expands correctly. Which is curious. If you look at the log you'll see:

document.getElementById("imagepanel") is null
[Break on this error] document.getElementById("imagepanel").height = y;


Which is very similiar to the line above it, except we have a typo: imagepanel needs a capital P.

Normal Bugs

And of course, not every error in our code will be seen as that by the javascript compiler. Sometimes, it will manifest as a program bug where the behavior isn't doing what we want. With some bugs, we can diagnose them by examining the code, and then comparing what we think it should do to what it does do. These bugs are usually not very severe and are often things like typos.

Some bugs though require the use of an integrated debugger where we can pause execution, and step through the code while looking at the values of different expressions. Firebug allows for this, as we will see. Check out this code.

The symptom is apparent, the X direction doesn't change, but the Y does. Lets pause the program when it gets to that function, and step through. To do this, go to the firebug pane, and look at the Script tab. It should show the first part of the HTML code. Put a break on line 6, the start of the mouse move event function. To do this, click the line number. A red dot should appear. Now, set it off by moving the mouse over the page area. If all is well, a yellow arrow should appear over the red dot. This signifies that the next line to execute is the one the arrow is pointing at.

Look at the four buttons in the top right of the firebug pane. One "continue"s the program (blue play button, hotkey is f8), one "steps into" the next function (the first one to the left of the play button, hotkey is f11), one "Steps Over" the next function (f10), and the last "Steps Out".

The continue button just resumes execution from where the yellow arrow is. The idea of taking one 'step' in code means allowing one command to execute and pausing again. If we do step into, and the next step is a user defined function, the code will step into that function and pause there. If we choose to step over, the function will execute and pause on the next line. This can save alot of time if you know some the function about to execute is correct, but don't want to resume. Stepping out will run until the current function returns, and then pause. It is by far the least used of the functions. Lets use these functions now.

Step once so that the

var X = evt.clientX;


will execute. Now hover over the X; it should display the current value of that variable. It probably isn't ten (it should be the current x local of the mouse pointer when that break was hit), which is what the width of the image seems to be. Put a break point at line 9 and resume, it should stop instantly. Highlight the part of code that says:

document.getElementById("imagePanel").width


Right click and go to 'add watch'. This should make it appear in the panel to the right, which displays the value along with the expression. The value should read as '10', which is what it looks like it is being set to. A closer examination of line 8 will show that it is using the value of the lower case 'x', which if we hover over, is in fact '10'. We are setting the upper case 'X' on line six, and since javascript is case sensitive, we get a very hard to spot error.

Note that the reason the lower case x is ten is because we set them as global variables. We also set a global variable for y, but the function will use it's own value of 'y' before using the global ones.

Knowing how to use these tools is very useful. Odds are you will spend 20% of your time writing new code, and 80% of it debugging code you've already written. You naturally want to do this as efficiently as possible.

Stacks and Consoles
We will go over two other tools, but not with any real examples.

The same pane that has the 'watch expressions' should have a tab next to watches called 'stack'. This shows your current function stack, and is useful in some instances. Your function stack is kind of like a map of the paths your current code has taken to get to where its gone; at the top of the stack is the function you are paused in. Below that is the function that called the function you are in, and it goes on like that. It is useful to see why your program is getting to a particular place.

If you look at the console pane, there is a little command line at the bottom. From there you can execute single javascript statements. With the current example loaded, go ahead and type in 'document.getElementById("imagePanel").width = 500' and hit enter. The picture should resize itself. If you hit the up arrow, it will go into the command history, so it will put 'document.getElementById("imagePanel").width = 500' back on that line. Add a zero to see the image get much bigger.

Go ahead and play with all the little tools firebug has. You should grow familiar with them. Have fun with it!

Sunday, December 21, 2008

jQuery

There are alot of things that javascript does not do out of the box that other scripting languages (say, Flash's actionscript) do.

However, not so out of the box, there are alot of free libraries available to help. The one we will look at now is jQuery, which you can download here and there are tutorials for here. Of keen interest is the user interface module of jQuery. View some live demos here.

Saturday, December 20, 2008

Objects in JavaScript

Objects

We have already gone through values in JavaScript. What we only touched on though is that values in javascript can be of different types.

We have already seen number, string and array types. These are called primitive types and they are built-in to the language.

There are alot of other types, we will call them defined types. Defined objects are containers of sorts for other values. For instance, lets define a 'person' object. A person, in our example has a name, an age and a gender:

var newPerson = new Object();
newPerson.Name = "Jason";
newPerson.Age = "21";
newPerson.Gender = "M";


And now we can later modify or view the attributes (sometimes called slots) on that new person object.

There are many different object libraries available for use, but the most useful one for javascript is the Document Object Model; which we go over now.

The DOM

The Document Object Model(DOM) is the way in which we can manipulate the html page the user sees through javascript.

The primary way to access the HTML document is via the 'document' variable that is made available as a global variable for your javascript. Furthermore, we can access indvidual elements inside the document so long as they have an ID by 'document.getElementById'; we have already seen this be used.

This is where knowledge of HTML is useful. If you know the attributes that are valid for an object in html, this will often times translate easily to attributes we can call from javascript. For instance, in the sample photo gallery, we set the 'src' attribute on an image element, and this was reflected in the picture that was shown. Another example is when we called 'document.write(...)' in an early tutorial.

Simple Javascript Photogallery

Here is an example of a very simple photo gallery.

View the source and lets look at it peice by peice:
function getImagePanel(){
          return document.getElementById("imagePanel");
}
This function is a shorthand to get the image element. The next tutorial will be on what exactly the 'document.getElementById' does and why it works, but for now it is simple enough to say that when you call 'document.getElementById("some-id")', it will give you an object from the html document. In particular, look down to this bit of html:
<img id="imagePanel" src=""/>


So basically we have set up an image box for us to put our images into. Then we gave it the ID of "imagePanel" so that we can modify it in our javascript.

Moving on, we have a few global variables:
var currentImage = 0;
var imageList = [ "http://upload.wikimedia.org/wikipedia/commons/thumb/f/f3/Youngkitten.JPG/800px-Youngkitten.JPG",
"http://upload.wikimedia.org/wikipedia/commons/thumb/9/9b/Domestic_cat_cropped.jpg/755px-Domestic_cat_cropped.jpg",
"http://upload.wikimedia.org/wikipedia/commons/thumb/3/37/2_russian_street_cats-crop.jpg/800px-2_russian_street_cats-crop\
.jpg"
];


Global variables can be referenced in any function in the entire document. Here, 'currentImage' is the index of the current image. The 'imageList' is an array of strings, in this case, image URL's of the pictures we want to display.

There are a number of important data structures that we will cover. The most basic and perhaps most useful is the array. An array can be thought of as a list of items that can't be added or removed from. In this example, the list holds file urls.

We can refer, for instance, to the first image location as 'imageList[0]' (These things are 0 based -- the first element is at zero, the second at 1, etc). If we combine this with the global 'currentImage', we can always get the current image location by 'imageList[currentImage]'. For instance, we have a function that will update the displayed image to the one specified by 'currentImage':

function setCurrentImage(){
     getImagePanel().src = imageList[currentImage];
}

Now whenever we change the currentImage variable, we can simply call 'setCurrentImage()' and the correct image will display. Notice that we are getting the image element, and setting the 'src' attribute to whichever image url we want. We do this in the functions we use to go forward and backward in the image list, which just happens to be this:

function rightClick(){
     currentImage++;
     if(currentImage > imageList.length - 1)
          currentImage = 0;
     setCurrentImage();
}

function leftClick(){
     currentImage--;
     if(currentImage < 0)
          currentImage =      imageList.length - 1;
      setCurrentImage();
}

You can observe the logic given to looping the 'currentImage' variable whenever it reaches a value above or below valid values. Ideally, the value should be equal or larger than 0, and less to or equal to the length of the array. Then we call that 'setCurrentImage()' to refresh the image panel.

Now we have to attach the links we provided for forward and back to the functions 'leftClick' and 'rightClick'. The way we do this is by setting events on the buttons we provide. Those buttons actually are html links:

<a id="anchor" href="#anchor" onclick="leftClick();"> <-- </a>
<a href="#anchor" onclick="rightClick();"> --> </a>


HTML provides alot of these kind of 'hooks'; where we can have fire off a javascript function when something like a click happens.

Right after that, we put another bit of script in. It doesn't appear in a function, so it executes as soon as it loads. This will make set the image to be correct on loading:

<img id="imagePanel" src=""/>
<script> setCurrentImage(); </script>


Thats it for the photo gallery. Leave a comment if anything is still a mystery about the code. Next time we will discuss the document object model, and how we can use that to do cool things.

Wednesday, December 17, 2008

The Basics

Values, Variables and Functions

Values are things like literal values. In the Hello World example, the "Hello World" string was an example of a value. The number '2' is another example of a value. Really, by Value, all we mean is Data.

Variables are things that store or hold data. We can say in javascript something like:
var foo = "bar";
So later on, you could say something like this:
alert(foo);
and the program would display "bar" in a text box.

Functions exist to allow you to abstract out parts of a program. They have 'parameters', which are variables that you can assign when you call the function, and often they have a return value which gives you some information about what the function did.

For instance, lets say we made this function:

 function getWebAddress(directory, filename) {
return "http://www.example.net/" + directory + "/" + filename ;
}
which returns a string value whenever we call it with a directory and filename like so:

var directory = "pictures";
var filename ="catPicture1.jpg";
var otherFileName = "otherCatPicture1.jpg";
var webAddress = getWebAddress(directory, filename);
var otherWebAddress = getWebAddress(directory, otherFileName);
And then the values at webAddress would be "http://www.example.net/pictures/catPicture1.jpg".

Functions are really useful in simplifying your code. If you can abstract some functionality out, then you can put it all in one spot, so when you find bugs or add features it all happens in one spot.

Flow Control

It is not enough to be able to call functions and store the results in variables. Sometimes we need to do different things for different values. Other times, we might want to do something multiple times.

For the first thing, we have the if statement. So we can say something like
var javascriptIsCool = true;
if(javascriptIsCool){
alert("Cool!");
} else {
alert("Lame!");
}
And the page will show "Cool!". If you change the '= true;' to '= false;', then it will show lame.

So if the part inside of the if statement evaluates to true (which 'javascriptIsCool' does, since we defined it as true), then it executes the first block (a block of code is generally considered to be the code between the brackets). If that statement isn't true, then it will execute the second block. Play around with that part of the code in firefox to get some familiarity with if statements, they are extremely useful.

Now on to loops. Let's start with the while loop.

The while loop looks and acts alot like the if statement, except, the block of code in the while loop will repeat while the statement in the while loop evaluates to true. So this code:
var number = 0;
while(number < 5){
number = number + 1; document.write(number + "...");
}
Will display a '0...1...2...3...4...' on a webpage. (We won't go into the document object model -- the 'document.write' part -- in detail now, but it is important later. Suffice to say that when you 'document.write("Example text.")', it will write that example text to the html page.)

A for loop does the exact same thing, but it is more concise when you are counting to a certain number like the last example. Here is code that does the same thing:
for(var number = 0;number < 5;number = number + 1){
document.write(number + "...");
}
Next time we will look at some real code, that interactively displays three images.

Setting up a Javascript Environment

What is Javascript?

Javascript is a scripting language related to ActionScript. It is mostly used on websites.

We are going to predominately use javascript in these posts because it is very easy to play around with. You can write your code inside of an html document, and test it on your own computer before uploading it to a webserver. It also has some very nifty features for a programming language that makes it forgiving for people who have never written code before.

Your first program

So lets get started! Open up any text editor program. On a windows computer for instance, go to Start->Run and type in 'wordpad', then hit enter. It should open the default text editor for windows. Now copy paste this into the editor:

<html>
<SCRIPT>
alert("Hello World!");
</SCRIPT>
</html>
This page should be viewable in any webbrowser. Simply save this file somewhere, such as 'test.html' and then open the file. Usually you can do this by just double clicking the file, or you can navigate to it directly from within the webbrowser.

When the page opens, it should display 'Hello World' in a little text box. Play around with it. Anything inside the script tags is javascript, and anything outside is normal html.

Tools

Before we go on too much further, there are some more tools that would be useful to have.

Important to any programming excercise is a good debugger. Javascript has one here. Firebug will let you step through javascript as it executes, as well as telling you when there are problems in your code. It is an add-on for firefox, but once the code works in firefox, with any luck, it will work in other browsers.

Another useful tool is a wordpad that provides syntax highlighting. Notepad++ can do this for javascript. If you are more comfortable with a normal notepad program though, there is no harm in just using that.