<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tutorialzine &#187; jQuery</title>
	<atom:link href="http://tutorialzine.com/category/tutorials/jquery-tutorials/feed/" rel="self" type="application/rss+xml" />
	<link>http://tutorialzine.com</link>
	<description>PHP MySQL jQuery CSS Tutorials, Resources and Freebies</description>
	<lastBuildDate>Wed, 28 Jul 2010 17:33:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>An AJAX Click to Appreciate Badge</title>
		<link>http://tutorialzine.com/2010/07/click-to-appreciate-badge-ajax-jquery-css/</link>
		<comments>http://tutorialzine.com/2010/07/click-to-appreciate-badge-ajax-jquery-css/#comments</comments>
		<pubDate>Wed, 28 Jul 2010 17:33:42 +0000</pubDate>
		<dc:creator>Martin Angelov</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://tutorialzine.com/?p=1036</guid>
		<description><![CDATA[If you've ever dropped by Behance, you've probably noticed their appreciate badge, with which you can show your appreciation for somebody's creative work. In this tutorial we are making an improved version, which you can include in every page of your site with a bit of jQuery magic.]]></description>
			<content:encoded><![CDATA[<p>When you publish something online, there are not that many ways to determine whether people like what you have to say. Comments, the cornerstone of blogging, are too demanding, and users often prefer not to post one. If you&#8217;ve dropped by <a href="http://www.behance.net/" target="_blank">Behance</a>, you&#8217;ve probably noticed their <strong>appreciate badge</strong>, which is a neat solution to this exact problem. With it people share their appreciation for somebody&#8217;s work.</p>
<p>Today we are implementing such a badge, which you can include in every page of your website with a bit of jQuery magic. So go ahead and download the zip from the button above (<em><strong>PSD included!</strong></em>) and continue with the tutorial.</p>
<h3>The Database Schema</h3>
<p>The script we are doing today uses two tables. The first holds one record for each of the pages which have the appreciate button enabled. The second one stores the IP of the person that voted along the unique ID of the page. This way we can easily determine whether the person has previously voted for the page and display the appropriate version of the button (active or disabled).</p>
<div id="attachment_1040" class="wp-caption alignnone" style="width: 630px"><img class="size-full wp-image-1040" title="Table Schema appreciate_pages" src="http://tutorialzine.com/wp-content/uploads/2010/07/i11.png" alt="Table Schema appreciate_pages" width="620" height="260" /><p class="wp-caption-text">Table Schema appreciate_pages</p></div>
<p>The hash field holds an <strong>MD5 </strong>sum of the URL of the page. This way we add an <strong>UNIQUE </strong>index which will speed up the <em>selects</em> we run on the records, as well ensure there are no duplicate records in the table. The <strong>appreciated </strong>column holds the number of appreciations of the pages.</p>
<div id="attachment_1041" class="wp-caption alignnone" style="width: 630px"><img class="size-full wp-image-1041" title="Table Schema appreciate_votes" src="http://tutorialzine.com/wp-content/uploads/2010/07/i21.png" alt="Table Schema appreciate_votes" width="620" height="260" /><p class="wp-caption-text">Table Schema appreciate_votes</p></div>
<p>The <strong>appreciate_votes</strong> table contains the IP of the person that has voted (in the form of an integer), and the id of the page from the <strong>appreciate_pages</strong> table. The timestamp is automatically updated to the current time when an insert occurs.</p>
<p>You can create these two tables by running the code from <strong>tables.sql</strong> in the <strong>SQL </strong>section of <strong>phpMyAdmin</strong> from the downloadable archive, part of this tutorial.</p>
<h3>Step 1 &#8211; XHTML</h3>
<p>Lets start with the XHTML part of the tutorial. The markup of the page is extremely simple. To have the appreciate button functioning, you just need to provide a  container in which the button is inserted, and an optional element,  which holds the total number of clicks on the button. You can safely omit the  latter one, leaving you with only one div to code.</p>
<h4>page.html</h4>
<pre class="brush:html">&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
&lt;head&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8" /&gt;
&lt;title&gt;An AJAX Click To Appreciate Badge&lt;/title&gt;

&lt;link rel="stylesheet" type="text/css" href="styles.css" /&gt;
&lt;link rel="stylesheet" type="text/css" href="appreciateMe/appreciate.css"/&gt;
&lt;/head&gt;

&lt;body&gt;

&lt;div id="countDiv"&gt;&lt;/div&gt;
&lt;div id="main"&gt;&lt;/div&gt;

&lt;script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"&gt;&lt;/script&gt;
&lt;script src="appreciateMe/plugin.js" type="text/javascript"&gt;&lt;/script&gt;
&lt;script src="script.js" type="text/javascript"&gt;&lt;/script&gt;

&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>In the page above, you can see that I am  including two stylesheet files. The first is <strong>styles.css,</strong> which is used to style the page, and <strong>appreciate.css</strong>, which is located in the plugin directory, and is responsible for the styling of the appreciate button.</p>
<p>Before the closing body tag, you can see that I also include the jQuery library from Google&#8217;s CDN repository, the <strong>plugin.js</strong> file and <strong>script.js</strong>, which uses the plugin to create the button on the page. You will only need to change the contents of <strong>script.js</strong> to make the script working on your pages.</p>
<div id="attachment_1042" class="wp-caption alignnone" style="width: 630px"><a href="http://demo.tutorialzine.com/2010/07/click-to-appreciate-badge-ajax-jquery-css/page.html"><img class="size-full wp-image-1042" title="Click To Appreciate Button" src="http://tutorialzine.com/wp-content/uploads/2010/07/i3.png" alt="Click To Appreciate Button" width="620" height="460" /></a><p class="wp-caption-text">Click To Appreciate - looks good on both dark and light backgrounds</p></div>
<h3>Step 2 &#8211; PHP</h3>
<p>PHP handles the database interactions and is on the backend of the AJAX requests. Most of the script logic is located in c <strong>script.php</strong> which you can see below. But first lets take a look at <strong>connect.php,</strong> which handles the database connection.</p>
<h4>appreciateMe/connect.php</h4>
<pre class="brush:php">$db_host = 'localhost';
$db_user = 'YourUsername';
$db_pass = 'YouPassword';
$db_name = 'NameOfDB';

@$mysqli = new mysqli($db_host, $db_user, $db_pass, $db_name);

if (mysqli_connect_errno()) {
	die('&lt;h1&gt;Could not connect to the database&lt;/h1&gt;');
}

$mysqli-&gt;set_charset("utf8");
</pre>
<p>Up until now, we&#8217;ve always used the old <strong>mysql</strong> extension for database connections under PHP, as it is a bit easier to use and I wanted to keep the code compatible with PHP 4. However, with the recent announcement that WordPress (our favorite blogging engine) will be <a href="http://wordpress.org/news/2010/07/eol-for-php4-and-mysql4/" target="_blank">dropping support for that version of PHP</a>, I decided that it is time to also make the switch to the new version &#8211; MySQLi (MySQL improved).</p>
<p>As you can see from the code above, the only major difference with the old way we connected to a database, is that here we create a <strong>MySQLi</strong> object instead of using the <strong>mysql_</strong> functions. Also, as you will see in a moment, when we query the database a MySQL resource object is returned, which in turn has its own set of methods. This might sound intimidating, but it will become perfectly clear once you see it in action.</p>
<h4>appreciateMe/script.php</h4>
<pre class="brush:php">/* Setting the error reporting level */
error_reporting(E_ALL ^ E_NOTICE);
include 'connect.php';

if(!$_GET['url'] || !filter_input(INPUT_GET,'url',FILTER_VALIDATE_URL)){
	exit;
}

$pageID			= 0;
$appreciated	= 0;
$jsonArray		= array();
$hash			= md5($_GET['url']);
$ip				= sprintf('%u',ip2long($_SERVER['REMOTE_ADDR']));

// $result is an object:
$result = $mysqli-&gt;query("SELECT id,appreciated FROM appreciate_pages WHERE hash='".$hash."'");

if($result)
{
	list($pageID,$appreciated) = $result-&gt;fetch_row();
	// fetch_row() is a method of result
}

// The submit parameter denotes that we need to write to the database

if($_GET['submit'])
{
	if(!$pageID)
	{
		// If the page has not been appreciated yet, insert a new
		// record to the database.

		$mysqli-&gt;query("
			INSERT INTO appreciate_pages
			SET
				hash='".$hash."',
				url='".$mysqli-&gt;real_escape_string($_GET['url'])."'"
		);

		if($mysqli-&gt;affected_rows){

			// The insert_id property contains the value of
			// the primary key. In our case this is also the pageID.

			$pageID = $mysqli-&gt;insert_id;
		}
	}

	// Write the vote to the DB, so the user can vote only once

	$mysqli-&gt;query("
		INSERT INTO appreciate_votes
		SET
			ip = ".$ip.",
			pageid = ".$pageID
	);

	if($mysqli-&gt;affected_rows){
		$mysqli-&gt;query("
			UPDATE appreciate_pages
			SET appreciated=appreciated+1 WHERE id=".$pageID
		);

		// Increment the appreciated field
	}

	$jsonArray = array('status'=&gt;1);
}
else
{
	// Only print the stats

	$voted = 0;

	// Has the user voted?
	$res = $mysqli-&gt;query("
		SELECT 1 FROM appreciate_votes
		WHERE ip=".$ip." AND pageid=".$pageID
	);

	if($res-&gt;num_rows){
		$voted = 1;
	}

	$jsonArray = array('status'=&gt;1,'voted'=&gt;$voted,'appreciated'=&gt;$appreciated);
}

// Telling the browser to interpret the response as JSON:
header('Content-type: application/json');

echo json_encode($jsonArray);
</pre>
<p>The script handles two different types of AJAX requests &#8211; <strong>read only request</strong> (which returns a JSON object with information about the number of appreciations of the page, and whether the current user has clicked the button), and <strong>write requests </strong>(which save the visitor&#8217;s vote to the database, and if necessary, save the page URL and hash as well).</p>
<p>As you an see in the code snippet above, one of the first things that the script does is to calulate the <strong>MD5</strong> hash of the page. This is used as a unique key in the database, as URLs have unlimited length which is incompatible with MySQL&#8217;s UNIQUE keys. As an MD5 hash is unique for most practical purposes, we can safely use it in our selects and inserts, instead of the long URL addresses.</p>
<p>In the last line of the code, we convert the <strong>$jsonArray</strong> array into a valid JSON object with the inbuilt <strong>json_encode</strong> PHP function, and output it with a <strong>applicatoin/json</strong> content type.</p>
<div id="attachment_1043" class="wp-caption alignnone" style="width: 630px"><a href="http://demo.tutorialzine.com/2010/07/click-to-appreciate-badge-ajax-jquery-css/page.html"><img class="size-full wp-image-1043" title="Click To Appreciate - Inactive" src="http://tutorialzine.com/wp-content/uploads/2010/07/i4.png" alt="Click To Appreciate - Inactive" width="620" height="260" /></a><p class="wp-caption-text">Click To Appreciate - Inactive</p></div>
<h3>Step 3 &#8211; jQuery</h3>
<p>Inside the <strong>appreciateMe</strong> directory you can find the plugin.js file. You must include it in the page you wish to show the Appreciate button on. It uses AJAX to request data from the PHP backend and uses the response it receives to create the markup of the button.</p>
<h4>appreciateMe/plugin.js</h4>
<pre class="brush:js">function(){

	$.appreciateButton = function(options){

		// The options object must contain a URL and a Holder property
		// These are the URL of the Appreciate php script, and the
		// div in which the badge is inserted

		if(!'url' in options || !'holder' in options){
			return false;
		}

		var element = $(options.holder);

		// Forming the url of the current page:

		var currentURL = 	window.location.protocol+'//'+
					window.location.host+window.location.pathname;

		// Issuing a GET request. A rand parameter is passed
		// to prevent the request from being cached in IE

		$.get(options.url,{url:currentURL,rand:Math.random()},function(response){

			// Creating the appreciate button:

			var button = $('&lt;a&gt;',{
				href:'',className:'appreciateBadge',
				html:'Appreciate Me'
			});

			if(!response.voted){
				// If the user has not voted previously,
				// make the button active / clickable.
				button.addClass('active');
			}
			else button.addClass('inactive');

			button.click(function(){
				if(button.hasClass('active')){

					button.removeClass('active').addClass('inactive');

					if(options.count){
						// Incremented the total count
						$(options.count).html(1 + parseInt(response.appreciated));
					}

					// Sending a GET request with a submit parameter.
					// This will save the appreciation to the MySQL DB.

					$.getJSON(options.url,{url:currentURL,submit:1});
				}

				return false;
			});

			element.append(button);

			if(options.count){
				$(options.count).html(response.appreciated);
			}
		},'json');

		return element;
	}

})(jQuery);
</pre>
<p>The script basically creates a new method in the main jQuery object. This differs from the plugins that we usually do, in that this type of plugins are not called on a set of elements (no need to select elements). You can just call <strong>$.appreciateButton()</strong> while passing a configuration object as a parameter. This is exactly what we&#8217;ve done in <strong>script.js</strong> add a button to the page:</p>
<h4>script.js</h4>
<pre class="brush:css">$(document).ready(function(){

	// Creating an appreciate button.

	$.appreciateButton({
		url		: 'appreciateMe/script.php',	// URL to the PHP script.
		holder	: '#main',				// The button will be inserted here.
		count	: '#countDiv'			// Optional. Will show the total count.
	});

});
</pre>
<p>The configuration object, which is passed as a parameter, has to contain a <strong>url</strong> and a <strong>holder</strong> properties, whereas <strong>count</strong> is optional. Notice that I&#8217;ve specified the path to <strong>script.php</strong> relatively, as appreciateMe is a child directory of the one the page is currently in.</p>
<p>However, if you plan to add the script to a site with a variable path structure, you should probably specify an absolute path. Either add a <strong>leading slash</strong>, or provide a complete URL with <strong>http://</strong>.</p>
<h3>Step 4 &#8211; CSS</h3>
<p>Now that we have all the markup and code in place, it is time to turn to the styling. The CSS rules that style the appreciate badge are located in <strong>appreciate.css</strong>. You could optionally copy these rules to your main stylesheet file, if you&#8217;d like to avoid the extra request, but beware that you will need to change the paths to the background images.</p>
<h4>appreciateMe/appreciate.css</h4>
<pre class="brush:css">.appreciateBadge{
	width:129px;
	height:129px;
	display:block;
	text-indent:-9999px;
	overflow:hidden;
	background:url('sprite.png') no-repeat;
	text-decoration:none;
	border:none;
}

.appreciateBadge.active{
	background-position:left top;
}

.appreciateBadge.active:hover{
	background-position:0 -129px;
}

.appreciateBadge.inactive{
	background-position:left bottom;
	cursor:default;
}
</pre>
<p>There are three versions of the appreciate badge image. A default one, a hover one, and an inactive one. All three of these reside in the same file &#8211; <strong>sprite.png</strong>, one below the other. With this technique you can switch between the versions instantaneously by offsetting the background image of the hyperlink.</p>
<h4>styles.css</h4>
<pre class="brush:css">#main{
	margin:80px auto;
	width:130px;
}

#countDiv{
	color:#eee;
	font-size:35px;
	margin-right:120px;
	position:absolute;
	right:50%;
	top:265px;
}
</pre>
<p>You can find the rest of the styles, which refine the looks of <strong>page.html</strong>, in <strong>styles.css</strong>. Only two sets of styles affect the appreciate button directly. The <strong>#main</strong> div, which contains the button and centers it on the page, and <strong>#countDiv</strong> in which the total number of appreciations is inserted.</p>
<p><strong>With this our Click to Appreciate Badge is complete!</strong></p>
<h3>Conclusion</h3>
<p>Before being able to run this script on your server, you first have to replace the MySQL credentials in <strong>connect.php</strong> with your own. Also, you will need to run the contents of <strong>tables.sql</strong> in the SQL tab of <strong>phpMyAdmin, </strong>so the two tables are created. Lastly, depending on your URL paths, you may have to change the URL property of <strong>appreciateMe/script.php</strong> in the script.js JavaScript File.</p>
]]></content:encoded>
			<wfw:commentRss>http://tutorialzine.com/2010/07/click-to-appreciate-badge-ajax-jquery-css/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Making a Custom YouTube Video Player With YouTube&#8217;s APIs</title>
		<link>http://tutorialzine.com/2010/07/youtube-api-custom-player-jquery-css/</link>
		<comments>http://tutorialzine.com/2010/07/youtube-api-custom-player-jquery-css/#comments</comments>
		<pubDate>Fri, 23 Jul 2010 18:06:04 +0000</pubDate>
		<dc:creator>Martin Angelov</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://tutorialzine.com/?p=1027</guid>
		<description><![CDATA[Today we are going to make a jQuery plugin which uses YouTube's chromeless player, and creates our own set of minimalistic controls, which allows for perfect integration with your designs. The supported controls include a Play/Pause/Replay button, and a clickable progress bar.]]></description>
			<content:encoded><![CDATA[<p>Video presentations are a great addition to any product page. With a presentation you can showcase your product&#8217;s features without making the visitor read through long paragraphs of text. But apart from producing the video, you still need to manually convert it and find (or code) some sort of flash player that will display it on your site.</p>
<p>The other possible path is that you upload it to a video sharing site such as youtube, but you are going to have a rough time trying to incorporate the player into your design.</p>
<p>Luckily for us, YouTube does provide a solution to this problem &#8211; their <a href="http://code.google.com/apis/youtube/youtube_player_demo.html?playerType=chromeless&amp;playerVersion=as3" target="_blank">chromeless player</a> (a stripped down version of the regular embeddable player), which allow you to build and style your own custom controls. This way you have both a quick and secure way to include videos in your pages, and the freedom to customize any way you might want to.</p>
<h3>The Idea</h3>
<p>Today we are going to make a jQuery plugin which uses YouTube&#8217;s <strong>chromeless player</strong>, and creates our own set of minimalistic controls, which   allows for perfect integration with your designs. The supported controls include a Play/Pause/Replay button, and a clickable progress bar.</p>
<p>The plugin is going to use YouTube&#8217;s <a href="http://code.google.com/apis/youtube/2.0/developers_guide_jsonc.html" target="_blank">gdata api</a> to determine whether embedding has been allowed for the video, and fetch extensive information about it, such as title, description, tags, screenshots &amp; more, which you can use to improve the plugin.</p>
<p>Using the plugin to embed videos is extremely easy:</p>
<pre class="brush:js">// Embed a video into the #player div:
$('#player').youTubeEmbed('http://www.youtube.com/watch?v=u1zgFlCw8Aw');

// Chaining is also supported:
$('#player').youTubeEmbed('http://www.youtube.com/watch?v=u1zgFlCw8Aw');
		.youTubeEmbed('http://www.youtube.com/watch?v=AsdfFdwlzdAw');
</pre>
<p>You can also specify a width for the embedded video (the height will be calculated automatically depending on the aspect ratio), and choose to disable the progress bar:</p>
<pre class="brush:js">$('#player').youTubeEmbed({
	video			: 'http://www.youtube.com/watch?v=u1zgFlCw8Aw',
	width			: 600, 		// Height is calculated automatically
	progressBar	: false		// Hide the progress bar
});
</pre>
<p>You can grab the plugin from the download button above, and start with the first step.</p>
<h3>Step 1 &#8211; XHTML</h3>
<p>Our plugin depends on <a href="http://jquery.thewikies.com/swfobject/" target="_blank">jQuery SWFObject</a> to embed the SWF files in the page. Below you can see the combined markup that is generated by both of the plugins.</p>
<h4>youtube-player.html</h4>
<pre class="brush:html">&lt;div class="flashContainer" style="width: 640px; height: 360px;"&gt;

	&lt;object height="360" width="640" id="video_26ELpS3Wc4Q" type="application/x-shockwave-flash"
	data="http://www.youtube.com/apiplayer?enablejsapi=1&amp;version=3"&gt;

		&lt;param value="always" name="allowScriptAccess"&gt;
		&lt;param value="transparent" name="wmode"&gt;
		&lt;param value="video_id=26ELpS3Wc4Q&amp;playerapiid=26ELpS3Wc4Q"
		name="flashvars"&gt;
		&lt;param value="http://www.youtube.com/apiplayer?enablejsapi=1&amp;version=3"
		name="movie"&gt;

	&lt;/object&gt;

	&lt;div class="controlDiv play"&gt;&lt;/div&gt;

	&lt;div class="progressBar"&gt;
		&lt;div class="elapsed"&gt;&lt;/div&gt;
	&lt;/div&gt;
&lt;/div&gt;</pre>
<p>The <strong>.flashContainerDiv</strong> is dynamically created by the plugin for each video on the page. It is populated with the embed code generated by  SWFObject, the <strong>.controlDiv</strong> (which acts as a play/pause button) and the progress bar.</p>
<p>As mentioned above, the insertion of the player itself is handled by the SWFObject plugin. Depending on the browser, it can output either an <strong>object</strong> element, or a non-standard <strong>embed</strong> element for IE. This lifts the burden from us and allows us to concentrate on tasks such as querying YouTube&#8217;s APIs and building the player controls.</p>
<div id="attachment_1032" class="wp-caption alignnone" style="width: 630px"><a href="http://demo.tutorialzine.com/2010/07/youtube-api-custom-player-jquery-css/youtube-player.html"><img class="size-full wp-image-1032" title="Custom YouTube Player" src="http://tutorialzine.com/wp-content/uploads/2010/07/i11.jpg" alt="Custom YouTube Player" width="620" height="460" /></a><p class="wp-caption-text">Custom YouTube Player</p></div>
<h3>Step 2 &#8211; jQuery</h3>
<p>The plugin&#8217;s code is located in the <strong>youTubeEmbed-jquery-1.0.js</strong> file. However, before being able to use it, you need to include the latest version of the jQuery library in the page, along with the jQuery SWFObject plugin and lastly <strong>script.js</strong>, which inserts two videos in the demonstration page and handles the submissions of the preview form.</p>
<pre class="brush:html">&lt;script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"&gt;&lt;/script&gt;
&lt;script src="jquery.swfobject.1-1-1.min.js"&gt;&lt;/script&gt;
&lt;script src="youTubeEmbed/youTubeEmbed-jquery-1.0.js"&gt;&lt;/script&gt;
&lt;script src="script.js"&gt;&lt;/script&gt;
</pre>
<p>Before we start digging into the player plugin&#8217;s code, lets take a look at a sample response from YouTube&#8217;s gdata api. It can give you a  lot of useful information about a video, including duration, access  control (both of which used by the plugin) and all sorts of additional  data such as title, description, tags, screenshots and more.</p>
<h4>Sample JSON response</h4>
<pre class="brush:js">{
    "id": "u1zgFlCw8Aw",
    "uploaded": "2008-03-05T01:22:17.000Z",
    "updated": "2010-07-23T01:02:42.000Z",
    "uploader": "GoogleDevelopers",
    "category": "People",
    "title": "The YouTube API: Upload, Player APIs and more!",
    "description": "Listen to the YouTube APIs and Tools team talk about...",
    "tags": ["youtube", "launch", "api", "engineering"],
    "thumbnail": {
        "sqDefault": "http://i.ytimg.com/vi/u1zgFlCw8Aw/default.jpg",
        "hqDefault": "http://i.ytimg.com/vi/u1zgFlCw8Aw/hqdefault.jpg"
    },
    "player": {
        "default": "http://www.youtube.com/watch?v=u1zgFlCw8Aw",
        "mobile": "http://m.youtube.com/details?v=u1zgFlCw8Aw"
    },
    "content": {
        "1": "rtsp://v4.cache5.c.youtube.com/CiILE..",
        "5": "http://www.youtube.com/v/u1zgFlCw8Aw?f..",
        "6": "rtsp://v3.cache4.c.youtube.com/CiILENy73.."
    },
    "duration": 259,
    "location": "san bruno, ca",
    "rating": 4.3,
    "likeCount": "119",
    "ratingCount": 144,
    "viewCount": 251024,
    "favoriteCount": 164,
    "commentCount": 118,
    "accessControl": {
        "syndicate": "allowed",
        "commentVote": "allowed",
        "rate": "allowed",
        "list": "allowed",
        "comment": "allowed",
        "embed": "allowed",
        "videoRespond": "allowed"
    }
}
</pre>
<p>All the fields of this response objects are available as properties in the <strong>data </strong>variable (<strong>data.fieldname</strong>). You could potentially modify the plugin to show the title with a link to the video page on youtube, or show the rating of the video.</p>
<p>Now lets dive directly into the script&#8217;s source code.</p>
<h4>youTubeEmbed-jquery-1.0.js &#8211; Part 1</h4>
<pre class="brush:js">(function($){

	$.fn.youTubeEmbed = function(settings){

		// Settings can be either a URL string,
		// or an object

		if(typeof settings == 'string'){
			settings = {'video' : settings}
		}

		// Default values

		var def = {
			width		: 640,
			progressBar	: true
		};

		settings = $.extend(def,settings);

		var elements = {
			originalDIV	: this,	// The "this" of the plugin
			container	: null,	// A container div, inserted by the plugin
			control		: null,	// The control play/pause button
			player		: null,	// The flash player
			progress	: null,	// Progress bar
			elapsed		: null	// The light blue elapsed bar
		};

		try{	

			settings.videoID = settings.video.match(/v=(\w+)/)[1];

			// safeID is a stripped version of videoID,
			// ready for use as a JavaScript function name

			settings.safeID = settings.videoID.replace(/[^a-z0-9]/ig,'');

		} catch (e){
			// If the url was invalid, just return the "this"
			return elements.originalDIV;
		}

		// Fetch data about the video from YouTube's API

		var youtubeAPI = 'http://gdata.youtube.com/feeds/api/videos?v=2&amp;alt=jsonc';

		$.get(youtubeAPI,{'q':settings.videoID},function(response){

			var data = response.data;

			if(!data.totalItems || data.items[0].accessControl.embed!="allowed"){

				// If the video was not found, or embedding is not allowed;

				return elements.originalDIV;
			}

			// data holds API info about the video:

			data = data.items[0];

			settings.ratio = 3/4;
			if(data.aspectRatio == "widescreen"){
				settings.ratio = 9/16;
			}

			settings.height = Math.round(settings.width*settings.ratio);
</pre>
<p>We start by defining our script as a jQuery plugin by adding it as a function to the <strong>$.fn</strong> object. To make the code easier to follow and read, I put all the elements of the page, such as the control and the progressBar divs in a structure called <strong>elements</strong>.</p>
<p>After extracting the <strong>id</strong> of the video (a unique 11 character sequence after the <strong>?v=</strong> parameter), we send a JSONP request to youtube&#8217;s gdata API. Depending on whether such a video exists, and on whether embedding is allowed on it, we proceed with calculating the aspect ratio. The height of the video is calculated by using this ratio and multiplying it to the width.</p>
<h4>youTubeEmbed-jquery-1.0.js &#8211; Part 2</h4>
<pre class="brush:js">			// Creating a container inside the original div, which will
			// hold the object/embed code of the video

			elements.container = $('&lt;div&gt;',{className:'flashContainer',css:{
				width	: settings.width,
				height	: settings.height
			}}).appendTo(elements.originalDIV);

			// Embedding the YouTube chromeless player
			// and loading the video inside it:

			elements.container.flash({
				swf			: 'http://www.youtube.com/apiplayer?enablejsapi=1&amp;version=3',
				id			: 'video_'+settings.safeID,
				height		: settings.height,
				width		: settings.width,
				allowScriptAccess:'always',
				wmode		: 'transparent',
				flashvars	: {
					"video_id"		: settings.videoID,
					"playerapiid"	: settings.safeID
				}
			});

			// We use get, because we need the DOM element
			// itself, and not a jquery object:

			elements.player = elements.container.flash().get(0);

			// Creating the control Div. It will act as a ply/pause button

			elements.control = $('&lt;div&gt;',{className:'controlDiv play'})
							   .appendTo(elements.container);

			// If the user wants to show the progress bar:

			if(settings.progressBar){
				elements.progress =	$('&lt;div&gt;',{className:'progressBar'})
									.appendTo(elements.container);

				elements.elapsed =	$('&lt;div&gt;',{className:'elapsed'})
									.appendTo(elements.progress);

				elements.progress.click(function(e){

					// When a click occurs on the progress bar, seek to the
					// appropriate moment of the video.

					var ratio = (e.pageX-elements.progress.offset().left)/elements.progress.outerWidth();

					elements.elapsed.width(ratio*100+'%');
					elements.player.seekTo(Math.round(data.duration*ratio), true);
					return false;
				});

			}
</pre>
<p>In the second part of the code, we use the <strong>SWFObject </strong>plugin to generate the embed code of  the youtube chromeless player. Notice that the id of the video is passed as a flashvar so the player can load it directly. The safeID variable (a JavaScript safe version of the videoid) becomes the value of the <strong>id</strong> parameter of the to-be generated object element. This way we can later fetch the DOM element by running <strong>document.getElementById(&#8216;video_&#8217;+settings.safeID)</strong> and get access to the <a href="http://code.google.com/apis/youtube/js_api_reference.html" target="_blank">methods which control the youtube player</a> (play, pause etc).</p>
<h4>youTubeEmbed-jquery-1.0.js &#8211; Part 3</h4>
<pre class="brush:js">var initialized = false;

// Creating a global event listening function for the video
// (required by YouTube's player API):

window['eventListener_'+settings.safeID] = function(status){

	var interval;

	if(status==-1)	// video is loaded
	{
		if(!initialized)
		{
			// Listen for a click on the control button:

			elements.control.click(function(){
				if(!elements.container.hasClass('playing')){

					// If the video is not currently playing, start it:

					elements.control.removeClass('play replay').addClass('pause');
					elements.container.addClass('playing');
					elements.player.playVideo();

					if(settings.progressBar){
						interval = window.setInterval(function(){
							elements.elapsed.width(
					((elements.player.getCurrentTime()/data.duration)*100)+'%'
							);
						},1000);
					}

				} else {

					// If the video is currently playing, pause it:

					elements.control.removeClass('pause').addClass('play');
					elements.container.removeClass('playing');
					elements.player.pauseVideo();

					if(settings.progressBar){
						window.clearInterval(interval);
					}
				}
			});

			initialized = true;
		}
		else{
			// This will happen if the user has clicked on the
			// YouTube logo and has been redirected to youtube.com

			if(elements.container.hasClass('playing'))
			{
				elements.control.click();
			}
		}
	}</pre>
<p>In order to be able to control the video player, we need to be notified when certain events (like playback stopped, video ready etc) occur. Normally, this would mean that we need to pass a callback function, which is executed by the player every time such an event happens.</p>
<p>Unfortunately, flash can only execute functions if they are defined in the global scope and cannot see the functions which are defined inside the plugin. However, by creating functions with unique names (with the <strong>safeID</strong>) and explicitly adding them to the <strong>window</strong> object we can make this happen. If it weren&#8217;t for this little trick, it would be impossible for the plugin to work.</p>
<h4>youTubeEmbed-jquery-1.0.js &#8211; Part 4</h4>
<pre class="brush:js">				if(status==0){ // video has ended
					elements.control.removeClass('pause').addClass('replay');
					elements.container.removeClass('playing');
				}
			}

			// This global function is called when the player is loaded.
			// It is shared by all the videos on the page:

			if(!window.onYouTubePlayerReady)
			{
				window.onYouTubePlayerReady = function(playerID){
					document.getElementById('video_'+playerID).addEventListener('onStateChange','eventListener_'+playerID);
				}
			}
		},'jsonp');

		return elements.originalDIV;
	}

})(jQuery);
</pre>
<p>The event listening function we created in the previous section of the code, is attached to the player with the <strong>addEventListener</strong> method. It is called every time when a &#8220;<strong>stateChange</strong>&#8221; occurs (playback start, playback pause, end of playback etc). A numeric code is passed to the event listening function as a parameter, corresponding to the event.</p>
<p>Now lets take a look at how our plugin is used.</p>
<h4>script.js</h4>
<pre class="brush:js">$(document).ready(function(){

	$('#player').youTubeEmbed('http://www.youtube.com/watch?v=u1zgFlCw8Aw');

	/*
		//You can alternatively pass an object:

		$('#player').youTubeEmbed({
			video			: 'http://www.youtube.com/watch?v=u1zgFlCw8Aw',
			width			: 600, 		// Height is calculated automatically
			progressBar	: false		// Hide the progress bar
		});

	*/

});
</pre>
<p>You just need to call the <strong>youTubeEmbed()</strong> method and pass it either a string or a configuration object. If a string is passed, it is assumed to be the URL of a YouTube video. If you are passing an object make sure that you are passing the <strong>video </strong>property with a correct video URL.</p>
<div id="attachment_1033" class="wp-caption alignnone" style="width: 630px"><a href="http://demo.tutorialzine.com/2010/07/youtube-api-custom-player-jquery-css/youtube-player.html"><img class="size-full wp-image-1033" title="Video Playing with a Progress Bar" src="http://tutorialzine.com/wp-content/uploads/2010/07/i21.jpg" alt="Video Playing with a Progress Bar" width="620" height="460" /></a><p class="wp-caption-text">Video Playing with a Progress Bar</p></div>
<h3>Step 3 &#8211; CSS</h3>
<p>Finally we are left with applying a few CSS styles to the player. They will change the design of the player controls and define the way they are positioned in the player window.</p>
<h4>youTubeEmbed-jquery-1.0.css</h4>
<pre class="brush:css">.flashContainer{

	/*	Setting the container to relative positioning
		so we can center the control div */

	position:relative;
	overflow:hidden;
}

.progressBar{
	display:none;
	position:absolute;
	width:auto;
	height:8px;
	left:20px;
	right:105px;
	bottom:20px;
	background-color:#141414;
	overflow:hidden;
	cursor:pointer;

	/* A light CSS3 bottom highlight */

	-moz-box-shadow:0 1px 0 rgba(255, 255, 255, 0.3);
	-webkit-box-shadow:0 1px 0 rgba(255, 255, 255, 0.3);
	box-shadow:0 1px 0 rgba(255, 255, 255, 0.3);
}

.progressBar .elapsed{
	position:absolute;
	width:0;
	height:100%;
	background-color:#1fa2f6;
	border-right:1px solid #49AFF0;
}

.controlDiv{
	/* Centering the control div */
	position:absolute;
	width:120px;
	height:120px;
	cursor:pointer;
	top:50%;
	left:50%;
	margin:-60px 0 0 -60px;
}

.controlDiv.play{
	background:url('img/play.png') no-repeat center center;
}

.controlDiv.replay{
	background:url('img/replay.png') no-repeat center center;
}

.controlDiv.pause{
	background:url('img/pause.png') no-repeat -99999px;
}

.flashContainer:hover .controlDiv.pause{
	background-position:center center;
}

/* Only show the progress bar when the video is playing */

.flashContainer.playing:hover .progressBar{
	display:block;
}</pre>
<p>To customize the look of the player you just need to change the color values above. Also you can edit the png files with the play/pause buttons. Clearly this is much easier than modifying the looks of the default youtube player. It also strips all of the unnecessary chrome and leaves you with what matters most &#8211; your video.</p>
<p><strong>With this our Custom YouTube Player plugin is complete!</strong></p>
<p>Did you like this tutorial? Share your thoughts in the comment section below.</p>
]]></content:encoded>
			<wfw:commentRss>http://tutorialzine.com/2010/07/youtube-api-custom-player-jquery-css/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Colortip &#8211; a jQuery Tooltip Plugin</title>
		<link>http://tutorialzine.com/2010/07/colortips-jquery-tooltip-plugin/</link>
		<comments>http://tutorialzine.com/2010/07/colortips-jquery-tooltip-plugin/#comments</comments>
		<pubDate>Wed, 14 Jul 2010 19:48:49 +0000</pubDate>
		<dc:creator>Martin Angelov</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://tutorialzine.com/?p=1019</guid>
		<description><![CDATA[In this tutorial we are going to write a simple jQuery tooltip plugin. It is going to convert the title attributes of elements withing your page, into a series of colorful tooltips.]]></description>
			<content:encoded><![CDATA[<p>In this tutorial we are going to write a simple jQuery tooltip plugin. It is going to convert the title attributes of elements withing your page, into a series of colorful tooltips. Six color themes are available, so you can easily match it with the rest of your design.</p>
<h3>Step 1 &#8211; XHTML</h3>
<p>The plugin we are about to write today, works by converting the title of an element on the page to a structure of three spans, which form a tooltip, displayed on hover. So if you start with a regular link like this one:</p>
<pre class="brush:html">&lt;a href="http://tutorialzine.com/" class="blue" title="Go to Tutorialzine"&gt;Tutorialzine&lt;/a&gt;</pre>
<p>jQuery will convert it to the markup you can see below.</p>
<pre class="brush:html">&lt;a class="blue colorTipContainer" href="http://tutorialzine.com/"&gt;Tutorialzine
&lt;span class="colorTip" style="margin-left: -60px;"&gt;Go to Tutorialzine
&lt;span class="pointyTipShadow"&gt;&lt;/span&gt;
&lt;span class="pointyTip"&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/a&gt;</pre>
<p>Notice that the first block of code above specifies a &#8220;<strong>blue</strong>&#8221; class name. This  is because we are overriding the default color of the tip (yellow). You  can choose from <strong>red</strong>, <strong>blue</strong>, <strong>green</strong>, <strong>yellow</strong>, <strong>white </strong>and <strong>black</strong>, or you can  create your own colors in the plugin stylesheet.</p>
<p>Users which have JavaScript disabled are still going to see the regular title tooltips on the page, so the script degrades gracefully.</p>
<h3>Step 2 &#8211; CSS</h3>
<p>To display the colorful tips on your page, you first need to include the plugin stylesheet file in the head section of the html document.</p>
<pre class="brush:html">&lt;link rel="stylesheet" type="text/css" href="colortip-1.0/colortip-1.0-jquery.css"/&gt;</pre>
<p>You could also just copy the styles from the file and paste them directly in your main stylesheet, if you do not want to keep a separate include file. This stylesheet defines both the positioning and the design of the tooltips. It comes with six color themes, and you can easily add more.</p>
<h4>colortip-1.0-jquery.css &#8211; Part 1</h4>
<pre class="brush:css">.colorTipContainer{
	position:relative;
	text-decoration:none !important;
}

.colorTip{
	/* This class is assigned to the color tip span by jQuery */

	display:none;
	position:absolute;
	left:50%;
	top:-30px;
	padding:6px;

	background-color:white;
	font-family:Arial,Helvetica,sans-serif;
	font-size:11px;
	font-style:normal;
	line-height:1;
	text-decoration:none;
	text-align:center;
	text-shadow:0 0 1px white;
	white-space:nowrap;

	-moz-border-radius:4px;
	-webkit-border-radius:4px;
	border-radius:4px;
}

.pointyTip,.pointyTipShadow{
	/* Setting a thick transparent border on a 0x0 div to create a triangle */
	border:6px solid transparent;
	bottom:-12px;
	height:0;
	left:50%;
	margin-left:-6px;
	position:absolute;
	width:0;
}

.pointyTipShadow{
	/* The shadow tip is 1px larger, so it acts as a border to the tip */
	border-width:7px;
	bottom:-14px;
	margin-left:-7px;
}</pre>
<p>The <strong>.colorTipContainer</strong> class is assigned to the elements to which the color tips are added. It sets their positioning to relative, so that the tips can be <a href="http://tutorialzine.com/2010/03/centering-div-vertically-and-horizontally/" target="_blank">centered</a> above them.</p>
<p>A neat CSS trick is used to create the triangular pointy tips. As  you know, divs and spans can only take a rectangular shape (or an ellipse / rounded rectangle if you apply border-radius). However, if you apply a thick border to a 0 by 0 element, the only way the borders are going to fit is to take up a triangular space on each side. Then, by setting the default border color to transparent, you can make visible any of the four triangular shapes.</p>
<div id="attachment_1023" class="wp-caption alignnone" style="width: 630px"><a href="http://demo.tutorialzine.com/2010/07/colortips-jquery-tooltip-plugin/colortips.html"><img class="size-full wp-image-1023" title="Making a triangular shape with a div" src="http://tutorialzine.com/wp-content/uploads/2010/07/i2.jpg" alt="Making a triangular shape with a div" width="620" height="260" /></a><p class="wp-caption-text">Making a triangular shape with a div</p></div>
<p>This is actually done on both the .<strong>pointyTip </strong>and the .<strong>pointyTipShadow </strong>spans, in order to give an impression that the pointy tip has a border applied so it matches the rest of the colortip design. Now lets take a closer look at the six color themes.</p>
<h4>colortip-1.0-jquery.css &#8211; Part 2</h4>
<pre class="brush:css">/* 6 Available Color Themes */

.white .pointyTip{ border-top-color:white;}
.white .pointyTipShadow{ border-top-color:#ddd;}
.white .colorTip{
	background-color:white;
	border:1px solid #DDDDDD;
	color:#555555;
}

.yellow .pointyTip{ border-top-color:#f9f2ba;}
.yellow .pointyTipShadow{ border-top-color:#e9d315;}
.yellow .colorTip{
	background-color:#f9f2ba;
	border:1px solid #e9d315;
	color:#5b5316;
}

.blue .pointyTip{ border-top-color:#d9f1fb;}
.blue .pointyTipShadow{ border-top-color:#7fcdee;}
.blue .colorTip{
	background-color:#d9f1fb;
	border:1px solid #7fcdee;
	color:#1b475a;
}

.green .pointyTip{ border-top-color:#f2fdf1;}
.green .pointyTipShadow{ border-top-color:#b6e184;}
.green .colorTip{
	background-color:#f2fdf1;
	border:1px solid #b6e184;
	color:#558221;
}

.red .pointyTip{ border-top-color:#bb3b1d;}
.red .pointyTipShadow{ border-top-color:#8f2a0f;}
.red .colorTip{
	background-color:#bb3b1d;
	border:1px solid #8f2a0f;
	color:#fcfcfc;
	text-shadow:none;
}

.black .pointyTip{ border-top-color:#333;}
.black .pointyTipShadow{ border-top-color:#111;}
.black .colorTip{
	background-color:#333;
	border:1px solid #111;
	color:#fcfcfc;
	text-shadow:none;
}</pre>
<p>Remember that only the borders are the only visible part of the pointy tips. You can add your own color themes by following the same structure.</p>
<h3>Step 3 &#8211; jQuery</h3>
<p>First you need to include the jquery library and the plugin files to the page, after which our script.js file, which is going to utilize the plugin and add colortips to the links on the page.</p>
<pre class="brush:html">&lt;script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="colortip-1.0/colortip-1.0-jquery.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="script.js"&gt;&lt;/script&gt;</pre>
<p>For performance reasons, I&#8217;ve put this code at the bottom of the <strong>colortips.html</strong> file. This allow for the page design to be rendered before the browser blocks for the loading of the js files.</p>
<p>Now lets take a look at the colortip the plugin.</p>
<h4>colortip-1.0-jquery.js &#8211; Part 1</h4>
<pre class="brush:js">(function($){
	$.fn.colorTip = function(settings){

		var defaultSettings = {
			color		: 'yellow',
			timeout		: 500
		}

		var supportedColors = ['red','green','blue','white','yellow','black'];

		/* Combining the default settings object with the supplied one */
		settings = $.extend(defaultSettings,settings);

		/*
		*	Looping through all the elements and returning them afterwards.
		*	This will add chainability to the plugin.
		*/

		return this.each(function(){

			var elem = $(this);

			// If the title attribute is empty, continue with the next element
			if(!elem.attr('title')) return true;

			// Creating new eventScheduler and Tip objects for this element.
			// (See the class definition at the bottom).

			var scheduleEvent = new eventScheduler();
			var tip = new Tip(elem.attr('title'));

			// Adding the tooltip markup to the element and
			// applying a special class:

			elem.append(tip.generate()).addClass('colorTipContainer');

			// Checking to see whether a supported color has been
			// set as a classname on the element.

			var hasClass = false;
			for(var i=0;i&lt;supportedColors.length;i++)
			{
				if(elem.hasClass(supportedColors[i])){
					hasClass = true;
					break;
				}
			}

			// If it has been set, it will override the default color

			if(!hasClass){
				elem.addClass(settings.color);
			}</pre>
<p>When you call the plugin, you can pass a configuration object, which holds the default color and the timeout after which the tooltips disappear on mouseleave.</p>
<p>You can choose from six possible colors and assign them as a class name to the element. The plugin would check if a color class is present, and if it is not, it will apply the default one you&#8217;ve passed in the config object. If you&#8217;ve not passed a config object, yellow will be used instead.</p>
<div id="attachment_1024" class="wp-caption alignnone" style="width: 630px"><a href="http://demo.tutorialzine.com/2010/07/colortips-jquery-tooltip-plugin/colortips.html"><img class="size-full wp-image-1024" title="Colortip jQuery Plugin" src="http://tutorialzine.com/wp-content/uploads/2010/07/i1.png" alt="Colortip jQuery Plugin" width="620" height="260" /></a><p class="wp-caption-text">Colortip jQuery Plugin</p></div>
<h4>colortip-1.0-jquery.js &#8211; Part 2</h4>
<pre class="brush:js">			// On mouseenter, show the tip, on mouseleave set the
			// tip to be hidden in half a second.

			elem.hover(function(){

				tip.show();

				// If the user moves away and hovers over the tip again,
				// clear the previously set event:

				scheduleEvent.clear();

			},function(){

				// Schedule event actualy sets a timeout (as you can
				// see from the class definition below).

				scheduleEvent.set(function(){
					tip.hide();
				},settings.timeout);

			});

			// Removing the title attribute, so the regular OS titles are
			// not shown along with the tooltips.

			elem.removeAttr('title');
		});

	}

	/*
	/	Event Scheduler Class Definition
	*/

	function eventScheduler(){}

	eventScheduler.prototype = {
		set	: function (func,timeout){

			// The set method takes a function and a time period (ms) as
			// parameters, and sets a timeout

			this.timer = setTimeout(func,timeout);
		},
		clear: function(){

			// The clear method clears the timeout

			clearTimeout(this.timer);
		}
	}</pre>
<p>In the second part of the plugin code, we bind event listeners to the hover event (combination of  a mouseenter and a mouseleave event).</p>
<p>Notice the event scheduler class. It is used to set a function to be executed after a predetermined period of time. At its heart lays a call to <strong> setTimeout</strong>. A <em><strong>clear()</strong></em> method is also provided as a part of the class, so previously scheduled events can be destroyed (useful when you move your mouse away from a tooltip and then move it back over before it has disappeared).</p>
<h4>colortip-1.0-jquery.js &#8211; Part 3</h4>
<pre class="brush:js">	/*
	/	Tip Class Definition
	*/

	function Tip(txt){
		this.content = txt;
		this.shown = false;
	}

	Tip.prototype = {
		generate: function(){

			// The generate() method returns either a previously generated element
			// stored in the tip variable, or generates and saves it in tip for
			// later use, after which returns it.

			return this.tip || (this.tip = $('&lt;span class="colorTip"&gt;'+this.content+
											 '&lt;span class="pointyTipShadow"&gt;&lt;/span&gt;&lt;span class="pointyTip"&gt;&lt;/span&gt;&lt;/span&gt;'));
		},
		show: function(){
			if(this.shown) return;

			// Center the tip and start a fadeIn animation
			this.tip.css('margin-left',-this.tip.outerWidth()/2).fadeIn('fast');
			this.shown = true;
		},
		hide: function(){
			this.tip.fadeOut();
			this.shown = false;
		}
	}

})(jQuery);</pre>
<p>In the last part of the code we define the tip class. It has a <strong>generate</strong>, <strong>show </strong>and <strong>hide </strong>methods. An object from this class is created for each of the tooltips. The generate method is called first, and the tooltip is stored in the local <strong>this.tip</strong> variable. The show and hide methods operate on this variable to run fade in/out animations.</p>
<p>Now we are only left with calling the plugin and adding colortips to all the links on the page.</p>
<h4>script.js</h4>
<pre class="brush:js">$(document).ready(function(){

	/* Adding a colortip to any tag with a title attribute: */

	$('[title]').colorTip({color:'yellow'});

});</pre>
<p>The configuration object here might as well be omitted, because yellow is the default value anyway. But you could specify a different color for the tooltips. If you apply <em>red,</em> <em>green,</em> <em>blue</em>, <em>white</em>, <em>yellow</em> or <em>black</em> as a class name of the element, the design of the tooltip will be overridden.</p>
<p><strong>With this our Colortip plugin is complete!</strong></p>
<h3>Wrapping it up</h3>
<p>Using the plugin we wrote today is really easy, as it does not require any specific configuration. It just takes a series of elements and replaces their title attributes with colorful tooltips. You can also easily create your own tooltip designs by just including three additional style classes to your stylesheet and adding an element to the supported colors array in <strong><em>colortip-1.0-jquery.js.</em></strong></p>
<p><strong>What do you think? How would you improve this plugin?<em><br />
</em></strong></p>
]]></content:encoded>
			<wfw:commentRss>http://tutorialzine.com/2010/07/colortips-jquery-tooltip-plugin/feed/</wfw:commentRss>
		<slash:comments>35</slash:comments>
		</item>
		<item>
		<title>Making a Slick MobileApp Website with jQuery &amp; CSS</title>
		<link>http://tutorialzine.com/2010/07/making-slick-mobileapp-website-jquery-css/</link>
		<comments>http://tutorialzine.com/2010/07/making-slick-mobileapp-website-jquery-css/#comments</comments>
		<pubDate>Fri, 09 Jul 2010 15:47:53 +0000</pubDate>
		<dc:creator>Martin Angelov</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://tutorialzine.com/?p=1006</guid>
		<description><![CDATA[This time we are making a complete jQuery &#038; CSS website for a fictional mobile application. It is going to feature semantic markup and a progressively enhanced slideshow effect.]]></description>
			<content:encoded><![CDATA[<p>As a web developer, you have to bring creativity and attention to detail to your work. It is often the little things that leave a lasting impression to a visitor. Be it a lovable character illustration, or unique slideshow, it is usually not the information you present that is memorable, but the way you present it.</p>
<p>Today we are making a complete jQuery &amp; CSS website for a fictional mobile application. It is going to feature semantic markup and a progressively enhanced slideshow effect. It will allow the user to see four of the most popular smartphones running the mobile app.</p>
<h3>Step 1 &#8211; XHTML</h3>
<p>When building websites it is important that you lay your code in a semantic way. This would include using tags for what they were supposed to be used for. You should use headings for titles, paragraphs for text (instead of generic divs) and lists where applicable.</p>
<h4>mobileapp.html</h4>
<pre class="brush:html">&lt;div id="page"&gt;

    &lt;h1 id="logoh1"&gt;&lt;a href="/" id="logo"&gt;MobileApp - the most useful mobile app!&lt;/a&gt;&lt;/h1&gt;

    &lt;div id="phoneCarousel"&gt;
    	&lt;div class="previous arrow"&gt;&lt;/div&gt;
        &lt;div class="next arrow"&gt;&lt;/div&gt;

        &lt;div id="stage"&gt;
            &lt;img id="iphone" class="default" src="img/phones/iphone.png" width="270" height="400" alt="iPhone" /&gt;
            &lt;img id="nexus" src="img/phones/nexus_one.png" width="270" height="400" alt="Nexus One" /&gt;
            &lt;img id="nokia" src="img/phones/nokia.png" width="270" height="400" alt="Nokia" /&gt;
            &lt;img id="blackberry" src="img/phones/blackberry.png" width="270" height="400" alt="BlackBerry" /&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;img class="availableAppStore" src="img/available_on_the_appstore.png" width="230" height="80" alt="Available on the Appstore" /&gt;

    &lt;div class="text"&gt;
    	&lt;h3&gt;&lt;img src="img/thumb.png" alt="MobileApp" width="114" height="114" class="thumb" /&gt;A wonderful app&lt;/h3&gt;
        &lt;p&gt;Lorem ipsum dolor sit amet.. &lt;/p&gt;
    &lt;/div&gt;

    &lt;div class="text"&gt;
    	&lt;h3&gt;&lt;img src="img/thumb.png" alt="MobileApp" width="114" height="114" class="thumb" /&gt;More awesome facts&lt;/h3&gt;
        &lt;p&gt;Lorem ipsum dolor sit amet.. &lt;/p&gt;
    &lt;/div&gt;

&lt;/div&gt;</pre>
<p>This is all the markup that is used to display the website. The h1 heading holds a hyperlink which is styled as the logo (the logo image is set as the background of the hyperlink and a negative text indent is used to hide the text of the link).</p>
<p>After this we have the <strong>#phoneCarousel</strong> div and inside it are the arrows and the stage. The phone images inside the stage are rotated with jQuery as you will see in a moment.</p>
<p>Lastly we have the <em>Available on the Appstore</em> badge, and two blocks of text.</p>
<div id="attachment_1010" class="wp-caption alignnone" style="width: 630px"><a href="http://demo.tutorialzine.com/2010/07/making-slick-mobileapp-website-jquery-css/mobileapp.html"><img class="size-full wp-image-1010" title="Slick MobileApp Website - Slideshow" src="http://tutorialzine.com/wp-content/uploads/2010/07/i1.jpg" alt="Slick MobileApp Website - Slideshow" width="620" height="460" /></a><p class="wp-caption-text">Slick MobileApp Website - Slideshow</p></div>
<h3>Step 2 &#8211; CSS</h3>
<p>CSS is responsible for converting our semantic markup into a true website. Take a closer look at the <strong>#stage</strong> styles in the second part of the code, as these are what make the animation possible.</p>
<h4>styles.css &#8211; Part 1</h4>
<pre class="brush:css">body{
	font-size:14px;
	color:#515151;
	background:url('img/bg.png') repeat-x #f6f8f9;
	font-family:'Myriad Pro',Arial, Helvetica, sans-serif;
}

#logoh1{ margin:40px 0 0;}

#page{
	/* This the main container div */
	width:1000px;
	min-height:700px;
	margin:0 auto;
	background:url('img/bokeh.jpg') no-repeat 0 120px;
	position:relative;
	padding-top:1px;
}

#phoneCarousel{
	/*	This is the carousel section, it
		contains the stage and the arrows */
	height:390px;
	margin:90px auto 120px;
	position:relative;
	width:800px;
}

#phoneCarousel .arrow{
	/* The two arrows */
	width:44px;
	height:44px;
	background:url('img/arrows.png') no-repeat;
	position:absolute;
	top:50%;
	margin-top:-22px;
	left:0;
	cursor:pointer;
}

#phoneCarousel .next{
	/* Individual styles for the next icon */
	background-position:right top;
	left:auto;
	right:0;
}

/* Hover styles */

#phoneCarousel .arrow:hover{
	background-position:left bottom;
}

#phoneCarousel .next:hover{
	background-position:right bottom;
}</pre>
<p>After defining the  body styles we can move on to styling the <strong>#page</strong> div, which holds everything together. Its <a href="http://demo.tutorialzine.com/2010/07/making-slick-mobileapp-website-jquery-css/img/bokeh.jpg" target="_blank">background image</a> is offset 120px vertically, so it matches the background of the body, filling the full width of the page.</p>
<p>Next is the <strong>#phoneCarousel</strong> div. It has a relative positioning applied, so the stage (where all the animations take place) can be <a href="http://tutorialzine.com/2010/03/centering-div-vertically-and-horizontally/" target="_blank">properly centered</a>. The previous/next arrows are styled as well.</p>
<h4>styles.css &#8211; Part 2</h4>
<pre class="brush:css">#logo{
	background:url('img/logo.png') no-repeat;
	height:40px;
	text-indent:-9999px;
	width:210px;
	display:block;
}

#stage{
	/* The stage contains the animated phone images */
	left:50%;
	margin-left:-350px;
	position:absolute;
	width:700px;
	height:100%;
}

#stage img{
	/* Hiding all the images by default */
	display:none;
}

#stage .default{
	/*	This class is applied only to the iphone img by default
		and it is the only one visible if JS is disabled */
	display:block;
	left:50%;
	margin-left:-135px;
	position:absolute;
}

#stage .animationReady{
	/* This class is assigned to the images on load */
	display:block;
	position:absolute;
	top:0;
	left:0;
}

.text{	margin-top:70px;width:700px;}

.text p,
.text h3{
	padding-bottom:15px;
	line-height:1.4;
	text-align:justify;
}

.text h3{	font-size:30px;}
.text p{	font-size:20px;}

.thumb{	float:left;margin-right:40px;}

.availableAppStore{float:right;}</pre>
<p>In the second part of the stylesheet, we continue with the <strong>#stage</strong> styles. The phone pictures are hidden by default, so if JavaScript is disabled, the user is not left with a bunch of scattered images.</p>
<p>As you will see in the next step, the animation is achieved through changing the top and left CSS properties. For this to work, the images must be absolutely positioned. This is why the <strong>.animatonReady</strong> class is assigned on load with jQuery (if JS is disabled, this style would not be applied).</p>
<p>Lastly we style the text blocks, which explain details about our fictional MobileApp.</p>
<div id="attachment_1011" class="wp-caption alignnone" style="width: 630px"><a href="http://demo.tutorialzine.com/2010/07/making-slick-mobileapp-website-jquery-css/mobileapp.html"><img class="size-full wp-image-1011" title="Text Blocks" src="http://tutorialzine.com/wp-content/uploads/2010/07/i2.png" alt="Text Blocks" width="620" height="260" /></a><p class="wp-caption-text">Text Blocks</p></div>
<h3>Step 3 &#8211; jQuery</h3>
<p>When you click on one of the arrows, an animation starts, which uses sine and cosine calculations to move and scale down the images, creating the illusion of a circular movement. It is not as complicated as it sounds, as you can see for yourself from the code below.</p>
<h4>script.js</h4>
<pre class="brush:js">$(document).ready(function(){

	var deg=0;

	/* Storing all the images into a variable */

	var images	= $('#stage img').removeClass('default').addClass('animationReady');
	var dim		= { width:images.width(),height:images.height()};

	var cnt = images.length;

	/* Finding the centers of the animation container: */
	var centerX = $('#stage').width()/2;
	var centerY = $('#stage').height()/2 - dim.height/2;

	function rotate(step,total){
		// This function will loop through all the phone images, and rotate them
		// with "step" degrees (10 in this implementation) till total &gt; 0

		/* Increment the degrees: */
		deg+=step;

		var eSin,eCos,newWidth,newHeight,q;

		/* Loop through all the images: */
		for(var i=0;i&lt;cnt;i++){

			/* Calculate the sine and cosine for the i-th image */

			q = ((360/cnt)*i+deg)*Math.PI/180;
			eSin		= Math.sin(q);
			eCos		= Math.cos(q);

			/*
			/	With the sine value, we can calculate the vertical movement,
			/	and the cosine will give us the horizontal movement.
			*/

			q = (0.6+eSin*0.4);
			newWidth	= q*dim.width;
			newHeight	= q*dim.height;

			/*
			/	We are using the calculated sine value (which is in the range
			/	of -1 to 1) to calculate the opacity and z-index. The
 			/	frontmost image has a sine value of 1, while the backmost
			/	one has a sine value of -1.
			*/

			// eq() extracts the image at the i-th position:

			images.eq(i).css({
				top			: centerY+15*eSin,
				left		: centerX+200*eCos,
				opacity		: 0.8+eSin*0.2,
				marginLeft	: -newWidth/2,
				zIndex		: Math.round(80+eSin*20)
			}).width(newWidth).height(newHeight);
		}

		total-=Math.abs(step);
		if(total&lt;=0) return false;

		// Setting the function to be run again in 40 milliseconds (equals to 25 frames per second):
		setTimeout(function(){rotate(step,total)},40);

	}

	// Running the animation once at load time (and moving the iPhone into view):
	rotate(10,360/cnt);

	$('#phoneCarousel .previous').click(function(){
		// 360/cnt lets us distribute the phones evenly in a circle
		rotate(-10,360/cnt);
	});

	$('#phoneCarousel .next').click(function(){
		rotate(10,360/cnt);
	});
});</pre>
<p>To start an animation you just need to call the <strong>rotate</strong> function with two arguments &#8211; a step, and a total rotation, both of which are numbers. Step can be negative, which would mean that the rotation is run in the opposite way. Each time the function is run, total is decremented with the absolute value of the step, and once it reaches zero the animation is stopped.</p>
<p>In a number of places in this code, you can see that I&#8217;ve used a specific calculation &#8211; <strong>360/cnt</strong>. This is done to distribute the phones evenly (360 being the number of degrees in a circle).  This way you can add or remove images and they will be properly animated.</p>
<div id="attachment_1012" class="wp-caption alignnone" style="width: 630px"><a href="http://demo.tutorialzine.com/2010/07/making-slick-mobileapp-website-jquery-css/mobileapp.html"><img class="size-full wp-image-1012" title="Slick MobileApp Website" src="http://tutorialzine.com/wp-content/uploads/2010/07/i3.jpg" alt="Slick MobileApp Website" width="620" height="260" /></a><p class="wp-caption-text">Slick MobileApp Website</p></div>
<p><strong>With this our Slick MobleApp Website is complete!</strong></p>
<h3>Wrapping it up</h3>
<p>Today we made a complete jQuery &amp; CSS website for a fictional  mobile application. You are free to modify the code and use it any way you see fit. If you liked the tutorial be sure to subscribe to our <a href="http://feeds.feedburner.com/Tutorialzine" target="_blank">RSS feed</a>, <a href="http://twitter.com/Tutorialzine">follow us on twitter</a>, or leave a comment in the section below.</p>
]]></content:encoded>
			<wfw:commentRss>http://tutorialzine.com/2010/07/making-slick-mobileapp-website-jquery-css/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Simple AJAX Commenting System</title>
		<link>http://tutorialzine.com/2010/06/simple-ajax-commenting-system/</link>
		<comments>http://tutorialzine.com/2010/06/simple-ajax-commenting-system/#comments</comments>
		<pubDate>Wed, 30 Jun 2010 18:02:24 +0000</pubDate>
		<dc:creator>Martin Angelov</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://tutorialzine.com/?p=990</guid>
		<description><![CDATA[This time, we are making a Simple AJAX Commenting System. It will feature a gravatar integration and demonstrate how to achieve effective communication between jQuery and PHP/MySQL with the help of JSON.]]></description>
			<content:encoded><![CDATA[<p>This time, we are making a Simple AJAX Commenting System. It will feature a gravatar integration and demonstrate how to achieve effective communication between jQuery and PHP/MySQL with the help of JSON.</p>
<h3>Step 1 &#8211; XHTML</h3>
<p>First, lets take a look at the markup of the comments. This code is generated by PHP in the Comment class, which we are going  to take a look at in a moment.</p>
<h4>demo.php</h4>
<pre class="brush:html">&lt;div class="comment"&gt;
    &lt;div class="avatar"&gt;
        &lt;a href="http://tutorialzine.com/"&gt;
        &lt;img src="http://www.gravatar.com/avatar/112fdf7a8fe3609e7af2cd3873b5c6bd?size=50&amp;default=http%3A%2F%2Fdemo.tutorialzine.com%2F2010%2F06%2Fsimple-ajax-commenting-system%2Fimg%2Fdefault_avatar.gif"&gt;
        &lt;/a&gt;
    &lt;/div&gt;

    &lt;div class="name"&gt;&lt;a href="http://tutorialzine.com/"&gt;Person's Name&lt;/a&gt;&lt;/div&gt;
    &lt;div title="Added at 06:40 on 30 Jun 2010" class="date"&gt;30 Jun 2010&lt;/div&gt;
    &lt;p&gt;Comment Body&lt;/p&gt;
&lt;/div&gt;</pre>
<p>The avatar div contains a hyperlink (if the user entered a valid URL when submitting the comment) and an avatar image, which is fetched from <a href="http://en.gravatar.com/site/implement/images/" target="_blank">gravatar.com</a>. We will return to this in the PHP step of the tut. Lastly we have the name and time divs, and the comment body.</p>
<p>The other important element in the XHTML part is the comment form. It is sent via <strong>POST</strong>. All fields except for the URL field are required.</p>
<h4>demo.php</h4>
<pre class="brush:html">&lt;div id="addCommentContainer"&gt;
	&lt;p&gt;Add a Comment&lt;/p&gt;
	&lt;form id="addCommentForm" method="post" action=""&gt;
    	&lt;div&gt;
        	&lt;label for="name"&gt;Your Name&lt;/label&gt;
        	&lt;input type="text" name="name" id="name" /&gt;

            &lt;label for="email"&gt;Your Email&lt;/label&gt;
            &lt;input type="text" name="email" id="email" /&gt;

            &lt;label for="url"&gt;Website (not required)&lt;/label&gt;
            &lt;input type="text" name="url" id="url" /&gt;

            &lt;label for="body"&gt;Comment Body&lt;/label&gt;
            &lt;textarea name="body" id="body" cols="20" rows="5"&gt;&lt;/textarea&gt;

            &lt;input type="submit" id="submit" value="Submit" /&gt;
        &lt;/div&gt;
    &lt;/form&gt;
&lt;/div&gt;</pre>
<p>The form is submitted via AJAX. The validation is performed entirely in the backend by <strong>submit.php</strong>, as you will see in the jQuery step of the tutorial. Every field has a corresponding label element, with an appropriate <strong>for</strong> attribute.</p>
<div id="attachment_998" class="wp-caption alignnone" style="width: 630px"><a href="http://demo.tutorialzine.com/2010/06/simple-ajax-commenting-system/demo.php"><img class="size-full wp-image-998" title="Simple AJAX Commenting System" src="http://tutorialzine.com/wp-content/uploads/2010/06/i11.jpg" alt="Simple AJAX Commenting System" width="620" height="460" /></a><p class="wp-caption-text">Simple AJAX Commenting System</p></div>
<h3>Step 2 &#8211; PHP</h3>
<p>PHP handles the communication with the MySQL database and generates the markup of the comments. It is also on the receiving end of the AJAX requests and inserts the comment data to the <strong>comments</strong> table. You can see the code that prints the comments to the page below.</p>
<h4>demo.php</h4>
<pre class="brush:php">/*
/	Select all the comments and populate the $comments array with objects
*/

$comments = array();
$result = mysql_query("SELECT * FROM comments ORDER BY id ASC");

while($row = mysql_fetch_assoc($result))
{
	$comments[] = new Comment($row);
}</pre>
<p>The MySQL query selects all the entries from the database and fills the <strong>$comments</strong> array with objects of the comment class, which you will see below. This array is outputted later in the execution of the script.</p>
<h4>demo.php</h4>
<pre class="brush:php">/*
/	Output the comments one by one:
*/

foreach($comments as $c){
	echo $c-&gt;markup();
}</pre>
<p>Each comment has a<strong> markup()</strong> method, which generates valid HTML code ready to be printed to the page. You can see the definition of this method and the class below.</p>
<p>The class takes a row from the database (fetched with <strong>mysql_fetch_assoc()</strong> ) and stores it in the private variable<strong> $data</strong>. It is available only to  the methods of the class and cannot be accessed from outside.</p>
<h4>comment.class.php &#8211; Part 1</h4>
<pre class="brush:php">class Comment
{
	private $data = array();

	public function __construct($row)
	{
		/*
		/	The constructor
		*/

		$this-&gt;data = $row;
	}

	public function markup()
	{
		/*
		/	This method outputs the XHTML markup of the comment
		*/

		// Setting up an alias, so we don't have to write $this-&gt;data every time:
		$d = &amp;$this-&gt;data;

		$link_open = '';
		$link_close = '';

		if($d['url']){

			// If the person has entered a URL when adding a comment,
			// define opening and closing hyperlink tags

			$link_open = '&lt;a href="'.$d['url'].'"&gt;';
			$link_close =  '&lt;/a&gt;';
		}

		// Converting the time to a UNIX timestamp:
		$d['dt'] = strtotime($d['dt']);

		// Needed for the default gravatar image:
		$url = 'http://'.dirname($_SERVER['SERVER_NAME'].$_SERVER["REQUEST_URI"]).
				'/img/default_avatar.gif';

		return '

			&lt;div class="comment"&gt;
				&lt;div class="avatar"&gt;
					'.$link_open.'
					&lt;img src="http://www.gravatar.com/avatar/'.
				md5($d['email']).'?size=50&amp;default='.
				urlencode($url).'" /&gt;
					'.$link_close.'
				&lt;/div&gt;

				&lt;div class="name"&gt;'.$link_open.$d['name'].$link_close.'&lt;/div&gt;
				&lt;div class="date" title="Added at '.
				date('H:i \o\n d M Y',$d['dt']).'"&gt;'.
				date('d M Y',$d['dt']).'&lt;/div&gt;
				&lt;p&gt;'.$d['body'].'&lt;/p&gt;
			&lt;/div&gt;
		';
	}</pre>
<p>This script uses <a href="http://en.gravatar.com/site/implement/images/" target="_blank">gravatar</a> to present avatars in the comments. For those of you, who have not used gravatar, this is a really useful service, which lets you associate an avatar with your email address. The avatar image can easily be fetched by passing an <strong>md5()</strong> encoded hash of your email address to gravatar.com. This is exactly what we do on <strong>line 48</strong>.</p>
<p>Notice <strong>line 39</strong> above it &#8211; the script tries to figure out the URL at which it is located, and determines the exact address of the <strong>default_avatar.gif</strong> image. This gif is passed to gravatar along the md5 hash, so if no avatar was found for this particular email, the fallback image is displayed instead.</p>
<h4>comment.class.php &#8211; Part 2</h4>
<pre class="brush:php">	public static function validate(&amp;$arr)
	{
		/*
		/	This method is used to validate the data sent via AJAX.
		/
		/	It return true/false depending on whether the data is valid, and populates
		/	the $arr array passed as a paremter (notice the ampersand above) with
		/	either the valid input data, or the error messages.
		*/

		$errors = array();
		$data	= array();

		// Using the filter_input function introduced in PHP 5.2.0

		if(!($data['email'] = filter_input(INPUT_POST,'email',FILTER_VALIDATE_EMAIL)))
		{
			$errors['email'] = 'Please enter a valid Email.';
		}

		if(!($data['url'] = filter_input(INPUT_POST,'url',FILTER_VALIDATE_URL)))
		{
			// If the URL field was not populated with a valid URL,
			// act as if no URL was entered at all:

			$url = '';
		}

		// Using the filter with a custom callback function:

		if(!($data['body'] = filter_input(INPUT_POST,'body',FILTER_CALLBACK,
						array('options'=&gt;'Comment::validate_text'))))
		{
			$errors['body'] = 'Please enter a comment body.';
		}

		if(!($data['name'] = filter_input(INPUT_POST,'name',FILTER_CALLBACK,
						array('options'=&gt;'Comment::validate_text'))))
		{
			$errors['name'] = 'Please enter a name.';
		}

		if(!empty($errors)){

			// If there are errors, copy the $errors array to $arr:

			$arr = $errors;
			return false;
		}

		// If the data is valid, sanitize all the data and copy it to $arr:

		foreach($data as $k=&gt;$v){
			$arr[$k] = mysql_real_escape_string($v);
		}

		// Ensure that the email is in lower case (for a correct gravatar hash):
		$arr['email'] = strtolower(trim($arr['email']));

		return true;

	}</pre>
<p>The<strong> validate()</strong> method above (also part of the class) is defined as <strong>static</strong>. This means that it can be evoked directly like <strong>Comment::validate()</strong>, without the need of creating an object of the class. What this method does, is validate the input data which is submitted via AJAX.</p>
<p>This method uses the new filter functions, which are available as of <strong>PHP 5.2.0</strong>. These allow us to easily validate and filter any input data that is passed to the script. For example <em>filter_input(INPUT_POST,&#8217;url&#8217;,FILTER_VALIDATE_URL)</em> means that we are checking whether <strong>$_POST['url']</strong> is a valid URL address. If it is, the function returns the value of the variable, otherwise it return <strong>false</strong>.</p>
<p>This is really useful, as up until now, we had to use custom regular expressions to validate data (and have series of if statements). Also, another advantage is that this data is fetched before any configuration-specific transformations (like magic quotes) are applied.</p>
<p>We also have the option of specifying a custom function which is going to apply some more advanced modifications of the data, as you can see from lines 31 and 37.</p>
<h4>comment.class.php &#8211; Part 3</h4>
<pre class="brush:php">	private static function validate_text($str)
	{
		/*
		/	This method is used internally as a FILTER_CALLBACK
		*/

		if(mb_strlen($str,'utf8')&lt;1)
			return false;

		// Encode all html special characters (&lt;, &gt;, ", &amp; .. etc) and convert
		// the new line characters to &lt;br&gt; tags:

		$str = nl2br(htmlspecialchars($str));

		// Remove the new line characters that are left
		$str = str_replace(array(chr(10),chr(13)),'',$str);

		return $str;
	}

}</pre>
<p>The last method is <strong>validate_text,</strong> which we are passing as a callback function in the two filter_input calls above. It encodes all special HTML characters, effectively blocking XSS attacks. It also replaces the newline characters with &lt;br /&gt; line breaks.</p>
<h4>submit.php</h4>
<pre class="brush:php">/*
/	This array is going to be populated with either
/	the data that was sent to the script, or the
/	error messages:
/*/

$arr = array();

$validates = Comment::validate($arr);

if($validates)
{
	/* Everything is OK, insert to database: */

	mysql_query("	INSERT INTO comments(name,url,email,body)
					VALUES (
						'".$arr['name']."',
						'".$arr['url']."',
						'".$arr['email']."',
						'".$arr['body']."'
					)");

	$arr['dt'] = date('r',time());
	$arr['id'] = mysql_insert_id();

	/*
	/	The data in $arr is escaped for the mysql insert query,
	/	but we need the unescaped text, so we apply,
	/	stripslashes to all the elements in the array:
	/*/

	$arr = array_map('stripslashes',$arr);

	$insertedComment = new Comment($arr);

	/* Outputting the markup of the just-inserted comment: */

	echo json_encode(array('status'=&gt;1,'html'=&gt;$insertedComment-&gt;markup()));

}
else
{
	/* Outputting the error messages */
	echo '{"status":0,"errors":'.json_encode($arr).'}';
}</pre>
<p><strong>submit.php</strong> receives the comment form data via an AJAX request. It validates it and outputs a JSON object with either the XHTML markup of the successfully inserted comment, or a list of error messages. jQuery uses the status property to determine whether to display the error messages or add the comment markup to the page.</p>
<p>You can see two example responses below.</p>
<h4>Successful response</h4>
<pre class="brush:js">{
    "status": 1,
    "html": "Html Code Of The Comment Comes Here..."
}</pre>
<p>The <strong>html</strong> property contains the code of the comment, similar to markup in step one.</p>
<h4>Failure response</h4>
<pre class="brush:js">{
    "status": 0,
    "errors": {
        "email": "Please enter a valid Email.",
        "body": "Please enter a comment body.",
        "name": "Please enter a name."
    }
}</pre>
<p>On failure, jQuery loops through the errors object, and outputs the errors next to the fields that caused them.</p>
<div id="attachment_999" class="wp-caption alignnone" style="width: 630px"><a href="http://demo.tutorialzine.com/2010/06/simple-ajax-commenting-system/demo.php"><img class="size-full wp-image-999" title="Fancy CSS3 &amp; jQuery Submit Form" src="http://tutorialzine.com/wp-content/uploads/2010/06/i21.jpg" alt="Fancy CSS3 &amp; jQuery Submit Form" width="620" height="460" /></a><p class="wp-caption-text">Fancy CSS3 &amp; jQuery Submit Form</p></div>
<h3>Step 3 &#8211; CSS</h3>
<p>Now that we have all the markup properly generated and displayed on the page, we can move on to styling it.</p>
<h4>styles.css &#8211; Part 1</h4>
<pre class="brush:css">.comment,
#addCommentContainer{

	/* Syling the comments and the comment form container */

	padding:12px;
	width:400px;
	position:relative;
	background-color:#fcfcfc;
	border:1px solid white;
	color:#888;
	margin-bottom:25px;

	/* CSS3 rounded corners and drop shadows */

	-moz-border-radius:10px;
	-webkit-border-radius:10px;
	border-radius:10px;

	-moz-box-shadow:2px 2px 0 #c2c2c2;
	-webkit-box-shadow:2px 2px 0 #c2c2c2;
	box-shadow:2px 2px 0 #c2c2c2;
}

.comment .avatar{

	/*
	/	The avatar is positioned absolutely,
	/	and offset outside the comment div
	/*/

	height:50px;
	left:-70px;
	position:absolute;
	width:50px;
	background:url('img/default_avatar.gif') no-repeat #fcfcfc;

	/* Centering it vertically: */

	margin-top:-25px;
	top:50%;

	-moz-box-shadow:1px 1px 0 #c2c2c2;
	-webkit-box-shadow:1px 1px 0 #c2c2c2;
	box-shadow:1px 1px 0 #c2c2c2;
}</pre>
<p>The .comment divs and the #addCommentContainer are styled at once because they share most of the styling. A number of CSS3 rules are applied, including rounded corners and a box-shadow. Needless to say, these do not work in older browsers, but as they are purely presentational, the script will still work without them.</p>
<h4>styles.css &#8211; Part 2</h4>
<pre class="brush:css">.comment .avatar img{
	display:block;
}

.comment .name{
	font-size:20px;
	padding-bottom:10px;
	color:#ccc;
}

.comment .date{
	font-size:10px;
	padding:6px 0;
	position:absolute;
	right:15px;
	top:10px;
	color:#bbb;
}

.comment p,
#addCommentContainer p{
	font-size:18px;
	line-height:1.5;
}

#addCommentContainer input[type=text],
#addCommentContainer textarea{

	/* Styling the inputs */

	display:block;
	border:1px solid #ccc;
	margin:5px 0 5px;
	padding:3px;
	font-size:12px;
	color:#555;
	font-family:Arial, Helvetica, sans-serif;
}

#addCommentContainer textarea{
	width:300px;
}

label{
	font-size:10px;
}

label span.error{
	color:red;
	position:relative;
	right:-10px;
}

#submit{

	/* The submit button */

	background-color:#58B9EB;
	border:1px solid #40A2D4;
	color:#FFFFFF;
	cursor:pointer;
	font-family:'Myriad Pro',Arial,Helvetica,sans-serif;
	font-size:14px;
	font-weight:bold;
	padding:4px;
	margin-top:5px;

	-moz-border-radius:4px;
	-webkit-border-radius:4px;
	border-radius:4px;
}

#submit:hover{
	background-color:#80cdf5;
	border-color:#52b1e2;
}</pre>
<p>In the second part of the stylesheet, we style the comment and form elements. Notice the <strong>input[type=text]</strong> selector, which selects elements depending on the type attribute.</p>
<h3>Step 4 &#8211; jQuery</h3>
<p>Now lets continue with jQuery, which is the last step of this tutorial. After including the library to the bottom of the page (best for the perceived performance of the page) we can start coding the script file.</p>
<h4>script.js</h4>
<pre class="brush:js">$(document).ready(function(){
	/* The following code is executed once the DOM is loaded */

	/* This flag will prevent multiple comment submits: */
	var working = false;

	/* Listening for the submit event of the form: */
	$('#addCommentForm').submit(function(e){

 		e.preventDefault();
		if(working) return false;

		working = true;
		$('#submit').val('Working..');
		$('span.error').remove();

		/* Sending the form fileds to submit.php: */
		$.post('submit.php',$(this).serialize(),function(msg){

			working = false;
			$('#submit').val('Submit');

			if(msg.status){

				/*
				/	If the insert was successful, add the comment
				/	below the last one on the page with a slideDown effect
				/*/

				$(msg.html).hide().insertBefore('#addCommentContainer').slideDown();
				$('#body').val('');
			}
			else {

				/*
				/	If there were errors, loop through the
				/	msg.errors object and display them on the page
				/*/

				$.each(msg.errors,function(k,v){
					$('label[for='+k+']').append('&lt;span class="error"&gt;'+
						v+'&lt;/span&gt;');
				});
			}
		},'json');

	});

});</pre>
<p>Starting from the top, we have the <strong>$(document).ready()</strong> call, which binds a function to the <em>DOM content loaded</em> event. The working variable acts as a flag, which tells the script if an AJAX request is in progress (thus preventing double posting).</p>
<p>In the callback function for the POST AJAX request, we check the status property to determine whether the comment was successfully inserted. If it was, we add the received markup to the page after the last comment with a <em>slideDown </em>animation.</p>
<p>If there were problems, we display the error messages by appending an error span to the appropriate label element (the for attribute of the label contains the id of the input that caused the error).</p>
<p><strong>With this our Simple AJAX Commenting System is complete!</strong></p>
<h3>Conclusion</h3>
<p>To be able to run this script on your server, you need to create the <strong><em>comments</em></strong> table in your MySQL database. You can do this by executing the SQL code found in <strong>table.sql</strong> from the SQL tab of phpMyAdmin. After this you need to enter your MySQL connection details in <strong><em>connect.php</em></strong>.</p>
<p>You are free to modify and use this code any way you see fit.</p>
<p><strong>What do you think? How would you improve this script?</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://tutorialzine.com/2010/06/simple-ajax-commenting-system/feed/</wfw:commentRss>
		<slash:comments>47</slash:comments>
		</item>
		<item>
		<title>Apple-like Retina Effect With jQuery</title>
		<link>http://tutorialzine.com/2010/06/apple-like-retina-effect-jquery-css/</link>
		<comments>http://tutorialzine.com/2010/06/apple-like-retina-effect-jquery-css/#comments</comments>
		<pubDate>Wed, 16 Jun 2010 09:12:20 +0000</pubDate>
		<dc:creator>Martin Angelov</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://tutorialzine.com/?p=954</guid>
		<description><![CDATA[Today we are making an Apple-like "Retina effect" with the help of jQuery &#038; CSS (and a bit of CSS3), similar to the effect they've used on their site to promote the new version of their iPhone.]]></description>
			<content:encoded><![CDATA[<p>Apple has long applied a winning strategy in marketing &#8211; create well designed products, have a dedicated fan base, and let the hype build up before every product release.</p>
<p>This is also the case with the latest version of their iPhone. But what I found interesting is the term they coined &#8211; &#8220;Retina display&#8221; and the promo image accompanying it.</p>
<div id="attachment_959" class="wp-caption alignnone" style="width: 630px"><a href="http://www.apple.com/iphone/"><img class="size-full wp-image-959" title="The image on apple.com that inspired it all" src="http://tutorialzine.com/wp-content/uploads/2010/06/i2.jpg" alt="The image on apple.com that inspired it all" width="620" height="260" /></a><p class="wp-caption-text">The image on apple.com that inspired it all</p></div>
<p>What made me wonder is if it was possible to turn this static image into a fully functional &#8220;Retina effect&#8221; with only jQuery and CSS. This is exactly what we are doing today. So grab the demo files from the button above and read on.</p>
<p><em><strong>UPDATE:</strong></em> Seems Apple folks have also liked the idea, and they&#8217;ve <a href="http://www.apple.com/iphone/features/retina-display.html" target="_blank">implemented it on apple.com</a>.</p>
<h3>Step 1 &#8211; XHMTL</h3>
<p>The markup for the effect is quite straightforward. You can see that we only have a number of divs and an image.</p>
<h4>demo.html</h4>
<pre class="brush:html">&lt;div id="main"&gt;

	&lt;div id="iphone"&gt;
		&lt;div id="webpage"&gt;
			&lt;img src="img/webpage.png" width="499" height="283" alt="Web Page" /&gt;
			&lt;div id="retina"&gt;&lt;/div&gt;
		&lt;/div&gt;
	&lt;/div&gt;

&lt;/div&gt;</pre>
<p>The <strong>#iphone</strong> div displays the iphone frame. Inside it is the <strong>#webpage</strong> div with the screenshot of the webpage. The screenshot is actually displayed at half its original size, as we are using the same image for both the small version (displayed in the  iPhone) and big version, which is shown in the rounded tooltip.</p>
<p>Lastly we have the retina div, which is rounded with CSS3 and displays the big version of the webpage screeshot as its background as it is moved around with the mouse.</p>
<div id="attachment_958" class="wp-caption alignnone" style="width: 630px"><a href="http://demo.tutorialzine.com/2010/06/apple-like-retina-effect-jquery-css/demo.html"><img class="size-full wp-image-958" title="Putting it together" src="http://tutorialzine.com/wp-content/uploads/2010/06/i1.jpg" alt="Putting it together" width="620" height="460" /></a><p class="wp-caption-text">Putting it together</p></div>
<h3>Step 2 &#8211; CSS</h3>
<p>Moving to the CSS part of the tutorial. We are going to style the <em>iphone</em>, <em>webpage </em>and <em>retina </em>divs, so we make the awesome effect possible.</p>
<h4>styles.css</h4>
<pre class="brush:css">#iphone{
	/* The iphone frame div */
	width:750px;
	height:400px;
	background:url('img/iphone_4G.png') no-repeat center center;
}

#webpage{
	/* Contains the webpage screenshot */
	width:499px;
	height:283px;
	position:absolute;
	top:50%;
	left:50%;
	margin:-141px 0 0 -249px;
}

#retina{
	/* The Retina effect */
	background:url('img/webpage.png') no-repeat center center white;
	border:2px solid white;

	/* Positioned absolutely, so we can move it around */
	position:absolute;
	height:180px;
	width:180px;

	/* Hidden by default */
	display:none;

	/* A blank cursor, notice the default fallback */
	cursor:url('img/blank.cur'),default;

	/* CSS3 Box Shadow */
	-moz-box-shadow:0 0 5px #777, 0 0 10px #aaa inset;
	-webkit-box-shadow:0 0 5px #777;
	box-shadow:0 0 5px #777, 0 0 10px #aaa inset;

	/* CSS3 rounded corners */
	-moz-border-radius:90px;
	-webkit-border-radius:90px;
	border-radius:90px;
}

#retina.chrome{
	/* A special chrome version of the cursor */
	cursor:url('img/blank_google_chrome.cur'),default;
}

#main{
	/* The main div */
	margin:40px auto;
	position:relative;
	width:750px;
}</pre>
<p>By specifying an absolute positioning on the webpage div, we can apply the <a href="http://tutorialzine.com/2010/03/centering-div-vertically-and-horizontally/">vertical and horizontal centering technique</a>, effectively putting the webpage screenshot in the middle of the iphone frame.</p>
<p>The <em>retina </em>div is also assigned an absolute positioning, so it is possible to move it in the jQuery part of the tutorial by just specifying a top and left offsets. This div also has the webpage screenshot as its background (in its original size). Offsetting the background with the movement of the div creates the illusion that it magnifies the small screenshot below it.</p>
<div id="attachment_960" class="wp-caption alignnone" style="width: 630px"><a href="http://demo.tutorialzine.com/2010/06/apple-like-retina-effect-jquery-css/demo.html"><img class="size-full wp-image-960" title="The Retina Effect" src="http://tutorialzine.com/wp-content/uploads/2010/06/i31.png" alt="The Retina Effect" width="620" height="460" /></a><p class="wp-caption-text">The Retina Effect</p></div>
<p>The retina div also has applied a border radius with a value of exactly half its width, which turns it into a perfect circle (at least in browsers which support the border-radius CSS3 property &#8211; Chrome, Safari, Opera &amp; Firefox).</p>
<p>And finally we hide the mouse pointer by providing a blank cursor file (Google Chrome fails to render completely blank cursors, so we provide a special 1px white cursor for it &#8211; at least it is better than nothing). The Opera browser completely ignores custom cursors and there are no workarounds, so users using this browser might not enjoy the full experience.</p>
<h3>Step 3 &#8211; jQuery</h3>
<p>If you can remember, a few months ago we did a <a href="http://tutorialzine.com/2010/02/photo-shoot-css-jquery/" target="_blank">tutorial here at Tutorialzine</a>, in which we used jQuery to create a photoshoot effect. This time we are using a similar technique to make the &#8220;retina effect&#8221;, as seen on Apple&#8217;s web site.</p>
<p>And since we have all the styling in place, it is a matter of some JavaScript coding with the help of the jQuery library.</p>
<h4>script.js</h4>
<pre class="brush:js">$(document).ready(function(){

	/* This code is executed on the document ready event */

	var left	= 0,
		top		= 0,
		sizes	= { retina: { width:190, height:190 },
				webpage:{ width:500, height:283 } },
		webpage	= $('#webpage'),
		offset	= { left: webpage.offset().left, top: webpage.offset().top },
		retina	= $('#retina');

	if(navigator.userAgent.indexOf('Chrome')!=-1)
	{
		/*	Applying a special chrome curosor,
			as it fails to render completely blank curosrs. */

		retina.addClass('chrome');
	}

	webpage.mousemove(function(e){

		left = (e.pageX-offset.left);
		top = (e.pageY-offset.top);

		if(retina.is(':not(:animated):hidden')){
			/* Fixes a bug where the retina div is not shown */
			webpage.trigger('mouseenter');
		}

		if(left&lt;0 || top&lt;0 || left &gt; sizes.webpage.width ||
			top &gt; sizes.webpage.height)
		{
			/*	If we are out of the bondaries of the
				webpage screenshot, hide the retina div */

			if(!retina.is(':animated')){
				webpage.trigger('mouseleave');
			}
			return false;
		}

		/*	Moving the retina div with the mouse
			(and scrolling the background) */

		retina.css({
			left				: left - sizes.retina.width/2,
			top					: top - sizes.retina.height/2,
			backgroundPosition	: '-'+(1.6*left)+'px -'+(1.35*top)+'px'
		});

	}).mouseleave(function(){
		retina.stop(true,true).fadeOut('fast');
	}).mouseenter(function(){
		retina.stop(true,true).fadeIn('fast');
	});
});
</pre>
<p>In the mousemove function, the current coordinates of the mouse are passed as <em>e.pageX</em> and <em>e.pageY</em>, but they are absolute with relation to the document. Subtracting the position offset of the website div, we end up with relative coordinates for the mouse, which are later used to position the retina div.</p>
<p>This, combined with the blank cursor we set up in the CSS part of the tutorial, creates the retina effect in pure JavaScript and CSS.</p>
<h3>Conclusion</h3>
<p>As the Flash / HTML5 debate heated up recently, people started looking  for ways to achieve the same level of functionality that flash provides,  without depending on an external plugin. This is possible for simple  interactions, but we still have to make sure that the solution is  cross-browser compatible, which is sometimes rather impossible (think of  IE here).</p>
<p>Hopefully, today we made something that would easily rival an equivalent Flash solution.</p>
<p><strong>What do you think? How would you improve this effect?</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://tutorialzine.com/2010/06/apple-like-retina-effect-jquery-css/feed/</wfw:commentRss>
		<slash:comments>34</slash:comments>
		</item>
		<item>
		<title>Making Your First Google Chrome Extension</title>
		<link>http://tutorialzine.com/2010/06/making-first-chrome-extension/</link>
		<comments>http://tutorialzine.com/2010/06/making-first-chrome-extension/#comments</comments>
		<pubDate>Wed, 09 Jun 2010 12:53:55 +0000</pubDate>
		<dc:creator>Martin Angelov</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://tutorialzine.com/?p=940</guid>
		<description><![CDATA[In this tutorial, we are going to create a simple extension, which puts a small icon next to Chrome's address bar, and, when clicked, will fetch Tutorialzine's RSS feed and display a fancy preview of our latest tutorials.]]></description>
			<content:encoded><![CDATA[<p>The Google Chrome web browser is slowly growing in popularity. This is no surprise, as it is a great browser, and is backed by no other than Google. It also provides great tools for web developers and I find myself using it more and more (actually Firebug is the only thing keeping me from crossing to the other side).</p>
<p>With the introduction of <a href="https://chrome.google.com/extensions" target="_blank">extensions</a>, Google Chrome became even more agile and powerful.</p>
<p>In this tutorial, we are going to create a simple extension, which puts a small icon next to Chrome&#8217;s address bar, and, when clicked, will fetch Tutorialzine&#8217;s RSS feed and display a fancy preview of our latest tutorials.</p>
<p>[By the way, we just launched <a href="http://www.zinescripts.com/" target="_blank">ZineScripts</a>! Use this Promo Code for a <strong>10% discount</strong>: <em>google-chrome-tut-93a2</em>]</p>
<p>First a few words about extensions.</p>
<h3>How Extensions Work</h3>
<p>Extensions in Google Chrome are basically webpages. You have javascript files, stylesheets and images. You can even use JavaScript libraries like  jQuery.</p>
<p>The extensions are, however, treated a bit differently than your regular webpage, which is displayed in the browser. You can have access to all the opened tabs, to the user&#8217;s browsing history, you can manipulate all the pages that are opened, send AJAX requests to any website and much more.</p>
<p>You also have the benefit (or the limitation) that your extension runs only on one browser. You can forget all compatibility issues and embrace Google Chrome&#8217;s hot new HTML5 features.</p>
<div id="attachment_945" class="wp-caption alignnone" style="width: 630px"><a href="http://demo.tutorialzine.com/2010/06/making-first-chrome-extension/demo.html"><img class="size-full wp-image-945" title="Tutorialzine's Google Chrome Extension" src="http://tutorialzine.com/wp-content/uploads/2010/06/i11.png" alt="Tutorialzine's Google Chrome Extension" width="620" height="460" /></a><p class="wp-caption-text">Tutorialzine&#39;s Google Chrome Extension</p></div>
<h3>Developing extensions</h3>
<p>Extension  are packed in a <strong>.crx</strong> file (arenamed zip file) but during development, you can map your working folder as an extension. This way you can quickly change and deploy code without the need of repackaging.</p>
<p>This is done by opening the extension page (type <em><a href="chrome://extensions/">chrome://extensions/</a></em> in the address bar, or click <em>Wrench icon &gt; Extensions</em>), and clicking <strong>Developer mode &gt; Load unpacked extension..</strong> on the page. After you make a change to the extension, just hit the Reload link below it.</p>
<p>After you&#8217;re done developing, click <strong>Pack extension..</strong> and a crx file will be created for you. You can serve this file from your site and enable your site&#8217;s visitors to install it.</p>
<p>Google Chrome is by far the easiest browser to make extensions for, as you will see from the steps below.</p>
<p><strong>A note about debugging</strong>: To debug your extension, right-click on your extension&#8217;s icon, next to the address bar, and choose <em>Inspect popup</em>. You can also check out <a href="http://code.google.com/chrome/extensions/tut_debugging.html" target="_blank">this tutorial</a>.</p>
<h3>Step 1 &#8211; Manifest.json</h3>
<p>The first step in creating an extension, is mapping a folder on your hard drive as an extension (as explained the above). You are going to put all your files in this folder.</p>
<p>The only thing required from your extension by Chrome, is the <strong>manifest.json</strong> file. This is a text file, which holds configuration settings in the form of a json object.</p>
<p>Here is the one we are going to use:</p>
<h4>manifest.json</h4>
<pre class="brush:js">{
	"name": "Tutorialzine Extension",
	"version": "1.0",
	"description": "Making your first Google Chrome extension.",
	"browser_action":	{
		"default_icon": "icon.png",
		"popup": "tutorialzine.html"
	},

	"icons":{
		"128":"icon_128.png"
	}
}</pre>
<p>In this file we are specifying the name of the extension and a number of other options, such as browser actions and permissions.</p>
<p>In <strong>browser_actions</strong>, we put settings that are in relation with the browser window. The <strong>popup</strong> property tells Chrome, that we are going to show <em>tutorialzine.html</em> as a popup. There are a number of settings you can put in browser_actions. You can read more on <a href="http://code.google.com/chrome/extensions/browserAction.html" target="_blank">Google Chrome&#8217;s Extension documentation</a>.</p>
<p>For this extension we do not need access to currently opened pages, nor manipulating tabs and windows. If we needed those, however, we would need to include a permissions property, with the addresses of the pages.</p>
<p>For more information about the manifest file, refer to <a href="http://code.google.com/chrome/extensions/manifest.html" target="_blank">Google Chrome&#8217;s documentation</a>.</p>
<h3>Step 2 &#8211; HTML 5</h3>
<p>As mentioned above, we told Chrome that <em>tutorialzine.html</em> is going to be opened as a popup. This is a regular html file, complete with stylesheets and js files.</p>
<p>And as Google Chrome has a really good support for HTML5, we can code tutorialzine.html in it. You could, however, use any HTML version you normally code your sites with.</p>
<h4>tutorialzine.html</h4>
<pre class="brush:html">&lt;!DOCTYPE html&gt; &lt;!-- The new doctype --&gt;
&lt;html&gt;
&lt;head&gt; &lt;!-- No title and meta tags are necessary for the extension --&gt;

&lt;link rel="stylesheet" type="text/css" href="style.css" /&gt;
&lt;script src="jquery.min.js"&gt;&lt;/script&gt; &lt;!-- Including jQuery --&gt;
&lt;script src="script.js"&gt;&lt;/script&gt; &lt;!-- Our script file --&gt;

&lt;/head&gt;

&lt;body&gt;

&lt;h1&gt;Latest Tutorials on Tutorialzine&lt;/h1&gt;

&lt;div id="content"&gt;
&lt;!-- The latest tutorials are going to be inserted here --&gt;
&lt;/div&gt;

&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>As you can see, we are addressing the css and js files directly. Chrome will include them for us. Just as if we are working on a regular webpage.</p>
<h3>Step 3 &#8211; CSS3</h3>
<p>As the extension is rendered Google Chrome, we do not need to limit ourselves with the least common denominator when it comes to CSS3 support. This is why we can afford to use fancy rules like <strong>-webkit-box-reflection</strong> and <strong>-webkit-gradient</strong>.</p>
<h4>styles.css &#8211; Part 1</h4>
<pre class="brush:css">*{
	margin:0;
	padding:0;
}

body{
	/* Setting default text color, background and a font stack */
	font-size:12px;
	color:#666;

	/* A webkit gradient: */
	background:-webkit-gradient(linear, 0% 0%, 0% 100%, from(#EEE), to(#DDD));

	text-shadow:1px 1px 0 white;
	font-family:Arial, Helvetica, sans-serif;
	overflow-x:hidden;
}

.tutorial{
	width:500px;
	padding:10px 20px;
	margin-bottom:10px;
}

img{
	width:100px;
	height:100px;
	float:left;

	/* Webkit CSS3 Reflection */
	-webkit-box-reflect: below 0 -webkit-gradient(linear, left top, left bottom, from(transparent), color-stop(0.75, transparent), to(rgba(255, 255, 255, 0.3))) 0 0 0 0 stretch stretch;
}</pre>
<p><strong>-webkit-box-reflect</strong> creates a pure CSS reflection under the thumbnail images. It takes a number of parameters to generate the reflection &#8211; position of the reflection, offset from the bottom of the image, and a mask (which is defined with a gradient).</p>
<h4>styles.css &#8211; Part 2</h4>
<pre class="brush:css">p,a{
	padding:10px 0 0 120px;
	display:block;
}

a,a:visited{
	color:#09F;
	text-decoration:none;
}

a:hover{
	text-decoration:underline;
}

h1{
	/* Webkit gradient: */
	background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#EEE), to(#DDD));

	border-bottom: 1px solid #F0F0F0;
	font-size: 24px;
	font-weight: normal;
	margin-bottom: 30px;
	padding: 30px 0px;
	text-align: center;
	text-shadow: white 0px 1px 1px;
}

h2{
	font-size:24px;
	font-weight:normal;
	right:40px;
	padding-left:120px;
}

h1,h2{
	font-family:"Myriad Pro",Arial,Helvetica,sans-serif;
}</pre>
<p>In the second part of the code we are also using a gradient, but this time as a background for the h1 element.</p>
<div id="attachment_946" class="wp-caption alignnone" style="width: 630px"><a href="http://demo.tutorialzine.com/2010/06/making-first-chrome-extension/demo.html"><img class="size-full wp-image-946" title="CSS3 Reflections &amp; Text Shadows" src="http://tutorialzine.com/wp-content/uploads/2010/06/i21.png" alt="CSS3 Reflections &amp; Text Shadows" width="620" height="260" /></a><p class="wp-caption-text">CSS3 Reflections &amp; Text Shadows</p></div>
<h3>Step 4 &#8211; jQuery</h3>
<p>The JavaScript is executed as if it was part of a regular web page. This means that we can include the jQuery library and define a <strong>$(document).ready()</strong> function as we would normally do in a web project.</p>
<p>Clicking the extension icon has the same effect for the scripts on the page, as opening the page in a browser.</p>
<p>Inside $(document).ready(), we fetch the latest results from Tutorialzine&#8217;s RSS feed, with the help of <strong>Yahoo&#8217;s YQL API</strong>. We&#8217;ve used this API a <a href="http://tutorialzine.com/?s=YQL" target="_blank">couple of times before</a>, here on Tz. It allows us to use an SQL-like syntax to fetch data in a JSON format.</p>
<p>After fetching the data, we generate the HTML markup and include it in <em>tutorialzine.html</em>. We also save it to <strong>localStorage</strong> as a simple caching solution. localStorage is a simple way to save persistent data (it survives between page loads). This makes the experience of using the extension a lot faster.</p>
<h4>script.js</h4>
<pre class="brush:js">$(document).ready(function(){

	var query = "SELECT * FROM feed WHERE url='http://feeds.feedburner.com/Tutorialzine' LIMIT 2";

	// Storing the seconds since the epoch in now:
	var now = (new Date()).getTime()/1000;

	// If there is no cache set in localStorage, or the cache is older than 1 hour:
	if(!localStorage.cache || now - parseInt(localStorage.time) &gt; 1*60*60)
	{
		$.get("http://query.yahooapis.com/v1/public/yql?q="+encodeURIComponent(query)+"&amp;format=json&amp;callback=?",function(msg){

			// msg.query.results.item is an array:
			var items = msg.query.results.item;
			var htmlString = "";

			for(var i=0;i&lt;items.length;i++)
			{
				var tut = items[i];

				// Extracting the post ID from the permalink:
				var id = tut.guid.content.match(/(\d+)$/)[0];

				// Looping and generating the markup of the tutorials:

				htmlString += '&lt;div class="tutorial"&gt;\
								&lt;img src="http://tutorialzine.com/img/posts/'+id+'.jpg" /&gt;\
								&lt;h2&gt;'+tut.title+'&lt;/h2&gt;\
								&lt;p&gt;'+tut.description+'&lt;/p&gt;\
								&lt;a href="'+tut.link+'" target="_blank"&gt;Read more&lt;/a&gt;\
								&lt;/div&gt;';
			}

			// Setting the cache
			localStorage.cache	= htmlString;
			localStorage.time	= now;

			// Updating the content div:
			$('#content').html(htmlString);
		},'json');
	}
	else{
		// The cache is fresh, use it:
		$('#content').html(localStorage.cache);
	}
});</pre>
<p>In localStorage we also store a timestamp. We use it to determine how old the cache in localStorage is. If it is older than an hour, we ignore it and fetch the data again.</p>
<p>Here is a sample of the data that is returned from YQL.</p>
<pre class="brush:js">{
	"query": {
		"count": "1",
		"created": "2010-06-09T12:02:33Z",
		"lang": "en-US",
		"results": {

			"item": {
				"title": "Neon Text Effect With jQuery &amp; CSS",
				"link": "http://feedproxy.google.com/..",

				"comments": [
					"http://tutorialzine.com/2010/06/neon-text-effect..",
					"11"
				],

				"pubDate": "Tue, 01 Jun 2010 20:11:54 +0000",
				"creator": "Martin Angelov",

				"category": [
					"CSS",
					"jQuery"
				],

				"guid": {
					"isPermaLink": "false",
					"content": "http://tutorialzine.com/?p=925"
				},

				"description": "In this combined design and coding tutorial..",
				"commentRss": "http://tutorialzine.com/2010/06/neon-text-e..",
				"origLink": "http://tutorialzine.com/2010/06/neon-text-eff.."

			}
		}
	}
}
</pre>
<p>This structure is made available to us in the <strong>msg</strong> variable on line 11 of script.js.</p>
<p><strong>With this your first Google Chrome extension is complete!</strong></p>
<h3>Conclusion</h3>
<p>You can read more about extensions (including advanced features not covered in this tutorial) on <a href="http://code.google.com/chrome/extensions/overview.html" target="_blank">Google Chrome&#8217;s Extension documentation page</a>. I hope that this tutorial has given you a great start in extending the browser&#8217;s functionality.</p>
<p><strong>What do you think? Would you make a Chrome extension for your website?</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://tutorialzine.com/2010/06/making-first-chrome-extension/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Neon Text Effect With jQuery &amp; CSS</title>
		<link>http://tutorialzine.com/2010/06/neon-text-effect-jquery/</link>
		<comments>http://tutorialzine.com/2010/06/neon-text-effect-jquery/#comments</comments>
		<pubDate>Tue, 01 Jun 2010 20:11:54 +0000</pubDate>
		<dc:creator>Martin Angelov</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://tutorialzine.com/?p=925</guid>
		<description><![CDATA[In this combined design and coding tutorial, we are creating a neon glow text effect with CSS and jQuery, perfect for spicing up your web pages while keeping an eye on SEO.]]></description>
			<content:encoded><![CDATA[<p>Tutorialzine is the home to some of the best web development tutorials on the net. Our focus has mainly been on the coding side of web development, but often creating a good design is equally important.</p>
<p>This is why today we are going to do the first tutorial on the site, which is both design and code oriented, to bring you the full web development experience. Share your thoughts on what you think about this new format in the comment section below.</p>
<h3>Step 1 &#8211; Design</h3>
<p>Today we are creating a neon glow text effect with CSS and jQuery. The first step to achieving this effect, is to create a background image, which contains two slightly different versions of the text. jQuery fades between those two versions creating a smooth transition effect.</p>
<p>To create the colorful background image, you first need to open a new Photoshop document <strong>650px</strong> wide and <strong>300px</strong> high, with a background color of <strong>#141414</strong>. Use your favorite typeface to write your heading. I used Century Gothic with a size of 60px.</p>
<p>After this Ctrl-click the text layer&#8217;s icon in the layers panel to select it.</p>
<div id="attachment_926" class="wp-caption alignnone" style="width: 630px"><img class="size-full wp-image-926" title="Ctrl+Click on the Text Layer" src="http://tutorialzine.com/wp-content/uploads/2010/06/i1.png" alt="Ctrl+Click on the Text Layer" width="620" height="260" /><p class="wp-caption-text">Ctrl+Click on the Text Layer</p></div>
<p>Use the <em>Rectangular Marquee Tool</em> while holding <strong>Shift+Alt</strong> to limit the selection to a single word of the text.</p>
<div id="attachment_928" class="wp-caption alignnone" style="width: 630px"><img class="size-full wp-image-928" title="Shift + Alt to Limit the Selection" src="http://tutorialzine.com/wp-content/uploads/2010/06/i2.png" alt="Shift + Alt to Limit the Selection" width="620" height="260" /><p class="wp-caption-text">Shift + Alt to Limit the Selection</p></div>
<p>While everything is selected, create a new layer, name it <strong>gradients</strong> and make it active by clicking it.</p>
<div id="attachment_929" class="wp-caption alignnone" style="width: 630px"><img class="size-full wp-image-929" title="Create a new Layer" src="http://tutorialzine.com/wp-content/uploads/2010/06/i3.png" alt="Create a new Layer" width="620" height="260" /><p class="wp-caption-text">Create a new Layer</p></div>
<p>Choose the <em>Gradient tool</em> from the toolbox, and color the words one by one using the technique discussed above to switch the selection between the individual words. These selections limit the effect of the gradient tool and with the &#8220;<em>gradients</em>&#8221; layer being the currently active one, all changes made by the tool are saved there.</p>
<div id="attachment_927" class="wp-caption alignnone" style="width: 630px"><img class="size-full wp-image-927" title="Gradients" src="http://tutorialzine.com/wp-content/uploads/2010/06/i4.png" alt="Gradients" width="620" height="260" /><p class="wp-caption-text">Gradients</p></div>
<p>After you finish the heading, duplicate it below the original and  apply a different set of gradients. Align the two versions of the colorful heading one above the other, so that it is easy to switch between them by simply providing a different value for the position of the background image in the CSS part.</p>
<div id="attachment_932" class="wp-caption alignnone" style="width: 630px"><a href="http://tutorialzine.com/wp-content/uploads/2010/06/i5.png"><img class="size-full wp-image-932" title="The Finished Background Image" src="http://tutorialzine.com/wp-content/uploads/2010/06/i5.png" alt="The Finished Background Image" width="620" height="260" /></a><p class="wp-caption-text">The Finished Background Image</p></div>
<p>You can find the <strong>PSD </strong>file that I created for this tutorial in the <strong>download archive</strong>.</p>
<h3>Step 2 &#8211; XHTML</h3>
<p>The XHTML markup is really simple, you just need a container (the <strong>#neonText</strong> H1) which holds the two versions of the background.</p>
<h4>demo.html</h4>
<pre class="brush:html">&lt;h1 id="neonText"&gt;
	Neon Text Effect With jQuery &amp; CSS.
	&lt;span class="textVersion" id="layer1"&gt;&lt;/span&gt;
	&lt;span class="textVersion" id="layer2"&gt;&lt;/span&gt;
&lt;/h1&gt;
</pre>
<p><em>Layer1</em> is shown above <em>layer2</em>, and lowering its opacity  will create a smooth neon glow effect as the background image of the  span below it fades into view.</p>
<p>For SEO reasons, we are also providing the content of the image in plain text. It is neatly hidden from view with a negative <strong>text-indent</strong>.</p>
<h3>Step 3 &#8211; CSS</h3>
<p>The styles, used by the effect are also pretty straightforward. The two spans share the same background image we did in step one, but by specifying a different background position, we show only the top or the bottom part of the image.</p>
<h4>styles.css</h4>
<pre class="brush:css">/* The two text layers */
#neonText span{
	width:700px;
	height:150px;
	position:absolute;
	left:0;
	top:0;

	background:url('img/text.jpg') no-repeat left top;
}

span#layer1{
	z-index:100;
}

span#layer2{
	background-position:left bottom;
	z-index:99;
}

/* The h1 tag that holds the layers */
#neonText{
	height:150px;
	margin:180px auto 0;
	position:relative;
	width:650px;
	text-indent:-9999px;
}</pre>
<p>The <strong>#neonText</strong> container is positioned relatively, so that the absolutely positioned spans inside it are shown exactly one on top of the other. Also notice the negative text-indent, which we are using to hide the contents of the container.</p>
<h3>Step 4 &#8211; jQuery</h3>
<p>The last step involves setting up the transitioning animation. As we are using the jQuery library (which we include in the page with a script tag), a couple of useful methods are made available &#8211; fadeIn and fadeOut, which we are using the code below.</p>
<h4>script.js</h4>
<pre class="brush:js">$(document).ready(function(){

	setInterval(function(){

		// Selecting only the visible layers:
		var versions = $('.textVersion:visible');

		if(versions.length&lt;2){
			// If only one layer is visible, show the other
			$('.textVersion').fadeIn(800);
		}
		else{
			// Hide the upper layer
			versions.eq(0).fadeOut(800);
		}
	},1000);

});</pre>
<p>The function inside of the <strong>setInterval </strong>statement is executed once every second and shows or hides the first span layer.</p>
<p><strong>With this our slick neon glow effect is complete!</strong></p>
<h3>Conclusion</h3>
<p>You can use this effect to freshen up your designs while still keeping the SEO value of your pages. I am sure that you can think of many interesting uses and modifications of this code. Be sure to share what you do with the community in the comment section below.</p>
]]></content:encoded>
			<wfw:commentRss>http://tutorialzine.com/2010/06/neon-text-effect-jquery/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>BounceBox Notification Plugin With jQuery &amp; CSS3</title>
		<link>http://tutorialzine.com/2010/05/bounce-in-box-plugin-jquery/</link>
		<comments>http://tutorialzine.com/2010/05/bounce-in-box-plugin-jquery/#comments</comments>
		<pubDate>Wed, 26 May 2010 13:43:57 +0000</pubDate>
		<dc:creator>Martin Angelov</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://tutorialzine.com/?p=916</guid>
		<description><![CDATA[In this tutorial, we are making an one-off animated notification solution in the form of an easy to use jQuery plugin. With it you can display validation messages, registration forms or even banner advertisement.]]></description>
			<content:encoded><![CDATA[<p>Earlier this week, while working on <a href="http://www.zinescripts.com/" target="_blank">ZineScripts</a>&#8216; coupon code system, I found the need to be able to dynamically create and present a message box to Zine&#8217;s visitors. The usual routine would include digging through jQuery&#8217;s plugin repository and ending up with using a lightbox alternative, but I decided to take the time and build an one-off notification solution, which I am sharing with you today.</p>
<h3>Step 1 &#8211; XHTML</h3>
<p>Going straight to the point, <strong>what do you need to create this effect?</strong></p>
<p>The only thing you need is to create a div on your page and put some content inside it. Something like this:</p>
<pre class="brush:html">&lt;div id="box"&gt;
&lt;p&gt;&lt;b&gt;Title!&lt;/b&gt;Boring explanation.&lt;/p&gt;
&lt;/div&gt;</pre>
<p>In our example the title of the message, the message body, and the warning icon are all created by using a single <strong>&lt;p&gt;</strong> tag with some CSS wizardry. The warning icon is its background, and the title is a regular bold tag contained inside the paragraph.</p>
<div id="attachment_920" class="wp-caption alignnone" style="width: 630px"><a href="http://demo.tutorialzine.com/2010/05/bounce-in-box-plugin-jquery/demo.html"><img class="size-full wp-image-920" title="BounceBox jQuery Plugin" src="http://tutorialzine.com/wp-content/uploads/2010/05/i12.png" alt="BounceBox jQuery Plugin" width="620" height="260" /></a><p class="wp-caption-text">BounceBox jQuery Plugin</p></div>
<h3>Step 2 &#8211; CSS</h3>
<p>The plugin, we are doing today, adds its own CSS rules for the box positioning, which make the bounce effect possible, but we still need to code the design of the box in our stylesheet file.</p>
<h4>styles.css &#8211; Part 1</h4>
<pre class="brush:css">/* The bouncing box */

#box{
	background:url('img/box_bg.jpg') repeat-x center top #fcfcfc;
	height:115px;
	padding:20px;
	margin-top:-10px;
	padding-top:30px;
	width:400px;
	border:1px solid #fcfcfc;
	color:#494848;
	text-shadow:1px 1px 0 white;
	font-family:'Myriad Pro',Arial,Helvetica,sans-serif;
}

#box p{
	font-size:25px;
	background:url('img/warning.png') no-repeat 10px center;
	padding-left:90px;
}

#box p b{
	font-size:52px;
	display:block;
}

#box,
#main,
a.button{
	-moz-border-radius:10px;
	-webkit-border-radius:10px;
	border-radius:10px;
}
</pre>
<p>Here we are styling the design of the <strong>bounceBox</strong>. There are also a couple of rules that are applied inline by jQuery, which assign a <strong>&#8216;fixed&#8217;</strong> positioning to the box and center it in the middle of the page, which is required for the animation. This way there is a clear division between the styles for design and those for functionality.</p>
<h4>styles.css &#8211; Part 2</h4>
<pre class="brush:css">/* Styling the big button */

a.button{
	color:white;
	letter-spacing:-2px;
	padding:20px;
	display:block;
	text-shadow:1px 1px 0 #145982;
	font-family:'Myriad Pro',Arial,Helvetica,sans-serif;
	font-size:80px;
	font-weight:bold;
	text-align:center;
	width:350px;
	border:1px solid #60b4e5;

	margin:60px auto;

	/*
		CSS3 gradients for webkit and mozilla browsers,
		fallback color for the rest:
	*/

	background-color: #59aada;
	background-image: -moz-linear-gradient(#5eb2e2, #4f9cca);
	background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#5eb2e2), to(#4f9cca));
}

a.button:hover{
	/* Lighter gradients for the hover effect */
	text-decoration:none;
	background-color: #5eb2e2;
	background-image: -moz-linear-gradient(#6bbbe9, #57a5d4);
	background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#6bbbe9), to(#57a5d4));
}
</pre>
<p>In the second part of the code we apply a number of CSS3 rules to the button to achieve that polished look. Notice the two <strong>gradient</strong> rules which are targeted at Mozilla Firefox and the Webkit browsers (Safari &amp; Chrome). Unfortunately, unlike with other CSS3 rules, they don&#8217;t share a common syntax for displaying a gradient, which raises the burden on the developer in some degree.</p>
<p>It is also important to specify a fallback background color in case the browser does not support CSS gradients.</p>
<div id="attachment_921" class="wp-caption alignnone" style="width: 630px"><a href="http://demo.tutorialzine.com/2010/05/bounce-in-box-plugin-jquery/demo.html"><img class="size-full wp-image-921" title="A Pure CSS3 Button - Gradients, Rounded Corners &amp; Text Shadow" src="http://tutorialzine.com/wp-content/uploads/2010/05/i22.png" alt="A Pure CSS3 Button - Gradients, Rounded Corners &amp; Text Shadow" width="620" height="260" /></a><p class="wp-caption-text">A Pure CSS3 Button - Gradients, Rounded Corners &amp; Text Shadow</p></div>
<h3>Step 3 &#8211; jQuery</h3>
<p>First lets start by creating our bounceBox plugin. As we&#8217;ve seen before, creating a jQuery plugin is just a matter of extending the <strong>$.fn</strong> object with a new function. The <strong>&#8216;this&#8217;</strong> of the new function is equivalent to the jQuery set of elements that the method was called on.</p>
<h4>bouncebox-plugin/jquery.bouncebox.1.0.js</h4>
<pre class="brush:js">(function($){

	/* The plugin extends the jQuery Core with four methods */

	/* Converting an element into a bounce box: */
	$.fn.bounceBox = function(){

		/*
			Applying some CSS rules that center the
			element in the middle of the page and
			move it above the view area of the browser.
		*/

		this.css({
			top		: -this.outerHeight(),
			marginLeft	: -this.outerWidth()/2,
			position	: 'fixed',
			left		: '50%'
		});

		return this;
	}

	/* The boxShow method */
	$.fn.bounceBoxShow = function(){

		/* Starting a downward animation */

		this.stop().animate({top:0},{easing:'easeOutBounce'});
		this.data('bounceShown',true);
		return this;
	}

	/* The boxHide method */
	$.fn.bounceBoxHide = function(){

		/* Starting an upward animation */

		this.stop().animate({top:-this.outerHeight()});
		this.data('bounceShown',false);
		return this;
	}

	/* And the boxToggle method */
	$.fn.bounceBoxToggle = function(){

		/*
			Show or hide the bounceBox depending
			on the 'bounceShown' data variable
		*/

		if(this.data('bounceShown'))
			this.bounceBoxHide();
		else
			this.bounceBoxShow();

		return this;
	}

})(jQuery);</pre>
<p>We are defining four separate methods which convert the div to a bounceBox (and apply the positioning CSS rules), show it, hide it or toggle between the two by using the <strong>animate()</strong> jQuery method.</p>
<p>For the toggling we are keeping an internal variable with the data method, which marks whether the box has been shown or hidden.</p>
<p>All of these methods are available to you after you include the jQuery library and the <em>jquery.bounce.1.0.js</em> files to the page. For the neat bounce effect, you will need the <strong>jQuery easing plugin</strong> as well, which is included in the plugin directory in the zip.</p>
<p>It is really easy to use the plugin, as you can see from the code below.</p>
<h4>script.js</h4>
<pre class="brush:js">$(document).ready(function(){

	/* Converting the #box div into a bounceBox: */
	$('#box').bounceBox();

	/* Listening for the click event and toggling the box: */
	$('a.button').click(function(e){

		$('#box').bounceBoxToggle();
		e.preventDefault();
	});

	/* When the box is clicked, hide it: */
	$('#box').click(function(){
		$('#box').bounceBoxHide();
	});
});
</pre>
<p>The code above is executed when the document ready event is fired so we are sure that all the page elements are available to jQuery. The first thing we then do is to covert the <strong>#box</strong> div to a bounceBox, and bind listeners to the click event on the button and the box itself.</p>
<p>You can put whatever HTML code you want in the box div and it will be properly converted to a bounceBox. You can also have more than one bounce box on the page in the same time.</p>
<p><strong>With this our BounceBox plugin is complete!</strong></p>
<h3>Conclusion</h3>
<p>You can use this jQuery plugin to present notifications to the user in an eye-catching manner. You can easily put a registration form,  newsletter signup or even some kind of advertisement as the content of the box div. Feel free to experiment and share what you&#8217;ve done in the comment section.</p>
]]></content:encoded>
			<wfw:commentRss>http://tutorialzine.com/2010/05/bounce-in-box-plugin-jquery/feed/</wfw:commentRss>
		<slash:comments>41</slash:comments>
		</item>
		<item>
		<title>Combined Facebook, Twitter &amp; RSS Social Stats with jQuery, PHP &amp; YQL</title>
		<link>http://tutorialzine.com/2010/05/showing-facebook-twitter-rss-stats-jquery-yql/</link>
		<comments>http://tutorialzine.com/2010/05/showing-facebook-twitter-rss-stats-jquery-yql/#comments</comments>
		<pubDate>Wed, 19 May 2010 21:50:43 +0000</pubDate>
		<dc:creator>Martin Angelov</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://tutorialzine.com/?p=909</guid>
		<description><![CDATA[This week we are going to create a simple widget, which combines the number of your RSS readers, twitter followers, and fans of your facebook fan page, to give a rough estimate of your social popularity.]]></description>
			<content:encoded><![CDATA[<p>As we increasingly depend on more and more social services, there rises the need to provide a simple way to let our website visitors take part of our diverse social presence.</p>
<p>In this tutorial we are going to create a simple widget, which combines the number of your RSS readers, twitter followers, and fans of your facebook fan page, to give a rough estimate of your social popularity.</p>
<p>We are using jQuery and the <a href="http://code.drewwilson.com/entry/tiptip-jquery-plugin" target="_blank">tipTip plugin</a>, object-oriented PHP, and <a href="http://developer.yahoo.com/yql/" target="_blank">Yahoo&#8217;s YQL</a>, while demonstrating a number of interesting web development techniques.</p>
<h3>Step 1 &#8211; PHP</h3>
<p>YQL is a free Yahoo web service, which enables us to communicate  with numerous third-party APIs through a consistent SQL-like language (and hence the name). It is basically a gateway that sits between you and the other APIs.</p>
<p>This is especially important here, as we are using Yahoo&#8217;s YQL for  three very different tasks:</p>
<ul>
<li>Fetch your RSS subscriber count with FeedBurner&#8217;s <a href="http://code.google.com/apis/feedburner/awareness_api.html" target="_blank"> awareness API</a> (which comes in the form of an XML file that has to be parsed).<strong><br />
Note: </strong><em>You have to enable the awareness API to use this widget with your own feed. This is done from the Publicize Tab on your feed settings page</em>;</li>
<li>Use twitter&#8217;s API to get your number of followers;</li>
<li>Use Facebook&#8217;s new <strong>Graph API</strong> (<a href="http://developers.facebook.com/docs/api" target="_blank">link</a>) to get  information about the number of fans of your facebook fanpage.</li>
</ul>
<p>If it weren&#8217;t for YQL, we&#8217;d have to research and implement three very different solutions, which would slow us down significantly.</p>
<h4>includes/subscriber_stats.class.php</h4>
<pre class="brush:php">class SubscriberStats{

	public	$twitter,$rss,$facebook;
	public	$services = array();

	public function __construct($arr){

		$this-&gt;services = $arr;

		$yqlQueries = array();

		// Forming the Feedburner Awaraness API URL from the passed feed URL:
		$feedBurnerAwarenessAPI = 'http://feedburner.google.com/api/awareness'.
		'/1.0/GetFeedData?uri='.end(split('/',trim($arr['feedBurnerURL'],'/')));

		// Building an array with queries:

		if($arr['feedBurnerURL'])
			$yqlQueries[] = '
				SELECT * FROM xml
				WHERE url=\''.$feedBurnerAwarenessAPI.'\'
			';

		if($arr['twitterName'])
			$yqlQueries[] = '
				SELECT * FROM twitter.user.profile
				WHERE id=\''.$arr['twitterName'].'\'
			';

		if($arr['facebookFanPageURL'])
			$yqlQueries[] = '
			SELECT fan_count FROM facebook.graph
			WHERE id=\''.end(split('/',trim($arr['facebookFanPageURL'],'/'))).'\'
			';

		// Combing them into a YQL multiquery:
		$multiQuery =
		'SELECT * FROM query.multi WHERE queries = "'.join(';',$yqlQueries).'"';

		// Executing the query:
		$result = json_decode(
			file_get_contents('http://query.yahooapis.com/v1/public/yql?q='.
			urlencode($multiQuery).'&amp;format=json&amp;diagnostics=false&amp;'
			'amp;env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys')
		)-&gt;query-&gt;results-&gt;results;

		// The results from the queries are accessible in the $results array:

		$this-&gt;rss = $result[0]-&gt;rsp-&gt;feed-&gt;entry-&gt;circulation;
		$this-&gt;twitter = $result[1]-&gt;item-&gt;meta[5]-&gt;content;
		$this-&gt;facebook = $result[2]-&gt;json-&gt;fan_count;
	}

	public function generate(){

		$total = number_format($this-&gt;rss+$this-&gt;twitter+$this-&gt;facebook);

		echo '
			&lt;div class="subscriberStats"&gt;
				&lt;div class="subscriberCount"
				title="'.$total.'+ Total Social Media Followers"&gt;'.$total.'&lt;/div&gt;

				&lt;div class="socialIcon"
				title="'.number_format($this-&gt;rss).' RSS Subscribers"&gt;
					&lt;a href="'.$this-&gt;services['feedBurnerURL'].'"&gt;
					&lt;img src="img/rss.png" alt="RSS" /&gt;&lt;/a&gt;
				&lt;/div&gt;

				&lt;div class="socialIcon"
				title="'.number_format($this-&gt;facebook).' Fans on Facebook"&gt;
					&lt;a href="'.$this-&gt;services['facebookFanPageURL'].'"&gt;
					&lt;img src="img/facebook.png" alt="Facebook" /&gt;&lt;/a&gt;
				&lt;/div&gt;

				&lt;div class="socialIcon"
				title="'.number_format($this-&gt;twitter).' Twitter Followers"&gt;
				&lt;a href="http://twitter.com/'.$this-&gt;services['twitterName'].'"&gt;
					&lt;img src="img/twitter.png" alt="Twitter" /&gt;&lt;/a&gt;
				&lt;/div&gt;
			&lt;/div&gt;
		';
	}
}</pre>
<p>When we create an object of this class, the construct method is called, and a YQL query is created and executed.</p>
<p>To request the data from YQL&#8217;s servers, we just use <strong>file_get_contents()</strong> with the query passed as a parameter of the URL address. This returns a JSON object (basically a JavaScript object) which we can decode into a native PHP array with the in-build <strong>json_decode()</strong> function.</p>
<p>The results of these queries are saved locally and are made available for use in the <strong>generate()</strong> method which renders all the needed markup.</p>
<p>And now lets see how this class is used:</p>
<h4>subscriber_count.php</h4>
<pre class="brush:php">require "includes/subscriber_stats.class.php";

$cacheFileName = "cache.txt";

// IMPORTANT: after making changes to this file (or the SubscriberStats class)
// remeber to delete cache.txt from your server, otherwise you wont see your changes.

// If a cache file exists and it is less than 6*60*60 seconds (6 hours) old, use it:

if(file_exists($cacheFileName) &amp;&amp; time() - filemtime($cacheFileName) &gt; 6*60*60)
{
	$stats = unserialize(file_get_contents($cacheFileName));
}

if(!$stats)
{
	// If no cache was found, fetch the subscriber stats and create a new cache:

	$stats = new SubscriberStats(array(
		'facebookFanPageURL'	=&gt; 'http://www.facebook.com/smashmag',
		'feedBurnerURL'			=&gt; 'http://feeds.feedburner.com/Tutorialzine',
		'twitterName'			=&gt; 'Tutorialzine'
	));

	// Serialize turns the object into a string,
	// which can later be restored with unserialize():

	file_put_contents($cacheFileName,serialize($stats));
}

//	You can access the individual stats like this:
//	$stats-&gt;twitter;
//	$stats-&gt;facebook;
//	$stats-&gt;rss;

//	Output the markup for the stats:

$stats-&gt;generate();</pre>
<p>Sending a query to YQL&#8217;s servers and receiving a response is a relatively slow process and would be unwise to request the same information on every page load (not to mention that we could get banned from the API for abuse).</p>
<p>This is why we implement a simple caching system. The idea is simple: if a cache file does not exist (or is older than 6 hours), connect to YQL, create a new cache file and output the XHTML markup. Otherwise, just read the cache and output directly. This way we send a request to the API only once every six hours which is perfect for any practical purposes.</p>
<div id="attachment_913" class="wp-caption alignnone" style="width: 630px"><a href="http://demo.tutorialzine.com/2010/05/showing-facebook-twitter-rss-stats-jquery-yql/demo.html"><img class="size-full wp-image-913 " title="Combined Social Media Followers Count" src="http://tutorialzine.com/wp-content/uploads/2010/05/i11.png" alt="Combined Social Media Followers Count" width="620" height="260" /></a><p class="wp-caption-text">Combined Social Media Followers Count</p></div>
<h3>Step 2 &#8211; XHTML</h3>
<p>As mentioned in the PHP section above, the generate() method renders all the XHTML markup used to display the stats. Here is what the generated code looks like:</p>
<h4>sample code</h4>
<pre class="brush:html">&lt;div class="subscriberStats"&gt;
    &lt;div class="subscriberCount"  title="25,382+ Total Social Media Followers&gt;25,382&lt;/div&gt;

    &lt;div class="socialIcon" title="5,921 RSS Subscribers"&gt;
        &lt;a href="http://feeds.feedburner.com/Tutorialzine"&gt;
        &lt;img alt="RSS" src="img/rss.png" /&gt;&lt;/a&gt;
    &lt;/div&gt;

    &lt;div class="socialIcon" title="16,813 Fans on Facebook"&gt;
        &lt;a href="http://www.facebook.com/smashmag"&gt;
        &lt;img alt="Facebook" src="img/facebook.png" /&gt;&lt;/a&gt;
    &lt;/div&gt;

    &lt;div class="socialIcon" title="2,648 Twitter Followers"&gt;
        &lt;a href="http://twitter.com/Tutorialzine"&gt;
        &lt;img alt="Twitter" src="img/twitter.png" /&gt;&lt;/a&gt;
    &lt;/div&gt;
&lt;/div&gt;
</pre>
<p>This code is fetched via AJAX and displayed on the page. Notice the title attributes. They are used as the contents of the fancy tooltips which are created by jQuery and the tipTip plugin, which we will discuss in a moment.</p>
<h3>Step 3 &#8211; CSS</h3>
<p>The CSS code is also quite simple and straightforward. The <strong>subscriberStats</strong> is the main outer div, inside it we have a number of <strong>.socialIcon</strong> divs and the <strong>subscrberCount</strong>.</p>
<h4>css/styles.css</h4>
<pre class="brush:css">.subscriberStats{
	height:35px;
	padding:5px;
	width:220px;
}

.socialIcon{
	float:left;
	height:32px;
	width:32px;
}

a img{
	border:none;
}

.subscriberCount{
	border-bottom:1px dotted #CCCCCC;
	color:#999999;
	float:left;
	font-size:28px;
	line-height:32px;
	margin-right:10px;
}

#main{
	height:100px;
	margin:140px auto 50px;
	position:relative;
	width:200px;
}
</pre>
<p>All of these are floated to the left. Also notice that we disable the borders on the icon images on line 14, which are displayed by default and ruin your design.</p>
<h3>Step 4 &#8211; jQuery</h3>
<p>After including the jQuery library to the page, we just need to listen to the $(document).ready event, which is executed when all the markup of the page is accessible (this happens before things like images are loaded and comes earlier than the onload event).</p>
<h4>js/script.js</h4>
<pre class="brush:js">$(document).ready(function(){

	// Using the load AJAX method to fetch the subscriber markup
	// from subscriber_count.php:

	$('#main').load('subscriber_count.php',function(){

		// Once loaded, convert the title attributes to tooltips
		// with the tipTip jQuery plugin:

		$('.subscriberStats div').tipTip({defaultPosition:'top'});
	})

});</pre>
<p><strong>#main</strong> is the div where we want to insert the stats. This could be your sidebar or website header. The load method fetches the markup from <strong>suscriber_count.php</strong> and displays it on the page.  The callback function is called after this and all the div titles are replaced with fancy tooltips by the <em>tipTip plugin</em>.</p>
<p><strong>With this our combined social stats widget is complete!</strong></p>
<h3>Conclusion</h3>
<p>With services like YQL working with third party APIs is a charm. Not only it provides a common interface to a sea of technologies, but it also guarantees that you will be able to access to the services you want even as the underlying APIs change overtime.</p>
<p><strong>What do you think? How would you improve this code?</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://tutorialzine.com/2010/05/showing-facebook-twitter-rss-stats-jquery-yql/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk
Page Caching using disk (enhanced) (user agent is rejected)

Served from: tutorialzine.com @ 2010-08-01 02:50:38 -->