Pass data from modal view back to parent in the iOS SDK

I recently came across a problem using the newest version of XCode (4.4), in which we can use the fantastic Storyboards feature. The question was simple - how do I present a modal view, ask the user for some data, and then return that to the parent view? In the past it was a pretty simple matter, but for me passing it back along via a navigation controller turned out to be slightly more complex that I predicted. Luckily the code to fix this issue is pretty concise and very easy to understand. Let's take a look.

Here's what we're dealing with in terms of the view setup:

First thing's first, give your modal segue an identifier like so:

Make this descriptive, for my app the modal view is used to add an order. And now we need to get our hands dirty and start coding. Jump to the modal view's header file and add this property:

@property (nonatomic, assign) id delegate;

This will allow us to assign a delegate to our view, in our case will allow the parent view to tell the modal view that it is the delegate, and therefore all data should be passed back to our parent. Note: Don't forget to @synthesize the above property in your .m file.

Now let's imagine you want to pass back the contents of an input box when a button is tapped, I'll assume you've setup a method called didFinishEnteringData:sender - a fairly common looking method name as generated by XCode. Here's the code you would use inside of this method:

- (IBAction)didFinishEnteringData:(id)sender {
    [self.delegate setInput:myInput.text];
    [self dismissModalViewControllerAnimated:YES];
}

And voilà! We are now talking to our delegate. But hang on, we need to have our parent assign itself as the delegate before the modal view is presented. And for that we need to jump to our parent view - an excellent point here is that the method applies to the storyboard configured method of presenting a modal view, rather than a programmatic approach. Here's the code:

-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {    
    if([segue.identifier isEqualToString:@"NewOrder"]){

        AddOrdersViewController *vc = (AddOrdersViewController *)[[[segue destinationViewController] viewControllers] objectAtIndex:0];
        
        [vc setDelegate:self];

    }
}

Notice the use of the identifier we configured before. Also note the modal view's class name, and the need to #import the header file of the modal view's class.

And that is how to simply access the parent to send data back from a modal view!

Implement the WordPress Geolocation Plugin

For a while now WordPress has had apps across the mobile spectrum, and a great feature of these is geolocation - great, but who wants to know where I'm blogging from right? Well recently I had to build a blog for someone travelling around the world, and it quickly became apparent that using the data saved by the app on the site would be a great feature. In this tutorial we'll see the basic implementation of adding the plugin, but more importantly look at how we can then plot a route across the globe using data from every post. So let's get started!

First off you'll need to go and grab the Geolocation plugin and install it on your site. The default behaviour of this plugin is to insert a link at the bottom of single posts and show a map to users when they hover over it. But what if we want to show the map by default? And what about using all that geolocation data from each post? Well the first request is relatively simple - in fact it's just a change of CSS. Here's the alteration to style.css in the goelocation folder:

#map { background: #fff; border: solid 1px #999; padding: 20px; visibility: hidden; }
.home #map { display: none; }

The second rule is useful if you use the the_content() on your home page, this is because only 1 map is actually used for every post meaning that otherwise you'll just have a big empty div.

Plotting your posts on a map

Here's the exciting bit, to begin with we'll look at creating a route out of post data, and displaying it on a nice big map. Thankfully the WordPress app doesn't use anything big, scary, or evil to store its data, it just stores it as a custom variable! So accessing the data is easy as pie! Now in this case I'm assuming that you're whacking the PHP code in something like map.php - a template for a page, and that the JavaScript coming later will be in footer.php - this is important because the JS will be using a PHP variable - namely the coordinates to plot. If you have a different structure, you'll need to find some way of getting this data from PHP, either via an AJAX request, or clever script positioning. Let's take a look at how we'd go about getting all of this data into our PHP backend, before utilising it with the Google Maps JavaScript API:

<?php 
    $points = '';
    query_posts('posts_per_page=500'); 

    while ( have_posts() ) : the_post(); 
    
        $points .= '(' . get_post_meta($post->ID, 'geo_latitude', true) . ',' . get_post_meta($post->ID, 'geo_longitude', true) . '),';  

    endwhile; 
    
    $points = substr($points, 1, -2); // Remove the initial '(' and final '),'
?>

<div id="canvas"></div>

So above we have the standard WordPress loop that cycles through the 500 most recent posts (courtesy of query_posts()) - this should all be familiar. Inside the loop we keep adding to the $points variable in the format (latitude_1, longitude_1), (latitude_2, longitude_2) and so on. We use the handy get_post_meta() function (here's the reference), to get the coordinates, and we end by removing the first bracket and last bracket and comma - we do this because when we switch to JS we need a clean array. Finally we have a div with the ID "canvas" - this is where we'll put our map - so feel free to style this in your CSS, I added the following to the theme's style.css:

#canvas {
    height:600px;
    width: 96%;
    margin-left: 2%;
}

And now we're ready to move into the crazy realm of JavaScript!

Luckily for us the Geolocation plugin already takes care of adding the Google Maps API v3, so we can get straight into using it with our site! But before we get into our JavaScript we're going to be good coders and only deliver our code to users on the map page, so we'll use yet another handy WordPress function to detect when we're on the map.php template page. Go ahead and whack this into footer.php:

<?php  if ( is_page_template('map.php') ) : ?>

     /* JS goes here... */

<?php endif; ?>

Now let's get to the really meaty code. The code below uses 1 jQuery call, and it's just to check that the DOM is fully loaded, so you can use any equivalent function or whack the code into onload="" in the body tag. First up we'll look at getting the data from PHP and making it usable, put the following code within <script> tags:

function init(){
    var p = "<?php global $points; echo $points; ?>", mapCoords = null;
	
    p = p.split("),(");
	
    for(var x = 0; x < p.length; x++){
        p[x] = p[x].split(",");
        if(mapCoords == null){
            mapCoords = [new google.maps.LatLng(p[x][0], p[x][1])];
        }else {
            mapCoords.push(new google.maps.LatLng(p[x][0], p[x][1]));
        }
    }	
	
    newMap('canvas', mapCoords);
}


$(function(){ init(); });

So the function above begins by taking the data we just extracted using PHP and puts it into a variable called p, we also define one called mapCoords. Then we turn p into an array by splitting up each pair of coordinates, before jumping into a for loop. If you've not used the Google Maps API before this may look a little daunting, but it's fairly simple once you get started. First off we set up our loop to cycle though every set of coordinates in our array, and once inside we split our coordinates into longitude and latitude and store that array in p. Then we check to see if mapCoords is empty, if it is we use square brackets to create the array, otherwise that's the only difference. Then we add a new value to the mapCoords array - this value is a special object provided by the API for processing points on the map, and we just have to pass it the relevant values for the longitude and latitude. Once the loop is complete, we call a mysterious function named newMap(), and pass it the ID of our map canvas, as well as our newly created route coordinates. Lets take a look at how we implement this new function.

function newMap(id, mapCoords){
    var centre = (new google.maps.LatLng(51.44031275716014, 0.3955078125)),
	zoomLevel = 6,
        route,
        myOptions,
        map;
	
    route = new google.maps.Polyline({
        path: mapCoords,
        strokeColor: "#2324e4",
        strokeOpacity: .70,
        strokeWeight: 7,
        editable: false
    });
		    	
    myOptions = {
        center: centre,
        zoom: zoomLevel,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
		
    map = new google.maps.Map(document.getElementById(id), myOptions);
    route.setMap(map);
}

First up we define a few variables: the map centre - as it appears to the user (here it's somewhere between the UK and France), zoom level - 6 will zoom pretty far out (16 is street level), and the route - we'll add to this soon. Then we make use of our route variable - this is a line that will be drawn on our map and will represent the route between posts. There are a number of options here, but the most important is the 'path' - we'll set it equal to the coordinates passed to our function. Next up we define some options for our map and put them into myOptions. Here we set the centre and zoom level - as defined above, as well as the type of map we want to display - here we've created a road-map. Finally we create our map, and tell our route that it needs to draw itself on that map.

Up to this point the code we've written will draw a blue line on your map, so if that's all you need you're done! But if you want to add your posts to the map as markers read on!

Plot Posts with Pins

Now it might be the case that you don't want a route plotted, or maybe you want a route with pins indicating where you've posted from - and once you've implemented the back-end above its remarkably simple. The only difference is that because we'll want to show the user an info window we'll need to store the names, dates, and links for our posts. This just requires a simple modification of the backend:

<?php 
    $points = '';
    $thePosts = '';

    query_posts('posts_per_page=500'); 

    while ( have_posts() ) : the_post(); 
    
        $points .= '(' . get_post_meta($post->ID, 'geo_latitude', true) . ',' . get_post_meta($post->ID, 'geo_longitude', true) . '),'; 
        $thePosts .= '(' . get_the_title() . '|' . get_permalink() . '|' . get_the_time() . '),';
    endwhile; 
    
    $points = substr($points, 1, -2); // Remove the initial '(' and final '),'
    $thePosts = substr($thePosts, 1, -2);
?>

<div id="canvas"></div>

So the only difference here is that we've now got another variable named $thePosts - which holds the title, permalink, and time posted for each post. We'll do essentially the same to this when we get into the JavaScript, and then we can use the data on the map. Notice I've used a pipe character (|) as the delimiter as it's common to have commas in titles. So lets take a look at the init() function in our JavaScript:

function init(){
    var p = "<?php global $points; echo $points; ?>", mapCoords;
	
    p = p.split("),(");
	
    for(var x = 0; x < p.length; x++){
	p[x] = p[x].split(",");
	if(mapCoords == null){
		mapCoords = [new google.maps.LatLng(p[x][0], p[x][1])];
	}else {
		mapCoords.push(new google.maps.LatLng(p[x][0], p[x][1]));
	}
    }	
	
    /* Create posts array */
    var posts = "<?php global $thePosts; echo $thePosts; ?>";
    posts = posts.split('),(');
	
    for(var x = 0; x < posts.length; x++){
	posts[x] = posts[x].split('|');
    }
	
    newMap('canvas', mapCoords, posts);
}

Here we've just added another variable and a for loop - notice this is above the newMap() call. We'll also alter this function to accept the posts variable. Now that we've got our variables set up, we can get into changing up our hefty newMap() function. But before we get to that we need to define a global variable that we'll use in the function, so go ahead and make a global variable like so:

var infowindow = new google.maps.InfoWindow();

This variable will be used to display an information window when the user clicks on a point, and we can utilise the handy API once again to do this. Now we can get into the juicy function to create our map:

function newMap(id, mapCoords, posts){
    var centre = (new google.maps.LatLng(51.44031275716014, 0.3955078125)),
	zoomLevel = 6,
        route,
        myOptions,
        map;

    route = new google.maps.Polyline({
        path: mapCoords,
        strokeColor: "#2324e4",
        strokeOpacity: .70,
        strokeWeight: 7,
        editable: false
    });
		    
    myOptions = {
        center: centre,
        zoom: zoomLevel,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };

    map = new google.maps.Map(document.getElementById(id), myOptions);
    route.setMap(map);
    
    // New code starts here
	
    function getInfoWindowEvent(marker, x) {
	infowindow.close()
	infowindow.setContent('<div class="infowindow"><a href="'+posts[x][1]+'"><strong>'+posts[x][0]+'</strong><br>'+posts[x][2]+'</a></div>');
	infowindow.open(map, marker);
    }
    
    var markers = [];
    
    for(var x = 0; x < mapCoords.length; x++){
        markers[x] = new google.maps.Marker({    
	    position: mapCoords[x],    
	    map: map,
	    icon: 'http://example.com/images/pin.png' // Remove this to use the default pin
	});
	    
	google.maps.event.addListener(markers[x], 'click', (function(x) {
	    return function(){ 
		getInfoWindowEvent(markers[x], x);
	    }
	})(x));			
    }  
}

Notice the comment about half way through - I'll begin explaining the code from there onwards.

First up we create ourselves a function called getInfoWindowEvent() - this will be used to move our info-window that we defined earlier around the map and to put our post content into it each time a point is clicked. The HTML inside the setContent() function is entirely up to you, so feel free to play with the styling and organisation of the code. Next up we create a new array called markers[] - this will hold every marker for the map. Then we have a for loop to iterate over every set of map coordinates that we have. Inside the loop we first create a new marker - the options here should be fairly obvious, but the icon one is entirely optional, remove it to use the default, well-known pin icon, otherwise supply a valid URL. Once we've got our array of markers we need to add event listeners to get ready for click events. The function we use simply calls the getInfoWindowEvent() function with the appropriate variables, namely the marker that has been clicked, and the index of that marker.

As a little side-note, if you want your own, custom pin on single post pages for the map, it's simply a matter of replacing img/wp-pin.png, and for greater customisation there's also wp_pin_shadow.png.

And that's it! You should now have a beautiful, dynamic map displaying all your posts - perfect for travel blogs!

Create a dynamic Twitter-search feed

For years the ancient (and some would say instinctive) art of tweeting was restricted to the avian species of the sky, but recently a service has come about that allows us humans to partake in the practise. You might have heard of this little company, they call themselves Twitter, and have provided an extensive API for us web-folk to play with their service. At this point you might be wondering what the heck I'm going on about, so how's this? We'll be creating a dynamic Twitter feed based on a search term, that automatically updates without the user having to refresh the page, while ensuring we don't overload our own servers with long-polling (more on that in a mo). We'll even take a look at allowing only a certain set of users to appear in our steam, to avoid spammers. Let's get started!

A quick bit of background about the technical side of this before we get going though. For us to be able to update our stream constantly we need AJAX to poll (or make a request) to a server, to ask for any new tweets. Now when I first began playing around I had a page on my own server that was requested every 10 seconds, that would then grab, parse, and output any new tweets, and return it to my stream. But, and it's a big but, this approach can devastate your servers if you're not careful. If you've never delved into long-polling before you're lucky! But take it from me, having 100 users requesting a page on your server every 10 seconds, each, is a really bad idea. So in this tutorial we'll look at how we can use JavaScript to parse and output results directly from Twitter's servers.

To begin we'll look at how we can GP+O (Get, Parse, and Output) our tweets with PHP. Here's our code:

function searchTwitter($search) {
    $url = 'http://search.twitter.com/search.atom?rpp=300&q='.urlencode($search) ;
    $ch = curl_init($url);
    curl_setopt ($ch, CURLOPT_RETURNTRANSFER, TRUE);
    $xml = curl_exec ($ch);
    curl_close ($ch);

    $result = new SimpleXMLElement($xml);
    
    foreach ($result->entry as $entry) {
    	$author = trim($entry->author->name);
		$name = explode(' (', $entry->author->name);
        $content = trim($entry->title);
        $time = @strtotime($entry->published);
        $id = $entry->id;

        echo "<li data-id=\"".str_replace('tag:search.twitter.com,2005:', '', $id)."\">
        		<img src=\"http://api.twitter.com/1/users/profile_image/$name[0]?size=normal\" />
        		<div class=\"content\">
        			<span class=\"name\">".substr($name[1], 0, -1).":</span><br> 
        			<span class=\"tweet\">".$content."</span><br>  
        			<span class=\"time\">Posted ".gmdate('j/n/y g:i a',$time)."</span>
        		</div>
        	</li>";
    }
}
	
searchTwitter('myquery');

Because we're good developers we're encapsulating our code into a handy, reusable function - aren't we good?! Let's look at what we're doing here. First off we use PHP's cURL library to make a request to Twitter. There are a bunch of URL variables avalible, all of which can be found over at the Twitter API docs, the only ones we're concerned with are "rpp" - results-per-page, and "q" - query. I've set the results-per-page pretty high, but the function of this variable is fairly self-explanatory, as for the query variable, notice the use of the handy urlencode() function, which will take care of encoding things like hash-tags and spaces in our queries. Phew! That the first line done! The next few lines simply request the page, and shove the resulting data into the $xml variable.

We then use the excellent SimpleXML parser to translate our raw XML data into a useful variable. From then onwards we use a foreach() loop to go through every tweet in our list. If you'd like to know what variables are contained in each entry, just whack a print_r() in the loop. For our purposes we only need to access a few parts of each entry. Here's a list of our variables, and what they do:

  • $author: The user's name in the format "[Full name] ([User name])"
  • $name: An array of the user's name in the form [0]=>"Full name", [1]=>"Username )" - yes that's a bracket on the end
  • $content: The tweet itself, all tidied up using trim()
  • $time: A useful representation of when the tweet was posted
  • $id: The unique tweet ID - we'll use this later when we request updates

We can use these variables to then output a list that looks very much like Twitter itself, with the user's profile image to the left and data to the right. Our code outputs list items with nicely formatted dates, and here's where you might want to update the code to reflect your markup. And that's it for the PHP! However, if you want to have a stream of tweets only from approved users, you would want the following, updated code:

function searchTwitter($search) {
    $url = 'http://search.twitter.com/search.atom?rpp=300&q='.urlencode($search) ;
    $ch = curl_init($url);
    curl_setopt ($ch, CURLOPT_RETURNTRANSFER, TRUE);
    $xml = curl_exec ($ch);
    curl_close ($ch);

    $result = new SimpleXMLElement($xml);
    
    $hidden = array();
    
    foreach ($result->entry as $entry) {
    	$author = trim($entry->author->name);
		$name = explode(' (', $entry->author->name);
		
    	if(in_array(strtolower($name[0]), array('user1', 'user2'))){
	        $content = trim($entry->title);
	        $time = @strtotime($entry->published);
	        $id = $entry->id;
	        echo "<li data-id=\"".str_replace('tag:search.twitter.com,2005:', '', $id)."\">
	        		<img src=\"http://api.twitter.com/1/users/profile_image/$name[0]?size=normal\" />
	        		<div class=\"content\">
	        			<span class=\"name\">".substr($name[1], 0, -1).":</span><br> 
	        			<span class=\"tweet\">".$content."</span><br>  
	        			<span class=\"time\">Posted ".gmdate('j/n/y g:i a',$time)."</span>
	        		</div>
	        	</li>";
	       
        }else { array_push($hidden, $name[0]); }
    }
    
	echo "<!-- Tweets from: ";
	for($x = 0; $x < count($hidden); $x++){
		echo $hidden[$x] . ', ';
	}
	echo " have been hidden -->";
}
	
searchTwitter('myquery');

Notice the addition of the $hidden array - which will allow us to keep track of any blocked tweets. Stepping inside our loop you'll notice the addition of an if statement that checks to see if the entry was posted by a user in an array of approved tweeters. If it is, then it continues to output the tweet, otherwise it adds it to the array of blocked users. And just for fun, we output a HTML comment at the end to let us know if any users were blocked.

Now that we've got our PHP sorted, let's take a look at how we can use JavaScript to make this bad-boy dynamic! Before we write any of our own code, we need to borrow for some excellent chaps for some utility functions - if you want to format the date any differently to how Twitter returns it by default, you'll want to go and grab the JavaScript Date.format code, and if you want to only allow tweets from pre-approved users, you'll want a translation of PHP's in_array() function. Once you've got that code, we can go straight ahead and use:

var lastUpdate;

function update(){
	$.ajax({
		url: "http://search.twitter.com/search.json?q=myquery&since_id="+lastUpdate,
		dataType: "jsonp",
		success : function(data){
			var tweets = data.results;
			tweets.reverse();
			for(var x = 0; x < tweets.length; x++){
				var date = new Date(tweets[x].created_at);
				date = date.format('d/m/y g:ia');
				$('.stream').prepend('<li data-id="'+tweets[x].id_str+'" class="new hidden"><img src="'+tweets[x].profile_image_url+'" /><div class="content"><span class="name">'+tweets[x].from_user_name+'</span><br><span class="tweet">'+tweets[x].text+'</span><br><span class="time">Posted '+date+'</span></div></li>');
				$('.new').slideDown().removeClass('new');			
			}
			
			if(tweets.length > 0){
				lastUpdate = tweets[tweets.length - 1].id_str;
			}
			
			setTimeout(function(){ update(); }, 10000);
		}
	});			
}

lastUpdate = $('.stream li:first').data('id');
setTimeout(function(){update();}, 10000);

So in the code above we've created a function that makes an AJAX request to Twitter to ask for new tweets. We use the most recent tweet's ID in our request, using the parameter "since_id" - stored in the lastUpdate variable (this is first assigned a value at the bottom of the code, and extracts the ID from the first list item in the ".stream" list). Notice the URL features a ".json" file extension - perfect JavaScript goodness, that will allow us to play around with the data. If the request is a success we then go about adding any new tweets to our stream.

We first create the tweets variable, and reverse it - we do this because they are returned in reverse-chronological order (most recent first), and we want to output them in chronological order. We then loop through all the new tweets, formatting, prepending, and sliding-down one-by-one. Once the loop is finished we check to see if we actually had any new tweets, and if we did, we update our lastUpdate variable to reflect the most recent tweet in our stream. Finally we use the setTimeout() function to call our function again in 10 seconds - essentially mimicking real-time updates. And that's our code!

If you want to allow updates from only approved users, here's what the JavaScript looks like:

var lastUpdate;
var allowedNames = ['user1','user2'];

function update(){
	$.ajax({
		url: "http://search.twitter.com/search.json?q=myquery&since_id="+lastUpdate,
		dataType: "jsonp",
		success : function(data){
			var tweets = data.results;
			tweets.reverse();
			for(var x = 0; x < tweets.length; x++){
				if(in_array(tweets[x].from_user, allowedNames)){
					var date = new Date(tweets[x].created_at);
					date = date.format('d/m/y g:ia');
					$('.stream').prepend('<li data-id="'+tweets[x].id_str+'" class="new hidden"><img src="'+tweets[x].profile_image_url+'" /><div class="content"><span class="name">'+tweets[x].from_user_name+'</span><br><span class="tweet">'+tweets[x].text+'</span><br><span class="time">Posted '+date+'</span></div></li>');
					$('.new').slideDown().removeClass('new');
				}else {
					$('.stream').prepend('<!-- Blocked Tweet from: '+tweets[x].from_user+' -->');
				}
			}
			
			if(tweets.length > 0){
				lastUpdate = tweets[tweets.length - 1].id_str;
			}
			
			setTimeout(function(){ update(); }, 10000);
		}
	});		
}

lastUpdate = $('.stream li:first').data('id');
setTimeout(function(){update();}, 10000);

And that is how to create a dynamic Twitter stream using PHP and JavaScript!

Create a bullet-proof contact form

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

Contact pages are usually one of the basic building blocks of any website, and while many simple feature an email address for spam bots to pick up and use, or even a handy 'mailto' link, the best ones feature a proper contact form. To make a bulletproof one we're going to need some thick glass and a riot shield PHP and JavaScript. Having those bad-boys on our side will ensure we can create a beautiful AJAX-enabled means of contact for our users. We also need to ensure our form will work on the rare occasion that a user has JavaScript turned-off *gasp* - I know, it's a scary thought, but I'm sure we'll figure something out!

So we'll start with some simple HTML to set out our fields, the following code is what we'll be working with:

<form id="contact" class="right" method="post" action="mail.php">
	<h3 class="hidden success"><br/>Message sent!</h3>
	
	<label>Name: <span class="warning right"></span>
		<input type="text" name="name" />
	</label>
	
	<label>Email: <span class="warning right"></span>
		<input type="text" name="email" />
	</label>

	<label>Message: <span class="warning right"></span>
		<textarea name="message"></textarea>
	</label>
	<input class="right" type="submit" value="Send" />
</form>

Aside from the obvious, the form features a few extra elements - namely the .warning elements - we'll see what they're for in a moment. I also assume that you have the class of .right set up to float elements to the right; if now, then you'll need to float the affected elements individually in your CSS. Right, that's the HTML sorted, lets take a look at the JavaScript for this puppy.

function validateEmail(email){ 
	 var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ 
	 return email.match(re); 
}

$('#contact').submit(function(){
	var name, email, message, errors;
	
	errors = 0;
	name = $('input[name=name]').val();
	email = $('input[name=email]').val();
	message = $('textarea[name=message]').val();
	
	$('.warning').text('');
	
	if(name==''){ $('input[name=name]').siblings('.warning').text('This field is required!'); errors++; }
	if(email==''){ $('input[name=email]').siblings('.warning').text('This field is required!'); errors++; }
	if(message==''){ $('textarea[name=message]').siblings('.warning').text('This field is required!'); errors++; }
	if(!validateEmail(email)){ $('input[name=email]').siblings('.warning').text('Please enter a valid email!'); errors++; }
	
	if(errors==0){
		var dataString = $(this).serialize() + '&js=true';
	
		$.ajax({
			url: 'contact-post.php',
			data: dataString,
			type: 'POST',
			success: function(data){
				$('form label, form input[type=submit]').slideUp(500, function(){
					$('form .success').hide().removeClass('hidden').slideDown(500);
				});
			}
		});
	}
	
	return false;
});

Now for the moment we'll ignore the validateEmail() function, and take a look at the form submission code. First off we set up some variables for the values in our form, this prevents us having to use longer code snippets and querying the DOM too much. Once we've got them set up we give the user the benefit of the doubt and remove any warning that may have previously been set by removing any text from the elements with the class of .warning. And then we validate the fields. The first three 'if' statements simply check that the user has entered a value in each field - if they haven't we tell them so, and increment our errors variable by 1. The last 'if' statement uses the validateEmail() function that we set earlier. There's no reason to worry if you don't understand how that function works, Regular Expressions are a world of their own. All we need to know, is that it tells us if the user has entered a valid email address.

Following our rather basic validation checks we then test to see if the form has passed - because we've been using our errors variable all along, if it's set to '0' we can rest assured nothing has gone wrong. If that's the case we serialise the form, and use a simple AJAX request to submit the data to our server. If our server is happy, we show our users a success message. Now all we need to do is set up our contact-post.php file, like so:

function redirect($hash){
	if($hash!='success'){
		echo 'Invalid ' . $hash;
	}else {
		echo 'Message sent!';
		echo '<meta http-equiv="refresh" content="0;url=http://example.com/">';
	}
	die();
}

if($_POST){
	if(empty($_POST['js'])){
		// Validate info here
		if(empty($_POST['name'])){ redirect('name'); }
		if(empty($_POST['email'])){ redirect('email'); }
		if(empty($_POST['message'])){ redirect('message');  }
		if(filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)){ redirect('email'); }
	}
	
	$sendto = 'you@example.com';

	$name = $_POST['name'];
	$email = $_POST['email'];
	$phone = $_POST['phone'];
	$message = $_POST['message'];
	
	$to = $sendto;
	$subject = "[MySiteName] Message";
	
	$message = "
	<html>
	<head>
	<title>Contact form Submission</title>
	</head>
	<body>
	<p style='font-family:Arial, Helvetica, sans-serif; color:black;'>The following was sent by <strong>".$name." (Email: ".$email."):</strong></p>
	<p style='font-family:Arial, Helvetica, sans-serif; color:black; font-size:16px;'>".nl2br(stripslashes($message))."</p>
	
	<p style='font-family:Arial, Helvetica, sans-serif; color:black;'>(Sent on: ".gmdate('d\/m\/y').")</p>
	</body>
	</html>
	";
	
	$headers = "MIME-Version: 1.0" . "\r\n";
	$headers .= "Content-type:text/html;charset=iso-8859-1" . "\r\n";
	$headers .= 'From: ' . $name;
	
	mail($to,$subject,$message,$headers);
	
	redirect('success');
}else {
        redirect('submission - no data entered!');
}

The function at the top will be used when we want to give the user some feedback - if they entered all the correct info, they'll be given a success message, and then redirected to your site in a timely fashion, otherwise they will be told what is wrong with their submission. Then we get to the guts of the script - we first make sure there is some data to play with - if there isn't we tell the user off, and if there is we go on to see if the user has JavaScript running. You may have noticed the little variable 'js' that we added to the serialised form back in our JavaScript - that is our way of finding out if the form is being submitted via an AJAX request in JavaScript - if the variable is empty, we let PHP validate our form's content - this is essentially identical to the JS code we used previously.

We then set up a really basic email, and send it to the address in the $sendto variable. Finally we redirect the user to the site. As a side note, do remember that this page will only be seen by users without JavaScript turned on.

And that's it! You now have a swanky contact form that, for all intents and purposes, is bullet-proof, but having said that, I wouldn't actually test that theory with a gun of any kind...

Prevent broken animations in jQuery

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

I recently posted an article on Animating a Site's Loading using jQuery - a handy technique to spice up any site. But an issue that became apparent using this technique, along with some other animation methods, is that sometimes user interaction can prevent loading and other animations from finishing correctly, and possibly lead to pages that look broken because of it. This is the sort of thing that only user-testing will usually uncover, as many web-designers simply sit back and watch the animations, before actually interacting with the site. To explain what I mean I'll show you a basic example of navigation animations - and the one that prompted this article.

$('nav li').each(function(index){
    $(this).slideDown(200*(index+1));
});

$('nav li').hover(function(){
    $(this).stop().animate({'paddingTop':'10px'},200);
});

Now the code above works perfectly fine - it slides-down each list element in my navigation panel, and whenever a user rolls over one with their mouse the list element moves down by 10 pixels. Great, but we have a slight problem; namely, the stop() function. The code uses it to prevent an animation build up if a user quickly moves their mouse over multiple list elements for example, and for that it works very well. But because we are using a loading animation, if a user hovers over a list element before it has completed the the slide-down animation, the list element will be stuck in limbo, or rather, it won't finish sliding down.

This is caused by the fact that the hover() is bound to each list element at the same time that the animations are being executed. To solve this issue we need to come up with a way of waiting for the animations to complete before binding any events to our elements. One way of doing this might be to add a class to each element as it finishes it's loading, and then checking to see if the class exists before performing any events. But that approach will quickly clog up both your JavaScript, and HTML. To avoid messy code, we should instead only bind such events once the animation has completed.

To do that, we just make a simple alteration, like so:

$('nav li').each(function(index){
    $(this).slideDown(200*(index+1), function(){
        $(this).hover(function(){
            $(this).stop().animate({'paddingTop':'10px'},200);
        });
    });
});

The code above uses the callback function of the slideDown() function to wait until the animation completes. We then bind the hover event to each element individually, and we have ourselves a much better setup to prevent our sites breaking in the hands of hover-happy users.

Importing hand-drawn art into Photoshop

Using Photoshop to design websites it great - it allows for pixel-perfect designs that can then be styled to your hearts-content using all the powerful tools included in the application. But sometimes it's nice to add a human touch, and have hand-drawn art in our designs. Now I personally don't do this all too often, but the other day when a client asked for a design that I simply couldn't create in Photoshop, I reached for the good-old pencil and paper to draw a fish sat in a chair (this might seem somewhat odd out of context, but there you go), and some nice lettering.

So what are our options? For me I wanted to draw the art, then colour it in with Photoshop, and add it to the site, and the distinct lack of thorough tutorials I found didn't do a great deal to help, so I thought I'd document my process here.

I started by sitting down and actually drawing the final product, and after an hour or two of trying to make a realistic fish I scanned the bad boy in, and came up with the following:

Hand-drawn fish

Great, I was happy with the simple design, and now I needed to 'vectorise' it. And here is where I hit my brick wall. Illustrator wouldn't play ball - I tried a billion different settings for the live trace tool, and it simply failed miserably. I concluded this was down to the opacity of the drawing, so I traced it with a 0.3mm fine-liner to make it stand out a little more. Here's what I ended up with:

Fish fineliner

Not bad, but still Illustrator just looked at me blankly. And that's when I found out about VectorMagic - an online tool to convert hand-drawn art to vectors. Now the service is free for the first 2 images you upload, and then there's a subscription of $8 a month, or you can buy the desktop version. So while it's not a complete solution, it works damn well! (I eventually forked out for the desktop client and I can honestly say it works every time). Now if you don't fancy being locked into a service like that the only other option is to manually trace (using the pen tool) in Photoshop - I know, this isn't really a solution, and that's why I seriously suggest you give VectorMagic a go.

So, having put my image through the VM process I got the following:

Traced Fish

Yay! It's starting to look a lot better. From there I began to colour in my creation using the fill tool, and the brush. After about 10 minutes I had:

Fish coloured-in

And then I added highlights and shadows to make it look more realistic - using a layer with the blend mode set to multiply, and a small brush using black and white for shadows and highlights respectively. The final fish took it's form:

Fish final

And that's now my process for importing vector art.

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.

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.