Easily add rotating banners to your wordpress site with jQuery

Sunday, 31 January 2010

View Comments

Adding a rotating banner to wordpress with jQuery is too easy. The jQuery cycle plugin is one of the oldest and the best and comes with a multitude of effects transitions and inculdes next previous and pager options if needed. Even more the plugin includes pause on hover, click to progress and even custom transitions, unleashing the power and versatlity of jQuery.


I want to show how to do a simple fade out to the next photo style banner which is popular on many sites and works well in the main banner position. It's a good idea to check out some of the examples on the cycle plugin site and find whichever transition suits your needs. Some of the more animated transitions would likely suit your sidebar if you wanted to draw more attention away from the page. I feel something more subtle works better at the top op the page.

A transitioning image on a recent site that I worked on:


Now there are many sites that teach you to include jQuery using the wp_enqueue_script method. The best way for you to include jQuery on any site is to use Google's CDN.

To do this add the following to your header.php file:
<script type=\"text/javascript\" src=\"http://www.google.com/jsapi\"></script>
<script type=\"text/javascript\">
 google.load(\"jquery\", \"1.4\");
</script>

Next populate a div on your page with images where you would like your banner to appear:
<div id=\"header\">
 <img src=\"<?php bloginfo(\'template_url\');?>/images/01.jpg\" alt=\"Image 01\" />
 <img src=\"<?php bloginfo(\'template_url\');?>/images/02.jpg\" alt=\"Image 02\" />
 <img src=\"<?php bloginfo(\'template_url\');?>/images/03.jpg\" alt=\"Image 03\" />
</div>

Make sure your images have been cropped and adjusted to a reasonable size, with you banner it works well if all the images have the same dimensions.

Next download and include the cycle plugin in the head after the jQuery include, paying attention to wherever you installed the plugin:
<script language=\"javascript\" type=\"text/javascript\" src=\"<?php bloginfo(\'template_directory\'); ?>/js/jquery.cycle.all.min.js\"></script>

The next bit is calling the plugin which is very straight forward:
jQuery(document).ready(function(){ 
 jQuery(\"#header\").cycle({
  delay:-4000,
  fx: \'fade\',
  pause: 1,
  timeout:1000,
  speed: 4000
 });
});

I have set a negative delay so that it doesn't wait to transition for the very first image. I have set the 'fade' effect with a transition speed of 4 seconds and a timeout speed of 1 second which is the length of time between transisitons. The last option is pause which simply pauses the effect while the mouse is over the images.

It's that easy and with the combined number of transitions you can really add some magic to your wordpress site.

Enjoy!




more...

Your next employee, 10 years experience or an avid learner?

Saturday, 30 January 2010

View Comments

How do you keep up to date in the IT world?

Several months ago we did a round of interviews for a new position at our company. We weren't interested in how many years experience a person had, what we wanted was someone who was as passionate about IT as the rest of our team. Our team spends much of our spare time discussing the latest trends in the industry and how we can apply new technologies and methodologies to our work. One question that really stumped most people was 'How do you keep up to date in the IT world?'.


From the number of people that we interviewed who could not provide a coherent answer to this question, I would assume that very few people regularly spend their time reading blogs, reading online news or even text books for that matter. I would have even accepted an "I check Digg every now and then to see what are the top results". Most of the time we had to prompt people by asking them more directly, such as do you regularly read any blogs or visit any tech sites. But this also yielded few precise answers.

By the sheer fact that you are reading this post I am likely preaching to the converted. But I would like to say that staying up to date with IT is important and to do that you need to read, read, read. IT is an industry that is constantly trying to justify itself, we have to make time and make money for an organisation in order to exist and hopefully to grow. IT is in constant change which is one of the great things about our industry, but to stay relevant and to keep in touch we must constantly learn.

So how can we encourage reading outside of the few text books that we bothered to take out of the plastic during your college / university years? Maybe this question, "'How do you keep up to date in the IT world?' should become a standard interview question for all new positions, I know it will be top of the list for me. Should we be taught about it by our teachers when we are at university?

One of the best things we can do for new starters and for our own teams is to share what you read. Do you encourage learning amongst your staff or your team, do you take time to discuss what you have read in the past week? Maybe you could set up a page on your companies intranet or blog to share your latest thoughts and ideas or send out an email with your top ten links for the week. Take time in your weekly team meetings to find out what each person has learnt while doing their job this week. Foster a team of learners and growers and encourage this trend for anyone who joins your team.

How you keep up to date is not just about what the individual knows, it is about how the individual will continue to contribute to your teams future. In the end there is not much difference between a basic "programmer" with 2 or 10 years experience. If you can find someone who wants to learn and share and challenge; they will be much more beneficial to your team. But you won't find this person unless you have a team that actively seeks and encourages this kind of person.

What type of person would you like to add to your team? Someone who has 5+ years experience in this or that language or someone who has their finger on the pulse and is actually interested in what they are doing by constantly learning and constantly improving themselves and their team.

Be sure to also check out this post for some good ideas on keeping you and your team learning.

If you have some good ideas on how you or your team keeps up to date with IT leave me a message in the comments below.
more...

Hints and tips for learning jQuery

Friday, 29 January 2010

View Comments

In this article I want to give some hints and tips for those of you who are just beginning with jQuery. jQuery can seem quite overwhelming at first, there appears to be a lot to cover and the syntax appears quite technical at first. The great thing is, once you have overcome the initial learning period, jQuery syntax is quite readable and will provide you with a fantastic tool with limitless potential.


I suggest before you begin, you also go over these tutorials. They are jQuery's own tutorials and are a good foundation. This tutorial will help you build on these basics and help you go further with jQuery.

To begin with jQuery is now available via Google's content delivery network (CDN). This means that you don't need to download anything to begin using jQuery. Here's how you can start a basic page which will load in jQuery via the CDN.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>jQuery test</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
 google.load("jquery", "1.4");
</script>
</head>
<body>
</body>
</html>

This basic page when loaded will contact Google's CDN from wherever you are in the world and include it in your page. So now we have jQuery up and ready.

The next thing that I suggest you do is to get a copy of Firebug for Firefox. There are many similar tools for other browsers, I will leave you to investigate those. Having Firebug (or equivelant) allows us to enter javascript directly and view the results of running those commands. You can see from the screen shot below, when I type in the $ command I get the result function.



Firebug will be your best friend will learning jQuery because it can show the results of your function calls, prevent you from refreshing the browser and using alert messages for feedback and will even show you which elements match your jQuery selectors. Selectors tell jQuery which part of your page a certain function should target.

So now you should have your page loading jQuery, which we have confirmed by using Firebug and typing in the $ command so let's dive in and start using jQuery.

The first thing you will want to do to your page is to include a regular javascript file. You need to do this in the head after the section that loads in jQuery. Something like this:

<script type="text/javascript" src="my_script.js"></script>

Open up the my_script.js file (or whatever you called it) and we will start with our jQuery code. If you have read any tutorials or had a play with jQuery you will know we need to start by adding in jQuery's document ready function so let's do that:

$("document").ready(function() {
 // Other code goes here!
});

So if we place an alert() inside this function it will alert us when the page is loaded and ready to be accessed with jQuery.

Besides the above, there is nothing else needed to start using jQuery and working with its awesome functionality. So let's start taking a look at the way the language itself works.

jQuery has two main types of functions: Those that require a selector and those that don't...

A jQuery function call with a selector
$("#details").hide();

A jQuery function call without a selector
$.ajax("url", {}, function(data) {
 });

So those with a selecter will be in the form $(<<selector>>).<<function>> and those without $.<<function>>. A selector allows us to target a specific element or elements on the page. So we have functions that allow us to target elements and functions that don't need to be targeted, such as AJAX calls.

We can suggest that the non-selector functions are actually targeted at the entire page, then all functions can be viewed as <<selector>>.<<function>>.

The function part of the call can be found in the API, a list of all the functions that jQuery currently provides, jQuery has a great API browser which you will eventually become familiar with, for now you can have a quick look to see some of the functionality available. You will notice that most of these is written as either .<<function name>> or jQuery.<<function name>>, jQuery.<<function name>> are the non-selector functions we mentioned.

jQuery selector syntax takes a bit of learning, but here are some basic tips that will get you on your way...

To start with jQuery selectors are based on CSS selectors, if you are already familiar with CSS selectors you have a very good head start. So if you want to target all the h3 elements we can just do like this $("h3"). If you want to target all elements of a specific class you can do it this way $(".someclass"). All of the available selectors are available in the selectors section of the jQuery API.

You can chain selectors just like CSS e.g. $(".someclass, h3")

You can specify all descendants like CSS e.g. $("#specials *")

jQuery even has special selectors to match child elements and for filtering out certain items from your selection. For now try and familiarise yourself with the basic selectors of class, attribute i.e. input[name='first_name'] and class selectors and build up from there. Just keep in mind, it is not unfamiliar, if you can select it in CSS you can select it using jQuery.

The best way to get to know selectors is by trying out each of the selectors and the best place to do this is jQuery's site. Go to any page on the jQuery site, open up Firebug and start typing out some selectors. You can start out by trying in $("*") and drill down from there or view the page source and see which elements you would like to try and target.

The next important thing to know about jQuery is chaining. Most jQuery functions will chain, meaning you don't need to type the selector out multiple times, you can just apply function after function as such;

<<selector>>.<<function 1>>.<<function 2>>.<<function 3>>... and so on.

For example:
$("#my_div").css("background", "red").addClass("dimensions").toggle();

This will apply each of the three functions to our first selector, as each function is called the result is passed along the chain until it reaches the end.

So now we know how to write a basic jQuery function call and how to chain. Let's get familiar with the API. Looking down the left hand side you will see the main categories of the API; AJAX, Attributes etc. let's look at the main categories in detail.

AJAX: Used for making AJAX calls
Attributes: Used for retrieve/updating/adding/removing attributes
CSS: Used for CSS manipulation (add class, remove class, set CSS rule)
Data: Used for storing extra data on a DOM element
Dimensions: Getting the size of elements on a page (width, height etc.)
Effects: Fade in, Fade out, animating and other effects
Events: Used for handling events such as onclick, mouseover etc.
Forms: Functions for manipulating forms
Manipulation: Clone items, DOM inserting etc.
Selectors: A run down on the jQuery selectors and associated functions
Traversing: Functions for traversing the DOM

There are several categories I have left out that are also worthwhile but are hard to generalise or only have a few functions. But you can get a good idea from above jQuery's main functionality. Again, have a play with some of the functions using jQuery's site and Firebug. Also if you click through on the function name in the API it will lead you to a lot of details information about each function including a demo of how it works.

Just in summary, here is a rundown of what we have covered:

  • Use Google's CDN to load jQuery
  • Get Firebug so you can see what is going on and to run javascript/jQuery commands without reloading
  • Use the document ready function to use jQuery when your page loads (you can also use jQuery inside a regular function call)
  • A basic function is made up of $(<<selector>>).<<function>>
  • Selectors are based on and in most cases identical to CSS selectors
  • jQuery's functions can be chained
  • Get familiar with selectors then get familiar with functions in API
  • Use Firebug and jQuery's site to test out selectors/functions rather than trying to build things to test yourself

Hopefully this gives you a leg up when starting out with jQuery. Let me know how you are going by leaving a comment below.




more...

Professional trust - delivering more than what the customer sees

Sunday, 24 January 2010

View Comments

What makes a person a professional? I would suggest two things; knowledge and experience. You can have knowledge without experience as in a college graduate and it's possible to have years of experience without learning anything new. As consumers we put a fair bit of faith in professionals, we trust what an auto mechanic says about our car and we must rely on the opinion of a doctor.


This trust is extended even further, we expect that a professional can do something better than we can do ourselves. If you go to get a haircut you never get specifically what you asked for, the reason for this is the person cutting our hair can see what we can't see ourselves and adjusts accordingly. So this is another special trait of a professional, they have an insight into their subject. When they look at a piece of work they can see when something has been done well and when something has been done poorly. We as a consumer need to extend our trust to relying on a quality piece of work, even when we can't see it ourselves.

This reminds me of an old episode of the Simpsons. Homer goes to visit his long lost brother who owns and operates a previously successful car design business. Homer's brother asks him to help design their next model car for the "average American". What ensues is an argument between the designers and Homer as to exactly how the car should look. The designers want to inerperate Homer's ideas into something that appears sleek and marketable while Homer just wants something that looks like what he has in his head. In the end, his brother agrees to let Homer build the car in his head and it ends up costing him his business.

So we see for success, although the customer may always be right, it takes a good quality professional to implement the ideas and not in exactly the same way that the customer expected.

So how do we apply this to the work we do in the IT industry. If you are on the other side of the fence and you are providing a client with work, you have the client's trust that you are going to deliver a good quality piece of work. In the IT industry we have an even greater level of smokescreen as we hide behind the code we write. The average guy on the street can see a good quality car or can pick out a bad haircut, but your customer has no chance of picking out your poorly written code.

There is an unfortunate acceptance of well presented, poorly implemented, badly structured, overly cluttered and user-unfriendly code within our industry. I've heard the excuse many times that bugs in design and usability of web applications attributed to "it just works that way and it can't be fixed" which is accepted as the norm. People just expect less of the IT industry because it's apparantly over technical and supposedly unwieldly.

The general acceptance of poorly written web sites results in people charging excesive amounts in return for something that is below par. Recently an IT colleague of mine recieved some code via another colleague (non-IT) that had been written by an agency. The initial delivery was table based HTML which would have fit well in 1996. After rejecting the code as unusable (it was to be included as part of a larger site), the rework came back and was the same code, but each TD, TR and TABLE element were replace with DIVs. Not only is there one person who still thinks it's acceptable to code this way, but there's a whole damn agency of monkeys who thinks it's fine to deliver this kind of work to a paying customer.

Delivering poor quality work to a customer who is both accepting and uneducated is not only unprofessional, but it shows a lack of respect for the customer. This trust is given in the hopes that a customer will get not only what they ask for, but also for what they can't see. Are you selling or delivering to your customers a beautiful car with a second-hand engine?

I wish I knew the source of this quote, I read it somewhere a while back. It said, when you work on a web application for your company, always write it to the highest possible standard. It doesn't matter that nobody will ever look at that piece of code and smile in recognition. What does matter is that you have delivered the best piece of work that you can. It's only by working to the best of your ability that you can continue to go further.

So don't try to sell your customers or your company short. If you are a professional you will be delivering professional quality work. If you are just using your customers to make a quick buck you won't be doing it for long... I've had too many bad haircuts to know when not to go back.




more...

Building great site navigation with jQuery and key listeners

Friday, 22 January 2010

View Comments

Good navigation is essential to any site. Gone are the days when everything should appear above the fold, users now want and expect a rich internet experience from the sites you build. A vital part of this is experience is a good layout and good navigation, especially if there are a large number of elements on the page.

On top of this it is also worthwhile to consider users with accessability issues and who are constantly stuck with using the tab key to navigate around often poorly designed web pages.


With jQuery it is possible and easy to improve keyboard site navigation by binding listeners to certain keys. In this post I will go over some of the basics to give you some ideas of how you can challenge your own designs and think about including a more clever way to navigate around the elements on your page.

In my sample application I will have nine boxes in a 3 x 3 square. Allowing us to navigate left, right, up and down and performing some function when the enter is pressed. My navigation will be indicated by switching the class on the currently selected item.



A working example of this code can be found here

You can download the actual code from here

Let's begin by looking at a simple function to getting your site to listen to key presses:

$("document").ready(function() {
 
 $(document).keydown(function(e) {
  switch (e.keyCode) {
  }
 }
});

Here we have our jQuery document ready function and a document level listener for the keydown event. The last piece is the switch statement which will determine what action is performed whenever a key is pressed. As we are looking at navigating around our site, let's bind some listeners to the arrow keys. Here are the codes that we will need:

37 Left arrow
38 Up arrow
39 Right arrow
40 Down arrow

I'm also going to add the enter key (code 13) to perform an action on the currently selected item.

You can find a full list of keycodes here

Let's look at some pseudocode to see how our navigation will work:

$("document").ready(function() {
 
 $(document).keydown(function(e) {
  switch (e.keyCode) {
   case 13:
    // Perform some action when enter is placed
    return;
   case 37:
    // Navigate left
    break;
   case 38:
    // Navigate up
    break;
   case 39:
    // Navigate right
    break; 
   case 40:
    // Navigate down
    break;   
  }
 }
});

Now let's look at the full code to see how it all holds together:

<body>
 <div id="container">
  <div class='item'>0</div>
  <div class='item'>1</div>
  <div class='item'>2</div>
  <div class='item'>3</div>
  <div class='item'>4</div>
  <div class='item'>5</div>
  <div class='item'>6</div>
  <div class='item'>7</div>
  <div class='item'>8</div>
  <div style='clear:both;'></div>
 </div>
 <div style='clear:both;'></div>
 <div id="debug"></div>
</body>

We can see our nine boxes all floated left in a containing div and all having the item class. Here is the javascript:

$("document").ready(function() {
 $(".item:first").addClass("selected");
 
 $(document).keydown(function(e) {
  // Current index
  var cur_idx = $(".item").index($(".selected"));
  var max_idx = $(".item").length - 1;
  var row_length = 3;
  
  switch (e.keyCode) {
   case 13:
    $(".item").eq(cur_idx).effect("explode", {}, 500, function() {$(this).remove();});
    $(".item:first").addClass("selected");
    return;
   case 37:
    // Get index of current item, if 1 then nothing, else move one back
    if (cur_idx == 0) {
     var next_idx = 0;
    } else {
     var next_idx = cur_idx - 1;
    }
    break;
   case 38:
    if ((cur_idx - row_length) <= 0) {
     var next_idx = 0;
    } else {
     var next_idx = (cur_idx - row_length);
    }
    break;
   case 39:
    // Get index of current item, if max then nothing, else move one forward
    if (cur_idx == max_idx) {
     var next_idx = cur_idx;
    } else {
     var next_idx = cur_idx + 1;
    }
    break; 
   case 40:
    if ((cur_idx + row_length) >= max_idx) {
     var next_idx = max_idx;
    } else {
     var next_idx = (cur_idx + row_length);
    }
    break;   
  }
  
  if (typeof next_idx != 'undefined') {
   $(".item.selected").removeClass("selected");
   $(".item").eq(next_idx).addClass("selected");
  }
 }); 
 
});

We begin by setting the selected class on the first of our boxes.

Next we set the keydown listener to the document. When the function is called we begin by getting the index of the currently selected item and also the number of items. The row_length variable is used to navigate up and down to the item above or below.

Next comes our keyCode swtich statement. For each of the arrow keys codes 37, 38, 39 and 40 we calculate whether we are going to go outside the item at index 0 or the last iem and we navigate accordingly by removing the class for the currently selected item and applying it to the item at the next_idx index by using the jquery eq() function to target the item at index next_idx.

If the enter key is pressed (code 13) we call the jQuery UI effect "explode" and then remove the item and reset the selected class back to the first item.

This is just the tip of the iceburg of what can be achieved using jQuery and key listeners but it should give you a glimpse of the possibilities for building a responsive, interactive web page.

If you have some good examples of sites with outstanding keyboard navigation share it with us with a comment below.




more...

Pervasive advertising and digital sharecroppers

Thursday, 21 January 2010

View Comments

Does pervasive advertising still work on the internet? As some of the big guys work hard to make a profit from their current business model pervasive advertising has crept onto pages and across screens. We've been led to believe that traditional methods of advertising are dying out; so why the full page ads, auto play video and pop-up like overlay advertisements? The simple answer is pervasive advertising works and still delivers a certain percentage of click throughs that can be depended on and on sold to clients. But internet advertising is a complex beast and one that big companies are struggling to make a profit from.


Digital sharecropping is a dirty word, but in the end who really cares? In Nicholas Carr's own words "What's being concentrated, in other words, is not content but the economic value of content.". But, again, who cares? Part of everyon'es big obsession with Web 2.0 is the celebrity status, if you were at all concerned that Twitter was making big bucks out of onselling your tweets you would blog in your own dark corner of the web. Youtube didn't drag you to their site or link to your video without your permission. So it is reasonable that they should be able to cash in on their traffic. The traffic that is the pitter, patter of millions of satisfied content creators and viewers.

What is interesting in the past five years of the internet, despite the large volumes of traffic flowing through Youtube, Twitter and other social sites, they are still finding it hard to come up with a successful model to compare with that made by the companies fund them (think the cost of buying Youtube to the profit made so far). Digital sharecropping aside, we have received a hell of a lot of joy in return for sharing our meager thoughts and content with these sites.

Social sites are just like reality TV, some people are willing to participate for free in hopes of celebrity, while a larger company sells advertising on their television network.

What's interesting to see is the way the big guys have gone about trying to get the best out of their clients advertising dollars. Like this example from yahoo:



Note, I didn't even click on this thing it just pops out at you and engulfs the entire screen. These type of adds are regular on yahoo's site and occasionally clicking on close will either redirect you to the sponsors site or just doesn't respond.

This next example from myspace is even better. The only thing worth looking at on myspace is the band pages, and the only thing on those pages is the music player. So clever myspace place the add directly over the music player. After closing an add it is replaced approximately every couple of minutes with a new one.



But the most memorable advertisement recently has to go to Digg with their Dragon Age full page advertisement. That caused a storm so big the instructions on how to remove the add reached the front page of Digg's own site. Have a look at the add below:



The Digg community went crazy with many threatening never to return. As the backlash reverberated around the halls of Digg HQ and at the risk of losing their beloved linkers (farmers?) it prompted this response. With full page adds never to be repeated since.

I'm sure we won't be seeing the end of pervasive advertising on the internet, but advertising in the internet is different to advertising in the real world. Most people tolerate advertising in return for entertainment. But on the internet, especially where users are giving up some of their own time and effort they are not willing to let the experience be degrade by advertising that interferes with the experience.

Sure we are willing to be sharecroppers and sure you can have advertising on your site and you can keep your traffic and we'll keep our 15 minutes of fame. By try and interrupt that experience and there might just be a workers strike.
more...

Save to database via Ajax using jQuery, php, mysql

When you start building your very first php + mysql applications you will likely have a loop that looks something like this:
* Display a form
* Submit a form to php page
* Update database
* Return user to form, possibly with success message

This is a good basic loop and works perfectly fine in very small scale sites or for something like a user sign-up form to a newsletter etc. But as web applications have moved forward and there is a greater focus on more fluid and dynamic applications form processing has also progressed and it is now possible to submit a form without reloading your page.


Think of the situation where someone has to use your web application to do a large amount of data entry or providing inline editing of a table. You wouldn't want your valuable users to be waiting while the page loads each time.

This tutorial will show you how you can process your form using Ajax.

A working version of this functionality can be viewed here.
You can download the code for this tutorial here

Our new loop will look like this:
* Display a form to the user
* Validation is performed on the form before submit, displaying an alert dialog if validation fails
* Form details are then sent to a php script via AJAX
* php script attempts to save to database and reports if there were any errors
* page is updated (form reset and success message) if successful or display error if save failed

To begin with we have a relatively plain HTML form:
<form id="personal_details" action="process.php" method="post">
 <fieldset>
  <legend>Personal Details</legend>
  <label for="name">Name</label>
  <input type="text" name="name"/>
  <label for="age_range">Age</label>
  <select name="age_range">
   <option value="">Please select an age range</option>
   <option value="1">0-12</option>
   <option value="2">12-16</option>
   <option value="3">16-21</option>
   <option value="4">21-30</option>
   <option value="5">30-50</option>
   <option value="6">50+</option>
  </select>
  <label for="sports">Please select your favourite sports</label>
  <input type="checkbox" name="sports[]" value="soccer" />&nbsp;Soccer<br />
  <input type="checkbox" name="sports[]" value="swimming" />&nbsp;Swimming<br />
  <input type="checkbox" name="sports[]" value="cycling" />&nbsp;Cycling<br />
  <input type="checkbox" name="sports[]" value="kayaking" />&nbsp;Kayaking<br />
  <input type="checkbox" name="sports[]" value="volleyball" />&nbsp;Volleyball<br />
  <input type="checkbox" name="sports[]" value="basketball" />&nbsp;Basketball<br />
  <button type="button" onclick="processDetails();">Submit</button>
  <div style="clear:both;"></div>
 </fieldset>
</form>



You can see we have a Submit button that calls the processDetails function. We also set processDetails as the submit function in the jQuery document ready function as such:
$("document").ready(function() {
 $("#personal_details").submit(function() {
  processDetails();
  return false;
 });
});

Now lets have a look at our processDetails function;
function processDetails() {
 var errors = '';
 
 // Validate name
 var name = $("#personal_details [name='name']").val();
 if (!name) {
  errors += ' - Please enter a namen';
 }
 // Validate age range
 var age_range = $("#personal_details [name='age_range']").val();
 if (!age_range) {
  errors += ' - Please select and age rangen';
 }
 // Validate sports selection
 var sports = $("#personal_details [name='sports[]']:checked").length;
 if (!sports) {
  errors += ' - Please select your favourite sportsn';
 }
 
 if (errors) {
  errors = 'The following errors occurred:n' + errors;
  alert(errors);
  return false;
 } else {
  // Submit our form via Ajax and then reset the form
  $("#personal_details").ajaxSubmit({success:showResult});
  return false;
 }
 
}

processDetails begins with our validating our three form inputs. We basically just check to see if they are set and if they have not been set we display an error message. If no errors are called we submit the form to Ajax by calling the ajaxSubmit function. ajaxSubmit is part of the jQuery forms plugin. This plugin has many great functions that we can use for processing forms. The ajaxSubmit function looks at the form elements action attribute and uses that to submit your form via Ajax so we don't need to worry about serializing and submitting the form manually, it all gets taken care of. I also pass in a success function showResult which will be called on Ajax submit success.

function showResult(data) {
 if (data == 'save_failed') {
  alert('Form save failed, please contact your administrator');
  return false;
 } else {
  $("#personal_details").clearForm().clearFields().resetForm();
  alert('Form save success');
  return false;
 }
}

On success we either display a success or failure alert message. If successful we also clear the form using the form plugins clearForm, clearFields and resetForm functions.

So now anything that happens in our php script is going to happen in the background after it has been called via Ajax.

In our php file we are going to do the following:
* Retrieve our data from the form post ($_POST)
* Check that we have been provided the amount of data we expected
* Try connecting to the database
* Clean the data from the post to ensure no attacks (please not in this example the cleaning is not extensive, you will need to learn about cleaning variables for database inserts elsewhere)
* Attempt to insert the data into the database

You will see that when there is an issue anywhere in the script we echo out 'save_failed' so that the javascript function showResult will know that there has been an issue.

Furthermore with any of the myqsl functions I have appended an @ to the front of the function call, this will supress any error messages given if accessing the database fails.

Let's have a look at the code:
// Retrieve form data
$name = $_POST['name'];
$age_range = $_POST['age_range'];
$sports = $_POST['sports'];
if (!$name || !$age_range || !$sports) {
 echo "save_failed";
 return;
}

// Convert sports array to a serialized string
$sports_list = serialize($sports);

We begin by retrieving the variables from the post and checking that they have been set.

Next we attempt to connect to the database, the details of your database will be provided by your host or depending how you have set them on your own personal server:
$db = array(
 'host' => 'host here',
 'login' => 'username here',
 'password' => 'password here',
 'database' => 'database here',
);
$link = @mysql_connect($db['host'], $db['login'], $db['password']);
if (!$link) {
 echo "save_failed";
 return; 
}
mysql_select_db($db['database']);

As mentioned, you will need to clean your variables to avoid database attacks. Begin by reading this to get a good idea of what's required. CakePHP has a very extensive cleaning function built in and is worth looking at if you want to do some further research.
// Clean variables before performing insert
$clean_name = mysql_real_escape_string($name);
$clean_age_range = mysql_real_escape_string($age_range);
$clean_sports_list = mysql_real_escape_string($sports_list);

Our last step is doing the actual insert into the database:
// Perform insert
$sql = "INSERT INTO details (name, age_range_ID, sports) VALUES ('{$clean_name}', {$clean_age_range}, '{$clean_sports_list}')";
if (@mysql_query($sql, $link)) {
 echo "success";
 @mysql_close($link);
 return;
} else {
 echo "save_failed";
 @mysql_close($link);
 return;
}

This is fairly straight forward; I try and run the query and then return the appropriate message and lastly close the database connection.

Hopefully this tutorial gives you some good insight into getting started on adding Ajax database updates to your web applications.


more...

A shout out to open source and free software

Friday, 15 January 2010

View Comments

Free and open source software is the lifeblood of the internet. You only need to look at the number of servers running open software, the number of sites written in open languages and the ability to be able to download a variety of top quality applications (virus protection, games, video players etc.) to know that; the figures speak for themselves.


On top of this we have the bloggers, the plug-in developers, the evangelists, the authors, distributors and hosts that all give something away to further the free and open cause. Let's also not forget the end users, they are also important, they purchase the books and manuals, make donations and attend the conferences. It is with great pleasure that you can survey the current software landscape and see the giving of time, knowledge and creativity for the benefit of everyone. For this I want to say a big thank you to everyone on behalf of everyone else.

As a developer, quite frequently during job interviews you will be asked if you contribute to open source or other online projects. I used to always answer no to this question. Sure everything I touched was built on open and free technology and my whole career depended on the stuff, but I had never gone so far as to actually participate.

So this is my call to everyone, developer or not, to go out and participate. How? You don't need to write lines of code to help, but you can still contribute. Like the software you're working on? Go out and talk about it, blog about it, write about it in forums, evangelise. Don't know how to write? Buy a manual and support an author, most of the time those people who wrote the book also helped write the code. Still can't think of a way to help, most projects make it quite easy to donate and every bit helps.

I love gimp, I love ubuntu, I love php and the list goes on. Go out and spread the love! Take some time out of your own schedule to contribute and don't forget to consider what we now enjoy thanks to open software.
more...

Give up your bad coding habits this new year

Thursday, 14 January 2010

View Comments

What bad programming habits do you have? Developers are definitely creatures of habit and we tend to get stuck in our ways. I want to look at some of the bad habits I have picked up over the years and hopefully it will inspire and challenge you to take a look at the way you write code and maybe this new year we can try and change our ways.


Most of these habits are not so bad (at least that's what I tell myself) that they are going to bring down a whole project, but a good coding practice reaps benefits; saving time, testing, number of bugs in your finalised code and even the sanity of your work mates. Good quality coding can become second nature with practice.

Coding style

I have to admit, I have the worlds worst hand writing. Beautiful hand writing is developed over years of practice. Your coding style is built up simarly over time, if you don't take time to indent your code, comment, consolidate and refactor as you go it will stay that way. By the time you reach the end of your page and look back at what you've typed you can't be bothered to go back and fix things up. It's like writing a paper and going back and dotting the 'i's once it's finished.
Get in to the habit of correctly styling your code and just like your hand writing your speed will increase over time to the point where you can write presentable, intelligable, clean written code.
Those of us with good coding styles also find it easier to switch styles on request. So if you move to another company or get a new client who requires a certain coding style you can easily adapt your current coding style.
And if your company doesn't have it's own coding style (and you really want to make friends), try and encourage everyone to develop a company standard coding style that raises the bar for everyone.

Not enough testing

Oh no! Oh FUUUUUUUUU! Not god damn testing. If you're the kind of person who gets violently ill when asked to test your own code then you may be pleasantly surprised to know that the more you test and the earlier you test the less number of times you are going to have to revisit the same piece of code. There's only one thing worse than testing and that's having someone else tell you your code is buggy, so make sure you take the time to test your code.
The best way to do this is to get some idea of how it's going to be used and once it's built go ahead and use it. Everyone writes buggy code, we write code fast because we can, but you can't code perfect. Apps and sites are built using building blocks, but you need to test each page and the site as a whole. Test after each section and test once you've put all the pieces together. You are more likely to find bugs testing like a user rather than testing like a developer so go ahead and click everything, try and break it and then plug those holes. People accept the fact you are going to write buggy code, but they will be surprised if you hand over a well tested piece of work. Remember these guys know how to break it better than we do, that's their job.

Read more

One of the questions we asked in a recent round of interviews was 'what sites do you like to visit online and how do you keep your skills up to date?'. We were surprised at the number of people who didn't have an answer for this. Members of our team are crazy about the web and the latest news. Reading tech books, blogs and news articles is part of our passion for IT. It's not something we do to keep up to date, it's something we do because we love it.
Even if you're just checking out Digg or looking at a few bugs on Stack Overflow, the more you read the better your skills become. We work in an industry that is always changing and developers are being required more and more to provide clever solutions for a multitude of problems. One of the early pieces of software I worked on was a small java app for a biometric finger scanner and I was hired as a php developer. Broaden your skillset and increase your value, the net is full of clever solutions.


Cut and past code

Who doesn't cut and paste code; we do it from the one page we are working on to another, from the net or even from old apps into new apps. I do it, we all do it. The problem with cut and past code is context and understanding. You cut and paste code from one area and stick it into another you want to be sure that it's doing exactly what it should be doing.
Good suggestions are ensuring that you relook at the way the code is commented; has the context changed? update the comments. Will you understand why it has been stuck there if you were to look at the same section of code in 3 months time? Try integrating the code by rewriting it, that is, only keep the good bits. If it looks out of place now, imagine what it will look like to someone else who looks at your code.
If you need to search the net for an easy solution to a particular problem, chances are you don't understand the problem yourself enough to write it from scratch. Try and understand code and if you have time and it's a clever solution, try and learn how to write it yourself from scratch.

Programming in one environment delivering in another

This is one of my current bad habits. Our company standard web browser is IE6, so everything must be delivered and working on IE6. God help me if I had to debug and use web tools on IE6; I can't live without Firebug. But the big issue here is that once it's working in FF it has to be tweaked in IE6, which occassionally doesn't happen (guilty look).
This really goes back to a good personal testing regime, but if you are developing for a particular environment your works not over until you have used and reviewed in that environment. And more than likely you will find more bugs if you use that environment more often. If you have a client who wants you to build for a particular environment or setup, try your hardest to work in that environment or at least do all of your quick and full reviews in that environment. If you code in FF and need to have it working in IE, have IE on the screen next to you, only use FF to fix bugs. Finding bugs saves you time rewriting the same code again.

Trying to code everything in the frontend/backend/database and overreliance on one language

This can be a real killer. If your coding relies heavily on one methodology or technology your work will suffer. Too much javascript or an overreliance on AJAX? Hate server side technologies and want to do everything in the backend?
Usually sites like these suffer from speed, usability or functionality just doesn't work quite right. Try and get an understanding of how a good working application is put together and find a good balance between front and back. And as always, the number one rule of usability, don't put useless shit into your site.

Comment, Comment and More Comments

How many times have I looked at code I wrote 4 weeks ago and have no idea why the hell I wrote what's in front of me. It's painful. Commenting is not only useful for yourself, but you should consider it a courtesy. You can also usually tell how good a coder someone is by how good there commenting is. Why? Because commenting is human readable, you can read it a lot faster than code, you can immediately see if someone understands what their code is doing.
Commenting is a quality not a quantity thing, but more often than not it's lacking, so I suggest to aim for slightly over commented rather than commenting where and when you think necessary.
Also as suggested elsewhere, if you touch a piece of code that is already commented, read the code and update the comments. Out of date commenting is just as dangerous as incorrect code.

If you have any suggestions (or confessions) of coding habits that should be changed in this new year (and decade) let us know in the comments below.

Have a great new year and happy coding!
more...

What's in the jQuery 1.4 release

Wednesday, 13 January 2010

View Comments

Well it's almost here. Just a couple of more sleeps and the official release of jQuery 1.4 is going to happen. I previously posted about what was expected to be included in jQuery 1.4. This post looks at the events surrounding the release and what has been included in jQuery 1.4.


To begin with you will want to head over to this site: this official site set up to celebrate the release of jQuery 1.4. It's going to have all the announcements and allows you to subscribe via RSS, email or Twitter @jquery so you won't miss a thing. The site is called 'The 14 Days of jQuery' (plus the two extra days they snuck on the front). you will notice a bunch of links towards the bottom of the site A,B,1,2 etc... which will show you each of the announcements for each day.



At the time of this post day A and B have already passed and there has already been some exciting goodies revealed. To start off with there has been a complete rewrite of the API and it looks awesome (see screenshot below). The API rewrite was done courtesty of Karl Swedberg in the process of writing the next version of the jQuery reference guide; it was so good they decided to turn his work into the new API site. So head on over to api.jquery.com, which is filled with all new examples and much more detail.



Even better, the new API even includes a section New or Changed in 1.4 so you don't need to go digging around in the API to find out. One thing I did notice, this page didn't mention the changes to live() which are one of the most talked about changes, but when I browsed the API to .live() it did mention that it has been changed for 1.4. Quote: "As of jQuery 1.4, the .live() method supports custom events as well as all JavaScript events." So I guess they will be updating that later. Which means there must be some more jQuery awesomeness hidden elsewhere that is not included in the New or Changed section so far.

Now if you are in hot anticipitation of the next release the fun doesn't stop here... If you can't wait till the actual release day, jQuery have released jQuery 1.4rc1 the first release candidate which will become the actual release some point in the next 48 hours. So you can get your hands on the almost complete jQuery 1.4 now and start using it in your projects today. Please note, if you come across any inconsitencies or errors while use the release candidate (or the final release) please head on over to jquery-dev and report the issues your having.

According to the site: "The final release (along with the full changelog) will occur this Thursday, on January 14th, coinciding with jQuery’s 4th birthday.". So we don't have long to wait.

The last piece of good news is that they are giving away free ebooks to any who makes a tax-deductable(please refer to your own countries tax laws, I don't know if this applies outside of the US) donation of US $20 or more. Go to the donation page to make your donation and recieve your bonus eBook. The jQuery Project is a non-profit, open source effort, supported by donations and contributions from developers, supporters and professional organizations. Your contributions help fund the continued rapid development and growth of jQuery and the jQuery community.

The jQuery 1.4 release gaurantees to be a killer, with major speed improvements and new functionality. I'm looking forward to the next 14 days. I also want to say a happy birthday to jQuery and many more to come. And a big thankyou to the developers who have made a tireless effort to get this release out on time.
more...

Put your database under version control

Tuesday, 12 January 2010

View Comments

In this tutorial I want to look at some strategies for including your database as part of your version control strategy.

Over the years that I have been writing web applications the majority of the sites I have worked on include some sort of database back-end. Whether they be large scale web applications or simply a sign-up for a newsletter, the database is an integral part of the system. It may come as a surprise that it has only been in the most recent of applications that I have started including the database as part of our version control strategy.


If you haven't started to include your database as part of your version control I would like to point out some of the benefits realised and convince you of why this should also become your habit and part of your regular release cycle or even if it's a single site, part of your site release / update regime.

Most of you should be are most definitely backing up your database regularly, so I won't be covering that area.

To kick things off I will explain to you how we were previously doing things before our recent changeover to versioning our database. In the not so distant past there were five of us working on different parts of the same app. Each of us were working off of the same database, which meant even if we weren't aware that someone was changing the database, there was a small chance of you finding out incidently that a change was made to the table you were working on (queue scream). We would each work on our separate parts and before Beta release day we would all come together and apply our changes to a clean database that would be used for production once Beta was over. Sounds scary right? It was worse than that; we all kept a text file with aforementioned database changes that could be thousands of lines of stored procedures, triggers and table updates. We did manage to make it work without huge dramas, but it's a terrible way to work.

You can imagine if someone forgot to add their changes or held off adding changes or their changes needed to be reverted. The exact reason that we have version control for all our files, so why the hell not for your database? Your situation may (or may not) be as bad as what is mentioned above but you can see the benefits of including your database as part of your versioning: who changed it, when was it changed, can we roll back to a previous version, what should be included in this release? All of these things were not being answered before and we also couldn't track the most basic problem 'if something had been changed?'. Our CRM has hundreds of tables and stored procedures (not an exaggeration), it is God damn huge, so it's not an easy task to manually verify if something is changed or missing. You can now start to see a big problem requiring an easy solution.

We had discussed the problem several times and could not come up with a suitable solution. We wanted something unobtrusive that would be less trouble than what we already had. With any IT team we are always looking for the solution which requires zero effort, has zero loop-holes in case someone forgets to (or is too damn lazy) to do it and is a complete solution to the problem (partial solution = likely fall back to personal methods = half of us do it this way and half of us do it our own way).

The search for a solution got put onto the shelf (inertia) for some time until I came across a query to generate the CREATE script for any table or stored procedure, after this everything else fell in to place. I'll run you over our steps for keeping our database inside version control:

Components:
* Database table; each row contains the name, type and script to (re)create our stored procedures or tables.
* Stored procedure; empties the above mentioned table and then repopulates with the current state of our database.
* php script; Calls the stored procedure then retrieves all the rows from the table. Loops over each row then stores (or updates) an invdividual file which is a .sql file with the CREATE statement. These files are stored inside /db/stored_procedures or /db/tables folder.

Steps:
* Developer makes a change to a table or stored procedure
* Developer finished making any changes to scripts and any other files that will form part of version control commit
* Developer runs the php script above so that database files stored inside the repository are updated
* Developer commits to version control and writes a lovely message for all to see
* Other developers update their repositories and are aware that changes have been made to the database

All is good, yay! But there is still one small issue, the zero loop-holes, what happens if someone forgets to commit there database changes? This is covered in our release cycle. Whoever is responsible for the release MUST run the php script and if there are any database changes that have not been committed yet then we have a slight problem. This is usually solved by a bit of finger pointing. We also have an agreed rule, if it doesn't belong to anyone and was written by some phantom menace then we just revert back to the previous version (this hasn't happened yet because I work with such lovely people).

Hopefully this gives you a good insight into how you can get your database into version control. It is hard for me to provide working examples as there are so many different combinations of databases and scripting languages. I have provided some links below that I used to get our MSSQL database under version control.

How to generate a CREATE TABLE statement for a given table in SQL server

For your stored procedures you can do something like the following:
protected function export_storedprocs() {
 $sp_dir = $_SERVER['APPL_PHYSICAL_PATH'] . 'dbstored_procs\';

 // Retrieve all SP names
 $strSQL = "SELECT Distinct SO.Name
    FROM sysobjects SO (NOLOCK)
    WHERE SO.Type = 'P'
    ORDER BY SO.Name";
 $sps = $this->fetchrows($strSQL);
 
 foreach ($sps as $sp) {
  $strSQL = "EXEC sp_helptext {$sp['Name']}";
  $splines = $this->fetchrows($strSQL);
  if ($splines) {
   $h = fopen($sp_dir . $sp['Name'] . ".sql", "w");
   foreach ($splines as $line) {
    fwrite($h, $line['Text']);
   }
   fclose($h);
  }
 }
 
 echo "Export complete";
}

Also checkout: worthy reading on the same topic
more...

jQuery Galleriffic gallery with Flickr feed

Friday, 8 January 2010

View Comments

This post looks at how you can combine the great look and functionality of the Galleriffic jQuery photo gallery plugin with Flickr.



Flick has great functionality already for you to share and view your photos, but the one thing that it doesn't provide is custom styling. If you want to combine a particular Flick photo album within a web design or your own blog you can do so relatively easy with the use of Flickr's API and a bit of javascript. Today I will look at grabbing a Flickr feed using JSON and combine that with the fast and fantastic jQuery Galleriffic plugin.

You can view a working example of this here. You can download the code here.

The Galleriffic plugin is well styled out of the box, but can easily be customised and has all the features you would want: pagination, slideshow and nice transition effects. My main interest in this plugin is that it looks classy and works well with very little customisation.

I will do a simple example and you can do the rest to integrate it into you site or design. I'm going to base my example on Galleriffic's own example-2.html. Begin by downloading Gallerific and you will find all the examples in the root directory. Open up example-2.html and let's begin editing.

Start by removing all of the li elements except for the first one from the thumbs div, we will be using the remaining li element to clone later on. It should now look something like this:

<div id="thumbs" class="navigation">
    <ul class="thumbs noscript">
        <li>
            <a class="thumb" name="leaf" href="http://farm4.static.flickr.com/3261/2538183196_8baf9a8015.jpg" title="Title #0">
                <img src="http://farm4.static.flickr.com/3261/2538183196_8baf9a8015_s.jpg" alt="Title #0" />
            </a>
            <div class="caption">
                <div class="download">
                    <a href="http://farm4.static.flickr.com/3261/2538183196_8baf9a8015_b.jpg">Download Original</a>
                </div>
                <div class="image-title">Title #0</div>
                <div class="image-desc">Description</div>
                <div class="image-auth"></div>
            </div>
        </li>
    </ul>
</div>

I also added in the image-auth div so I can give some credit to the authors of the photos used in my example.

Next we are going to change the document ready function. I'm going to show you the whole thing so you know where I'm coming from. Have a scan over it first and then I will explain what's going on. This is located at the bottom of the page just before the closing body tag.

jQuery(document).ready(function($) {
    $.getJSON("http://api.flickr.com/services/feeds/groups_pool.gne?id=32142572@N00&lang=en-us&format=json&jsoncallback=?", function(data){
            $.each(data.items, function(i,item){
                var newthumb = $("ul.thumbs").children("li:first").clone();
                var baseimg = item.media.m;
                
                var thumbimg = baseimg.replace("_m.jpg", "_s.jpg");
                $(newthumb).find("img").attr("src", thumbimg);
                
                var disimg = baseimg.replace("_m.jpg", ".jpg");
                $(newthumb).find(".thumb").attr("href", disimg);
                
                var lgeimg = baseimg.replace("_m.jpg", "_b.jpg");
                $(newthumb).find(".download").children("a").attr("href", lgeimg);
                
                var title = item.title;
                var description = item.description;
                
                var desc = $("<div />").append(description);
                if ($(desc).children().size() == 3) {
                    description = $(desc).children("p:last").html();
                } else {
                    description = "";
                }
                
                $(newthumb).find(".image-title").empty().html(title);
                $(newthumb).find(".image-desc").empty().html(description);
                $(newthumb).find(".image-auth").empty().html(item.author);
                
                $("ul.thumbs").append(newthumb);
            });    
            
            $("ul.thumbs").children("li:first").remove();
            
            // Initially set opacity on thumbs and add
            // additional styling for hover effect on thumbs
            var onMouseOutOpacity = 0.67;
            $('#thumbs ul.thumbs li').opacityrollover({
                mouseOutOpacity:   onMouseOutOpacity,
                mouseOverOpacity:  1.0,
                fadeSpeed:         'fast',
                exemptionSelector: '.selected'
            });
            
            // Initialize Advanced Galleriffic Gallery
            var gallery = $('#thumbs').galleriffic({
                delay:                     2500,
                numThumbs:                 12,
                preloadAhead:              10,
                enableTopPager:            true,
                enableBottomPager:         true,
                maxPagesToShow:            7,
                imageContainerSel:         '#slideshow',
                controlsContainerSel:      '#controls',
                captionContainerSel:       '#caption',
                loadingContainerSel:       '#loading',
                renderSSControls:          true,
                renderNavControls:         true,
                playLinkText:              'Play Slideshow',
                pauseLinkText:             'Pause Slideshow',
                prevLinkText:              '&lsaquo; Previous Photo',
                nextLinkText:              'Next Photo &rsaquo;',
                nextPageLinkText:          'Next &rsaquo;',
                prevPageLinkText:          '&lsaquo; Prev',
                enableHistory:             false,
                autoStart:                 false,
                syncTransitions:           true,
                defaultTransitionDuration: 900,
                onSlideChange:             function(prevIndex, nextIndex) {
                    // 'this' refers to the gallery, which is an extension of $('#thumbs')
                    this.find('ul.thumbs').children()
                        .eq(prevIndex).fadeTo('fast', onMouseOutOpacity).end()
                        .eq(nextIndex).fadeTo('fast', 1.0);
                },
                onPageTransitionOut:       function(callback) {
                    this.fadeTo('fast', 0.0, callback);
                },
                onPageTransitionIn:        function() {
                    this.fadeTo('fast', 1.0);
                }
            });                        
    });

    // We only want these styles applied when javascript is enabled
    $('div.navigation').css({'width' : '300px', 'float' : 'left'});
    $('div.content').css('display', 'block');
});

You will notice that almost everything is now wrapped inside the getJSON call. We need to ensure our pictures are loaded before we call the gallerific function.

The getJSON call is a simple call to the Flickr Feed API. Once you get the hang of what's going on in this tutorial your next step is getting a Flick developer key and using JSON, you can do all sorts of cool things with the Flickr API. For this post I'm just keeping it simple and we will just be using a Group feed.

The main part of the getJSON call is the URL: http://api.flickr.com/services/feeds/groups_pool.gne?id=32142572@N00&lang=en-us&format=json&jsoncallback=?. It calls the groups_pool services feed and simply passes in the group ID. This can be retrieved easily from any group by going to the group's Flickr page and clicking on the RSS link near the bottom left hand corner of the page. The RSS feed will have an URL similar to this: http://api.flickr.com/services/feeds/groups_discuss.gne?id=1239213@N21&lang=en-us&format=rss_200 and you just grab the value of the id variable.

The next thing we do is loop over the results:

$.each(data.items, function(i,item){
    var newthumb = $("ul.thumbs").children("li:first").clone();
    var baseimg = item.media.m;
    
    var thumbimg = baseimg.replace("_m.jpg", "_s.jpg");
    $(newthumb).find("img").attr("src", thumbimg);
    
    var disimg = baseimg.replace("_m.jpg", ".jpg");
    $(newthumb).find(".thumb").attr("href", disimg);
    
    var lgeimg = baseimg.replace("_m.jpg", "_b.jpg");
    $(newthumb).find(".download").children("a").attr("href", lgeimg);
    
    var title = item.title;
    var description = item.description;
    
    var desc = $("<div />").append(description);
    if ($(desc).children().size() == 3) {
        description = $(desc).children("p:last").html();
    } else {
        description = "";
    }
    
    $(newthumb).find(".image-title").empty().html(title);
    $(newthumb).find(".image-desc").empty().html(description);
    $(newthumb).find(".image-auth").empty().html(item.author);
    
    $("ul.thumbs").append(newthumb);
});    

data is returned in our callback function to the getJSON call. We then just loop over the data.items. If you want to look at what the feed looks like you can easily read it by going here and just replacing the Group id.

When we loop over each of the items we begin by cloning our first item in the .thumbs unordered list. We then get the baseimg which is the image source URL passed in from the feed. For each photo you upload to Flickr they have several formats but all have similar URLs so we are going to take advantage of this knowledge and we don't need to manipulate the image we retrieve from Flickr into different sizes e.g.

An image: http://farm4.static.flickr.com/3261/2538183196_8baf9a8015.jpg
Image thumbnail: http://farm4.static.flickr.com/3261/2538183196_8baf9a8015_s.jpg
Big version: http://farm4.static.flickr.com/3261/2538183196_8baf9a8015_b.jpg

You can now see they are almost identical. So we are going to build these three image links from the one retrieved in the feed. Our three images are thumbimg, disimg and lgeimg; our thumbnail, display image and large image. We then use jQuery's selectors to replace these URLs in the cloned li element $(newthumb).

Next we want to get and set the title, description and author. The feed contains a preformated description with it's own thumbnail (who knows why, I guess for convenience). So we check the description HTML to see if it has three sections, if it does then a user description has been entered on Flickr and we grab it, otherwise just leave it blank:

var desc = $("<div />").append(description);
if ($(desc).children().size() == 3) {
    description = $(desc).children("p:last").html();
} else {
    description = "";
}

In the last step we insert the title, description and author and then append our cloned and updated li element:

$(newthumb).find(".image-title").empty().html(title);
$(newthumb).find(".image-desc").empty().html(description);
$(newthumb).find(".image-auth").empty().html(item.author);

$("ul.thumbs").append(newthumb);

Now that all the elements have been looped over and added we have one final thing to do before we proceed to build our gallery, we just need to remove our initial and no longer need first li element:

$("ul.thumbs").children("li:first").remove();

After this is done we just call the gallerific function as per the initial example and then we're all ready to go.

There's one small thing that I changed and that's the variable numThumbs which determines how many thumbs are displayed per page.

One last thing to note is that the Flickr feeds only provide 20 items. If you want to get more from your feeds you will need to get a developer key and use the Flickr API. The public feeds are deliberately restricted to avoid abuse.

Enjoy!
more...