Animate a site’s loading

Note: This article has been marked for a quality review and will soon be updated.

There are a lot of things we can do as web designers to improve the UX of a site, much of the time subtle animations can be added to add a bit of finesse to a page, and a new trend is that of adding animations to the loading of pages to make it look a bit better. So what do I mean by 'loading animations'? I'm not talking about the annoying "feature" of having a site load in a flash and then display a loading spinner while it actually pulls up the content using AJAX; rather adding a tiny amount of code to gain more control over how our site loads. But before we jump in to the code we need to remember a couple of things: first the animations can't take very long, after all we're trying to improve the user experience, so having a site take 5 seconds to load in will just frustrate the user. And second, as we will be using JavaScript for this, we need to add a fallback in case it's turned off.

Here's what we'll be creating (new window).

So to begin I've written up a very simple page, here's the HTML:

<!DOCTYPE HTML>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<title>Animated Loading</title>
	<!--[if IE]>
		<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
	<![endif]-->
	<link rel="stylesheet" href="style.css" type="text/css" />
</head>
<body>
	<div class="wrapper">
		<header>
			<h1 class="left">My Website</h1>
			<nav>
				<ul>
					<li>Home</li>
					<li>More</li>
					<li>About</li>
					<li>Contact</li>
				</ul>
			</nav>
		</header>
		<section class="hidden">
			<h2>Welcome</h2>
			<p>Yay for loading animations!</p>
		</section>
		<footer class="hidden">
			<p>Copyright goes here</p>
		</footer>
	</div>
</body>
</html>

Notice the use of the class "hidden" - that does exactly what you might think, and to make sure it actually works, let's hook up the CSS:

/* Globals */
.wrapper {
	max-width:1200px;
	display: block;
	margin:0 auto;
	padding:0 10px;
}

.hidden {
	display: none;
}

.left { float:left; }
.right { float:right; }

body {
	background: #dfdfdf;
}

/* Header */
header {
	overflow: hidden;
	position: relative;
	top:-145px;
}

h1 {
	background: #222;
	padding:50px;
	font-size: 2.5em;
	line-height: 0.4em;
	color: #fff;
}
		
nav {
	float: right;
}

	nav li {
		padding-top:52px;
		float: left;
		width:91px;
		text-align: center;
		height:90px;
		cursor: pointer;
		margin-right:2px;
		display: none;
	}
	
/* Sections */
section {
	margin-top:2%;
	padding:2%;
	background: #fff;
	overflow: hidden;
}
	
	section h2 {
		font-size: 1.25em;
		font-weight: bold;
	}

/* Footer */
footer {
	text-align: center;
	padding-top:10px;
}

Again, some very basic CSS to ensure it actually looks like a functional website. Notice how elements such as the 'nav li' elements are hidden using CSS (you might want to just add a class in the HTML, but if they are dynamically generated, this is your best bet).

If we open the page now we don't see very much, some would say it was blank, many people actually. This is what users without JavaScript enabled will see. So to remedy that we need to make use of the <noscript> tag in our header. Just before the closing <head> tag, add the following code:

<noscript>
	<style type="text/css">
		header {
			top:0px !important;
		}
		
		section, footer, nav li {
			display: block !important;
		}
	</style>
</noscript>

That code will only be executed if we don't have access to JavaScript, and so will force the elements we worked so hard to hide, to show up. Good stuff, we're not breaking the internet by requiring JavaScript! And on that note, let's write some.

Here's the code I wrote for the example - it's very basic, and executes within 2.45 seconds (but because some animations are in parallel it feels like 1.25 seconds). Make sure you include jQuery on your page, and then whack in the following code:

$(function(){
	/* Loading Animations */
	$('header').animate({'top':0},500, function(){
		$('nav li').each(function(index){
			$(this).slideDown(300*(index+1));
		});
		
		$('section, footer').fadeIn(750).removeClass('hidden');
	});
	

	$('a:link').click(function(){
		$('header').animate({'top':'-185px'},300);
		$('section, footer').fadeOut(300);
	});
});    		 

The first part of the that code waits for the DOM to be fully loaded, and then animates the header to slide in. When the header has finished showing up we cycle through the navigation's list elements, sliding them down at a growing animation length (notice the '+1' to ensure we don't multiply by zero). Once that's done we fade in any other elements we had hidden, and remove the class of 'hidden' - here you could use another each() cycle, but in the interests of speed I just stuck with a simple fade in effect. The next block of code is for links away from the page. We look for any links, and then whenever they are clicked, we quickly animate the contents of the page out in 0.3 seconds - I think this is just a nice touch. With a bit of tweaking of things like timings and the odd animation, you can make a visitor smile before they've even read what's on your site.

And that's how to improve the UX of your websites with subtle loading animations.

Reality check: Why Adobe Muse doesn’t matter.

Recently a number of people in the web community, specifically developers have been complaining about Adobe Muse, a website creation tools for people without coding knowledge. And while I agree that Adobe doesn't know what the community wants, I think the reactions to this tool have been a little too big. Here are my musings (I couldn't resist that badboy).

First up Muse isn't a new concept. In fact there are a billion and one tools to allow people without knowledge of coding to build websites, SquareSpace is just one example. They are not aimed at people who know HTML and CSS, and so people like me don't use them. But the reason these applications are popular isn't because making websites is easy, or because everyone has a web-designer within them, it's because people usually start off with a great template. People who don't have a design background and who then use a service like Muse to build a site without a template, generally end up with a crap website. Does that bother me? Nope, it doesn't impact my trade in a bad way, in fact it's good if anything because I can say to potential clients "look at what this guy did, it doesn't look very good does it? And that' why you should work with me.".

Using a tool like Muse is like buying a microwave meal, it looks the part, it tastes mediocre, and it's full of crap. Although you can create websites with Muse, as developers know, the code it spits out isn't great. This impacts things like SEO, thus making the website harder to find.

Anyone that follows me on Twitter knows that I do sometimes complain about Photoshop. Sure there are some bugs, it's way over-priced, and the company that makes it has lost touch with the creative industry, but to be honest it does the job. I don't expect great things from Adobe, and neither should you. While they are off spending time and effort creating nasty applications like Muse (written in AIR), I'm confident others are looking for an alternative.

So stop complaining about Muse, it wasn't built for you, it doesn't affect you, and although Adobe has changed (despite it once being about the music), it doesn't matter.

10 Best Practises for jQuery Beginners

Note: This article has been marked for a quality review and will soon be updated.

jQuery is the one of the most popular JavaScript frameworks available; it enables developers to write code that is easy to understand but that also allows really powerful functionality. There are a boat-load of tutorials out there on jQuery, and the documentation is awesome, but in this article I'll go over the things that all beginners should know about jQuery.

1) Document.ready

One thing that often catches newbies out is that their code doesn't seem to be having any effect on their page, despite all of it being correct. A major cause of this is that their jQuery code is attempting to access DOM elements before they exist. This can happen because developers place their JavaScript in the <head> of their pages, and so by the time the rest of the page has loaded jQuery doesn't know what's going on. The simple way to solve this issue is by telling jQuery to execute the code only when the DOM has finished loading, like so:

$(document).ready(function(){
	//Code goes here
});

But be warned, there are some circumstances where you shouldn't bother wrapping code in it. For example if you're clued-up about performance and already have all your code at the bottom of your page, it's unnecessary to use it, because all the elements already exist. Other exceptions might include wanting better code reusability - say for instance placing non-jQuery functions outside of the wrapping.

2) Cache elements

A lot of the time people write functions like:

$('.myelement').click(function(){
	$(this).doSomething();
	$(this).doSomethingElse();
	$(this).fadeOut(500);
});

And there isn't anything wrong with that. But if you started doing 10 things to the element once it were clicked it would start to look a little messy. To fix this it's a good idea to put the $(this) selector into a variable, like so:

$('.myelement').click(function(){
	var el = $(this);	
	el.doSomething();
	el.doSomethingElse();
	el.fadeOut(500);
});

This will give you less code to write in the long run, and using descriptive variable names will also help you keep focus on what you are manipulating. But more important than that is the performance increase - asking jQuery to return an element over and over as we did before wastes valuable performance - so caching will speed up your code!

3) Chaining

And the above brings me nicely to my next point - chaining. You can chain jQuery functions, meaning that you don't have to separate all those lovely functions, so the code I just wrote could actually look like:

$('.myelement').click(function(){
	$(this).doSomething().doSomethingElse().fadeOut(500);
});

And by just chaining those functions we have condensed 3 lines of code into 1.

4) AJAX

One reason why a number of developers like jQuery is because it has an excellent syntax for AJAX. In Javascript making AJAX requests is cumbersome and difficult to learn, but in jQuery it's pretty easy. So if you've taken the time to fade in messages to your users using jQuery, why not go ahead and submit forms using AJAX, thus creating a more cohesive user experience.

This is how it's done:

$('.myform').submit(function(){
	var dataString = $(this).serialize();
	
	$.ajax({
		url: 'process.php',
		data: dataString,
		type: 'POST',
		success: function(data){
			//Do something
		}
	});
});

The above code waits for the form with a class of '.myform' to be submitted, and then sends the data in the form via a POST method to 'process.php'. If the whole thing works well the success function is called and accepts some data. You would simply set up process.php to either return an error or simply say 'success', and then act accordingly - perhaps showing a success balloon or error notification.

5) Using delegate()

Most beginners typically start by using syntax such as:

$('.myelement').click(function(){
	//Do something
});

Just as I did above. There isn't anything technically wrong with that code, it's just that it could be better. Newbies will often find them googeling why their click() method doesn't work on dynamically created elements (as could be done using AJAX), and the reason for this is because jQuery binds the event handlers to the elements when the page is loaded. So we have to change the way we write our code to ensure we don't run into any issues.

To do that we can use the handy delegate() method. For example:

$('.myWrapper').delegate('p', 'hover', function(){
	$(this).doSomething();
});

The code above tells jQuery to listen for hover events on paragraph elements within the .wrapper element. The method allows us to add elements without worrying if event handlers will listen out for changes to them, and so it is good practise to use it in production.

6) Using powerful selectors

Complex selectors in jQuery allow us to tailor more specific and targeted interactions on our websites. Say for instance we want to target all paragraphs, except those with a class of 'not-me'. A great way to do this is like so:

$('p:not(.not-me)').click(function(){
	$(this).doSomething();
});

There we used the :not() syntax to exclude elements with a class of '.not-me' - a simple, but very effective way of selecting only the elements we want. Furthermore we may only wish to select the first paragraph on our page, to do that we would use another handy selector:

$('p:first').click(function(){
	$(this).doSomething();
});

There are a bunch of powerful selectors besides just class and ID based ones, you can take a look in the docs over at: http://api.jquery.com/category/selectors/

7) Use callback functions

I often answer questions from people who want to know how they can trigger actions once other actions have finished execution. And the simple answer is by using callbacks. For those new to jQuery the term by be unfamiliar, but you've already witnessed one in the AJAX example above! A callback method is one that is called after the method in question has done it wants to do, in jQuery a lot of functions allow you to pass a callback function of your own; let's take a look at how we'd do this:

$('.myelement').click(function(){
	$(this).fadeOut(500, function(){
		alert('Element faded out!');
	});
});

The code above listens for a click on our elements, fades it out, and then alerts the user about it. The callback function is passed as a separate parameter to our fadeOut() method, and is executed after the element is faded-out.

8 ) Use a context

In the interests of performance let's take a moment to think about how jQuery finds elements. When you say something like:

$('.myelement').click(function(){  });

jQuery searches the entire DOM for it. But what if you only have things with that class within say a div with a class of '.main-content'? If so you can provide a context to jQuery (much like we did with the delegate() method above). Doing this enables jQuery to only search within that context, thus saving on performance. And here's how it would look:

var context = $('.main-content');

$('.myelement', context).click(function(){
	$(this).doSomething();
});

The more specific (and smaller) your context, the faster your code.

9) Pass objects not identifiers

When writing your own functions it might seem like a good idea to do something like:

function myfunction(id){
	$(id).doSomething();
}

myFunction(“.myElement");

But that really isn't very flexible. It's far better to actually pass the object around like so:

function myfunction(el){
	el.doSomething();
}

myFunction($(“.myElement"));

10) Don't depend on jQuery

While the techniques above are good advice for writing solid jQuery, you certainly shouldn't depend on the thing. Never use jQuery as a replacement for CSS - not only is it more inefficient, but you are ignoring users without Javascript turned on, and it's a sure fire way to annoy users.

Force JS replace to work on all occurrences of needle

When manipulating strings in JavaScript a useful method to know about is the replace() method. It take 2 parameters - the needle and the haystack. So if you wanted to replace 'cat' with 'dog' it might look something like this:

var myString = "The cat jumped over the fence";
var myNewString = myString.replace("cat","dog");
document.write(myNewString);

Great it worked. You can also use regular expressions for the needle if you're into that kind of thing - say for instance, if you want to generate a valid URL. It when doing just that, that I realised I had a problem on my hands. My code used 2 replace methods - one for removing special characters, the other to remove spaces. The first was a regular expression, while the second was a basic method searching for a space and replacing it with a dash. My problem was that it was only replacing the first space. And so I had to reach for a regular expression to help me out.

Don't worry if you're not too great with RegEx, this one is really basic, and here's what it looks like:

var myString = "The cat jumped over the fence to meet another cat."
var myNewString = myString.replace(/cat+/g,'dog');
document.write(myNewString);

That bit of code tells the rendering engine that we are using a RegEx with our forward slashes, inside we have the word we are looking to replace, then the plus symbol tells it to match the preceding word (in our case 'cat'), 1 or more times. Then the magic happens - we use the 'g' character to tell it to look for all occurrences.

And that is how you ensure all occurrences of a needle are replaced when using the replace() method. Hopefully this article will save you scratching your head over why a seemingly obviously method won't play ball.

Build an early sign-up mailing list system

Note: This article has been marked for a quality review and will soon be updated.

When you've got a great idea for a product its often hard to resist buying up the domain name for it, but what do you put there? A coming soon logo? A paragraph about what you're making? How about allowing visitors to sign-up to hear updates when the products becomes public? The last point is the most useful because not only does it let you keep track of early interest, it ensures your visitors don't go getting all excited and then forget about the product when it launches a couple of months down the line. So our system will allow users to pop their email address into a form, and will then insert it into a database and send an email to the new subscriber. We'll look at how to build in admin notification, as well as having a system in place that requires users to confirm their email address before they are added to the list. We'll be making a script that we can use on multiple sites with little alteration so if, like me, you have a number of projects awaiting public release you will be able to stick it on all your different servers with relative ease. Let's get started.

First up we will do the simple task of creating our database. Depending on the features you want, you may want to alter the structure a little, but in our case we will build in support for users to enter their name, email, and to have to confirm their subscription. So for that we will need the fields: ID - our primary key, name - if we want to collect the subscriber's name, email, confirmed - if they have verified their email address, site - which mailing list they subscribed to, created - when did they subscribe? So our process should look like this: User Enters Email -> Added to Database & Verification Email Sent -> User Confirms -> Database Updated. So go ahead and add that table to your database, I called my database 'mailing_lists', with my table named 'users'. Here is the SQL to create the table:

CREATE TABLE `users1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(150) NOT NULL,
  `email` varchar(200) NOT NULL,
  `confirmed` tinyint(4) NOT NULL DEFAULT '0',
  `site` varchar(150) NOT NULL,
  `created` varchar(10) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;

Now we'll build the main PHP script list.php that will handle all the heavy lifting. To begin we'll define some important variables, and create a connection to our database, here's what that looks like:

define(REQUIRES_NAME, false);
define(NOTIFY_OWNER, true);
define(OWNER_EMAIL, 'YOUR EMAIL HERE');
define(SITE_NAME, 'SITE NAME HERE');

define(DB_USER, "USERNAME");
define(DB_PASS, "PASSWORD");
define(DB_HOST, "DB HOST");
define(DB_NAME, "DB NAME");

$db = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);

We're using MySQLi for a speed increase and to allow us to use Object Orientated Programming. Now we will create the function that will allow us to insert new subscribers to the database, we'll call it addToList().

function addToList($email, $name = ''){
	if($name=='' && REQUIRES_NAME){
		// Name required and not provided
		echo 'Invalid name';
	}else {
		$email = strtolower($email);
		global $db;
		
		$cur = $db->query("SELECT * FROM users WHERE email = '".$email."' && site = '".SITE_NAME."'");

		if($cur->num_rows > 0){
			echo 'Duplicate entry detected';
			return false;
		}else {
			$db->query("INSERT INTO users(name, email, confirmed, site, created) VALUES('$name', '$email', 0,'".SITE_NAME."', '".time()."')") or die('Error inserting into database');
			return true;
		}		
	}
}

Let's see what that function does. First up we check if we should be collecting the user's name, if we are and it isn't there, we stop the script and send out a warning. Otherwise we set up the $email variable and make sure we have access to our $db variable. The next part makes queries the database to make sure the user hasn't already subscribed to the list, if they have we tell them that a duplicate entry was detected, and if not we insert their data into our table. Great stuff, we've done the main part of our script. But if we want the user to be able to confirm their email address, and even send an email to the admin, we'll need to write a few more functions. And to make sure we don't go writing duplicate code, we will create our own function for sending mail that will in turn call PHP's mail() function. Here's what it looks like:

function list_mail($to, $subject, $message){
	if(!empty($to) && !empty($subject) && !empty($message)){
		$headers  = 'MIME-Version: 1.0' . "\r\n";
		$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";	
		$headers .= 'From: noreply@'. SITE_NAME . "\r\n";		

		mail($to, $subject, $message, $headers);
	}else {
		echo 'Bad parameters passed to list_mail()';
	}
}

It's a pretty basic function that checks that the parameters of $to, $subject, and $message aren't empty, and then sends a HTML email if everything checks out. Otherwise we echo out a handy error.

The next two functions we will write are the two that handle the content of the emails sent to our users and our admin, so you'll need to alter them accordingly.

function sendConfrimMail($email, $name = ''){
	$subject = 'Subscription Confirmation';
	$message = '<html>
			<head><title>Subscription Confirmation</title></head>
			<body>
				<center><p style="margin-top:20px;">You have successfully subscribed to updates from '.SITE_NAME.', thank you for signing up to be the first to receive information about our exciting new project, we look forward to providing you with something amazing in the near future.

<p>But before you can receive updates you need to confirm your subscription by visiting: http://'.SITE_NAME.'/confirm.php?e='.$email.'&t='.md5($email.SITE_NAME).'</p> <p>-The Management</p></center> </body> </html>'; list_mail($email, $subject, $message); } function notifyOwner(){ global $db; $subCount = $db->query("SELECT COUNT(*) FROM users WHERE site = '".SITE_NAME."'"); $subCount = $subCount->fetch_array(); $subCount = $subCount[0]; $subject = 'New '.SITE_NAME.' Subscription!'; $message = '<html> <head><title>New '.SITE_NAME.' Subscription!</title></head> <body> <center><p style="margin-top:20px;">A new subscription has just been submitted to the site! We currently have '.$subCount.' subscribers!</p> <p>Let\'s make em happy!</p></center> </body> </html>'; list_mail(OWNER_EMAIL, $subject, $message); }

Now those functions both do essentially the same thing, they just send messages to different people. And as a handy addition the notifyOwner() function also includes the subscriber count in the message. Feel free to go made coding up a beautiful HTML email and playing around with the content at this point.

You should notice that in the confirmation email we included a link that links to the site name we provided /confirm.php, and passes the variables 'e' and 't' (not the friendly alien) along with it. The 't' variable is the encrypted version of the user's email, plus our site name as a salt. This is something we can easily replicate when we build confirm.php a little later.

So where are we at? Well we have a bunch of great functions that we can port to different sites with relatively little hassle, but, as the more astute among you may have noticed, none of them are ever called! So we're going to have to write 10 more lines of code to make it happen! And it just so happens I've already done that :).

if(filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)){
	if(addToList($_POST['email'], $_POST['name'])){
		sendConfrimMail($_POST['email'], $_POST['name']);
		if(NOTIFY_OWNER){
			notifyOwner();
		}
		echo 'Success';
	}
}else {
	echo 'Invalid email address';
}

So this code first validates the email address passed to us using the filter_var() function that works it's magic by using a complex regular expression for validation - this saves us having to write one ourselves. Next we call our addToList() function from within an if statement. This ensures that the following code only executes if all goes well, and because the function also handles the error output we don't need a matching else for that statement. If all does go well, we then send the confirmation email to our user, check if we need to notify the list's owner/admin, and then echo 'Success'. Otherwise we tell the world that the email provided wasn't valid. Excellent. Now we only have 2 more parts to add; that's the form itself, with which we will use some jQuery to handle our error, and the confirmation page. So let's start with the server-side.

Here is the code for confirm.php:

if(!empty($_GET['e']) && !empty($_GET['t'])){
	define(SITE_NAME, 'SITE NAME');
	
	define(DB_USER, "USERNAME");
	define(DB_PASS, "PASSWORD");
	define(DB_HOST, "DB HOST");
	define(DB_NAME, "DB NAME");
	
	$db = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);

	$email = $db->real_escape_string($_GET['e']);

	$result = $db->query("SELECT * FROM users WHERE email = '$email' AND site = '".SITE_NAME."'");
	
	if($row = $result->num_rows > 0){
		if($row['confirmed']=='0'){
			if($_GET['t']==md5($_GET['e'].SITE_NAME)){
				$db->query("UPDATE users SET confirmed = 1 WHERE email = '$email' AND site = '".SITE_NAME."'");
				echo 'Subscription confirmed!';
			}else {
				echo 'Invalid Token!';
			}
		}else {
			echo 'Email already confirmed!';
		}
	}else {
		echo 'No record found.';
	}

}else {
	echo 'Invalid URL!';
}

So here we check to make sure we have both the user's email, and their confirmation token, and then connect to our database. We then create a variable called $email - a sanitised version of the email addressed passed to us in the URL. However we still use the one provided to us later - this is because a user might have a special character in their email address, and may not be a hacker, so if our function returns something slightly different it will alter the confirmation token. We then make sure that the record exists, and that it hasn't yet been confirmed. If it hasn't we test the confirmation token and update the database. Notice the 5 echo statements to keep the user updated about what's going on. And that's it for PHP for today. Let's build our snazzy form.

Now our script expects only the email address of any subscriber, but we can optionally also pass it the name of a new subscriber. In this case we'll just pass the email address to keep it simple, but if you wanted to include the name you would add another input named 'name'.

<form action="list.php" method="post">
	<span class="status">Enter your email address below to hear updates.
<input type="text" name="email" placeholder="Email address..." /> <input type="submit" value="Subscribe to Updates" /> </form>

And we'll add some jQuery to submit the form using AJAX, and to handle the errors accordingly.

$(function(){ 
	$('form').submit(function(){
		$.ajax({
			url: 'list.php',
			type: 'POST',
			data: 'email='+$('input[name=email]').val(), //Add name here if you want it
			success: function(data){
				if(data=='Success'){
					$('form input').fadeOut(500, function(){
						$('.status').text('Email submitted! Please check your email to confirm your subscription.').css('font-weight','bold');
					});
				}else if(data=='Invalid email address') {
					$('.status').text('Please ensure you have entered a valid email address!').css('font-weight','bold');
				}else if(data=='Duplicate entry detected'){
					$('.status').text('Duplicate entry detected! You have already signed up.').css('font-weight','bold');
				}else {
					$('.status').text('Error processing data, please try again in a moment.').css('font-weight','bold');
				}
			}
		});
		return false;
	});
});

The code above is some simple jQuery to submit the form to list.php, and to handle what it returns. If the script outputs 'Success' it's all good, and we can tell the user just that. We then process the rest of the errors that we cater for in our script, and humanise the data accordingly, and if the error is anything else - possibly to do with the server being busy, we just put out a standard error message.

And that is how to build an early sign up mailing list!

Download the source here.

Spice up your Hyperlinks!

Now the words 'hyperlink' and 'sexy' rarely frequent the same sentence in my household, but something which appears to have come into fashion lately (namely I'm using it ;)) is the fading in of the hover state on hyperlinks. So instead of simply specifying the :hover state in your CSS, you use JavaScript or CSS3 to spice up the whole hovering thing. Here's what we will be creating, now lets see how we might go about doing it.

First off let's take a look at the CSS3 way - apparently all the cool kids are using it. If we had a link which we wanted to 'sexify' we might do something like:

.spice {
	color:blue;	
	transition: all .2s linear;
        -o-transition: all .2s linear;
        -moz-transition: all .2s linear;
        -webkit-transition: all .2s linear;
}

	.spice:hover {
		color: red;
	}

Bam! Right there we have one sexy hyperlink using only one CSS3 transition. So when we hover over a link with the class of 'spice' we should see it fade to a lovely bright red, and then upon mousing out, back to that delicious blue. But what happens if (God forbid) a user visits in IE8 or something?! We have support for Opera, Firefox, Chrome and Safari, but not IE. Well surprise surprise we need to have a fall-back for older browsers. And for that, we will be using jQuery (other JavaScript frameworks are available).

Before we continue I should add that I would always suggest using the CSS3 way over the jQuery method, but in any case this is how we do it:

$(function(){
	var color = '';
	
	$('.spice-jq').hover(function(){
		color = $(this).css('color');
		$(this).animate({'color':'red'},200);
	}, function(){
		$(this).animate({'color':color},200);
	})
});    		

Above we first wait for the DOM to be finished loading, and then create ourselves a variable called 'color' to hold the value of the link's colour in it's normal state (if all your links are the same colour, you can just replace every occurrence of 'color' with whatever colour you want). We then animate the colour of the link back and fourth using the hover() function. But before you wonder why the code above doesn't work on your site, I should add that for colour animations, the jQuery Color Plugin is required - so go ahead and include that in your page before the above script.

So now we could using something like Modernizr to detect if the user's browser has CSS3 transitions support, and if not, whack the above jQuery code onto our page. And with that, you should now have a set of beautiful links on your site that make it that little bit slicker.

Building a Confirmation Dialog in JavaScript

Note: This article has been marked for a quality review and will soon be updated.

A common feature of desktop applications is that when a user prompts a potentially destructive action, the program will display a confirmation dialog to ensure that the user doesn't go and do something silly. To do this we will use some basic JavaScript. In this tutorial I will be using jQuery to display and manipulate our elements, but this technique uses good old' JavaScript to get the job done. So let's get started. Click here to see the finished product.

Thee are a few ways to do this, namely we could create a global variable and wait for it to be changed by our dialog function and then proceed; or we could have our function return either true or false based on the user input, and then carry on. However the method we will be using will be to mole net a function that accepts a callback function as one of its parameters. If the user confirms the action the callback function will be called, and of not we will simply hide our dialog and do nothing. So with that in mind, lets create the HTML for our dialog. Here's what I've got:

<span class="lightswitch" style="display:none">
<div class="confirm" style="display:none">
	<div class="wrapper">
		<h3>Are you sure?
		<p>This will clear all the changes you have made.

<button class="left" id="confirm-continue">Continue <button class="right" id="confirm-cancel">Cancel </div> </div>

So we have 2 elements to worry about here - the .lightswitch span, and our .confirm div. The light-switch code will be used to dim the rest of the screen while the dialog is open to ensure focus is directed to whatever we want to put on our pop-up. All that's left is to style our dialog - feel free to go mad with your CSS at this point, but this is what I ended up with:

.right { float:right; }
.left { float: left; }

.confirm {
	display: block;
	width:350px;
	left:50%;
	top:50%;
	margin-top:-100px;
	margin-left:-175px;
	z-index: 1500;
	overflow: hidden;
	cursor: default;
	position: fixed;
	background: #fff;
	border-radius: 5px;
	-moz-border-radius: 5px;
	-webkit-border-radius: 5px;
}

	.confirm .wrapper {
		padding-bottom:10px;
		overflow: hidden;
		font-family: sans-serif;
		color: #000;
	}

	.confirm span {
		width: 90%;
		margin:0 5%;
		display: block;
	}
	
	.confirm h3 {
		background: #212121;
		font-size: 22px;
		color: #fff;
		width:91%;
		padding:2% 5%;
		margin:0;
		border-radius: 4px 4px 0 0;
		-moz-border-radius: 4px 4px 0 0;
		-webkit-border-radius: 4px 4px 0 0;
	}
	
	.confirm button {
		border:none;
		border-radius: 5px;
		-moz-border-radius: 5px;
		-webkit-border-radius: 5px;
		color: #fff;
		background: #212121;
		padding:5px 10px;
		font-size: 15px;
	}

.lightswitch {
	display: block;
	background: rgba(0,0,0,0.75);
	z-index:1000;
	width:100%;
	height:100%;
	position: absolute;
	top:0;
	left:0;
	position: fixed;
	overflow: hidden;
}

The CSS above gives us a centred box with a dimmed background overlaid on top of the rest of the page. The rest of it is just basic styling that you'll want to change to fit with your own UI.

And now to the JavaScript! Here's how it looks:

function confirmIt(title,text,callback){
	$('body').append('');
	$('.lightswitch').fadeIn(300, function(){
		$('.confirm').fadeIn(100);
	});
	
	$('#confirm-continue').click(callback);
	$('#confirm-cancel').click(function(){ $('h1 span').text('Action Cancelled'); })
	
	$('.confirm button').click(function(){
		$('.confirm').fadeOut(500, function(){
			$('.lightswitch').fadeOut(200, function(){
				$('.confirm, .lightswitch').remove();
			});
		})
	});
}			

Let's go through what it does. On the first line we can see the 3 parameters we pass to the function for the title, text, and callback function for our dialog. If the user confirms the action they initiated the callback function will be called, and if not, the action will be cancelled. The function beings by appending the HTML we wrote earlier to the end of our page and then fades-in our .lightswitch to dim the background; and when that completes it fades in the actual confirmation dialog. That's the first part sorted.

We then have to set up some event handlers - for when the user clicks "Continue" and when they click "Cancel". For our continue button we can simply use the function passed to us to confirm the action was intended. We could leave our cancel button without an event handler, but in our case we will change the content of our main heading to reflect the user's choice. But neither of those lines actually get rid of our dialog, so even if the user confirmed/canceled the action our box would still be visible. So to remove it from the screen we will bind a function to the click events of both buttons. In that function we simply reverse the fading-in of the elements, and then remove them from the DOM to ensure we don't go having multiple elements with the same IDs in the future.

And with that we are finished! We now have a good system in place to ensure our users don't accidentally delete or perform some other destructive action on their data.

An introduction to OOP

Note: This article has been marked for a quality review and will soon be updated.

Object-orientated programming is a concept that is more likely to pop up when programming desktop applications rather than those for the web. But once you start using OOP you will wonder why you ever used procedural programming (that's simply using a program that calls a load of functions/procedures), well maybe not completely - OOP has its place on the web, and in this tutorial we will explore a practical usage of the common programming-paradigm. So what is it? Put simply OOP is when programmers create objects in which they can store data, and ask those objects to do certain things. So for an example, we might have a person object for which we can set things like eye colour and height - these values would be stored in variables. We might also have some instructions that we can give to our person object* like "star jump!", our person would then do a star jump, in our case it might be more like writing something to the screen like "I just did a star jump!".

So how do we know what variables and instructions we have for any give object? Put simply, with our class. A class is a file which contains all the information about any objects that will be created. The most common analogy for a class is a blue-print - it's a good one, because our class contains all the information we need to know about anything we make using it. Just as a blueprint for a house tells us the dimensions of the thing, it also shows us how the doors open and where the water comes in. When we actually make our house in the real world we build it, in the world of computers we instantiate it. When we've finished building in the real world we say we have a house, in programming we call it an instance of the house class.

Deep breaths people! Let's move onto the why we might want to program like this.

OOP really re-enforces a number of good programming techniques, and the 4 principles of the paradigm are as follows: A PIE. No, not the tasty treat, but another acronym! Now if your background isn't in programming the next 4 words might fly over your head - but for the moment I need you to grab a net and get ready to catch them. A PIE stands for Abstraction, Polymorphism, Inheritance, and Encapsulation. Now if you've done any programming on the web or otherwise it's likely you've done at least 2 of the above things. So let's go through them one at a time.

Abstraction

This refers to the technique of taking a problem and focusing on the 'abstract' rather than the individual. Take a look at this function:

function addMyNumbers($a, $b){
    return $a + $b;
}

Above is a very basic example of abstraction at work. Instead of writing 4 + 7 directly into our code, we have written a function that adapts to return a value based on what we pass to it. Therefore we have abstracted that concept. In OOP we use abstraction to make classes. For instance, in our person class we might have an instance method of runOneMileThatWay() - a method that does exactly what the name suggests. But the problem with such a method is that it is very specific. If we wanted our person object to run 5 miles instead of 1 (they are very fit by the way), we would either have to write a new method, or call the same method 5 times. The solution to this is to copy our add method above, and pass a value which tells our instance to run $x amount of times. This makes our program more efficient and easier to maintain.

Polymorphism

If any of these words is going to trip you up, this is gonna be the one. Bear with me here. Polymorphism is the term used to describe the idea that variables, objects, and functions can have more than one form. We don't need to go too deep into why this is important, but let's take a look at an example where polymorphism comes into play.

$x = (int) 4;
$y = (float) 5.76532;

echo $x + $y;

Perfectly legal right? We've declared 2 variables - one integer, and one floating point number, and then added them together. Run this code and you get a number just below 10. But technically this shouldn't work. Integers and floats are stored using different methods, but thanks to polymorphism PHP knew to simply add the two together as we humans would, instead of complaining about the distinction between integers and floats. And that's all you really need to know about polymorphism for now.

Inheritance

Nice and simple - your mum has blue eyes, so you have blue eyes right? Well human genetics is a little more complex than what we're going to be doing, but you get the idea - you inherit (or get) your traits from your parents and general ancestry. In OOP our objects can also inherit things like methods from their super classes. In certain languages you must always tell the world (or rather compiler) what class you are inheriting from. For example in Objective-C - the language used on iOS, the most common class to inherit from is called NSObject. As I said before you can inherit methods which ensures you don't repeat yourself, and can easily maintain your code. NSObject contains really useful methods such as 'description' which can do all kinds of things.

In our example we might have methods such as 'wake up' and 'sleep', but these behaviours are not limited to humans, all living things do this (I should think), so maybe we could create a class called 'Animal'. In the animal class we could have methods such as wakeUp and fallAsleep, and then we could sub class it and make our person class inherit from it. Lets see the PHP way of doing just that.

Class Animal {
	private $awake = false;

	public function wakeUp(){
		$this->awake = true;
	}
	
	public function fallAsleep(){
		$this->awake = false;
	}
}

Class Person Extends Animal {
	public $name;
	
	public function starJump(){
		echo $this->name . ' did a star jump!';
	}
}

$me = new Person();

$me->wakeUp();
$me->name = 'Tom';
$me->starJump();

Don't worry about the syntax too much if you're not familiar with it; but here we can see that we have 2 classes. Our first is 'Animal' which has the methods we said we'd create, and the second is 'Person' which allows us to do a star jump - I've never seen a monkey do one of those, so I think we're safe to keep that within our own species for now. We then create a new object based on the person class, and immediately call the 'wakeUp' function - but this doesn't exist in our Person class, so what's going on?! Well because we used the keyword 'Extends' - (syntax varies from language to language) our $me object has access to all the methods implemented in our Animal class. And that's inheritance.

Encapsulation

Last but not least is this badboy. The term is means when we take the data (instance variables/ivars) and instructions (methods), and put it all within a class. When we do this we make our objects self-sufficient. Think about it like so. Without encapsulation our person class might have to be operated on by another function outside of our class to, say for instance, make a curry. So it might send a bunch of messages (that's just calling the methods of a class), to our object, and fiddle around with our public instance variables. That way of doing things will get the job done. But, and it's a big but, it ain't good practise!

If you were working on a project where your people objects had to be able to make a curry (maybe it's a restaurant game), and you wrote your curry method outside of your person class it would work. But then what happens if you start a new project, and the people objects in that scenario need the curry shizzle?! Bad things start to happen, that what happens. So let it be known, objects should know what they are doing without needing help (anything beyond variable data), from the rest of your program. Maybe you decide not all people should need to know how to make a curry (plain craziness quite frankly), it would be a better idea to sub-class the Person object to something like a 'Chef' class - using your handy friend inheritance .

And with that we have finished with the main concepts of OOP. As you can see above, most of the A PIE concepts work together to create a beautiful paradigm (to a programmer at least), and one that will ensure you consistently write good quality code. Although this has been written from the perspective of web development, should you ever wish to move into complied programming languages such as Objective-C for iOS, you will find that they are heavily class based, so you've learnt something that should serve you well in the future - well done you!

* I am by no means suggesting that you objectify men or women.

Protect your assets with expiring URLs

Note: This article has been marked for a quality review and will soon be updated.

A problem that many web developers face is how to protect their assets. Specifically ones that users are supposed to pay for - say a video training site for instance, you don't want every Tom, Dick and Harry being able to guess the URL, or worse crack open the source code to find an unprotected URL. IF this happens companies can lose a lot of money, so it's kind of an important subject. The more astute of you out there (or those that read the title), might have already guessed that today we will be building a system that will allow us to force expiring URLs. Head over to the example to see what we'll be creating here.

To do this we won't be naming our files anything too funky, nor will we leave polite messages in our source; instead we will create a media-serving script that will make sure the request isn't coming from an unscrupulous source. For that we will need to get time on our side, and generate unique hash-keys that will allow us to verify the request. On a side note you could have a system which connected to a database to see if a hash existed, and if it wasn't expired, but for this tutorial, we will stick with using good ol' time. We'll only request our protected files from our script, and send 2 parameters to make sure we get what we want, they will be our file path, and our token in hash form. We will also use some nifty htaccess trickery to ensure users don't just copy and past the file path from our URL to their browser window - because that would just invalidate what we are about to do. Let's get started!

To begin we will create our media serving script, so go ahead and create a new file called asset.php - this script will decide if the request is genuine and if so will serve up our media. Here is the code for that file:

$t = $_GET['t'];
$url = $_GET['url'];

if(!empty($t) && !empty($url)){
	if($t==md5(date('his').'my_amazing_salt')){
		$image = imagecreatefromjpeg($url);
		header('Content-Type: image/jpeg');
		imagejpeg($image);	
	}else {
		echo 'Invalid URL!';
	}
}else {
	echo 'Invalid URL!';
}

Now the code above works under the pretence that we are only serving jpegs - if you wanted to only serve something like pngs for instance, you would just need to alter the content type, and fiddle with the loading of the actual file. So what does it actually do? Well at the top we make sure the variables passed to the script in the URL aren't empty, and then go on to validate them. The token system we're using here is one that generates a hash-key based on the current time, along with our own 'my_amazing_salt' string (just to make things even more secure) - which is then encrypted using the handy md5() function. We then load in the image, set the header (so it displays as an image and not a bunch of random characters), and serve up our media. If any of the checks fail along the way we just output a little message to our users.

If you want to have links that expire after an minute for example, you would simply alter the parameter passed to the date() function to something like "hi" for hour and minutes - check out the date function for more info.

Great, we've done the hard part, now we just need to replace any image URLs on our site with ones that point to our script that we just made. We can generate the URLs like so:

$url = 'asset.php?url=food.jpg&t='.md5(date('his').'my_amazing_salt'); 

And just alter the 'url' parameter where appropriate. I would recommend picking a totally random salt to add to the end of your encryption just so others won't have a clue what it is.

Ok, so now we have a working system whereby we can request our media from one file, and if that URL is visited by the user after the page load, they will be shown the door. But we still have one problem. Users will still be able to access our files using the path we pass to our script - they could just copy and paste it into their browser, and hey presto they've gotten what they wanted. So how do we fix this? Well the best way is using some htaccess magic to prevent direct loading of our media files.

Whack the following line of code into your htaccess file (if it doesn't exist, create one in your media directory):

RewriteEngine On
RewriteRule ^(.*).jpg$ asset.php?src=$1 [L]

That rule above simply sends all requests for images with the extension 'jpg' to the script we just created; and as we know, because the redirect will go to a URL without a token, it will invariably be rejected. At this point you might want to alter the code above to reflect whatever kind of media you are trying to protect.

And that's how to protect your assets! This method is useful when you want to conserve bandwidth and stop users from simply grabbing a load of subscription/payment-based files from your server.

Update

Is would seem the kids these days are into also protecting these moving-picture thingy-ma-jigs, so I thought I'd update this post to encompass protecting videos. Depending on what video format you wish to use, some of the code below will need changing, but I'll highlight that when we get there.

The code is nearly identical to what we used for images, with a couple of alterations, so here's the code you put in your .htaccess file:

RewriteEngine On

RewriteRule ^(.*).m4v$ asset.php?src=$1 [L]

Notice the ".m4v" extension - this is something you'll have to alter if you're using another format.

Then our PHP file changes to:

$t = $_GET['t'];
$url = $_GET['url'];

if(!empty($t) && !empty($url)){
	if($t==md5(date('his').'my_amazing_salt')){
		$filename = $_GET['url'];
		$fsize = filesize($filename);
		header('Content-Disposition: filename='.$url);
		header('Content-Type: video/quicktime');
		header('Content-Length: '.(string)$fsize);
		readfile($filename);
	}else {
		echo 'Invalid URL';
	}
}else {
	echo 'Invalid URL';
}
	

Again, notice the file extension here and alter accordingly. To include the video on your page you can do all manner of things, for instance you might want to use a flash player or the swanky <video> tag. In the video example I've used an iFrame.

And that's how to protect videos!

Search a UITableView

Note: This article has been marked for a quality review and will soon be updated.

As with most things there are a bunch of tutorials on the internet about how to search a UITableView, but when I was attempting to implement my search I hit a brick wall with it and ended back where I started - Apple's developer docs - the code from which will be used in this here tutorial. I trawled through many tutorials and cannibalised a load of code, but finally I tamed the beast and got myself a lovely search bar. So this post is as much a form of catharsis for me, as it is a tutorial for you 🙂 Let's get started.

To begin we need to think about what we need for this - we want a search bar, we need a search button, we may even need some scope titles to allow us to filter our results. Something which might not be too obvious to begin with is the fact that we also need to think about the UITableView in which to load our results. When we've finished loading this UITableView, it will display it to the user to scroll through. In terms of variables we also need to consider the fact that we will need a duplicate of our main data - be it an array or dictionary, so that we can store our search results. Lastly we need to store the search term and selected scope so that if our users switch to another view we can retain that information. All of this code is available from Apple, but I'll show you it here in a real world implementation - they use their own "Product" class, but I'll show you how to accomplish search with an NSDictionary and NSArray. Now at this point you may be wondering what you've let yourself in for, after all I've just gone through a rather long list of UI elements that are required to search our table, but luckily for us Apple provides a UISearchDisplayController class, which handles the UI, and expects only the back-end implementation to be written by us. So I'm going to create a new view-based project and get started.

My data structure will be as follows: I will have an NSArray populated with NSDictionary objects holding all my data, I will then populate my table-view with that data, and implement the search functionality based on that structure. If you want to use some other type of object, just replace all mention of NSArray etc. You should also note that Apple's implementation places code inside a view controller based on the UITableView class, not the UIView class - this will affect what variables we need, and what we need to hook up in IB. In this tutorial we will put a UITableView within a UIView.

Go ahead and add a UITableView, and then add a "Search Bar and Search Display Controller" to your UITableView, and link up the dataSource and delegate parts, making sure to implement their relevant protocols - you know how to set up a UITableView right? That handy object, as you might be able to tell, handles our search bar, and the controller for our search. We don't need to link to these expressly in our code by creating variables and properties, but we will need to implement a couple of protocols - namely the UISearchDisplayDelegate, UISearchBarDelegate ones. The search controller that we added in IB automatically sets it's delegate, so there's no need to hook that up manually. So now let's set up our variables. I'm putting these in my .h file:

NSArray*listItems;
NSMutableArray *filteredListItems;
NSString *savedSearchTerm;
NSInteger savedScopeButtonIndex;
BOOL SearchWasActive;
IBOutlet UITableView tableView; // Be sure to hook this up in IB

The role of some of these variables will soon become clear. Don't forget to link the tableView variable up in IB before continuing. Then to finish up in the .h file we need to add our properties like so:

@property (nonatomic, retain) NSArray *listItems;
@property (nonatomic, retain) NSMutableArray *filteredListItems;

@property (nonatomic, copy) NSString *savedSearchTerm;
@property (nonatomic) NSInteger savedScopeButtonIndex;
@property (nonatomic) BOOL searchWasActive;

Notice the mutability of our filtered content array - this is very important as we will be changing the content of this data store each time the user performs a search. If you want to use a dictionary at this point, you know what to do. And with that we can wave goodbye to our header, and welcome our implementation. Once you've synthesised your variables, we need to look at the methods required by the protocols we promised to implement.

The first two we will write are fairly simple, they will be called when a search is performed:

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
    [self filterContentForSearchText:searchString scope:
			[[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:[self.searchDisplayController.searchBar selectedScopeButtonIndex]]];

    return YES;
}


- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption {
    [self filterContentForSearchText:[self.searchDisplayController.searchBar text] scope:
			[[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:searchOption]];
    return YES;
}

Those two bad-boys each call another function, and then exit while returning "YES". When a user types something in the search field the first function is called, it then passes what it knows to the function filterContentForSearchText:scope:. The second is called whenever the user selects a different scope, and does the same as the first. Great stuff, we only have 1 more function to implement our search and a few lines to put elsewhere a little later on. And this is the part that caught me out to begin with. For some reason Apple neglected to provided simple code concerned with searching something like an array, and instead they provide a separate class - maybe that's more common where they come from, but round these parts I'm rather partial to the ol' NSArray and NSDictionary. So I changed certain parts of the following code to allow the use of said objects in our table. Just so you know my dictionaries that are stored in my listItems array have the keys "title" and "type". This is what I got:

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{	
	[filteredListItems removeAllObjects]; // Clear the filtered array.

	for (NSDictionary *item in listItems)
	{
		if ([scope isEqualToString:@"All"] || [[item objectForKey:@"type"]  isEqualToString:scope]  || scope == nil)
		{
			NSComparisonResult result = [[item objectForKey:@"title"] compare:searchText options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) range:NSMakeRange(0, [searchText length])];
            if (result == NSOrderedSame)
			{
				[filteredListItems addObject:item];
            }
		}
	}
}

This function first clears the filtered array, and then uses fast enumeration to search through our main array for matches. If you don't know what fast enumeration is, in short it is a more efficient way of iterating of collections of data. Inside our loop we compare the scope to "All", and if we have a match we use some nifty functions to see if our search term matches what we have in our array. Notice the if statement also features two other parts - the second compares our "type" key - so maybe dinner or snack, to the scope buttons, and the last checks to see if the scope is nil - meaning we haven't set any buttons for our scope. So if we select the "Snack" scope button it will only compare items with a type set to "Snack".

This next bit of code is for your viewDidLoad method.

// create a filtered list that will contain products for the search results table.
//filteredListItems = [NSMutableArray arrayWithCapacity:[listItems count]];
filteredListItems = [[NSMutableArray alloc] initWithCapacity:[listItems count]];

// restore search settings if they were saved in didReceiveMemoryWarning.
if (self.savedSearchTerm){
    [self.searchDisplayController setActive:self.searchWasActive];
    [self.searchDisplayController.searchBar setSelectedScopeButtonIndex:self.savedScopeButtonIndex];
    [self.searchDisplayController.searchBar setText:savedSearchTerm];
                
    self.savedSearchTerm = nil;
}

[self.tableView reloadData];

Here we simply restore any data that we have retained if our user dismissed the current view, and then reload our table to reflect any changes. Now we need to update our viewDidDisappear to make sure we actually save the data we are using in the above function, so go ahead and add the following lines to your viewDidDisappear method:

self.searchWasActive = [self.searchDisplayController isActive];
self.savedSearchTerm = [self.searchDisplayController.searchBar text];
self.savedScopeButtonIndex = [self.searchDisplayController.searchBar selectedScopeButtonIndex];

And add this to your viewDidUnload method:

 self.filteredListItems = nil;

Now we need to think about our already-implemented UITableView methods - no you're not going mad, I've not written them here, but we need to change them up a bit. At the moment they all return data based on our main list called "listItems", this is okay if we need to display our table to users, but when in search mode, our functions will be returning the unfiltered data - let's get a fixin'.

The easy way to do this is to set up an if statement to detect if we are in search mode, and then return different data based on that information, that if statement looks like:

if (tableView == self.searchDisplayController.searchResultsTableView){
    // Search mode
}else {
    // Normal mode
}

So go ahead and add this to all your protocol methods; as an example your method for returning the number of rows in a section would look like:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (tableView == self.searchDisplayController.searchResultsTableView){
        return [self.filteredListItems count];
    }
    else{
        return [self.listItems count];
    }
}

Now we are ready to run it! Go ahead and hit run, and type something in the search bar, you should see a filtered list appear as you type. Now you may be getting a warning or two if you used the variable name "tableView", about the method parameters hiding your instance variables, in this case it's not a big deal, but it might be a good idea to change the name to something a little more descriptive in the future.

So what if we want to implement some scope buttons? Well now we've done all the work behind the scenes, we can jump into IB, and add some titles. So go to IB and select your search-bar. In the attributes inspector you should see a box that says "Scope titles", just above that is a check box that says "Shows Scope Bar" - check that, and use the +/- controls to add titles. Then if you want your scope bar to be visible all the time leave the check box checked, but if you want it to only appear when the search becomes active, uncheck the box. Now when you run the program you should see that a scope bar has appeared!

And with that, we have successfully added search to our app. If you have any issues with this code do let me know, and if you want the completed project use the link below.

Completed XCode 4 Project