Archive for the ‘Javascript’ Category.

Implementing JSON templates for Ajax in Kohana 3.1

Over the last few days, I’ve been toying around with the Kohana PHP Framework.  I’ve attempted to learn various PHP frameworks on many occasions, but I always seemed to lose interest because of too much documentation, or a lack of documentation, or just being forced to add too much complexity to an otherwise simple web application.  For the first time, however, I’ve managed to get the hang of one, and as a learning exercise, I turned my personal website into a Kohana application.

One of the features I wanted was to have a single controller that was able to send the full HTML page (with header, navigation, content view and footer) to the client on regular (non-AJAX) requests, or switch to a simple JSON response containing just the new content for AJAX requests.  This is just a short example of how I was able to implement template switching in my main controller so my alternate JSON template would be used when a request was done via AJAX.

PLEASE READ THIS FIRST! We’re going to assume you understand about Kohana template controllers.

My two template views

First we’ll have a look at the HTML template with the full header, navigation & footer.  This is the one I will use when responding to all normal non-AJAX requests.  I simply named it template.php, and it’s located in application/views/miracleblue.

<!DOCTYPE html>
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title><?php echo $title ?></title>
		<?php foreach ($styles as $file => $type) echo HTML::style($file, array('media' => $type)), PHP_EOL ?>
		<?php foreach ($scripts as $file) echo HTML::script($file), PHP_EOL ?>
    </head>
    <body id="body" class="bgimage">
		<div style="width: 1px; height: 1px; position:absolute; display: block; overflow: auto;" id="preload">
			<img src="/blue_eyes_fade_title.jpg" onload="$(function(){imagesLoaded();});" />
		</div>
		<div id="loader" style="text-align: center;margin:auto;margin-top:300px;display:none;">
			<img src="/ajax-loader.gif" />
		</div>
		<script type="text/javascript">$("#loader").css("display","block");</script>
		<div style="width: 900px; margin: auto; height: 500px;" id="wrapper">
			<div id="nav" class="bgshadow">
				<?php foreach ($nav as $key=>$link) : ?>
					<a href="/<?php echo $key; ?>" class="<?php echo $link['class']; ?>"><?php echo $link['title']; ?></a>
				<?php endforeach; ?>
			</div>
			<div id="content" class="bgshadow">
				<div id="inner-content">
					<?php echo $content; ?>
				</div>
			</div>
			<div id="info">
				<a href="http://www.soundcloud.com/miracleblue" tip="Soundcloud"><img src="/orange_white_24.png" /></a>
				<a href="http://www.myspace.com/miracleblue" tip="Myspace"><img src="/myspace-icon24.png" /></a>
				<a href="http://www.facebook.com/miraclebluemusic" tip="Facebook"><img src="/facebook_icon.png" /></a>
				<a href="http://www.beatport.com/artists/miracleblue" tip="Beatport"><img src="/beatport_icon_24.png" /></a>
				<a href="http://itunes.apple.com/artist/miracleblue/id409867809" tip="iTunes"><img src="/itunes_icon_24.png" /></a>
			</div>
		</div>
		<script type="text/javascript">$("#wrapper, #content").css("display","none");</script>
    </body>
</html>

As you can see, it’s the full page.  It includes the header, footer, and everything in-between, renders it, and sends it to the client.  This is what gets sent when any normal request comes in.  However, when a request is received that contains the “Ajax” header (X-Requested-With: XMLHttpRequest), the main HTML template is swapped out for a really basic JSON template, that includes only the new page “title”, a “name” of the page (that corresponds with the relevant link in the navigation bar), and the new content html (which is a rendered view) to be put in the “inner-content” element.  Here’s an example of a fully rendered JSON packet.

{
	"name": "about",
	"title": "MiracleBlue - About Me",
	"content": "<p>This is some body content, to go in the page.<\/p>"
}

And here’s the template file, simply named ajax_template.php, in the same folder as the main template file.

<?php
    header("Content-Type: application/json");
    echo json_encode(array("name" => $name, "title" => $title, "content" => $content));
?>

That should be pretty self-explanatory.  The javascript that makes the AJAX request also processes the returned JSON accordingly.  You would, naturally, implement your own processing routines, so we won’t be going into that here.

Switching the template

The way to do this conditional template-switching is actually very simple, but I haven’t seen this technique documented anywhere, so someone who is still new to the Kohana framework (like me) may be hesitant to try figuring it out on their own, just in case it goes horribly wrong and – you know – accidentally brings on the apocalypse and the end of mankind (hey, it could happen!).

So, to avoid that, let me show you exactly how it’s done.  In your template controller class (the one that extends Controller_Template), you should have defined a public variable $template that points to your main HTML template view file.  This will be the default template view for all normal requests.  In your before() method, at the very start of the method before any other code, is where the template switch happens.  Then in your after() method, you need to manually call render() on your content view.  Here’s an example of what mine looks like.

<?php
	defined('SYSPATH') or die('No direct script access.');

	class Controller_Miracleblue extends Controller_Template
	{

		// Define our default HTML template
		public $template = 'miracleblue/template';

		public function before()
		{
			// Switch template to JSON version if request is AJAX
			if ($this->request->is_ajax())
			{
				$this->template = 'miracleblue/ajax_template';
			}
			// NOW we can call the parent method
			parent::before();
			// And do other stuff
			if ($this->auto_render)
			{
				// Do stuff here
			}
		}

		public function after()
		{
			// Manually render the string of the inline view on AJAX requests
			if ($this->request->is_ajax()) {
				$this->template->content = $this->template->content->render();
			}
			// Otherwise, continue as normal
			else {
				if ($this->auto_render)
				{
					// Do stuff here
				}
			}
			parent::after();
		}
	}
?>

There you go.  The paths to your template files should be modified accordingly to your own filenames and paths, of course.  It is very important to note that you NEED to call render() manually in your after() method.  This will convert the HTML view for your inline content into a string, which is then fed to the json_encode() function in your AJAX template.  Leaving this out could result in the end of the world, so don’t forget ;)

Using Asual’s jQuery Address plugin [version 1.4.x]

Internet
Photo by transCam
Oh, hello there!  I bet you thought you’d never see another blog post on here again, didn’t you?  Thought I had abandoned this blog for good?  Well, quite frankly, so did I for a little while.  The good news is, we were both wrong!

This is just a short example on the basic usage of the jQuery Address plugin by Asual, which provides AJAX applications with deep-linking and state/history management.  If you have ever come across this plugin and tried to figure it out, chances are you found the official documentation to be of little or no help.  You are not alone.  I had been wanting to integrate it into my personal website – for which I required deep linking and state management – for about a week.  Finally, yesterday, I became determined to figure out enough about how the plugin worked in order to get the functionality I needed out of it.

In my website, I wanted to use jQuery Address for deep-linking and history management, but I also wanted it to take advantage of HTML5′s new pushState method in browsers that support it, and only use location.hash as a fallback method for dynamically changing the displayed URL (jQuery Address supports both these methods).  The reason I want to avoid using hashed URLs for deep-linking when possible is because the only way to read any data contained in a hash segment is with Javascript.  This is because the hash segment of a URL is not visible to the server; only the browser can use it.  Therefore, having a hashed URL requires the user to have javascript enabled in order for the application to know what content the user is requesting.  I know some of you are probably asking why we should care about users who don’t enable javascript in their browsers, however that is not the point of this blog post.

What I wanted to achieve

I have a main navigation bar with a set of links which point to real URLs which I want to load dynamically via AJAX when clicked.  Since they are real URLs, they point to real content, and can be loaded directly without AJAX.  My server-side logic will return a full HTML page for normal requests, and JSON-encoded data containing only the dynamic content to be inserted into the page for AJAX requests.

Loading the plugin

In order to enable jQuery Address to use HTML5 pushState functionality, we need to set one of the plugin’s configuration parameters called “state”, which points to the base path of your website or application.  In this case, my base path is the webroot “/”.  You can set this and other configuration parameters in query-string format, like so:

<script type="text/javascript" src="jquery.address.js?state=/"></script>

The code that makes it happen

Here’s an edited snippet of the code that I wrote for my site that makes it all happen, explained step-by-step in the comments:

$(document).ready(function(){
	// Add jQuery Address functionality to the links in the navbar
	$("#nav a").address();
	// Our event responder that triggers whenever the address is changed (including on first load!)
	$.address.change(function(event) {
		// Set shortcut to URI value
		var uri = event.value;
		// Run ajax call and get JSON data
		$.getJSON(uri, function(data){
			// All parsing and processing of returned data should happen here
		});
	});
})

Voila!

You can see a live, working example of the code and how I have implemented it over on my main website.  Feel free to take a look at the full code, which is in the main.js file.

I hope this helps you to have a basic understanding of how to make this plugin Just Work™ so you can start using it.  As always, leave questions and feedback in the comments!

Colourify: My (Probably) Useless Javascript Gradient Algorithm

Hey guys!  Long time no post.  A few months back I was coding a small unrelated project when I got somewhat bored and noticed I had a page with a lot of black text that wasn’t really doing much of anything.  Suddenly I had this idea in my head: Why not give the text a pretty gradient colour scheme?  It could even follow your mouse when you hover your text over it!

So that’s exactly what I did.  I borrowed some RGB/Hex conversion math from the internets and spent about an hour coding a totally useless algorithm that gives your text a gradient colour scheme that follows the mouse on hover.  Cool, huh?

Check the demo here: http://www.miracleblue.com/colourify.html

Bejeweled Blitzer 0.1

UPDATE: Unfortunately, because of fundamental changes in the Bejeweled Blitz game itself, this script no longer works.  If anyone would like to assist in making it work for the new version, please get in touch.

I’m proud to present my first Greasemonkey script release, Bejeweled Blitzer 0.1!

About:
Bejeweled Blitzer is a high score hack tool for the Bejeweled Blitz facebook game. It will present you with a box that sits above the game, allowing you to enter in whatever high score you want to give yourself. Simply apply pressure to button, and voila!

Instructions:
1) Make sure you’re running Firefox and have the Greasemonkey Firefox Extension installed. If it’s not installed, go do it now!
2) Once it’s installed, follow the link after these instructions. Greasemonkey should automagically detect it and prompt you to install.
3) Browse to the Bejeweled Blitz facebook app, and enjoy!

Download: http://pie.miracleblue.com/downloads/bejeweledblitzer.user.js

Screenshot

Screenshot

Using PrototypeJS Object.extend, a very simple example

Recently I’ve been working on a personal project of mine (For which I will eventually be putting the code up here for all to download and use at will), and I have been using the PrototypeJS framework and many of it’s very useful features.

One of these features that I have just discovered and found very useful for this project in particular is the Object.extend method.  Looking at the API docs on the prototype website, you find that it doesn’t have any examples of how to go about using Object.extend.  So, I’ve decided to do my best at writing a very simple example on how one would use it.  This is based on how I’ve used it in my project =] hopefully it should help those looking for insight on what it does.

Okay.  Let’s just say for example you’re writing a class that contains an array of link urls, and has a method that simply writes them out as html.  This class also has a property which holds the value of the class attribute to be used in all the <a> elements that are written out.  This is the code:

var LinkStuff = function() {
	this.config = {
		links: [
			'http://cnn.com',
			'http://google.com',
			'http://php.net',
			'http://miracleblue.com'
		],
		className: 'linky'
	};

	this.writeLinks = function() {
		// Do some link stuff
	};
};

var myLinks = new Linkstuff();

Here we’ve also created an instance of the class as the “myLinks” object.  The configuration properties are in myLinks.config, which is where the writeLinks method will be getting the list of links to write as well as the classname to assign to all the anchor elements.  As it is, if you wanted to change the links in the array that will be written, you’d have to change the class manually, or set the values in your new object directly (like by doing myLinks.config.className = “newclass”).  Wouldn’t it be easier to have the properties in the config object assigned when you create an instance of the class?

This is one example of where we can use Object.extend!

Let’s give our class an argument called “options”, which we will use to pass a hash of properties to be assigned to the config object.  This is the concept of inheritence.  Basically, any properties we pass in the options argument will be “added” to the config object in our class, and any property that has the same name as a property in the config object will replace (or “overwrite”) the original property.  Then we will use Object.extend to copy the options object over to the config object.

var LinkStuff = function(options) {
	this.config = {
		links: [
			'http://cnn.com',
			'http://google.com',
			'http://php.net',
			'http://miracleblue.com'
		],
		className: 'linky'
	};

	Object.extend(this.config, options);

	this.writeLinks = function() {
		// Do some link stuff
	};
};

The two arguments we provide to Object.extend are the Destination object and the Source object (In this case, this.config and options).  The properties in the source object will be copied over to the destination object.

Now to initialize the class and assign a new array of links, as well as setting the className to “mylinks”, we can do this:

var myLinks = new LinkStuff({
	links: ['http://facebook.com','http://cnet.com','http://foreverskybound.com'],
	className: 'mylinks'
});

Voila.  To see if it worked, try returning the value of myLinks.config.className, and you should get the string “mylinks”.

Note: While Object.extend will now copy all properties in the ojbect we passed as the options argument when we initialize the LinkStuff class,  you do not have to pass all the original properties.  Hmm…maybe I’ll just show you what I mean.

Let’s say for instance you want to create a new instance of LinkStuff and only change the className property, but keep the original array of links which are already defined in the LinkStuff class.  You then only need to pass an object with a className property.  Like this:

var myLinks = new LinkStuff({
	className: 'mylinks'
});

Now the only property that will be over-written will be className, and the links array will have all its original values.

In fact, you don’t even have to pass anything in the argument at all!  If you want all the properties to keep their original values, it’s as simple as:

/* */
var myLinks = new Linkstuff();

And there you go!  I hope that after reading this post, anyone trying to figure out what Object.extend does will have at least a vaguely better understanding.  =]