WP To Top – a WordPress plugin that takes you to the top

About WP To Top

WP To Top is a WordPress plugin that adds a “Back to top” link in your blog without modifying your template files. This is useful especially if you have long posts or long pages. You will have a nice “Back to top” or whatever-text-you-want link floating at the bottom right/left of your page.

Features

  • Smooth scrolling animation and fade in, fade out effect, powered by the YUI library
  • Customizable options via the admin panel, from the text to the position of the link
  • Works on almost all browsers including IE6 (yes!)

Download

You can get the plugin here

Demo

You have a demo on this page. Just scroll a little bit and you will see a nice “Take me up” link appearing at the bottom of your page.

Installation

  • Extract wptotop.zip in the “/wp-content/plugins/” directory
  • Activate the plugin through the “Plugins” menu in WordPress
  • Go to “Settings” and then “WP To Top” to configure the plugin. The options are self-explanatory and easy to understand.

Thanks

I got the inspiration to write this plugin after having a look at David Walsh’s jQuery topLink Plugin. Thanks to the YUI team for the great YUI library and Semih’s Animated Page Scroll with YUI.

twitree.com – see on which leaves the birds are…

I am happy to announce the launch of twitree.com. It’s a twitter application which allows a twitterer to view his followers in a tree-like navigation, which can be expanded.

twitree makes extensive use of the YUI library. The following components were used :

  • grids css – for the layout
  • yahoo dom event – for DOM and event handling
  • connection manager – for AJAX requests like getting the list of followers for a user
  • container family – to display modal dialogs like prompting for a twitter username, displaying the loading panel
  • JSON utility – to parse the JSON data twitree receives from the twitter servers
  • cookie utility – to fetch username information from a cookie so that the user doesn’t have to input his username every time
  • and finally the treeview control which provides a nice tree and dynamically loads the data upon clicking on a node

The application is very much in an initial phase and there are some limitations, like only 100 followers are being returned, rate limiting, etc…

Stay tuned for further information

Latest update :

twitterers can now

  • update their status via twitree
  • follow a user by right clicking on the user and choose “Follow” from the contextual menu
  • send a direct message to a fellow twitterer by right clicking on the user and choose “Send message” from the contextual menu

FAQ has also been added

Alternate colors to table rows with javascript (YUI)

This article will show you how to add alternate colors to table rows without any server side development or hard coding your scripts, thus providing good readability for your users and great flexibility for you. We will use the YUI library for that.

The HTML

We need to create our basic HTML file containing a table and adding a class name to it.

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
		<title>Alternate colors</title>
	</head>
	<body>
		<table class="alternateRows">
			<tr>
				<td>First Row</td>
			</tr>
			<tr>
				<td>Second Row</td>
			</tr>
			<tr>
				<td>Third Row</td>
			</tr>
			<tr>
				<td>Fourth Row</td>
			</tr>
			<tr>
				<td>Fifth Row</td>
			</tr>
		</table>
	</body>
</html>

The Javascript

Next we need to include the YUI libraries, served from their CDN. We need the

  • YAHOO global object which contains a number of methods that are used throughout the library
  • DOM collection which provides methods that simplify common DOM-scripting tasks, including element positioning and CSS style management
  • Event utility for various event handling
<!-- Combo-handled YUI JS files: --> 
<script type="text/javascript" src="http://yui.yahooapis.com/combo?2.6.0/build/yahoo-dom-event/yahoo-dom-event.js"></script>

And also our javascript file, alternate.js

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

So our HTML page looks like this:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
		<!-- Combo-handled YUI JS files: --> 
<script type="text/javascript" src="http://yui.yahooapis.com/combo?2.6.0/build/yahoo-dom-event/yahoo-dom-event.js"></script>
		<script type="text/javascript" src="alternate.js"></script>
		<title>Alternate colors</title>
	</head>
	<body>
		<table class="alternateRows">
			<tr>
				<td>First Row</td>
			</tr>
			<tr>
				<td>Second Row</td>
			</tr>
			<tr>
				<td>Third Row</td>
			</tr>
			<tr>
				<td>Fourth Row</td>
			</tr>
			<tr>
				<td>Fifth Row</td>
			</tr>
		</table>
	</body>
</html>

Invoking the javascript

To add the alternate colors to your table rows, you just have to put the following javascript code in your HTML page.

	YAHOO.util.Event.on(window, 'load', function(){
		YAHOO.htmlblog.alternateRows.init('alternateRows', '#fff', '#ccc');
	});

That means that after the page has been loaded, we call the alternateRows.init function, with 3 parameters:

  • the table class name, in our case it’s “alternateRows”
  • the first color in hex, e.g #fff
  • the second color in hex, e.g #ccc

Our complete HTML page

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
		<!-- Combo-handled YUI JS files: --> 
<script type="text/javascript"src="http://yui.yahooapis.com/combo?2.6.0/build/yahoo-dom-event/yahoo-dom-event.js"></script>
		<script type="text/javascript" src="alternate.js"></script>
		<script type="text/javascript">
			YAHOO.util.Event.on(window, 'load', function(){
				YAHOO.htmlblog.alternateRows.init('alternateRows', '#fff', '#ccc');
			});
		</script>
		<title>Alternate colors</title>
	</head>
	<body>
		<table class="alternateRows">
			<tr>
				<td>First Row</td>
			</tr>
			<tr>
				<td>Second Row</td>
			</tr>
			<tr>
				<td>Third Row</td>
			</tr>
			<tr>
				<td>Fourth Row</td>
			</tr>
			<tr>
				<td>Fifth Row</td>
			</tr>
		</table>
	</body>
</html>

Bubble menu javascript or playing with YUI’s event delegation

bubble
Image courtesy of jobee59’s photostream

Event delegation refers to the use of a single event listener on a parent object to listen for events happening on its children (or deeper descendants). Event delegation allows developers to be sparse in their application of event listeners while still reacting to events as they happen on highly specific targets. This proves to be a key strategy for maintaining high performance in event-rich web projects, where the creation of hundreds of event listeners can quickly degrade performance. More on event delegation including examples.

This post illustrates the use of event delegation to create a “bubble” menu, inspired by Bedrich Rios’ post on Nettuts.

The HTML

We’ll need the following components from the YUI library:

  • yahoo-dom-event – for DOM/Event handling
  • animation – for sliding effects

So our basic HTML page is like this:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
		<!-- Combo-handled YUI JS files: -->
		<script type="text/javascript" src="http://yui.yahooapis.com/combo?2.6.0/build/yahoo-dom-event/yahoo-dom-event.js&2.6.0/build/animation/animation-min.js"></script>
	</head>
	<body>

	</body>
</html>

Next we’ll add some structural markup, a simple list, with “menu” as class name and with 5 items.

<ul class="menu">
	<li>Menu item 1</li>
	<li>Menu item 2</li>
	<li>Menu item 3</li>
	<li>Menu item 4</li>
	<li>Menu item 5</li>
</ul>

Updated HTML page:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
		<!-- Combo-handled YUI JS files: -->
		<script type="text/javascript" src="http://yui.yahooapis.com/combo?2.6.0/build/yahoo-dom-event/yahoo-dom-event.js&2.6.0/build/animation/animation-min.js"></script>
	</head>
	<body>
		<ul class="menu">
			<li>Menu item 1</li>
			<li>Menu item 2</li>
			<li>Menu item 3</li>
			<li>Menu item 4</li>
			<li>Menu item 5</li>
		</ul>
	</body>
</html>

The Javascript

Then we just have to add the bubble.js javascript file to our page and it’s done, we’ll have a nice “bubble” menu.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
		<!-- Combo-handled YUI JS files: -->
		<script type="text/javascript" src="http://yui.yahooapis.com/combo?2.6.0/build/yahoo-dom-event/yahoo-dom-event.js&2.6.0/build/animation/animation-min.js"></script>
		<!-- our bubble file -->
		<script type="text/javascript" src="bubble.js"></script>
	</head>
	<body>
		<ul class="menu">
			<li>Menu item 1</li>
			<li>Menu item 2</li>
			<li>Menu item 3</li>
			<li>Menu item 4</li>
			<li>Menu item 5</li>
		</ul>
	</body>
</html>

bubble.js

/**
*	Bubble Menu
*	@author Asvin Balloo (https://htmlblog.net)
*/
bubbleMenu = {
	// private variables
	// class name of our menu
	menuClassName: null,
	// by how much we are sliding
	moveToLength : 10,
	
	/**
	*	Init the whole process here
	*	@method init
	*	@params menuClassName {string} class name of our menus
	*/
	init: function(menuClassName){
		// set our class name to be used later one
		bubbleMenu.menuClassName = menuClassName;
		
		// get all the lists with the class name
		var list = YAHOO.util.Dom.getElementsByClassName(menuClassName);
		
		// loop through them
		for(var i=0; i<list.length; i++) {
			// add the onmouseover event to it, call the mouseOverHandler function
			YAHOO.util.Event.on(list[i], "mouseover", bubbleMenu.mouseOverHandler);
			
			// get the first child and its padding left for future reference. Useful when using onmouseout to 

restore the item to original state
			var listItems = list[i].getElementsByTagName('li');
			var startingPadding = parseInt(YAHOO.util.Dom.getStyle(listItems[0], 'paddingLeft'));
			
			// add the onmouseout event, call the mouseOutHandler function
			YAHOO.util.Event.on(list[i], "mouseout", bubbleMenu.mouseOutHandler, {'list':list[i], "padding" : 

startingPadding});
		}
	},
	
	/**
	*	Mouse over handler
	*	@params e {Event} the event
	*/
	mouseOverHandler: function(e){
		// get the target
		var elTarget = YAHOO.util.Event.getTarget(e);
		
		// calculate the current padding left
		var paddingLeft = parseInt(YAHOO.util.Dom.getStyle(elTarget, 'paddingLeft'));
		
		// call the delegate method, with the target and the padding left value
		bubbleMenu.delegate(elTarget, paddingLeft);
	},
	
	/**
	*	Mouse out handler
	*	@params e {Event} the event
	*	@params o {JSON} JSON data containing the list + padding value, eg. {'list': mylist, 'padding': 10} 
	*/
	mouseOutHandler: function(e, o){
		// get the target
		var elTarget = YAHOO.util.Event.getTarget(e);
		
		// calculate the left padding, the original padding value - by how much we have padded
		var paddingLeft = o.padding - bubbleMenu.moveToLength;
		
		// call the delegate method with the target and padding value
		bubbleMenu.delegate(elTarget, paddingLeft);
	},
	
	/**
	*	Cool things go here, like animation
	*	@params elTarget {Target} our target
	*	@params padding {Int} by how much we are going to padd
	*/
	delegate: function(elTarget, padding){
		//walk up the DOM tree looking for an <li> in the target's ancestry; desist when you reach the container with our class name
		while (elTarget.className != bubbleMenu.menuClassName) {
			// are you an LI?
			if(elTarget.nodeName.toUpperCase() == "LI") {
				// if so then animate, set the attributes, in our case the left padding
				var attributes = { paddingLeft: {"to": [padding + bubbleMenu.moveToLength] } };
				
				// create our animation
				var anim = new YAHOO.util.Motion(elTarget, attributes, 0.6, YAHOO.util.Easing.bounceOut);
				
				// then animate
				anim.animate();
				break;
			}
			else {
				// it's not an li, so we keep looking and looking
	            elTarget = elTarget.parentNode; 
	        } 
		}
	}
};

// init the whole thing here
YAHOO.util.Event.on(window, "load", function(){
	bubbleMenu.init("menu");
});

You can have unlimited (don’t abuse) number of bubble menus by just adding the “menu” class to each one of them and including the bubble.js file.
If you’re not happy with the menu class or you found another cool class name, then you’ll have to update the bubble.js file towards the end:

// init the whole thing here
YAHOO.util.Event.on(window, "load", function(){
	bubbleMenu.init("mycoolclass");
});

Also you can modify by how much an item slides by modifying the moveToLength variable (default 10):

// by how much we are sliding
moveToLength : 30,

Note that the demo is using reset-fonts-grids CSS and the page has been styled with the following:

body {
	margin: 0;
	padding: 0;
	background: #1d1d1d;
	font-family: "Lucida Grande", Verdana, sans-serif;
	font-size: 100%;
}
			
.menu li{
	padding-left: 20px;
	line-height: 2em;
	width: 150px;
	color: #999;

	background: #222;
	border: 1px solid #1a1a1a;
	-moz-border-radius: 10px;
}

Pixidou – an Open Source AJAX Image Editor (PHP and YUI based)

Pixidou is a new open source AJAX image editor which will allow you to :

  • adjust brightness
  • adjust contrast
  • cropping
  • flipping
  • negative
  • resizing
  • rotating
  • tint

images.

What you need to get running

  • PHP5.2+ installed on your webserver
  • GD2
  • a web browser

Demo

Installation
Unzip/untar the software in your web directory and that’s all 😉
Also ensure the images folder is writable by your webserver.
Have fun !!!

Download
Get it and follow it at github

All the image manipulation is PHP-based with the help of the great class.upload.php class by Colin Verot which I highly recommend.

The frontend is the most interesting part, where I’ve use the one and only YUI library. Here are the component I used (served from Yahoo CDN) :

  • reset-fonts.css – for all resetting, style information
  • utilities – for all AJAX, animation, drag drop, event handling stuff
  • container – for all panels, dialogs, alerts
  • menu – for the top navigation menu together with the submenus
  • button – provides nice buttons
  • slider – for adjusting contrast and brightness
  • color picker – to choose the color to tint the image
  • resize – to resize the image
  • image cropper – image cropping utility
  • json – to parse all JSON data returned from PHP scripts
  • layout – the general layout
  • tabview – for the about information

I’ve not used the grids.css since it caused some problems while using the color picker.

It’s only the beginning of Pixidou and I’am currently looking for some collaborators. So, if you think you can give a helping hand in any way to Pixidou, don’t hesitate to contact me (asvin.balloo [@] gmail.com), I’ll happily add you as a contributor to the repository on github.

Since it’s an early version, there must be some bugs lying everywhere, don’t hesitate to drop me an email.

AJAX image cropper with YUI and PHP

This post will show you how to build an AJAX crop image tool using the image cropper control from YUI library and PHP.


The ImageCropper Control from the YUI library gives you an interactive interface for getting the dimensions to crop an image and using these dimensions in PHP, we can do some cropping.

The script we are going to build will

  • allow users to upload an image via AJAX
  • then allow them to select an area for cropping
  • lastly, provide a download link for the cropped image.

There are 3 files we are going to use

  • index.php – will contain the form for image upload as well as the cropping interface
  • upload.php – provides uploading functionality
  • crop.php – provides cropping functionality

From a technical point of view, the flow will be like this :

  1. user uploads jpg image (index.php)
  2. index.php then posts the image asynchronously to upload.php which will do the upload on the server, returning JSON data containing the image file name, its width and its height.
  3. with the JSON data and innerHTML we put the image in our page
  4. initialize the javascript cropping tool
  5. generate a download link (crop.php)


Let’s have a look at index.php

The index.php is our main file where users will be able upload images and then download the cropped ones.

We’ll need the following components from the YUI library :

  • yahoo-dom-event.js – for DOM manipulation and Event handling
  • dragdrop – dependency for the image cropper control
  • element – dependency for the image cropper control
  • resize – dependency for the image cropper control
  • connection – for AJAX requests, in our case for image uploads via AJAX
  • json – for parsing JSON data
  • imagecropper – our most important control

Of course we’ll use Yahoo combo handling and add the js to our page along with the CSS needed for the above controls :

<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.5.2/build/resize/assets/skins/sam/resize.css" />
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.5.2/build/imagecropper/assets/skins/sam/imagecropper.css" />
<!-- js -->
<script type="text/javascript" src="http://yui.yahooapis.com/combo?2.5.2/build/yahoo-dom-event/yahoo-dom-event.js&2.5.2/build/dragdrop/dragdrop-min.js&2.5.2/build/element/element-beta-min.js&2.5.2/build/resize/resize-beta-min.js&2.5.2/build/imagecropper/imagecropper-beta-min.js&2.
5.2/build/connection/connection-min.js&2.5.2/build/json/json-min.js"></script>

Next users must be able to upload images via AJAX, so we add a form to our page:

<form action="upload.php" enctype="multipart/form-data" method="post" name="uploadForm" id="uploadForm">
	Image : <input type="file" name="uploadImage" id="uploadImage" />
	<input type="button" id="uploadButton" value="Upload"/>
</form>

We have an onclick event to the upload button to fire the uploading process.

// add listeners
YAHOO.util.Event.on('uploadButton', 'click', uploader.carry);

We’ll also need 2 containers :

  • imageContainer – will contain our uploaded image
  • downloadLink – will contain the download link
<div id="imageContainer"></div>
<div id="downloadLink"></div>

Both containers will be updated via innerHTML afterwards.

AJAX upload

For the AJAX upload, Code Central

has an excellent tutorial which I highly recommend. I took the code sample and modified it a bit to fit my needs. Finally I came up with a nice JSON object called uploader which has one method, carry. The latter just posts form data to a specified URL.

uploader = {
	carry: function(){
		// set form
		YAHOO.util.Connect.setForm('uploadForm', true);
		// upload image
		YAHOO.util.Connect.asyncRequest('POST', 'upload.php', {
			upload: function(o){
				// parse our json data
				var jsonData = YAHOO.lang.JSON.parse(o.responseText);
				
				// put image in our image container
				YAHOO.util.Dom.get('imageContainer').innerHTML = '<img id="yuiImg" src="' + jsonData.image + '" width="' + jsonData.width + '" height="' + jsonData.height + '" alt="" />';
						
				// init our photoshop
				photoshop.init(jsonData.image); 
							
				// get first cropped image
				photoshop.getCroppedImage();
			}
		});
	}
};

When upload is complete, we get the JSON data we mentioned earlier on. For e.g :

{"image" : "images/myimage.jpg", "width" : "500", "height" : 400}

With this data and using innerHTML we update our imageContainer div to put our image which will have yuiImg as id :

YAHOO.util.Dom.get('imageContainer').innerHTML = '<img id="yuiImg" src="' + jsonData.image + '" width="' + jsonData.width + '" height="' + jsonData.height + '" alt="" />';

It’s very important to specify the image width and height else the image cropper won’t work.
Next we initialize another JSON object, photoshop which we’ll have a look now.

Our photoshop object

photoshop = {
	image: null,
	crop: null,
	
	init: function(image){
		// set our image
		photoshop.image = image;
					
		// our image cropper from the uploaded image					
		photoshop.crop = new YAHOO.widget.ImageCropper('yuiImg');
		photoshop.crop.on('moveEvent', function() {
			// get updated coordinates
			photoshop.getCroppedImage();
		});
	},
	
	getCroppedImage: function(){
		var coordinates = photoshop.getCoordinates();
		var url = 'crop.php?image=' + photoshop.image + '&cropStartX=' + coordinates.left +'&cropStartY=' + coordinates.top +'&cropWidth=' + coordinates.width +'&cropHeight=' + coordinates.height;
		YAHOO.util.Dom.get('downloadLink').innerHTML = '<a href="' + url + '">download cropped image</a>';		

	},

	getCoordinates: function(){
		return photoshop.crop.getCropCoords();
	}
};

The init function iniatializes the YUI image cropper from the uploaded image which has yuiImg as id.

photoshop.crop = new YAHOO.widget.ImageCropper('yuiImg');

We also subscribe to the moveEvent for the cropper since we’ll need to update the download link for the cropped image. So whenever the image cropper is moved/resized, we call the getCroppedImage function.

photoshop.crop.on('moveEvent', function() {
	// get updated coordinates
	photoshop.getCroppedImage();
});

The getCroppedImage function will generate the download link for the cropped image. To do image cropping in PHP we’ll need

  • the image we want to crop
  • the X,Y coordinates
  • height and width of the to be cropped area

Fortunately the YUI cropper utility has a function which will give us what we want, it’s the getCropCoords() method. So, whenever the getCroppedImage function is called, we get the coordinates of the cropped area, build a URL and finally put the download link in our downloadLink container.

// get coordinates
var coordinates = photoshop.getCoordinates();

// build our url
var url = 'crop.php?image=' + photoshop.image + '&cropStartX=' + coordinates.left +'&cropStartY=' + coordinates.top +'&cropWidth=' + coordinates.width +'&cropHeight=' + coordinates.height;

// put download link in our page
YAHOO.util.Dom.get('downloadLink').innerHTML = '<a href="' + url + '">download cropped image</a>';

This is all we need for the index page.

upload.php

if(!empty($_FILES["uploadImage"])) {
  	// get file name
	$filename = basename($_FILES['uploadImage']['name']);
		
	// get extension
  	$ext = substr($filename, strrpos($filename, '.') + 1);
  		
  	// check for jpg only
  	if ($ext == "jpg") {
      		// generate unique file name
  		$newName = 'images/'.time().'.'.$ext;
  			
  		// upload files
        	if ((move_uploaded_file($_FILES['uploadImage']['tmp_name'], $newName))) {
			
        		// get height and width for image uploaded
        		list($width, $height) = getimagesize($newName);
        		
        		// return json data
           		echo '{"image" : "'.$newName.'", "height" : "'.$height.'", "width" : "'.$width.'" }';
        	}
        	else {
           		echo '{"error" : "An error occurred while moving the files"}';
        	}
  	} 
  	else {
     		echo '{"error" : "Invalid image format"}';
  	}
}	

The upload.php file too is self explanatory, we check for a jpg image only, then generate an unique filename, put it in the images folder and finally build json data which we’ll use for DOM manipulation. Of course the images folder must be writable by the web server.

crop.php

// get variables
$imgfile = $_GET['image'];
$cropStartX = $_GET['cropStartX'];
$cropStartY = $_GET['cropStartY'];
$cropW = $_GET['cropWidth'];
$cropH = $_GET['cropHeight'];

// Create two images
$origimg = imagecreatefromjpeg($imgfile);
$cropimg = imagecreatetruecolor($cropW,$cropH);

// Get the original size
list($width, $height) = getimagesize($imgfile);

// Crop
imagecopyresized($cropimg, $origimg, 0, 0, $cropStartX, $cropStartY, $width, $height, $width, $height);

// force download nes image
header("Content-type: image/jpeg");
header('Content-Disposition: attachment; filename="'.$imgfile.'"');
imagejpeg($cropimg);

// destroy the images
imagedestroy($cropimg);
imagedestroy($origimg);

Crop.php allows us to crop our uploaded image. First we get all the variables passed to us via the AJAX request,

// get variables
$imgfile = $_GET['image'];
$cropStartX = $_GET['cropStartX'];
$cropStartY = $_GET['cropStartY'];
$cropW = $_GET['cropWidth'];
$cropH = $_GET['cropHeight'];

Then we create 2 images, the original one and the cropped one, and use the imagecopyresized function to generate the cropped image. We add some header information to tell the world it’s an image and prompt for a save dialog.

Show/hide containers by only adding CSS classes without writing javascript code (YUI-based)

This post will show you how to add the collapse/expand functionality in your HTML pages, perfect for FAQs by only adding two class names to your existing page and including the scripts below. Of course it’s all YUI-based and also a demo of the fantastic YUI selector utility.

What does the script do ?

OK, suppose you have a FAQ page where you have traditional anchor methods, i.e you click on the question and then you go to the bottom of the page to get the answer or you get redirected to another page. But now your users are complaining your site’s not trendy enough and want to have the answer displayed immediately after clicking the question.

The solution.

After downloading the javascript file, include it at the bottom of your page with the following HTML code:

<script type="text/javascript" src="http://yui.yahooapis.com/combo?2.5.2/build/yahoo-dom-event/yahoo-dom-event.js&2.5.2/build/selector/selector-beta-min.js"></script> 
<script type="text/javascript" src="js/toggler.js"></script>

We need to include the selector utility which will be used to retrieve a collection of elements that match a given CSS selector. For e.g if we want to retrieve all div nodes in HTML page having the class “foo”, we can write :

var myNodes = YAHOO.util.Selector.query('div.foo');

The selector is used in the toggler.js file.

After adding the scripts, now you have to add CSS classes to your containers. For example for the FAQ, for questions (or main, call it whatever you want), you add the class “htmlblog-main” and for the answers (or sub), add the “htmlblog-sub” class.

Before :

<div>1. Question</div>
<div>Answer1</div>
<div>2. Question 2</div>
<div>Answer 2</div>

After :

<div class="htmlblog-main">1. Question</div>
<div class="htmlblog-sub">Answer1</div>
<div class="htmlblog-main">2. Question 2</div>
<div class="htmlblog-sub">Answer 2</div>

If you already had a class for that container, no problem you can add the htmlblog-main or htmlblog-sub class :

<div class="myclass htmlblog-main">1. Question</div>

What next ?

That’s all ! All your answer containers will be hidden and questions will have a [+] besides them. Pretty easy

Am I obliged to use the htmlblog-main and html-sub classes ? And I don’t want to use div tags, I want li tags.

Don’t worry, if you don’t like the class names you can put whatever you want but you’ll have to edit the toggler.js file at the following lines :

YAHOO.util.Event.addListener(window, 'load', function(){
	YAHOO.htmlblog.init('div', 'htmlblog-main', 'htmlblog-sub');
});

For e.g, if you’re using li tags instead of divs with the “myMainClass” as main and “mySubClass” as sub, the code goes :

YAHOO.util.Event.addListener(window, 'load', function(){
	YAHOO.htmlblog.init('li', 'myMainClass', 'mySubClass');
});

I’am getting an alert saying “Number of main and subs incorrect”.

That means the number of main/subs are not the same. You need to have the number of the main class equals the number of the sub class.

nouzil.com – a new Mauritian portal on the web (YUI-based)

I came to know the existing of a new Mauritian portal via Avinash called nouzil (which means our island in creole) and I must say at first look it reminds me of Netvibes a lot. I think the nouzil.com team picked up some bits and pieces from Netvibes.com.
Anyway, looking behind the scenes I notice that the new portal uses YUIa lot, in fact it’s all YUI-based. Had a look at the source and they are using the following YUI components (with my comments) :

  • utilities – for XHR requests, dragging of widgets, various DOM manipulations
  • cookie – to save the state of the widgets and order I presume
  • container – for various settings panels and the loading panel at the start
  • json – json data (hadn’t seen any in my Firebug panel)
  • element – ?
  • calendar – calendar widget at the bottom
  • tabview – when doing a Google search the results are displayed in a new tab
  • reset-fonts-grids – for layout, they are using the 974px width template

Unfortunately the nouzil.js was minified thus unreadable and couldn’t get very far in my analysis 😉

Overall I find the portal quite nice and find the CanalSat widget very useful since the CanalSat Reunion website is very slow and the widget shows the current programs on air. It would be interesting if the user could choose the time frame he wishes to view the programme. The Flickr widget too is cool, showing the latest photos from Mauritius and I think it’s an exact replica from that of Netvibes, so is the delicious one.

Another thing I noticed is that the team did not follow Yahoo’s performance rules for website, no caching, no gzipping and I have to download the same images again and again. I think they can improve it and take it very far, why not compete with the big boys.

Good luck to the nouzil.com team and congrats for that all YUI-basedportal.

YUI-based alert box – replace your ugly javascript alert box

This tutorial will explain how you can override the default alert box of your browser, without modifying your existing code and by adding 2 lines of javascript code.

Those 2 famous lines

After downloading the package and extracting it to your folder, add the following lines at the end of your page.

<script type="text/javascript" src="http://yui.yahooapis.com/combo?2.5.2/build/yuiloader/yuiloader-beta-min.js"></script>
<script type="text/javascript" src="js/alert.js"></script> 

We make use of YUI’s fantastic loader utility which will allows us to load specific YUI components and their dependencies into our page via script from their servers. The second file actually contains all the code which will replace the default alert box by a YUI-based and YUI-skinned one.
Note that it’s better to include the files at the bottom of your page as told earlier as recommended by Yahoo’s Exceptional Performance team for speeding your page.

The HTML code

<a href="#" onclick="alert('Hello World !');">Click to say hi</a>

That’s all, you don’t need to include any CSS or other javascript files. They are all taken from Yahoo servers and you get a nice alert message. If for one reason or another you’re fed up with this alert box, you just remove the included javascript files and it will fall back to the default alert box.

Behind the scenes.

You can open the alert.js file which is well commented to have a look at what’s going behind the scenes. Dav Glass wrote something about this replacement for alert, it’s almost the same thing except all is done through the loader utility. 😉

The alert.js file contains 2 JSON objects namely :

  • bootstrap
  • ui

bootstrap

bootstrap is responsible for fetching all the components from the Yahoo servers namely :

  • container – since we are using the SimpleDialog component to render the alert box
  • button – to have the nice button in the box
  • fonts – which offers cross-browser typographical normalization and control
  • selector – to perform some lookups to add the yui-skin-sam class to the body so as we can use YUI’s skinning system.

ui

The ui in fact initializes our SimpleDialog and then render it

// our dialog for info, to show messages to the users
ui.dialogInfo = new YAHOO.widget.SimpleDialog("simpledialog1", 
{
width: "300px",
fixedcenter: true,
visible: false,
draggable: false,
zIndex: 9999,
close: true,
modal: true,
effect:{effect:YAHOO.widget.ContainerEffect.FADE,duration:0.25},
constraintoviewport: true,
buttons: [ { text:"close", handler: function(){this.hide();}, isDefault:true }]
});
ui.dialogInfo.setHeader("information");
// Render the Dialog
ui.dialogInfo.render(document.body);

It also contains the showDialogInfo method which is called when alert function is called.

window.alert = function(text){
	ui.dialogInfo.setBody(text);
	ui.dialogInfo.show();
};

f-lv.com – download YouTube videos in FLV/MP4/3GP format

After playing with the YouTube API and Python over the past week, I’am pleased to announce the launch of f-lv.com

You will be able to :

  • download your favorite YouTube videos in FLV/MP4 format
  • email the video download link to your friend
  • have a look at a nice carousel (thanks Bill for that) with the latest downloaded videos


Site is built in PHP5 with a tiny bit of Python for generating the link part, powered by the one and only YUI library for all AJAX stuff, dialogs, panels.

Latest update (22 August 2008):
Support for 3GP files has been added. Users can now download 3GP files which are perfect for their mobile phones.