JavaScript Libraries – jQuery (CCW Part 4)

To start off with, I wanted to title this ‘animations’, but JavaScript libraries such as jQuery can do so much more than just animation. I also did not want to get into teaching Flash.

Why not Flash?

Flash has been a big debate in the web community since its inception. Why? Because Flash is a self contained program running within a browser’s window. This sometimes causes browser crashes when something goes wrong and the browser has no way to compensate. More modern browsers have introduced isolated tabs to deal with this so that when Flash crashes, only the tab is affected.

Another strike against Flash, but which is not the product’s fault, is lack of support on Apple products. Mr. Jobs does not like Flash and therefore does not have support for it on his mobile OS. Thus, your iPad, iPhone, iPod, etc… does not show any Flash media.

So, what is Flash used for then? Flash is mainly used for streaming video, however there are people who use it to build dynamic websites. The film industry is a big user of Flash websites where they can create rich animated content. However, most websites don’t need this because people want quick information, not loading animation, when they visit a site.

So what do you use?

JavaScript.

JavaScript, once the evil monster with a thousand difficult tentacles of coding, has now been compacted into libraries which make code quicker and easier to use. Two script libraries stand out above the others: MooTools and jQuery, with jQuery being the #1 in popularity.

Since jQuery is so popular, and thus has a lot of uses, that is what I’ll be focusing on in this lesson.

Basic jQuery

I’m not going to get too into it since it can go on forever, but I will tell you about the areas and what they do by using a handy dandy image rotator example. What the given example does is that it takes a thumbnail’s link and information and transfers it to a different key set of areas when selected- thereby changing the main image and its description.

A few notes: Properly nesting and closing code is VERY important in jQuery. A misplaced ‘;’ will cause your entire code to fail.  For longer scripts finding a mistake is very hard, so be sure to keep notes (by commenting next to the code) on what you have changed.

Commenting in jQuery is easily accomplished. A comment looks like this:

//This is a comment in jQuery

Most code will be well documented with the above style of comments, but it is helpful to keep your own comments around to know what you’ve worked on.

Let’s dissect some code

It’s been my experience that when dealing with more complex codes jumping in and dissecting what the code is and what it does helps immensely with the learning process. Therefore, I’m going to throw a block of code down and then explain every single little piece of it and why it’s there and what it does.

$(document).ready(function() {	

	$(".main_image_wordbox").show(); 
	$(".main_image_info").animate({ opacity: 0.85 }, 1 ); 

	$(".navi_1 ul li").click(function(){ 
		
		var imgAlt = $(this).find('img').attr("alt"); 
		var imgTitle = $(this).find('a').attr("href"); 
		var imgDesc = $(this).find('.image_info').html(); 	
				
		if ($(this).is(".active")) {  
			return false; 
		} else {
			
			$(".main_image_1 .main_image_info").animate({ opacity: 0 }, 350 , function() {
				$(".main_image_1 .main_image_info").html(imgDesc).animate({ opacity: 0.85 }, 350 );
				$(".main_image_1 img").attr({ src: imgTitle , alt: imgAlt});
			});
		}
		return false;
	});
});

First off:            $(document).ready(function() {     });

This says that when the document (page) is ready (fully loaded), perform the function (actions) within the {}.  This, or a reasonable variant of it, will be on every jQuery script either in the actual plugin or within the page script.

Next, we specify some elements and what we’re going to do with them.

$(".main_image_wordbox").show();

$(".main_image_info").animate({ opacity: 0.85 }, 1 );

The $ specifies a new element in jQuery. The main_image_wordbox that I’m referencing from my CSS is now a primary element that will be acted upon.

The .show() is a jQuery action which tells the script to show the wordbox by default.  The ‘;’ closes the statement.

Next comes the information that is displayed within the wordbox. When the info changes, I want to animate it. Thus, I apply the .animate() action to the main_image_info CSS reference. Within the animate action, I set what I want to change/animate. In this case I want to change the property called ‘opacity’ to .85 so I place the properties within {} and specify the speed at which the animation will take place outside of the {} as ‘1’ so that it’s instantaneous/very fast.

Now we come to our main action:

$(".navi_1 ul li").click(function(){         });

When a list item is clicked within an unordered list in the CSS .navi_1 box activate the function within the {}.

var imgAlt = $(this).find('img').attr("alt");

var imgTitle = $(this).find('a').attr("href");

var imgDesc = $(this).find('.image_info').html();

‘var’ designates a variable which can be used over and over throughout the script. Thus, ‘imgAlt’ used further down in the script will naturally refer up to the ‘var’ and say “Oh, ‘imgAlt’ means to do this.”.

$(this) refers to the code above it- in other words   $(".navi_1 ul li").click

Thus, the first ‘var’ says when the li is clicked find the image within the li and get it’s attribute of alt.

So what it’s doing is this:   <li><img src=”image_thumnail.jpg” alt=”A Blue Building” /></li>

IE:  The first ‘var’ translates into- The variable ‘imgAlt’ is equal to ‘when the li is clicked find the attribute of “alt” within the image tag’.

The other 2 variables operate under the same principles.

Now comes your ‘if/else’ statement.

if ($(this).is(".active")) {

return false;

}

If your li is already clicked and therefore has the class of ‘active’ then do nothing. IE: Is animation needed? No? then “return false” – do nothing. ‘else’, if it isn’t already active then do the action within the else tags. Afterwards stop by ‘return(ing) false’ as the action taken is now active.

else {           } return false;

Going within the ‘else’ for the heart of your animation

$(".main_image_1 .main_image_info").animate({ opacity: 0 }, 350 , function(){

        $(".main_image_1 .main_image_info").html(imgDesc).animate({ opacity: 0.85   }, 350 );

	$(".main_image_1 img").attr({ src: imgTitle , alt: imgAlt});

});

The top tells me that when I animate the css elements I want to, by default, animate the opacity to 0 at a speed of 350. I further specify it by saying that within the animation of the objects the function(){} further expounds on what I specifically want done during the animation.

The animation function says that the animation consists of:

1. Replacing the .main_image_info’s html with the variable ‘imgDesc’ information and when doing so to animate the opacity to .85 at a speed of 350.

2. Taking the .main_image_1’s img tag and replacing the attributes of src and alt with the variables ‘imgTitle’ and ‘imgAlt’ information.

Putting it all together

So here’s how the script works:

The page loads and image rotator comes up and the text box appears. Animation instantly changes the text box to have a slightly lower opacity so you can moderately see the image behind it. It stops. Nothing happens until you click a list item (ie: thumbnail) which then takes the link location and alt on the thumbnail and shoves that information into the main image while taking the html out of the CSS class ‘image_info’ and placing that into the text box which at the start of the animation had faded to zero, but now fades back to the original .85 opacity. Animation ends. New image and text are displayed in the rotator.

Tada! You’ve just learned about a jQuery image rotator.

So what about all the other stuff?

Yes, jQuery does a lot more than this, but most of it is easily customizable and come in the form of various plugins. The above example was to give you an insight into how jQuery basically operates/works.

For more information on jQuery and a list of its plugins, go to:      http://docs.jquery.com/Main_Page

Commenting on Code in Code

commentimage

Ever wonder how web designers keep everything in order when they’re typing out their code? Well, commenting helps a lot in organizing. By using comments, you can also signal out things you want to fix, make note of, or even just keep track of. So how do you keep the comments from messing up the 18 hours of coding you just did? Well, there are different options for different languages.

HTML

Below is the style for your basic html web page which really shouldn’t have too many comments- just nice clean code.

<!-- Comment Here -->

CSS

For organizing your styles and your main boxes- or whatever else you need- this commenting style works for single line or block quotes.

/* Comment Here */

JavaScript or jQuery

For JavaScript or jQuery, this method comments out the entire line starting from behind the back slashes. It is used as an end of line comment. CSS style is used as a short single line comment.

// Comment Here

/* Comment Here */

For block comments the code looks like CSS, but remember to keep an asterisk on each line.

/*
* Comment Here
*/

PHP

PHP can use the JavaScript method, or the pound symbol to comment out a line.

// Comment Here

# Comment Here

For multiple lines, the comment code is like the CSS code but unlike the JavaScript, no further asterisks are needed.

/* Comment
Here */

Ajax

To comment in Ajax, use the same method as in JavaScript.

// Comment Here

ActionScript

When working with flash, you might want to use these to comment on your action script. The first works for multiple lines and single lines while the second is just used for single lined short comments.

/* Comment Here */

// Comment Here

Interactive Campus Map v2.0

So, here we are:  nearly a year later and yet another Google Maps post.

This new version is the next level of progression for the map, which includes some of these new features:

  • Use of Google Maps’ default map tiles which shows all streets and other landmarks
  • Overlay of all buildings that sits on top of the default Google Maps tiles
  • Addition of Driving Directions to/from each building to any address
  • Addition of Walking Directions to/from each building to any address
  • Wide screen, which leads to much more viewable space
  • Links to other key campus maps

While the previous iteration was useful and a big improvement over what the campus map used to be before Google Maps, I think this direction is the right one to take.

The biggest advantage of this update is that the building overlay is being dynamically generated by UA’s Cartography Lab.  This means that whenever a building is added or removed from this overlay, you will immediately see the results.  With the other map, anytime a building was changed it would mean cutting up the images (it better be exactly the same!) and all of that mess.

The biggest disadvantage of this update is that, due to UA’s recent construction, the roads aren’t really matching up with the buildings.  This has more to do with Tuscaloosa not being a major metropolitan area, thus having to wait on Tele Atlas to update their tiles for the University.  Eventually they will match up with our ever-changing campus.  However, I think the advantages far outweigh any disadvantages from doing this.

Without further ado, here is the new campus map:  http://tour.ua.edu/map

Let me know your feedback and opinions in the comments.

Looking for the previous custom Google Map?

Click here if you want to see the old campus map.  I have kept it around for informational purposes.

Flash Detection using SWFObject

I thought I would expound a little bit on the Flash detection we are using in the new UA Video Newsroom (and elsewhere). Andy mentioned it briefly, but I would like to explain in more detail why I went this route.

The previous method we were using was Adobe’s Flash Detection Kit. Up until recently, this was truly the best method for trying to create a better experience for users when they encountered Flash. However, the practical application of this code made adding videos to your page convoluted and confusing.

I wanted a simple to integrate and easy to read solution. Luckily, a natural successor to the Flash Detection Kit is out there and it’s called SWFObject.

What is SWFObject and why is it better than Flash Detection Kit?

  • It’s an open source code base
  • Offers a Javascript API that allows me to dynamically work with our Flash content
  • Allows me to deliver multiple forms of alternate content I want (more on this shortly)
  • Active with only one Javascript file
  • SEO-friendly embed code

Alternative Content

Delivering alternative content is essential to make our users aware they are missing something by not having Flash installed or not having Javascript enabled. If you simply did no detection at all, users can encounter a few different things depending on what is or isn’t installed, but worst case scenario is that nothing is displayed.

This is what you could encounter if you have Javascript enabled, but no Flash installed:
Broken SWF

Now, we can do some cool stuff with SWFObject. The best part is that we can integrate Adobe’s Auto Install SWF with a simple variable declaration and local file. Using this method shows a dialog box to install the latest version of Flash and, after installing the update, it automatically brings the user back to the previous page.
Adobe's Auto Install

If for some reason, the user has no Flash installed or Javascript turned off, they will simply receive this message:

“This page contains video that requires JavaScript and a recent version of Adobe’s Flash Player. Download the latest Adobe Flash Player now to view this content.”

Ideally, the Adobe Auto Install initiates.  and at the very least, the user will be presented with a link to download the latest version of Flash.  If you have any Flash video to embed on your websites, I recommend using SWFObject.

Custom Google Maps

Recently, I launched our new Interactive Campus Map that integrates with the Google Maps interface. Some of you may remember my past experiences working with the Google Maps API. Well, this is much more complicated. Although this took me more time than I would have liked to get working, I now know my way around the API (mostly). This is a huge advantage moving forward because there’s even more that I can do with it and even more to come.

Unlike the last post, this will not be a tutorial but more of a guide to get you started. You may want to walk through my source code to understand what I’m talking about. If you haven’t yet read my previous post on how to get a simple Google Maps working on your site, you might want to start there. Okay, let’s get to it.

Here’s a list of tools and resources that I used:

What I wanted out of my custom Google Map was to use my own images (Google calls these tiles), to be able to zoom in and out, have a marker for every building with some data in the info bubble, and have some kind of search function. What you end up with is a fully interactive map in an interface that most users will already be familiar with.

Here are the steps you need to take to integrate a custom tiled map onto your site:

  1. Find an image to use, preferably one with high quality for zooming
  2. Use this tool to figure out the coordinates of your tiles over the standard Google Maps tiles. NOTE: if you plan on showing the standard Google Maps in addition to your custom map, you will need to ensure your image lines up and scales correctly. If you do not do this, the markers you place later will be aligned incorrectly. However, if you know you only want to show your custom map, you can be a little more forgiving on the coordinates.
  3. Once you obtain the coordinates, you can configure the Automatic Tile Cutter script.
  4. After you plug in your options and save the file, go into Photoshop, open your image and run the script (File->Scripts->Browse). Here it will cut up your image into 256×256 squares for all of the different zoom levels you wanted.
  5. Now that you have all of your images, you are ready to add the code to make them show up in Google Maps. Follow the steps in the Mapki to create all of the GCopyright Javascript objects you need.
  6. The next step is to add the custom GTileLayer object. This is what tripped me up the most because the Mapki’s tile function is a little out of date. I referenced this tutorial and used the second CustomGetTileUrl function at the bottom of the page. Eventually, I added bounds checks to display a blank image outside of the x/y coordinates. NOTE: the zoom levels passed to the GTileLayer are based off an array numbering system. For example, my lowest zoom level is 15 and my highest is 17. Therefore, in the GTileLayer object I must pass 14 and 16, respectively, in order for the tiles to show up correctly.
  7. Now all that is left to do is add our custom map and center it.
  8. From there, you can add your own markers via XML. Make your life easier by storing your data in a CSV file and generating the XML from that. If you were industrious, you could store your data in a SQL database and dynamically generate the XML that way.

Whew. As you can see, there’s really a lot to it with quite a few pitfalls. Google doesn’t make this any easier by providing less than helpful documentation. Plus, whatever tutorials you find are either too simple or out of date. But, the upside is that Google lets you customize just about any aspect that you would like. The one downside I would point out is that we can’t have a “Directions To/From Here” function yet. Because of all the construction and road changes around campus, the default Google Maps tiles have yet to be updated which means Google’s directions would be incorrect most of the time.

Keep an eye on the Interactive Campus Map because it will continue to be improved with new functionality. If you have any questions, just let me know.

UPDATE

The campus map has been updated and no longer uses custom tiles.  For more information on this change, please read this post.  However, if you would still like to see the results of the above steps, click here to view the old custom Google map.