<?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>Xguiden &#187; JavaScript</title>
	<atom:link href="http://xguiden.dk/category/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://xguiden.dk</link>
	<description>Dine guides findes her</description>
	<lastBuildDate>Sat, 13 Mar 2010 16:37:57 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Awesome CSS+JS form styling</title>
		<link>http://xguiden.dk/2010/03/10/awesome-cssjs-form-styling/</link>
		<comments>http://xguiden.dk/2010/03/10/awesome-cssjs-form-styling/#comments</comments>
		<pubDate>Wed, 10 Mar 2010 10:14:37 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Engelske guides]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[attribute]]></category>
		<category><![CDATA[auto login]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[content]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[element]]></category>
		<category><![CDATA[function]]></category>
		<category><![CDATA[GET]]></category>
		<category><![CDATA[input type text]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[javascript library]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[login]]></category>
		<category><![CDATA[open source project]]></category>
		<category><![CDATA[scenarios]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[Transparent]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[webkit]]></category>

		<guid isPermaLink="false">http://xguiden.dk/?p=5558</guid>
		<description><![CDATA[Sexy CSS+JS Form

I was working on our new open source project that i think you will like and I was working on the registration page. This is what I got in the end and i will walk you trough the process with me. This new tutorial is about styling the forms of your website, I [...]]]></description>
			<content:encoded><![CDATA[<div><a rel="attachment wp-att-312" href="http://xguiden.dk/?attachment_id=312"><img class="size-medium wp-image-312" src="http://blog.ajaxmasters.com/wp-content/uploads/2010/03/sexy-form-300x214.png" alt="Sexy CSS Form" width="300" height="214" /></a>Sexy CSS+JS Form</p>
</div>
<p>I was working on our new open source project that i think you will like and I was working on the registration page. This is what I got in the end and i will walk you trough the process with me. This new tutorial is about styling the forms of your website, I find it very good looking and very simple to implement. We will use simple CSS and some JavaScript.</p>
<p>Usually for inserting text into the inputs or our forms we set the value attribute with the text and then use javascript to check for different scenarios for doing some fancy things. This is different we will use labels to fill the text and move them under the inputs and then just do our magic with JS.</p>
<p>The JavaScript library that we will use to create this effect for our forms is <a href="http://jquery.com" target="_blank">Jquery</a></p>
<p><strong>1. Creating the markup!</strong></p>
<pre>            &lt;div id="login"&gt;
                &lt;div class="sayit"&gt;Log In:&lt;/div&gt;
                &lt;form action="javascript:void(0)" onsubmit="login()" autocomplete="off"&gt;
                    &lt;label for="username"&gt;Username&lt;/label&gt;
                    &lt;input type="text" id="username"/&gt;
                    &lt;label for="password"&gt;Password&lt;/label&gt;
                    &lt;input type="password" id="password"/&gt;
                    &lt;input type="submit" class="medium button green" value="Log me In"/&gt;
                &lt;/form&gt;
            &lt;/div&gt;</pre>
<p>The above code is our markup and as you can see is very simple and it can be changed as you like because the code that we will use for checking for different scenarios in javascript will work without necessary classes or ids. We have 2 inputs and 2 labels, one is password one is text and we can work with these ones, you can add as many as you like.</p>
<p>Now let’s style these bastards! <img class="wp-smiley" src="http://blog.ajaxmasters.com/wp-content/plugins/smilies-themer/pidgin/smile-big.png" alt=":D" /></p>
<p><strong>2. Use CSS to style the form elements!</strong></p>
<pre>input[type=text],input[type=password]{padding: 5px 10px; background-color: transparent;	position: relative; z-index: 2;}
label{position: absolute; z-index: 1;-webkit-transition: opacity 0.15s linear; color: #bababa; background-color: #FFFFFF; }

#login{width: 290px; margin: 0 auto;}
#login input[type=text],#login input[type=password]{width:270px; margin: 5px 0; font-size: 24px; font-weight: bold; border: 1px solid #ccc; -moz-border-radius:5px; -webkit-border-radius:5px; color: #595959;}
#login label{font-size: 24px; margin: 14px 10px;}

#login .sayit{font-size:24px; color: #595959; font-style: italic; padding-bottom: 5px;}</pre>
<p>What we did here is make the label absolute so it will go under the input. This is important you will have to place the label before the input so remember this! The input will have a position relative and a z-index of 2 so we can be sure it will land above the label. Next we define the login div by using his id(<em>#login</em>). We use CSS3 for creating the round borders for the input and style the label by setting a big font-size to fit the input. The rest is pretty obvious, if you have trouble understanding this then let us know in the comments.</p>
<p><strong>3. Make everything move with JS!</strong></p>
<pre>$(document).ready(function(){
    $.string(String.prototype);
    $("input,textarea").each(function (type) {
        $(this).focus(function () {
            if($(this).val().blank())
                $(this).prev("label").fadeTo('fast',0.45);
        });

        $(this).keypress(function () {
            $(this).prev("label").fadeTo('fast',0);
        });

        $(this).blur(function () {
            if($(this).val().blank()){
                $(this).prev("label").fadeTo('fast',1);
            }
        });
    });
});</pre>
<p>We use here jQuery of course that we add using the google api like this:</p>
<pre>        &lt;script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"&gt;&lt;/script&gt;</pre>
<p>And one plugin that I use to extend the jQuery string properties and that is <a href="http://stilldesigning.com/dotstring/">$.string plugin</a>. After we do that we create the above code and we assign to input and textarea elements a focus, keypress and blur actions. We use the focus action to lower the labels opacity to 45% then on keypress we just hide it for good. Then on blur we check to see if anything was written in our sexy element and if not then we fade the label back to 100%. This is kind of everything we do here, pretty simple. <img class="wp-smiley" src="http://blog.ajaxmasters.com/wp-content/plugins/smilies-themer/pidgin/smile.png" alt=":)" /></p>
<p><strong>4. Showing of a demo and download source</strong></p>
<p>I’ve set up a demo here: <a href="http://tutorials.ajaxmasters.com/sexy-form/" target="_blank"><strong><em>DEMO</em></strong></a></p>
<p>The source code you can either pick it from the demo page or from here: <a href="http://tutorials.ajaxmasters.com/sexy-form/source.zip"><strong><em>SOURCE</em></strong></a></p>
<p><strong>5. Wrapping up!</strong></p>
<p>So here is our nice form styling that you can use on your website and that can be done very easily. Feel free to leave us comments and suggestions. <strong>Thanks a lot!</strong></p>
<p>Have fun coding!<img src="http://feeds.feedburner.com/~r/AjaxmastersBlogRss/~4/0J4er0tKB4Q" alt="" width="1" height="1" /></p>

	Tags: <a href="http://xguiden.dk/tag/ajax/" title="AJAX" rel="tag">AJAX</a>, <a href="http://xguiden.dk/tag/attribute/" title="attribute" rel="tag">attribute</a>, <a href="http://xguiden.dk/tag/auto-login/" title="auto login" rel="tag">auto login</a>, <a href="http://xguiden.dk/tag/code/" title="code" rel="tag">code</a>, <a href="http://xguiden.dk/tag/content/" title="content" rel="tag">content</a>, <a href="http://xguiden.dk/tag/css/" title="CSS" rel="tag">CSS</a>, <a href="http://xguiden.dk/tag/css3/" title="css3" rel="tag">css3</a>, <a href="http://xguiden.dk/tag/design/" title="design" rel="tag">design</a>, <a href="http://xguiden.dk/tag/element/" title="element" rel="tag">element</a>, <a href="http://xguiden.dk/tag/function/" title="function" rel="tag">function</a>, <a href="http://xguiden.dk/tag/get/" title="GET" rel="tag">GET</a>, <a href="http://xguiden.dk/tag/input-type-text/" title="input type text" rel="tag">input type text</a>, <a href="http://xguiden.dk/tag/java/" title="Java" rel="tag">Java</a>, <a href="http://xguiden.dk/tag/javascript/" title="JavaScript" rel="tag">JavaScript</a>, <a href="http://xguiden.dk/tag/javascript-library/" title="javascript library" rel="tag">javascript library</a>, <a href="http://xguiden.dk/tag/jquery/" title="jquery" rel="tag">jquery</a>, <a href="http://xguiden.dk/tag/js/" title="js" rel="tag">js</a>, <a href="http://xguiden.dk/tag/login/" title="login" rel="tag">login</a>, <a href="http://xguiden.dk/tag/open-source-project/" title="open source project" rel="tag">open source project</a>, <a href="http://xguiden.dk/tag/scenarios/" title="scenarios" rel="tag">scenarios</a>, <a href="http://xguiden.dk/tag/script/" title="script" rel="tag">script</a>, <a href="http://xguiden.dk/tag/transparent/" title="Transparent" rel="tag">Transparent</a>, <a href="http://xguiden.dk/tag/tutorial/" title="tutorial" rel="tag">tutorial</a>, <a href="http://xguiden.dk/tag/webkit/" title="webkit" rel="tag">webkit</a><br />

	<h4>Related posts</h4>
	<ul class="st-related-posts">
	<li><a href="http://xguiden.dk/2010/03/10/making-a-mosaic-slideshow-with-jquery-and-css/" title="Making a Mosaic Slideshow With jQuery and CSS (10/03/2010)">Making a Mosaic Slideshow With jQuery and CSS</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/02/15/how-to-code-up-a-web-design-from-psd-to-html/" title="How to Code up a Web Design from PSD to HTML (15/02/2010)">How to Code up a Web Design from PSD to HTML</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/02/13/sweet-ajax-tabs-with-jquery-1-4-and-css3/" title="Sweet AJAX Tabs With jQuery 1.4 and CSS3 (13/02/2010)">Sweet AJAX Tabs With jQuery 1.4 and CSS3</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/02/13/making-a-photoshoot-effect-with-jquery-css/" title="Making a Photoshoot Effect With jQuery and CSS (13/02/2010)">Making a Photoshoot Effect With jQuery and CSS</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/03/03/how-we%e2%80%99ll-be-building-websites-in-5-years-html5-and-css3-layout/" title="How We’ll be Building Websites in 5 years: HTML5 and CSS3 layout (03/03/2010)">How We’ll be Building Websites in 5 years: HTML5 and CSS3 layout</a> (0)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://xguiden.dk/2010/03/10/awesome-cssjs-form-styling/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Making a Mosaic Slideshow With jQuery and CSS</title>
		<link>http://xguiden.dk/2010/03/10/making-a-mosaic-slideshow-with-jquery-and-css/</link>
		<comments>http://xguiden.dk/2010/03/10/making-a-mosaic-slideshow-with-jquery-and-css/#comments</comments>
		<pubDate>Wed, 10 Mar 2010 10:11:30 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Engelske guides]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[content]]></category>
		<category><![CDATA[css styles]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[element]]></category>
		<category><![CDATA[function]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[mosaic effect]]></category>
		<category><![CDATA[mosaic gallery]]></category>
		<category><![CDATA[mosaic slideshow]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[slide image]]></category>
		<category><![CDATA[slide style]]></category>
		<category><![CDATA[transition effect]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://xguiden.dk/?p=5559</guid>
		<description><![CDATA[When designing a product page, it is often necessary to present a number of images in a succession, also known as a slideshow. With the raise of the jQuery library and its numerous plugins, there is an abundance of ready-made solutions which address this problem. However, to make a lasting impression to your visitors, you [...]]]></description>
			<content:encoded><![CDATA[<p>When designing a product page, it is often necessary to present a number of images in a succession, also known as a slideshow. With the raise of the jQuery library and its numerous plugins, there is an abundance of ready-made solutions which address this problem. However, to make a lasting impression to your visitors, you need to present them with something they have not seen before.</p>
<p>Today we are making a jQuery &amp; CSS mosaic gallery. Mosaic, because it will feature an interesting tile transition effect when moving from one slide to another.</p>
<h3>Step 1 – XHTML</h3>
<p>The mosaic effect of the slideshow is achieved by dividing the original image into smaller parts. These tiles, which contain parts of the image, are sequentially hidden from view, which causes the effect. The markup of the slideshow is pretty straightforward. It consists of the main slideshow container element (<strong>#mosaic-slideshow</strong>), a left and right arrow for previous and next transition and the mosaic-slide div, which is inserted by jQuery at run-time.</p>
<h4>demo.html</h4>
<pre>&lt;div id="mosaic-slideshow"&gt;
	&lt;div class="arrow left"&gt;&lt;/div&gt;
	&lt;div class="arrow right"&gt;&lt;/div&gt;

	&lt;div class="mosaic-slide" style="z-index: 10;"&gt;

		&lt;!-- The mosaic-slide div and the tiles are generated by jQuery --&gt;
		&lt;div class="tile" style="..."&gt;&lt;/div&gt;
		&lt;div class="tile" style="..."&gt;&lt;/div&gt;
		&lt;div class="tile" style="..."&gt;&lt;/div&gt;
		&lt;div class="tile" style="..."&gt;&lt;/div&gt;

	&lt;/div&gt;
&lt;/div&gt;</pre>
<p>The div with the <strong>mosaic-slide</strong> class name is added to the page by jQuery after the<strong> transition()</strong> JavaScript function is executed (we will come back to this in the third step). Inside it you can see the <strong>tile </strong>divs. There are a total of 56 such divs, each of which has a 60px by 60px portion of the slide image set as its background.</p>
<div><a href="http://tutorialzine.com/wp-content/uploads/2010/03/i1.jpg"><img class="size-full wp-image-766" src="http://tutorialzine.com/wp-content/uploads/2010/03/i1.jpg" alt="Mosaic Slideshow" width="620" height="460" /></a>Mosaic Slideshow</p>
</div>
<h3>Step 2 – CSS</h3>
<p>To make this effect work (and most importantly look good), we have to add a few lines of CSS. Only the code directly used by the gallery is shown here. You can see the code that styles the rest of the demonstration page in <strong>styles.css</strong>.</p>
<h4>styles.css – Part 1</h4>
<pre>#mosaic-slideshow{
	/* The slideshow container div */
	height:500px;
	margin:0 auto;
	position:relative;
	width:670px;
}

.mosaic-slide{
	/* This class is shared between all the slides */
	left:80px;
	position:absolute;
	top:25px;

	border:10px solid #555;

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

.tile{
	/* The individual tiles */
	height:60px;
	width:60px;
	float:left;
	border:1px solid #555;
	border-width:0 1px 1px 0;
	background-color:#555;
}</pre>
<p>The slideshow is contained inside the div with an ID of <strong>mosaic-slideshow</strong> (or #mosaic-slideshow, if we refer to it in a form of a CSS / jQuery selector).  There can be only one such div in the page, hence the use of an ID attribute.</p>
<p>However there can be more than one <strong>mosaic-slide</strong> divs in the page. The effect itself is achieved by stacking two slides on top of each other and hiding the tiles of the first one to reveal the ones of the second. This is why we are using a class name instead of an ID.</p>
<p>Some of the more interesting rules presented here are the three CSS3 rules for rounded corners. As the CSS3 standard is still a work in progress, browsers don’t support the regular <strong>border-radius </strong>property yet (except for the new 10.50 version of Opera), and need vendor-specific prefixes to recognize it. The<strong> -moz-</strong> prefix is used by Firefox, and <strong>-webkit-</strong> is used by Safari and Chrome.</p>
<h4>styles.css – Part 2</h4>
<pre>.arrow{
	/* The prev/next arrows */
	width:35px;
	height:70px;
	background:url("img/arrows.png") no-repeat;
	position:absolute;
	cursor:pointer;
	top:50%;
	margin-top:-35px;
}

.arrow.left{
	left:15px;
	background-position:center top;
}

.arrow.left:hover{
	background-position:center -70px;
}

.arrow.right{
	right:15px;
	background-position:center -140px;
}

.arrow.right:hover{
	background-position:center -210px;
}

.clear{
	/* This class clears the floats */
	clear:both;
}</pre>
<p>The <strong>arrow</strong> class is shared by the previous and next arrows. They do need individual styling in addition to this common rule, so we add it after this. We are also using a CSS sprite as the background for the arrow divs. It contains a regular and hover state for both arrows, which spares us from having to use four individual images.</p>
<blockquote><p>“<strong>CSS spriting</strong>” is a widespread technique used by web designers. It allows the designer to join multiple smaller images into a single larger one, called a sprite, which is downloaded faster and saves the web server from multiple download requests. After this, the designer can use the CSS background property in conjunction with setting the elements to a fixed size, to show only the part of the sprite image that they need.</p></blockquote>
<div><a href="http://tutorialzine.com/wp-content/uploads/2010/03/i2.jpg"><img class="size-full wp-image-767" src="http://tutorialzine.com/wp-content/uploads/2010/03/i2.jpg" alt="Mosaic Slideshow" width="620" height="260" /></a>Mosaic Slideshow</p>
</div>
<h3>Step 3 – jQuery</h3>
<p>After including the jQuery library to the page, we can move on to creating the script that will make the slideshow tick. To achieve the mosaic effect, the script defines 4 functions:</p>
<ul>
<li><strong>transition()</strong> – this function makes an animated transition between the currently shown slide, and a new one specified by the id parameter. It works by positioning the new slide we want to show, below the current one, and then hiding the current one one tile at a time;</li>
<li><strong>generateGrid()</strong> – this function is used by transition() to generate a grid of tiles. Each tile contains a part of the slide image as its background;</li>
<li><strong>next()</strong> – detects which the next slide is and runs the transition() function with its index;</li>
<li><strong>prev()</strong> – analogous to next().</li>
</ul>
<h4>script.js – Part 1</h4>
<pre>/* The slide images are contained in the slides array. */
var slides = new Array('img/slide_1.jpg',
					   'img/slide_2.jpg',
					   'img/slide_3.jpg',
					   'img/slide_4.jpg',
					   'img/slide_5.jpg');

$(document).ready(function(){
	/* This code is executed after the DOM has been completely loaded */

	$('.arrow.left').click(function(){
		prev();

		/* Clearing the autoadvance if we click one of the arrows */
		clearInterval(auto);
	});

	$('.arrow.right').click(function(){
		next();
		clearInterval(auto);
	});

	/* Preloading all the slide images: */

	for(var i=0;i&lt;slides.length;i++)
	{
		(new Image()).src=slides[i];
	}

	/* Showing the first one on page load: */
	transition(1);

	/* Setting auto-advance every 10 seconds */

	var auto;

	auto=setInterval(function(){
		next();
	},10*1000);
});</pre>
<p>The <strong>$(document).ready()</strong> method is executed once the page has finished loading. This will ensure that all the divs and other elements are accessible to the script. Inside it we bind a function for the click event on the previous and next arrows, preload all the images, show the first slide (otherwise the slideshow would be empty) and set up the auto-advance interval.</p>
<h4>script.js – Part 2</h4>
<pre>var current = {};
function transition(id)
{
	/* This function shows the slide specified by the id. */

	if(!slides[id-1]) return false;

	if(current.id)
	{
		/* If the slide we want to show is currently shown: */
		if(current.id == id) return false;

		/* Moving the current slide layer to the top: */
		current.layer.css('z-index',10);

		/* Removing all other slide layers that are positioned below */
		$('.mosaic-slide').not(current.layer).remove();
	}

	/* Creating a new slide and filling it with generateGrid: */
	var newLayer = $('&lt;div class="mosaic-slide"&gt;').html(generateGrid({rows:7,cols:8,image:slides[id-1]}));

	/* Moving it behind the current slide: */
	newLayer.css('z-index',1);

	$('#mosaic-slideshow').append(newLayer);

	if(current.layer)
	{
		/* Hiding each tile of the current slide, exposing the new slide: */
		$('.tile',current.layer).each(function(i){
			var tile = $(this);
			setTimeout(function(){
				tile.css('visibility','hidden');
			},i*10);
		})
	}

	/* Adding the current id and newLayer element to the current object: */
	current.id = id;
	current.layer = newLayer;
}</pre>
<p>The transition function uses the global <strong>current</strong> object to store the id of the currently shown slide, and a reference to the current slide div. This is later used to remove leftover slides and prevent a transition from occurring if the same slide as the currently active one is to be shown.</p>
<p>Notice how we use the each method on line 31 to loop through the tiles of the current slide and schedule them to be hidden in <strong>i*10 milliseconds</strong> in the future. As <strong>i</strong> is incremented for every tile, this mean that they are hidden 10 milliseconds apart from one another.</p>
<div><a href="http://tutorialzine.com/wp-content/uploads/2010/03/i31.png"><img class="size-full wp-image-768" src="http://tutorialzine.com/wp-content/uploads/2010/03/i31.png" alt="Slide Transition" width="620" height="460" /></a>Slide Transition</p>
</div>
<h4>script.js – Part 3</h4>
<pre>function next()
{
	if(current.id)
	{
		transition(current.id%slides.length+1);
	}
}

function prev()
{
	if(current.id)
	{
		transition((current.id+(slides.length-2))%slides.length+1);
	}

}

/* Width and height of the tiles in pixels: */
var tabwidth=60, tabheight=60;

function generateGrid(param)
{
	/* This function generates the tile grid, with each tile containing a part of the slide image */

	/* Creating an empty jQuery object: */
	var elem = $([]),tmp;

	for(var i=0;i&lt;param.rows;i++)
	{
		for(var j=0;j&lt;param.cols;j++)
		{
			tmp = $('&lt;div&gt;', {
					"class":"tile",
					"css":{
						"background":'#555 url('+param.image+') no-repeat '+(-j*tabwidth)+'px '+(-i*tabheight)+'px'
					}
			});

			/* Adding the tile to the jQuery object: */
			elem = elem.add(tmp);
		}

		/* Adding a clearing element at the end of each line. This will clearly divide the divs into rows: */
		elem = elem.add('&lt;div class="clear"&gt;&lt;/div&gt;');
	}

	return elem;
}</pre>
<p>The parameter passed to <strong>generateGrid()</strong> is an object containing the rows and the columns we want to be generated, as well as the image to be set as the background of the tiles. While generating the tiles, the background image is offset according to the current position of the tile in the row and in the column. Finally the tile is added to an empty jQuery object which is returned at the end.</p>
<p><strong>With this the mosaic slideshow is complete!</strong></p>
<h3>Wrapping it up</h3>
<p>Today we created a slideshow with an animated mosaic transition effect. You can modify it to include a different number of rows and columns or change the way slides are changed entirely.</p>
<p><strong>What do you think? How would you use this slideshow?</strong></p>
<p><img src="http://feeds.feedburner.com/~r/Tutorialzine/~4/0GM-mbwkGBs" alt="" width="1" height="1" /></p>

	Tags: <a href="http://xguiden.dk/tag/code/" title="code" rel="tag">code</a>, <a href="http://xguiden.dk/tag/content/" title="content" rel="tag">content</a>, <a href="http://xguiden.dk/tag/css/" title="CSS" rel="tag">CSS</a>, <a href="http://xguiden.dk/tag/css-styles/" title="css styles" rel="tag">css styles</a>, <a href="http://xguiden.dk/tag/css3/" title="css3" rel="tag">css3</a>, <a href="http://xguiden.dk/tag/design/" title="design" rel="tag">design</a>, <a href="http://xguiden.dk/tag/element/" title="element" rel="tag">element</a>, <a href="http://xguiden.dk/tag/function/" title="function" rel="tag">function</a>, <a href="http://xguiden.dk/tag/html/" title="HTML" rel="tag">HTML</a>, <a href="http://xguiden.dk/tag/image/" title="image" rel="tag">image</a>, <a href="http://xguiden.dk/tag/javascript/" title="JavaScript" rel="tag">JavaScript</a>, <a href="http://xguiden.dk/tag/jquery/" title="jquery" rel="tag">jquery</a>, <a href="http://xguiden.dk/tag/mosaic-effect/" title="mosaic effect" rel="tag">mosaic effect</a>, <a href="http://xguiden.dk/tag/mosaic-gallery/" title="mosaic gallery" rel="tag">mosaic gallery</a>, <a href="http://xguiden.dk/tag/mosaic-slideshow/" title="mosaic slideshow" rel="tag">mosaic slideshow</a>, <a href="http://xguiden.dk/tag/script/" title="script" rel="tag">script</a>, <a href="http://xguiden.dk/tag/slide-image/" title="slide image" rel="tag">slide image</a>, <a href="http://xguiden.dk/tag/slide-style/" title="slide style" rel="tag">slide style</a>, <a href="http://xguiden.dk/tag/transition-effect/" title="transition effect" rel="tag">transition effect</a>, <a href="http://xguiden.dk/tag/tutorial/" title="tutorial" rel="tag">tutorial</a><br />

	<h4>Related posts</h4>
	<ul class="st-related-posts">
	<li><a href="http://xguiden.dk/2010/03/10/awesome-cssjs-form-styling/" title="Awesome CSS+JS form styling (10/03/2010)">Awesome CSS+JS form styling</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/02/13/sweet-ajax-tabs-with-jquery-1-4-and-css3/" title="Sweet AJAX Tabs With jQuery 1.4 and CSS3 (13/02/2010)">Sweet AJAX Tabs With jQuery 1.4 and CSS3</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/02/13/making-a-photoshoot-effect-with-jquery-css/" title="Making a Photoshoot Effect With jQuery and CSS (13/02/2010)">Making a Photoshoot Effect With jQuery and CSS</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/03/03/how-we%e2%80%99ll-be-building-websites-in-5-years-html5-and-css3-layout/" title="How We’ll be Building Websites in 5 years: HTML5 and CSS3 layout (03/03/2010)">How We’ll be Building Websites in 5 years: HTML5 and CSS3 layout</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/02/15/how-to-code-up-a-web-design-from-psd-to-html/" title="How to Code up a Web Design from PSD to HTML (15/02/2010)">How to Code up a Web Design from PSD to HTML</a> (0)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://xguiden.dk/2010/03/10/making-a-mosaic-slideshow-with-jquery-and-css/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Uncovering jQuery’s Hidden Features</title>
		<link>http://xguiden.dk/2010/03/09/uncovering-jquery%e2%80%99s-hidden-features/</link>
		<comments>http://xguiden.dk/2010/03/09/uncovering-jquery%e2%80%99s-hidden-features/#comments</comments>
		<pubDate>Tue, 09 Mar 2010 12:22:53 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Engelske guides]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[Cool]]></category>
		<category><![CDATA[element]]></category>
		<category><![CDATA[function]]></category>
		<category><![CDATA[GET]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[reference]]></category>
		<category><![CDATA[Source]]></category>
		<category><![CDATA[valid]]></category>

		<guid isPermaLink="false">http://xguiden.dk/?p=5533</guid>
		<description><![CDATA[jQuery is not always as it appears. There&#8217;s a lot of cool stuff going on under the surface, and there are many methods just waiting to be discovered, and many potential usages of jQuery&#8217;s API that you may not have considered before. In this article I&#8217;ll be taking you through a few of the not-so-obvious [...]]]></description>
			<content:encoded><![CDATA[<p>jQuery is not always as it appears. There&#8217;s a lot of cool stuff going on under the surface, and there are many methods just waiting to be discovered, and many potential usages of jQuery&#8217;s API that you may not have considered before. In this article I&#8217;ll be taking you through a few of the not-so-obvious things I&#8217;ve discovered about jQuery.</p>
<p><span> </span></p>
<h2><span>1. </span>Understand jQuery!</h2>
<p>When you call <em>&#8216;jQuery&#8217;</em> what happens?</p>
<p>The jQuery function itself is very simple:</p>
<pre>jQuery = function (selector, context) {
    // The jQuery object is actually just the init constructor 'enhanced'
    return new jQuery.fn.init(selector, context);
};</pre>
<p>Under its skin, the jQuery function (commonly referred to as the &#8220;wrapper&#8221; function) simply returns an instantiated jQuery object — i.e. an instance of the <em>&#8216;jQuery.fn.init&#8217;</em> constructor.</p>
<p>This is useful to know; with this information we know that each time we call <em>&#8216;jQuery&#8217;</em> we&#8217;re actually creating a totally unique object with a set of properties. jQuery is clever in that it gives you an object that can be treated as an array. Each of your elements (all together, commonly known as the &#8220;collection&#8221;) is referenced within the object under a numerical index, just like within an array. And jQuery also gives this object a <em>&#8216;length&#8217;</em> property, just as you would expect from an array. This opens up a world of possibilities. For one, it means that we can borrow some functionality from <em>&#8216;Array.prototype&#8217;</em>. jQuery&#8217;s <em>&#8217;slice&#8217;</em> method is a good example of this — modified from the source:</p>
<pre>/* ... jQuery.fn.extend({ ... */
slice: function() {
    return this.pushStack(
        Array.prototype.slice.apply( this, arguments ),
        "slice",
        Array.prototype.slice.call(arguments).join(",")
    );
},
/* ... */</pre>
<p>The native <em>&#8217;slice&#8217;</em> method doesn&#8217;t care that <em>&#8216;this&#8217;</em> is not a real array– it&#8217;ll be fine with anything that&#8217;s got a <em>&#8216;length&#8217;</em> property and <em>[0]</em>, <em>[1]</em>, <em>[2]</em> etc.</p>
<p>There are some other interesting properties within this jQuery object — <em>&#8216;.selector&#8217;</em> and <em>&#8216;.context&#8217;</em> will, most of the time, reflect the arguments that you pass into <em>&#8216;jQuery(…)&#8217;</em>.</p>
<pre>var jqObject = jQuery('a');
jqObject.selector; // =&gt; "a"</pre>
<p>One thing that&#8217;s important to note is that jQuery will sometimes give you new jQuery objects to work with. If you run a method that changes the collection in some way, such as <em>&#8216;.parents()&#8217;</em>, then jQuery won&#8217;t modify the current object; it&#8217;ll simply pass you a brand new one:</p>
<pre>var originalObject = jQuery('a');
var anotherObject = originalObject.parents();

originalObject === anotherObject; // =&gt; false</pre>
<p>All methods that appear to mutate the collection in some way return a brand new jQuery object — you can still access the old object though, via <em>&#8216;.end()&#8217;</em>, or more verbosely, via <em>&#8216;.prevObject&#8217;</em>.</p>
<h2><span>2. </span>Bread-and-butter Element Creation</h2>
<p>Central to jQuery&#8217;s DOM capabilities, is its element creation syntax. 1.4 brought with it an entirely new way to create your elements quickly and succinctly. E.g.</p>
<pre>var myDiv = jQuery('&lt;div/&gt;', {
    id: 'my-new-element',
    class: 'foo',
    css: {
        color: 'red',
        backgrondColor: '#FFF',
        border: '1px solid #CCC'
    },
    click: function() {
        alert('Clicked!');
    },
    html: jQuery('&lt;a/&gt;', {
        href: '#',
        click: function() {
            // do something
            return false;
        }
    })
});</pre>
<p>As of 1.4 you can pass a second argument to the jQuery function when you&#8217;re creating an element — the object you pass will, for the most part, act as if you were passing it to <em>&#8216;.attr(…)&#8217;</em>. However, jQuery will map some of the properties to its own methods, for example, the <em>&#8216;click&#8217;</em> property maps to jQuery&#8217;s <em>&#8216;click&#8217;</em> method (which binds an event handler for the <em>&#8216;click&#8217;</em> event) and <em>&#8216;css&#8217;</em> maps to jQuery&#8217;s <em>&#8216;css&#8217;</em> method etc.</p>
<p>To check out what properties map to jQuery&#8217;s methods, open your console and type <em>&#8216;jQuery.attrFn&#8217;</em>.</p>
<h2><span>3. </span>Serialize your Inputs</h2>
<p>jQuery provides a method that you can use to serialize all of the inputs within one or more forms. This is useful when submitting data via XHR (&#8220;Ajax&#8221;). It&#8217;s been in jQuery for a long time but it&#8217;s not often talked about and so many developers don&#8217;t realise it&#8217;s there. Submitting an entire form via Ajax, using jQuery, couldn&#8217;t be simpler:</p>
<pre>var myForm = $('#my-form');
jQuery.post('submit.php', myForm.serialize(), function(){
    alert('Data has been sent!');
});</pre>
<p>jQuery also provides the <em>&#8217;serializeArray&#8217;</em> method, which is designed to be used with multiple forms, and the <em>&#8216;param&#8217;</em> helper function (under the jQuery namespace) which takes a regular object and returns a query string, e.g.</p>
<pre>var data = {
    name: 'Joe',
    age: 44,
    profession: 'Web Developer'
};

jQuery.param(data); // =&gt; "name=Joe&amp;age=44&amp;profession=Web+Developer"</pre>
<h2><span>4. </span>Animate Anything</h2>
<p>jQuery&#8217;s <em>&#8216;animate&#8217;</em> method is probably the most flexible of jQuery&#8217;s methods. It can be used to animate pretty much anything, not just CSS properties, and not just DOM elements. This is how you would normally use <em>&#8216;animate&#8217;</em>:</p>
<pre>jQuery('#box').animate({
    left: 300,
    top: 300
});</pre>
<p>When you specify a property to animate (e.g. <em>&#8216;top&#8217;</em>) jQuery checks to see if you&#8217;re animating something with a style property (<em>&#8216;element.style&#8217;</em>), and it checks if the specified property (<em>&#8216;top&#8217;</em>) is defined under <em>&#8217;style&#8217;</em> — if it&#8217;s not then jQuery simply updates <em>&#8216;top&#8217;</em> on the element itself. Here&#8217;s an example:</p>
<pre>jQuery('#box').animate({
    top: 123,
    foo: 456
});</pre>
<p><em>&#8216;top&#8217;</em> is a valid CSS property, so jQuery will update <em>&#8216;element.style.top&#8217;</em>, but <em>&#8216;foo&#8217;</em> is <strong>not</strong> a valid CSS property, so jQuery will simply update <em>&#8216;element.foo&#8217;</em>.</p>
<p>We can use this to our advantage. Let&#8217;s say, for example, that you want to animate a square on a canvas. First let&#8217;s define a simple constructor and a <em>&#8216;draw&#8217;</em> method that&#8217;ll be called on every step of the animation:</p>
<pre>function Square(cnvs, width, height, color) {

    this.x = 0;
    this.y = 0;
    this.width = width;
    this.height = height;
    this.color = color;

    this.cHeight = cnvs.height;
    this.cWidth = cnvs.width;
    this.cntxt = cnvs.getContext('2d');

}

Square.prototype.draw = function() {

    this.cntxt.clearRect(0, 0, this.cWidth, this.cHeight);
    this.cntxt.fillStyle = this.color;
    this.cntxt.fillRect(this.x, this.y, this.width, this.height);

};</pre>
<p>We&#8217;ve created our &#8216;Square&#8217; constructor, and one of its methods. Creating a canvas and then animating it couldn&#8217;t be simpler:</p>
<pre>// Create a &lt;canvas/&gt; element
var canvas = $('&lt;canvas/&gt;').appendTo('body')[0];
canvas.height = 400;
canvas.width = 600;

// Instantiate Square
var square = new Square(canvas, 70, 70, 'rgb(255,0,0)');

jQuery(square).animate({
    x: 300,
    y: 200
}, {
    // 'draw' should be called on every step
    // of the animation:
    step: jQuery.proxy(square, 'draw'),
    duration: 1000
});</pre>
<p>This is a very simple effect, but it does clearly demonstrate the possibilities. You can see it in action here: <a href="http://jsbin.com/ocida" target="_blank">http://jsbin.com/ocida</a> (this will only work in browsers that support the HTML5 canvas)</p>
<h2><span>5. </span>jQuery.ajax Returns the XHR Object</h2>
<p>jQuery&#8217;s Ajax utility functions (<em>&#8216;jQuery.ajax&#8217;</em>, <em>&#8216;jQuery.get&#8217;</em>, <em>&#8216;jQuery.post&#8217;</em>) all return an <em>&#8216;XMLHttpRequest&#8217;</em> object which you can use to perform subsequent operations on any request. For example:</p>
<pre>var curRequest;

jQuery('button.makeRequest').click(function(){
    curRequest = jQuery.get('foo.php', function(response){
        alert('Data: ' + response.responseText);
    });
});

jQuery('button.cancelRequest').click(function(){
    if (curRequest) {
        curRequest.abort(); // abort() is a method of XMLHttpRequest
    }
});</pre>
<p>Here we&#8217;re making a request whenever the <em>&#8216;makeRequest&#8217;</em> button is clicked — and we&#8217;re cancelling the active request if the user clicks the <em>&#8216;cancelRequest&#8217;</em> button.</p>
<p>Another potential usage is for synchronous requests:</p>
<pre>var myRequest = jQuery.ajax({
    url: 'foo.txt',
    async: false
});

console.log(myRequest.responseText);</pre>
<p>Read more about the <em><a href="https://developer.mozilla.org/en/XMLHttpRequest" target="_blank">&#8216;XMLHttpRequest&#8217;</a></em> object and also be sure to check out <a href="http://api.jquery.com/category/ajax/" target="_blank">jQuery&#8217;s Ajax utilities</a>.</p>
<h2><span>6. </span>Custom Queues</h2>
<p>jQuery has a built-in queuing mechanism that&#8217;s used by all of its animation methods (all of which use <em>&#8216;animate()&#8217;</em> really). This queuing can be illustrated easily with a simple animation:</p>
<pre>jQuery('a').hover(function(){
    jQuery(this).animate({paddingLeft:'+=15px'});
}, function(){
    jQuery(this).animate({paddingLeft:'-=15px'});
});</pre>
<p>Quickly hovering over a bunch of anchors and then hovering over them again will cause the animations to queue up and occur one at a time — I&#8217;m sure many of you have witnessed this queuing effect before. If not, check it out here: <a href="http://jsbin.com/aqaku" target="_blank"><strong>http://jsbin.com/aqaku</strong></a></p>
<p>The <em>&#8216;queue&#8217;</em> method is similar to the well-known <em>&#8216;each&#8217;</em> method in how it&#8217;s called. You pass a function, which will eventually be called for each of the elements in the collection:</p>
<pre>jQuery('a').queue(function(){
    jQuery(this).addClass('all-done').dequeue();
});</pre>
<p>Passing just a function to <em>&#8216;queue&#8217;</em> will cause that function to be added to the default <em>&#8216;fx&#8217;</em> queue, i.e. the queue used by all animations done by jQuery. Therefore, this function will not be called until all current animations occurring on each element in the collection (in this case, all anchors) have completed.</p>
<p>Notice that we&#8217;re adding a class of <em>&#8216;all-done&#8217;</em> in the function above. As outlined, this class will only be added when all current animations are complete. We&#8217;re also calling the <em>&#8216;dequeue&#8217;</em> method. <strong>This is very important</strong>, as it will allow jQuery to continue with the queue (i.e. it lets jQuery know that you&#8217;re finished with whatever you&#8217;re doing). jQuery 1.4 provides another way of continuing the queue; instead of calling <em>&#8216;dequeue&#8217;</em>, simply call the first argument passed to your function:</p>
<pre>jQuery('a').queue(function(nextItemInQueue){
    // Continue queue:
    nextItemInQueue();
});</pre>
<p>This does exactly the same, although it&#8217;s slightly more useful in that it can be called anywhere within your function, even within a mess of closures (that typically destroy the <em>&#8216;this&#8217;</em> keyword). Of course, pre-jQuery-1.4 you could just save a reference to <em>&#8216;this&#8217;</em>, but that would get a bit tiresome.</p>
<p>To add a function to a custom queue, simply pass your custom queue&#8217;s name as the first argument and the function as the second:</p>
<pre>jQuery('a').queue('customQueueName', function(){
    // Do stuff
    jQuery(this).dequeue('customQueueName');
});</pre>
<p>Notice that, since we&#8217;re not using the default <em>&#8216;fx&#8217;</em> queue, we also have to pass our queue&#8217;s name to the <em>&#8216;dequeue&#8217;</em> method, in order to allow jQuery to continue with our custom queue.</p>
<p>Read more about <a href="http://api.jquery.com/queue" target="_blank"><em>&#8216;queue&#8217;</em></a>, <a href="http://api.jquery.com/dequeue/" target="_blank"><em>&#8216;dequeue&#8217;</em></a> and <a href="http://api.jquery.com/jQuery.queue/" target="_blank"><em>&#8216;jQuery.queue&#8217;</em></a>.</p>
<h2><span>7. </span>Event Namespacing</h2>
<p>jQuery provides a way for you to namespace events, which can be very useful when authoring plugins and third-party components. If needed, the user of your plugin can effectively disable your plugin by unbinding all event handlers that it&#8217;s registered.</p>
<p>To add a namespace when registering an event handler, simply suffix the event name with a period and then your unique namespace (e.g. <em>&#8216;<span>.fooPlugin</span>&#8216;</em>):</p>
<pre>jQuery.fn.foo = function() {

    this.bind('click.fooPlugin', function() {
        // do stuff
    });

    this.bind('mouseover.fooPlugin', function() {
        // do stuff
    });

    return this;
};

// Use the plugin:
jQuery('a').foo();

// Destroy its event handlers:
jQuery('a').unbind('.fooPlugin');</pre>
<p>Passing just the namespace to <em>&#8216;unbind&#8217;</em> will unbind all event handlers with that namespace.</p>
<h2>Conclusion</h2>
<p>So which ones did I miss? Any helpful features that you feel jQuery doesn’t document well enough? Let’s discuss in the comments!</p>
<p><a href="http://feedads.g.doubleclick.net/~a/WA01DphnOQdl0SzTX7fYcInH-q8/0/da"><img src="http://feedads.g.doubleclick.net/~a/WA01DphnOQdl0SzTX7fYcInH-q8/0/di" border="0" alt="" /></a><br />
<img src="http://feedads.g.doubleclick.net/~a/WA01DphnOQdl0SzTX7fYcInH-q8/1/di" border="0" alt="" /></p>
<p><img src="http://feeds.feedburner.com/~r/nettuts/~4/sNBgElc3bIw" alt="" width="1" height="1" /></p>

	Tags: <a href="http://xguiden.dk/tag/ajax/" title="AJAX" rel="tag">AJAX</a>, <a href="http://xguiden.dk/tag/cool/" title="Cool" rel="tag">Cool</a>, <a href="http://xguiden.dk/tag/element/" title="element" rel="tag">element</a>, <a href="http://xguiden.dk/tag/function/" title="function" rel="tag">function</a>, <a href="http://xguiden.dk/tag/get/" title="GET" rel="tag">GET</a>, <a href="http://xguiden.dk/tag/html/" title="HTML" rel="tag">HTML</a>, <a href="http://xguiden.dk/tag/html5/" title="html5" rel="tag">html5</a>, <a href="http://xguiden.dk/tag/jquery/" title="jquery" rel="tag">jquery</a>, <a href="http://xguiden.dk/tag/php/" title="php" rel="tag">php</a>, <a href="http://xguiden.dk/tag/reference/" title="reference" rel="tag">reference</a>, <a href="http://xguiden.dk/tag/source/" title="Source" rel="tag">Source</a>, <a href="http://xguiden.dk/tag/valid/" title="valid" rel="tag">valid</a><br />

	<h4>Related posts</h4>
	<ul class="st-related-posts">
	<li><a href="http://xguiden.dk/2010/02/18/make-your-mootools-code-shorter-faster-and-stronger/" title="Make your MooTools Code Shorter, Faster, and Stronger (18/02/2010)">Make your MooTools Code Shorter, Faster, and Stronger</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/02/13/jquery-ajax-validation-contact-form-with-modal-slide-in-transition/" title="jQuery AJAX Validation Contact Form with Modal + Slide-in Transition (13/02/2010)">jQuery AJAX Validation Contact Form with Modal + Slide-in Transition</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/02/15/how-to-code-up-a-web-design-from-psd-to-html/" title="How to Code up a Web Design from PSD to HTML (15/02/2010)">How to Code up a Web Design from PSD to HTML</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/03/09/2-different-ways-for-getting-twitter-status-php-and-jquery/" title="2 Different Ways For Getting Twitter Status / PHP and jQuery (09/03/2010)">2 Different Ways For Getting Twitter Status / PHP and jQuery</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/02/13/protect-your-flash-files-from-decompilers-by-using-encryption/" title="Protect Your Flash Files From Decompilers by Using Encryption (13/02/2010)">Protect Your Flash Files From Decompilers by Using Encryption</a> (0)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://xguiden.dk/2010/03/09/uncovering-jquery%e2%80%99s-hidden-features/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creative Button Animations with Sprites and JQuery (Part 1: Photoshop)</title>
		<link>http://xguiden.dk/2010/03/03/creative-button-animations-with-sprites-and-jquery-part-1-photoshop/</link>
		<comments>http://xguiden.dk/2010/03/03/creative-button-animations-with-sprites-and-jquery-part-1-photoshop/#comments</comments>
		<pubDate>Wed, 03 Mar 2010 22:07:26 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Engelske guides]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Photoshop]]></category>
		<category><![CDATA[3D]]></category>
		<category><![CDATA[animation]]></category>
		<category><![CDATA[avi]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[fil]]></category>
		<category><![CDATA[Gradient]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[IP]]></category>
		<category><![CDATA[Over]]></category>
		<category><![CDATA[png]]></category>
		<category><![CDATA[text]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://xguiden.dk/?p=5322</guid>
		<description><![CDATA[This tutorial will show you how to build creative hover animations for buttons using sprites. The particular effect illustrated in this tutorial is inspired by the “Download” buttons on Tutorial9.net. Part 1 of this tutorial explains the design process in Photoshop. In Part 2 we will convert it to XHTML + CSS and as a [...]]]></description>
			<content:encoded><![CDATA[<p>This tutorial will show you how to build creative hover animations for buttons using sprites. The particular effect illustrated in this tutorial is inspired by the “Download” buttons on Tutorial9.net. Part 1 of this tutorial explains the design process in Photoshop. In Part 2 we will convert it to XHTML + CSS and as a bonus we will also use jQuery for a fading hover effect.</p>
<p><a href="http://tutorial9.net/demos/button-sprites/demo.html"></a></p>
<p><strong>Skip to Part 2:</strong> (<em>Demo files available for download</em>)</p>
<h3>Step 1 – Create the shape</h3>
<p>Create a new document in photoshop fit to your needs. In this instance, I’ll be creating a 570px wide button. The height of the new canvas should be <strong>twice</strong> the height of the button needed (<em>explained later, but for now just use the top half of the canvas</em>).</p>
<div><img src="http://tutorial9.s3.amazonaws.com/wp-content/uploads/2010/02/design_1.png" alt="shape of the button" width="600" height="180" /></div>
<p>We’re going to make a rounded button. Use the <strong>Rounded Rectangle Tool</strong> with a <strong>radius of 5px</strong>. Keep in mind that we will add a border and shadow, so leave some white space around the button.</p>
<h3>Step 2 – Add layer styles</h3>
<p>We will use a pretty basic color scheme for the initial state of the button. The surprise (<em>I call it the wow-effect because of the contrast</em>) will be added in the color scheme of the hover state<em> </em> button.</p>
<div>
<h4>Note from Editor</h4>
<p>The diagrams shown are not in English, but the diagrams will apply to English versions of Photoshop as well. We apologize for any inconvenience.</p>
</div>
<p><strong>Drop shadow</strong></p>
<div><img src="http://tutorial9.s3.amazonaws.com/wp-content/uploads/2010/02/design_2.png" alt="Drop shadow" width="571" height="348" /></div>
<p><strong>Gradient overlay</strong></p>
<div><img src="http://tutorial9.s3.amazonaws.com/wp-content/uploads/2010/02/design_3.png" alt="Gradient overlay" width="571" height="348" /></div>
<p><strong>Stroke</strong></p>
<div><img src="http://tutorial9.s3.amazonaws.com/wp-content/uploads/2010/02/design_4.png" alt="Stroke" width="571" height="453" /></div>
<h3>Step 3 – Highlights</h3>
<div><img src="http://tutorial9.s3.amazonaws.com/wp-content/uploads/2010/02/design_5.png" alt="highlight, gloss" width="300" height="241" /></div>
<p>Select the the shape of the button: <strong>Ctrl</strong> (Cmd for Mac users) +<strong> Click the Layer Thumbnail</strong> in the Layers Palette. Now add a new layer and fill the selection with the color <strong>#fafafa</strong> (use the <strong>Bucket tool</strong>). Select the <strong>selection tool</strong> and move the selection 1px to the right. Now click <strong>backspace</strong> and the selection will be deleted. Now you need to move the selection 1px up and delete the selection. The last step is to move the selection 2px down and delete the selection. What remains is a sleek highlight effect on the left side of the button.</p>
<p>Apply the same trick on the right side of the button.</p>
<h3>Step 4 – Button text</h3>
<p>Type the text &#8220;Send&#8221; or &#8220;Submit&#8221;, or whatever you wish:</p>
<ul>
<li>font: Helvetica Neue Bold</li>
<li>font-size: 35px</li>
<li>color: #343434</li>
</ul>
<p>Add also the following layer style:</p>
<div><img src="http://tutorial9.s3.amazonaws.com/wp-content/uploads/2010/02/design_6.png" alt="Text with layer styles" width="571" height="215" /></div>
<p><strong>Final image</strong></p>
<div><img src="http://tutorial9.s3.amazonaws.com/wp-content/uploads/2010/02/design_7.png" alt="Text with layer styles" width="570" height="64" /></div>
<p> </p>
<h3>Step 5 – Prepare the canvas for a sprite</h3>
<p>We’re going to make a sprite of the buttons. Why sprites and not single images? Why combine all those images? Isn’t it quicker to have smaller images?</p>
<blockquote><p><a href="http://www.tutorial9.net/web-tutorials/building-faster-websites-with-css-sprites/">Using CSS sprites</a> allows you to greatly increase your websites speed by using single image files that contain multiple graphics. In other words, when you have many images to be used, instead of having them as different individual files, we combine them into one. Therefore, the client computer only downloads one image for all the different graphics to be displayed.</p></blockquote>
<p>Measure the height of the button. My example has a height of 64px. The <em>link hover</em> button will have the same size as the <em>link</em> button so my Photoshop canvas needs to have a height of 128px (= 2 x 64px). Use Ctrl/Cmd + Alt + C to change the height of the canvas.</p>
<h3>Step 6 – The link hover button</h3>
<p>Select all layers in the layers palette and place them in one group. Duplicate this group and move it down to the empty space. Now you have the same two buttons in the sprite.</p>
<div><img src="http://tutorial9.s3.amazonaws.com/wp-content/uploads/2010/02/design_8.png" alt="Sprite image" width="570" height="128" /></div>
<p>Change the color of the copied text to <strong>#fffff</strong> and change the drop shadow:</p>
<div><img src="http://tutorial9.s3.amazonaws.com/wp-content/uploads/2010/02/design_9.png" alt="Drop shadow text hover button" width="571" height="215" /></div>
<p>Add the following layer styles on the copied button shape:</p>
<p><strong>Drop shadow</strong>: don’t change it.</p>
<p><strong>Gradient overlay</strong></p>
<div><img src="http://tutorial9.s3.amazonaws.com/wp-content/uploads/2010/02/design_10.png" alt="Gradient overlayhover button" width="571" height="348" /></div>
<p><strong>Stroke</strong></p>
<div><img src="http://tutorial9.s3.amazonaws.com/wp-content/uploads/2010/02/design_11.png" alt="Stroke hover button" width="571" height="453" /></div>
<p><strong>Final touches</strong></p>
<p>We’re going to add some gloss to the <em>link hover</em> button. Select the the shape of the button: <strong>Ctrl/Cmd + Click the Layer Thumbnail</strong> in the Layers Palette. And fill a new layer with the color<strong> #ffffff </strong>using the <strong>Bucket</strong> tool. Cut Away the bottom part with the Selection tool and change the <strong>opacity to 7%</strong>.</p>
<div><img src="http://tutorial9.s3.amazonaws.com/wp-content/uploads/2010/02/design_12.png" alt="Gloss effects" width="570" height="192" /></div>
<p>The final touch is changing the opacity of the highlights to 30% (which is already applied in the image above), because the original ones are too strong for the green button.</p>
<p><strong>Final image</strong></p>
<div><img src="http://tutorial9.s3.amazonaws.com/wp-content/uploads/2010/02/design_13.png" alt="Final sprite" width="570" height="128" /></div>
<p><a href="http://www.tutorial9.net/web-tutorials/creative-button-animations-with-sprites-and-jquery-part-2/"></a></p>
<div>
<h4>Ending Design Note: Create your own buttons</h4>
<p>Use colors that fit into your design. To create a simple 3D effect for the <em>link hover</em> button, you can also flip (the background of) the link button vertically. This works fine if you’re using a simple gradient.</p>
<p>Don’t use too many buttons like these on your website. If you wan’t to use several buttons on one page it’s better to create small buttons</p>
</div>

	Tags: <a href="http://xguiden.dk/tag/3d/" title="3D" rel="tag">3D</a>, <a href="http://xguiden.dk/tag/animation/" title="animation" rel="tag">animation</a>, <a href="http://xguiden.dk/tag/avi/" title="avi" rel="tag">avi</a>, <a href="http://xguiden.dk/tag/css/" title="CSS" rel="tag">CSS</a>, <a href="http://xguiden.dk/tag/design/" title="design" rel="tag">design</a>, <a href="http://xguiden.dk/tag/fil/" title="fil" rel="tag">fil</a>, <a href="http://xguiden.dk/tag/gradient/" title="Gradient" rel="tag">Gradient</a>, <a href="http://xguiden.dk/tag/html/" title="HTML" rel="tag">HTML</a>, <a href="http://xguiden.dk/tag/image/" title="image" rel="tag">image</a>, <a href="http://xguiden.dk/tag/images/" title="images" rel="tag">images</a>, <a href="http://xguiden.dk/tag/ip/" title="IP" rel="tag">IP</a>, <a href="http://xguiden.dk/tag/over/" title="Over" rel="tag">Over</a>, <a href="http://xguiden.dk/tag/photoshop/" title="Photoshop" rel="tag">Photoshop</a>, <a href="http://xguiden.dk/tag/png/" title="png" rel="tag">png</a>, <a href="http://xguiden.dk/tag/text/" title="text" rel="tag">text</a>, <a href="http://xguiden.dk/tag/tutorial/" title="tutorial" rel="tag">tutorial</a><br />

	<h4>Related posts</h4>
	<ul class="st-related-posts">
	<li><a href="http://xguiden.dk/2010/03/03/design-a-prettier-web-form-with-css-3/" title="Design a Prettier Web Form with CSS 3 (03/03/2010)">Design a Prettier Web Form with CSS 3</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/02/13/personal-vcard-pt-2/" title="Personal vCard Pt.2 (13/02/2010)">Personal vCard Pt.2</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/02/15/how-to-code-up-a-web-design-from-psd-to-html/" title="How to Code up a Web Design from PSD to HTML (15/02/2010)">How to Code up a Web Design from PSD to HTML</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/02/18/coding-a-css3-html5-one-page-website-template/" title="Coding a CSS3 &amp; HTML5 One-Page Website Template (18/02/2010)">Coding a CSS3 &amp; HTML5 One-Page Website Template</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/03/08/design-and-code-a-cool-iphone-app-website-in-html5/" title="Design and Code a Cool iPhone App Website in HTML5 (08/03/2010)">Design and Code a Cool iPhone App Website in HTML5</a> (0)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://xguiden.dk/2010/03/03/creative-button-animations-with-sprites-and-jquery-part-1-photoshop/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creative Button Animations with Sprites and JQuery (Part 2: CSS, XHTML, JQuery)</title>
		<link>http://xguiden.dk/2010/03/03/creative-button-animations-with-sprites-and-jquery-part-2-css-xhtml-jquery/</link>
		<comments>http://xguiden.dk/2010/03/03/creative-button-animations-with-sprites-and-jquery-part-2-css-xhtml-jquery/#comments</comments>
		<pubDate>Wed, 03 Mar 2010 22:06:27 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Engelske guides]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[animation]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[fil]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[IP]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Over]]></category>
		<category><![CDATA[png]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[Source]]></category>
		<category><![CDATA[tag]]></category>
		<category><![CDATA[tags]]></category>
		<category><![CDATA[text]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[URL]]></category>

		<guid isPermaLink="false">http://xguiden.dk/?p=5323</guid>
		<description><![CDATA[In Part 1 of this tutorial, you designed a button sprite that will be coded with HTML, CSS, and JQuery in this part of the tutorial.
If you do not want to complete part one of this tutorial, you can download the source files created in that lesson here.
Step 1 – HTML
Different people will require a [...]]]></description>
			<content:encoded><![CDATA[<p>In Part 1 of this tutorial, you designed a button sprite that will be coded with HTML, CSS, and JQuery in this part of the tutorial.</p>
<p>If you do not want to complete part one of this tutorial, you can <strong>download the source files</strong> created in that lesson <a href="http://tutorial9.s3.amazonaws.com/wp-content/uploads/2010/02/Button-Source-Files-and-Demo.zip">here</a>.</p>
<h3>Step 1 – HTML</h3>
<p>Different people will require a button for different purposes. The remainder of this tutorial will explain a simple scenario where the button functions as a simple download link. Create a link to an imaginary (<em>or real</em>) file for download:</p>
<pre>&lt;a href="path/to/download.zip" class="button"&gt;&lt;/a&gt;</pre>
<h3>Step 2 – CSS</h3>
<p>Add the following CSS to your HTML document:</p>
<pre>.button {
	width:570px;
	height:64px; /* Notice that the height is not the height of the whole sprite, but the height of one single button */
	display:block;
	background-image:url(images/downloadbutton.png); /*path to the sprite*/
	background-position: top; /* the background position (in combination with the height!) makes it possible that only the top of the whole sprite will be visible */
}</pre>
<p>When you apply the CSS code above, you will only see the <strong>grey</strong> button, because it’s <em>positioned on top</em> and the <em>height is 64px</em></p>
<p><strong>Link hover button</strong></p>
<pre>.button:hover{
	width:570px;
	background-position: bottom;
	height:64px;
	background-image:url(images/downloadbutton.png) no repeat;
}</pre>
<p>When you apply the CSS code above, you will only see the <strong>green</strong> button when you hover the download button, because it’s <em>positioned at the bottom</em> and the <em>height is 64px</em></p>
<p><strong>Demo:</strong> <a rel="external" href="http://tutorial9.net/demos/button-sprites/demo.html">View Live Demo</a></p>
<h3>Step 3 – Fading hover effect</h3>
<p>This step is not necessary, but it’s an optional step. The transition will be smoothed with JavaScript. We’re going to use the popular jQuery library.</p>
<p>The original tutorial comes from <a rel="external" href="http://greg-j.com/static-content/hover-fade-redux.html">this website</a>. I’ll do my best to explain.</p>
<h3>Step 4 – Add code between the head tags</h3>
<p><a rel="external" href="http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js">Download jQuery</a>. First we need to refer in the head to the .js file that we’ve just downloaded.</p>
<pre>&lt;script type="text/javascript" src="path/to/jquery-1.3.2.min.js"&gt;&lt;/script&gt;</pre>
<p>After that we can add the following code between the head tags.</p>
<pre>&lt;script type="text/javascript"&amp;gt
	$(document).ready(function() {
		// Add the class 'button' just like in CSS with a dot in front of it
		$('.button').append('&lt;span class="hover"&amp;gt&lt;/span&amp;gt').each(function () {
	  		var $span = $('&amp;gt span.hover', this).css('opacity', 0);
	  		$(this).hover(function () {
	    		$span.stop().fadeTo(500, 1); //Change the number 500 to change the speed of the Fade In
	 		}, function () {
	   	$span.stop().fadeTo(500, 0); //Change the number 500 to change the speed of the Fade Out
	  		});
		});
	});
&lt;/script&gt;</pre>
<div>
<h4>How to deal with several buttons on one page</h4>
<p>If you have several buttons on one page and you’d like to add the fading hover effect, you can give it a different class in the HTML and add this in the JavaScript above after the word .button and you need also to separate the words with a comma. (Example: ‘.button,.buttonTwo’)</p>
</div>
<h3>Step 5 – Edit the CSS</h3>
<pre>.button {
	position:relative;
	display:block;
	height: 64px;
	width: 570px;
	background:url(images/downloadbutton.png) no-repeat;
	background-position: top;
}</pre>
<pre>.button span.hover { /*notice the different class: span.hover*/
	position: absolute;
	display: block;
	height: 64px;
	width: 570px;
	background: url(images/downloadbutton.png) no-repeat;
	background-position: bottom;
}</pre>
<p><a rel="external" href="http://tutorial9.net/demos/button-sprites/demo.html">View Live Demo</a> to check the result.</p>
<h3>Download the source files (PSD included)</h3>
<div><a rel="external" href="http://www.tutorial9.net/wp-content/uploads/2010/02/Button-Source-Files-and-Demo.zip">Download</a></div>
<p><a href="http://feedads.g.doubleclick.net/~a/wmKScpUgbZJn0S3ZMx4Pr4Cgi7I/0/da"><img src="http://feedads.g.doubleclick.net/~a/wmKScpUgbZJn0S3ZMx4Pr4Cgi7I/0/di" border="0" alt="" /></a><br />
<a href="http://feedads.g.doubleclick.net/~a/wmKScpUgbZJn0S3ZMx4Pr4Cgi7I/1/da"><img src="http://feedads.g.doubleclick.net/~a/wmKScpUgbZJn0S3ZMx4Pr4Cgi7I/1/di" border="0" alt="" /></a></p>
<div><a href="http://feeds.feedburner.com/~ff/tutorial9?a=ah9hL4UWD4Q:F8fjrMYYvMY:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/tutorial9?i=ah9hL4UWD4Q:F8fjrMYYvMY:D7DqB2pKExk" border="0" alt="" /></a> <a href="http://feeds.feedburner.com/~ff/tutorial9?a=ah9hL4UWD4Q:F8fjrMYYvMY:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/tutorial9?i=ah9hL4UWD4Q:F8fjrMYYvMY:gIN9vFwOqvQ" border="0" alt="" /></a> <a href="http://feeds.feedburner.com/~ff/tutorial9?a=ah9hL4UWD4Q:F8fjrMYYvMY:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/tutorial9?i=ah9hL4UWD4Q:F8fjrMYYvMY:F7zBnMyn0Lo" border="0" alt="" /></a> <a href="http://feeds.feedburner.com/~ff/tutorial9?a=ah9hL4UWD4Q:F8fjrMYYvMY:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/tutorial9?d=7Q72WNTAKBA" border="0" alt="" /></a> <a href="http://feeds.feedburner.com/~ff/tutorial9?a=ah9hL4UWD4Q:F8fjrMYYvMY:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/tutorial9?d=qj6IDK7rITs" border="0" alt="" /></a></div>
<p><img src="http://feeds.feedburner.com/~r/tutorial9/~4/ah9hL4UWD4Q" alt="" width="1" height="1" /></p>

	Tags: <a href="http://xguiden.dk/tag/animation/" title="animation" rel="tag">animation</a>, <a href="http://xguiden.dk/tag/css/" title="CSS" rel="tag">CSS</a>, <a href="http://xguiden.dk/tag/design/" title="design" rel="tag">design</a>, <a href="http://xguiden.dk/tag/fil/" title="fil" rel="tag">fil</a>, <a href="http://xguiden.dk/tag/html/" title="HTML" rel="tag">HTML</a>, <a href="http://xguiden.dk/tag/image/" title="image" rel="tag">image</a>, <a href="http://xguiden.dk/tag/images/" title="images" rel="tag">images</a>, <a href="http://xguiden.dk/tag/ip/" title="IP" rel="tag">IP</a>, <a href="http://xguiden.dk/tag/java/" title="Java" rel="tag">Java</a>, <a href="http://xguiden.dk/tag/javascript/" title="JavaScript" rel="tag">JavaScript</a>, <a href="http://xguiden.dk/tag/over/" title="Over" rel="tag">Over</a>, <a href="http://xguiden.dk/tag/png/" title="png" rel="tag">png</a>, <a href="http://xguiden.dk/tag/script/" title="script" rel="tag">script</a>, <a href="http://xguiden.dk/tag/source/" title="Source" rel="tag">Source</a>, <a href="http://xguiden.dk/tag/tag/" title="tag" rel="tag">tag</a>, <a href="http://xguiden.dk/tag/tags/" title="tags" rel="tag">tags</a>, <a href="http://xguiden.dk/tag/text/" title="text" rel="tag">text</a>, <a href="http://xguiden.dk/tag/tutorial/" title="tutorial" rel="tag">tutorial</a>, <a href="http://xguiden.dk/tag/url/" title="URL" rel="tag">URL</a><br />

	<h4>Related posts</h4>
	<ul class="st-related-posts">
	<li><a href="http://xguiden.dk/2010/03/08/design-and-code-a-cool-iphone-app-website-in-html5/" title="Design and Code a Cool iPhone App Website in HTML5 (08/03/2010)">Design and Code a Cool iPhone App Website in HTML5</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/02/13/jquery-ajax-validation-contact-form-with-modal-slide-in-transition/" title="jQuery AJAX Validation Contact Form with Modal + Slide-in Transition (13/02/2010)">jQuery AJAX Validation Contact Form with Modal + Slide-in Transition</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/03/03/how-we%e2%80%99ll-be-building-websites-in-5-years-html5-and-css3-layout/" title="How We’ll be Building Websites in 5 years: HTML5 and CSS3 layout (03/03/2010)">How We’ll be Building Websites in 5 years: HTML5 and CSS3 layout</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/02/15/how-to-code-up-a-web-design-from-psd-to-html/" title="How to Code up a Web Design from PSD to HTML (15/02/2010)">How to Code up a Web Design from PSD to HTML</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/02/18/coding-a-css3-html5-one-page-website-template/" title="Coding a CSS3 &amp; HTML5 One-Page Website Template (18/02/2010)">Coding a CSS3 &amp; HTML5 One-Page Website Template</a> (0)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://xguiden.dk/2010/03/03/creative-button-animations-with-sprites-and-jquery-part-2-css-xhtml-jquery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Quick Tip: Learning jQuery 1.4’s $.proxy</title>
		<link>http://xguiden.dk/2010/03/03/quick-tip-learning-jquery-1-4%e2%80%99s-proxy/</link>
		<comments>http://xguiden.dk/2010/03/03/quick-tip-learning-jquery-1-4%e2%80%99s-proxy/#comments</comments>
		<pubDate>Wed, 03 Mar 2010 21:54:33 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Engelske guides]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[GET]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[IP]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[text]]></category>

		<guid isPermaLink="false">http://xguiden.dk/?p=5357</guid>
		<description><![CDATA[One of my favorite new features in jQuery 1.4 is the new $.proxy method. It allows us force a particular context when calling a method. In JavaScript, there can be times when it’s difficult to hold on to the this keyword. For example, when it’s bound to some event handler, this now refers to the [...]]]></description>
			<content:encoded><![CDATA[<p>One of my favorite new features in jQuery 1.4 is the new $.proxy method. It allows us force a particular context when calling a method. In JavaScript, there can be times when it’s difficult to hold on to the <em>this</em> keyword. For example, when it’s bound to some event handler, <em>this</em> now refers to the target of the handler, rather than your desired object.</p>
<p>If this sounds a bit confusing, don’t worry; today’s four-minute video quick tip should clear things up.</p>
<p><span> </span></p>
<div><a href="http://jsbin.com/inupo"><img src="http://net.tutsplus.com/wp-content/themes/nettuts/site_images/button_src_nm.jpg" alt="" /></a><br />
<a href="http://jsbin.com/inupo"><img src="http://net.tutsplus.com/wp-content/themes/nettuts/site_images/button_demo_nm.jpg" alt="" /></a></div>
<pre>// Create an object.
var obj = {
        // this = obj
	somevar : 'some value',

	doSomething : function() {
		alert(this.somevar);
	}
};

// When bound to an event handler, this will
// refer to the target of the handler, or the div - not obj.
$('div').click(obj.doSomething); // undefined. 

// With $.proxy, we pass two parameters.
// 1. The method to call.
// 2. The context.
// In this case, we're forcing obj to once again be equal to this.
$('div').click( $.proxy(obj.doSomething, obj) ); // some value</pre>
<p><img src="http://feeds.feedburner.com/~r/nettuts/~4/kgBwvQ-R2iY" alt="" width="1" height="1" /></p>

	Tags: <a href="http://xguiden.dk/tag/get/" title="GET" rel="tag">GET</a>, <a href="http://xguiden.dk/tag/image/" title="image" rel="tag">image</a>, <a href="http://xguiden.dk/tag/images/" title="images" rel="tag">images</a>, <a href="http://xguiden.dk/tag/ip/" title="IP" rel="tag">IP</a>, <a href="http://xguiden.dk/tag/java/" title="Java" rel="tag">Java</a>, <a href="http://xguiden.dk/tag/javascript/" title="JavaScript" rel="tag">JavaScript</a>, <a href="http://xguiden.dk/tag/script/" title="script" rel="tag">script</a>, <a href="http://xguiden.dk/tag/text/" title="text" rel="tag">text</a><br />

	<h4>Related posts</h4>
	<ul class="st-related-posts">
	<li><a href="http://xguiden.dk/2010/02/13/use-ajax-to-create-a-cacheing-system/" title="Use ajax to create a cacheing system (13/02/2010)">Use ajax to create a cacheing system</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/02/13/smooth-horizontal-tweened-menu-with-as3/" title="Smooth Horizontal Tweened Menu with AS3 (13/02/2010)">Smooth Horizontal Tweened Menu with AS3</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/02/13/quick-and-easy-way-to-implement-drag-n-share-with-jquery/" title="Quick and Easy Way to Implement Drag n Share With jQuery (13/02/2010)">Quick and Easy Way to Implement Drag n Share With jQuery</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/02/13/making-image-overlay-caption-using-css/" title="Making Image Overlay Caption Using CSS (13/02/2010)">Making Image Overlay Caption Using CSS</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/02/13/jquery-fade-in-fade-out-effect-%e2%80%93-updated/" title="Jquery Fade In, Fade Out Effect – Updated (13/02/2010)">Jquery Fade In, Fade Out Effect – Updated</a> (0)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://xguiden.dk/2010/03/03/quick-tip-learning-jquery-1-4%e2%80%99s-proxy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The jQuery Hover Method</title>
		<link>http://xguiden.dk/2010/02/25/the-jquery-hover-method/</link>
		<comments>http://xguiden.dk/2010/02/25/the-jquery-hover-method/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 16:59:58 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Engelske guides]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[avi]]></category>
		<category><![CDATA[IP]]></category>
		<category><![CDATA[Over]]></category>
		<category><![CDATA[script]]></category>

		<guid isPermaLink="false">http://xguiden.dk/?p=5226</guid>
		<description><![CDATA[When building a navigation menu, or any other jQuery script, it is often necessary to have a robust method with which to define a mouse over and mouse out state. This is where the hover() method comes along. Here is how it is used:
$('.selectorClass').hover(
function(){
	$(this).stop().fadeTo('slow',0.4);
},
function(){
	$(this).stop().fadeTo('slow',1);
});

This assigns the first function to be executed when the mouse moves [...]]]></description>
			<content:encoded><![CDATA[<p>When building a navigation menu, or any other jQuery script, it is often necessary to have a robust method with which to define a mouse over and mouse out state. This is where the <strong>hover()</strong> method comes along. Here is how it is used:</p>
<pre>$('.selectorClass').hover(
function(){
	$(this).stop().fadeTo('slow',0.4);
},
function(){
	$(this).stop().fadeTo('slow',1);
});
</pre>
<p>This assigns the first function to be executed when the mouse moves above the elements on the page, which share the <strong>selectorClass</strong> class name, and the second one is executed when the mouse moves away.</p>
<p>You can use “<strong>this”</strong> inside of the functions, to access the element that triggered the event.</p>
<p>Hover actually binds the first function to the <strong>mouseenter</strong> event, and the second one to <strong>mouseleave</strong>, so you could alternatively write this:</p>
<pre>$('.selectorClass').mouseenter(function(){
	$(this).stop().fadeTo('slow',0.4);
}).mouseleave(function(){
	$(this).stop().fadeTo('slow',1);
});
</pre>
<p>As of <strong>version 1.4</strong> of jQuery, it is now possible to pass a single function to hover, which will be called on both mouseenter and mouseleave. This way you can shorten your code even more by writing only one function:</p>
<pre>$('.selectorClass').hover(function(){
	this.check = this.check || 1;
	$(this).stop().fadeTo('slow',this.check++%2==0 ? 1 : 0.4);
});
</pre>
<p>The example above increments <strong>this.check</strong> every time the function is run. Depending on whether the number is even or not, it chooses the opacity level to pass to <strong>fadeTo()</strong> (1 being completely visible).</p>
<p>This is also a great place to use the jQuery toggle functions like <strong>.slideToggle()</strong> and <strong>.toggleClass()</strong>.</p>

	Tags: <a href="http://xguiden.dk/tag/avi/" title="avi" rel="tag">avi</a>, <a href="http://xguiden.dk/tag/ip/" title="IP" rel="tag">IP</a>, <a href="http://xguiden.dk/tag/over/" title="Over" rel="tag">Over</a>, <a href="http://xguiden.dk/tag/script/" title="script" rel="tag">script</a><br />

	<h4>Related posts</h4>
	<ul class="st-related-posts">
	<li><a href="http://xguiden.dk/2010/02/13/using-google-maps%e2%80%99-new-features-for-flash/" title="Using Google Maps’ New Features for Flash (13/02/2010)">Using Google Maps’ New Features for Flash</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/02/13/quick-tip-create-a-copy-to-clipboard-button-in-flash/" title="Quick Tip: Create a Copy to Clipboard Button in Flash (13/02/2010)">Quick Tip: Create a Copy to Clipboard Button in Flash</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/02/13/protect-your-flash-files-from-decompilers-by-using-encryption/" title="Protect Your Flash Files From Decompilers by Using Encryption (13/02/2010)">Protect Your Flash Files From Decompilers by Using Encryption</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/02/25/php-and-mysql-file-download-counter/" title="PHP and MySQL File Download Counter (25/02/2010)">PHP and MySQL File Download Counter</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/02/13/personal-vcard-pt-2/" title="Personal vCard Pt.2 (13/02/2010)">Personal vCard Pt.2</a> (0)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://xguiden.dk/2010/02/25/the-jquery-hover-method/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Coding your First jQuery UI Plugin</title>
		<link>http://xguiden.dk/2010/02/25/coding-your-first-jquery-ui-plugin/</link>
		<comments>http://xguiden.dk/2010/02/25/coding-your-first-jquery-ui-plugin/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 16:56:26 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Engelske guides]]></category>
		<category><![CDATA[CD]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[DOCTYPE]]></category>
		<category><![CDATA[fil]]></category>
		<category><![CDATA[GET]]></category>
		<category><![CDATA[guide]]></category>
		<category><![CDATA[help]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[IP]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[LP]]></category>
		<category><![CDATA[META]]></category>
		<category><![CDATA[Over]]></category>
		<category><![CDATA[reference]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[Source]]></category>
		<category><![CDATA[standard]]></category>
		<category><![CDATA[Start]]></category>
		<category><![CDATA[Sten]]></category>
		<category><![CDATA[switch]]></category>
		<category><![CDATA[table]]></category>
		<category><![CDATA[text]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://xguiden.dk/?p=5232</guid>
		<description><![CDATA[jQuery contains the fn.extend() method, which makes authoring jQuery plugins quite easy, allowing us to write code that is used in exactly the same way as other jQuery methods. jQuery UI also contains structures that make authoring custom jQuery UI plugins easy. So that’s what we’ll be looking at over the course of this tutorial. [...]]]></description>
			<content:encoded><![CDATA[<p>jQuery contains the <strong>fn.extend()</strong> method, which makes authoring jQuery plugins quite easy, allowing us to write code that is used in exactly the same way as other jQuery methods. jQuery UI also contains structures that make authoring custom jQuery UI plugins easy. So that’s what we’ll be looking at over the course of this tutorial. The methods used differ from that of standard jQuery plugins, and there are stricter conventions that should be followed, which is why I feel the topic is deserving of an article.</p>
<p><span> </span></p>
<div><a href="http://nettuts.s3.cdn.plus.org/579_jqueryui/code.zip"><img src="http://net.tutsplus.com/wp-content/themes/nettuts/site_images/button_src_nm.jpg" alt="" /></a><a href="http://nettuts.s3.cdn.plus.org/579_jqueryui/code/captionator.html"><img src="http://net.tutsplus.com/wp-content/themes/nettuts/site_images/button_demo_nm.jpg" alt="" /></a></div>
<p>Over the course of this tutorial, I’ll show you the coding conventions and general guidelines that should be adhered to when authoring plugins for jQuery UI. We’ll be creating a simple plugin that just adds captions to images on the page. It’s purposely simple so that we can focus on what is needed to make a jQuery UI plugin without getting lost in the code. Anyone that’s written a jQuery plugin should have no problems. Knowledge of jQuery UI may help but shouldn’t be essential to complete this tutorial. Let’s get started.</p>
<h2>Getting Started</h2>
<p>We’ll need a copy of jQuery as well as a couple of files from jQuery UI, but it needs to be jQuery UI 1.8 (this can be found on <a href="http://blog.jqueryui.com/2010/01/jquery-ui-1-8rc1/">the blog</a>). Create a working directory somewhere on your machine called <strong>jqueryui-plugin</strong>, then inside this create a <strong>css</strong> folder, a <strong>js</strong> folder and an <strong>img</strong> folder (the images used in this tutorial can be found in the code download).</p>
<p>Download the library and unpack it somewhere accessible. We only need a few files from the archive, namely the jQuery source file which is in the root of the archive as <strong>jquery-1.4.1.js</strong>, and the <strong>jquery.ui.core.js</strong> and <strong>jquery.ui.widget.js</strong> files, which are both in the <strong>ui</strong> folder. Grab these and put them into the <strong>js</strong> folder in your working directory. We’ll be making light use of the CSS framework as well, so we’ll need one of the theme style sheets available with the current stable version of jQuery UI (I used <strong>ui-lightness</strong> in this example).</p>
<p>We’ll be making a captionator widget, so we’ll also need a page, with a bunch of images on it, to develop/test the plugin with. This example uses the following page:</p>
<pre>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"&gt;
&lt;html&gt;
	&lt;head&gt;
		&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"&gt;
		&lt;title&gt;jQuery UI Captionator&lt;/title&gt;
		&lt;link rel="stylesheet" type="text/css" href="css/ui-lightness/jquery-ui-1.7.2.custom.css"&gt;
		&lt;link rel="stylesheet" type="text/css" href="css/ui.captionator.css"&gt;
	&lt;/head&gt;
	&lt;body&gt;
		&lt;img src="img/1.jpg" alt="Royal Air Force Eurofighter Typhoon"&gt;
		&lt;img src="img/2.jpg" alt="A British military GR-9 Harrier"&gt;
		&lt;img src="img/3.jpg" alt="Two RAF Tornado GR-4s pull away from a KC-135 Stratotanker after refueling"&gt;
		&lt;script type="text/javascript" src="js/jquery.js"&gt;&lt;/script&gt;
		&lt;script type="text/javascript" src="js/jquery.ui.core.js"&gt;&lt;/script&gt;
		&lt;script type="text/javascript" src="js/jquery.ui.widget.js"&gt;&lt;/script&gt;
		&lt;script type="text/javascript" src="js/jquery.ui.captionator.js"&gt;&lt;/script&gt;
	&lt;/body&gt;
&lt;/html&gt;</pre>
<p>We’ll keep things pretty simple for now; we’ve just three images on the page, followed by four script files; three link to the jQuery and jQuery UI source files, the fourth to our plugin’s source file which we’ll create shortly. The <strong>jquery.ui.core.js</strong> file is required by all jQuery UI widgets/plugins. The <strong>jquery.ui.widget.js</strong> file is the widget factory and allows for the creation of consistent widgets that share common API functionality. Most library components require this, and we’ll be using it to create our plugin.</p>
<h2>Creating the Plugin File</h2>
<p>Create a new JavaScript file and save it as <strong>jquery.ui.captionator.js</strong> in the <strong>js</strong> folder; we should keep to jQuery UI’s naming convention, which has just been updated in the 1.8 version of the library, and use <strong>jquery.ui.plugin_name.js</strong>. Add the following code to the new file:</p>
<pre>(function($) {

})(jQuery);</pre>
<p>All of the code that makes up our plugin should be encapsulated within a self-executing anonymous function. The jQuery object is passed into this function and is used inside the function via the <strong>$</strong> alias; this is to ensure that the plugin is compatible with jQuery’s <strong>noConflict()</strong> method. This is a specified requirement and should always be adhered to.</p>
<p>Next we need to define the plugin; add the following code to our anonymous function:</p>
<pre>$.widget("ui.captionator", {

});</pre>
<p>The pattern for using the widget factory is simple to use, we just call the <strong>widget()</strong> method specifying the name of the plugin as the first argument, and an object literal containing the properties and methods that make the plugin function. This allows our plugin to be called (and created) using the commen jQuery syntax <strong>$(“element_caption_applied_to”).captionator();</strong> like any other jQuery or jQuery UI method.</p>
<p>The widget factory provides a number of these properties and methods for us; for example, we can set the default options for the plugin using the <strong>options</strong> property, and add an initialisation function that is executed automatically by the widget factory as soon as an instance of the plugin is invoked. Within the object that appears as the second argument in the previous code add the following code:</p>
<pre>options: {
  location: "bottom",
  color: "#fff",
  backgroundColor: "#000"
},</pre>
<p>These are the only options we’ll use in our example plugin; users (and by users I mean implementers, not end users) of the plugin can specify the position of the caption to be either at the top of the image it is called on, or the bottom, they can specify the color of the text on the caption, or change the background-color of the caption. To change a configurable option of any jQuery UI widget prior to initialisation the implementing developer would just use something like this:</p>
<p><strong>$(“element_caption_applied_to”).captionator({ location: “top” });</strong></p>
<p>Next we can create our initialisation function, after the options object add the following method:</p>
<pre>_create: function() {

	var self = this,
		o = self.options,
		el = self.element,
		cap = $("&lt;span&gt;&lt;/span&gt;").text(el.attr("alt")).addClass("ui-widget ui-caption").css({
			backgroundColor: o.backgroundColor,
			color: o.color,
			width: el.width()
		}).insertAfter(el),
		capWidth = el.width() - parseInt(cap.css("paddingLeft")) - parseInt(cap.css("paddingRight")),
		capHeight = cap.outerHeight() - parseInt(cap.css("paddingTop")) + parseInt(cap.css("paddingBottom"));

	cap.css({
		width: capWidth,
		top: (o.location === "top") ? el.offset().top : el.offset().top + el.height() - capHeight,
		left: el.offset().left,
		display: "block"
	});

	$(window).resize(function(){
		cap.css({
			top: (o.location === "top") ? el.offset().top : el.offset().top + el.height() - capHeight,
			left: el.offset().left
		});
	});
},</pre>
<p>The method name should begin with an underscore as jQuery UI prevents any plugin method that begins with an underscore from being called from outside of the plugin, so this stops it being accidentally called from the HTML page. Any method that we begin with an underscore will be protected in this way.</p>
<p>The majority of our initialization method is a series of variables; within our function the keyword this refers to an object passed into the method which represents the instance of the plugin. The first variable caches a reference to the current instance of the plugin; the <strong>_create</strong> method is called for each element that the plugin method is called on, which could be a single element or several.</p>
<p>We can access the default options of the plugin (which are overridden automatically if the implementer configures any of them) using the <strong>options</strong> property of the object; we cache this in the second variable. The element that the plugin method (<strong>captionator()</strong>) was called on, which in this example would be an image, can be accessed using the <strong>element</strong> property of the object. We store this in the third variable.</p>
<p>We use the fourth variable to store a reference to the new caption element, which is built from a simple <strong>&lt;span&gt;</strong>; the <strong>&lt;span&gt;</strong> has its <strong>innerText</strong> set to the <strong>alt</strong> attribute of the current image, and several class names are added to it; we give it the <strong>ui-widget</strong> class name so that it can pick up some default styling from the current jQuery UI theme. We also give it a custom class name so that we can add some of our own styling.</p>
<p>Next we need to set some CSS properties; we’ll be using a separate style sheet for some styles, but certain things, such as the <strong>color</strong> and <strong>background-color</strong> styles are controllable via configurable options, so we need to set these using the plugin. The width of the caption needs to match the width of the image that it overlays, so we also need to determine this and set it programmatically. Finally the new <strong>&lt;span&gt;</strong> is injected into the page directly after the target image.</p>
<p>Once the caption has been inserted, it needs to be sized and positioned; the only way it can be sized accurately is if it already exists in the DOM and has CSS rules applied to it, such as the font-size. This is why we append the caption to the page, and then determine its exact dimensions, which are then stored in the variables <strong>capWidth</strong> and <strong>capHeight</strong>.</p>
<p>Once the caption has been appended to the page (and only then) we can work set the correct width, height and position of each caption, which we set using the <strong>css()</strong> method once again. The captions are actually completely separate from the images; they are inserted directly after each image and then positioned to appear to overlay the images, after all, we can’t append the <strong>&lt;span&gt;</strong> as a child of the <strong>&lt;img&gt;</strong>.</p>
<p>This is fine, until the browser is resized, at which point the images move but the captions don’t because they are absolutely positioned. To remedy this, we’ve used a basic resize handler attached to the window which simply repositions each caption to the new position of its image. This event handler is the last thing in our initialization method.</p>
<p>Another method that our plugin should expose is the <strong>destroy()</strong> method which is common to all jQuery UI plugins. We must provide an implementation of this method in order to clean up after our plugin. For our example plugin, the method can be as simple as this:</p>
<pre>destroy: function() {
	this.element.next().remove();

	$(window).unbind("resize");
},</pre>
<p>All we need to do is remove the captions and unbind our window resize handler. This method can be called by an implementer using the plugin so we shouldn’t begin this method name with an underscore. To call this method, the implementer would use <strong>$(“element_caption_attached_to”).captionator(“destroy”);</strong> which is how any of our public methods would be called.</p>
<p>We need to provide another method controlled/executed by the widget factory; we saw earlier how a developer could change a configurable option prior to initialisation, but what about after initialisation? This is done using the <strong>option</strong> method using the following syntax: <strong>$(“element_caption_attached_to”).captionator(“option”, “location”, “top”);</strong> so we need to add the built-in method <strong>_setOption</strong> to handle this:</p>
<pre>_setOption: function(option, value) {
	$.Widget.prototype._setOption.apply( this, arguments );

	var el = this.element,
		cap = el.next(),
		capHeight = cap.outerHeight() - parseInt(cap.css("paddingTop")) + parseInt(cap.css("paddingBottom"));

	switch (option) {
		case "location":
			(value === "top") ? cap.css("top", el.offset().top) : cap.css("top", el.offset().top + el.height() - capHeight);
			break;
		case "color":
			el.next().css("color", value);
			break;
		case "backgroundColor":
			el.next().css("backgroundColor", value);
			break;
	}
}</pre>
<p>We start this method with an underscore because the implementer uses <strong>option</strong>, not <strong>_setOption</strong> to actually change the options; we don’t need to worry about how this is handled, we just need to provide this method to deal with anything specific to our plugin. Because this method already exists in the widget factory we should call the original method, which we do first of all in our method using the prototype of the <strong>Widget</strong> object, specifying the method name (<strong>_setOption</strong> in this case but we could do it for other built-in methods as well) and use <strong>apply</strong> to call it. We can then proceed with the code specific to our plugin.</p>
<p>The function will automatically receive two arguments which are the option to change and the new value. We cache some commonly used elements, such as the image and the caption, and obtain the current height of each caption. We then use a simple switch-case statement to handle each of our three options being changed. Repositioning the captions is the most complex, but is still quite trivial and similar to how we positioned them initially.</p>
<h2>Adding Events</h2>
<p>It’s important to add events that developers using your plugin can add callbacks for so that they can react to different things happening when users interact with the widget in some way. The widget factory handles most of this task for us, all we need to do is trigger the event. This plugin doesn’t really do much, but we could still trigger an event after each caption is added to the page; to do this add the following code directly before the resize event handler:</p>
<pre>self._trigger("added", null, cap);</pre>
<p>That’s all we need to do! A single line of code and we have a custom event that can be reacted to. We call the <strong>_trigger()</strong> method of the plugin instance (which we stored in the variable <strong>self</strong>) and pass the method three arguments; the first is the name of the event, the second is for the event object (we don’t need to use this in our example plugin, hence the <strong>null</strong> value) and the third is a reference to the caption element. The widget factory will automatically pass the event object (if supplied) and the data we pass in the third parameter to a callback function that uses the added event. A developer could hook into this event using the following syntax: <strong>$(“element_caption_attached_to”).captionator({ added: function(e, ui){ //do stuff });</strong></p>
<h2>Styling the Plugin</h2>
<p>We only need a very tiny style sheet for our plugin, literally we have just three styles. It’s almost not even worth creating a separate file for the styles! But we will, so create a new file called <strong>ui.captionator.css</strong>, which is the required format for plugin style sheets, and save it in the <strong>css</strong> directory. Add the following styles to it:</p>
<pre>.ui-caption { display:none; position:absolute; padding:10px; }</pre>
<p>That’s all there is to it. Our plugin is now functionally and visually complete. The captions should appear like this:</p>
<div><img src="http://nettuts.s3.cdn.plus.org/579_jqueryui/img1.jpg" alt="Final Product" /></div>
<h2>Summary</h2>
<p>Like jQuery’s plugin creation method <strong>fn.extend()</strong>, jQuery UI also has its own mechanism that allows developers to quickly and easily write robust and scalable plugins that meet the jQuery UI projects high standards, although in terms of what it actually does for us, it’s even better that jQuery. The widget factory has been created in such a way that pretty much all of the hard work is taken out of custom plugin creation.</p>
<p>It’s easy to work with the methods provided by the widget factory to add methods to our plugins that are common across UI widgets, such as the <strong>destroy</strong> and <strong>option</strong> methods, which implementing developers would expect to find in any plugin. We also saw just how easy it is to trigger custom events that developers can use to react to interactions or occurrences with the widget.</p>
<p><img src="http://feeds.feedburner.com/~r/nettuts/~4/duMeYRc0dfY" alt="" width="1" height="1" /></p>

	Tags: <a href="http://xguiden.dk/tag/cd/" title="CD" rel="tag">CD</a>, <a href="http://xguiden.dk/tag/css/" title="CSS" rel="tag">CSS</a>, <a href="http://xguiden.dk/tag/doctype/" title="DOCTYPE" rel="tag">DOCTYPE</a>, <a href="http://xguiden.dk/tag/fil/" title="fil" rel="tag">fil</a>, <a href="http://xguiden.dk/tag/get/" title="GET" rel="tag">GET</a>, <a href="http://xguiden.dk/tag/guide/" title="guide" rel="tag">guide</a>, <a href="http://xguiden.dk/tag/help/" title="help" rel="tag">help</a>, <a href="http://xguiden.dk/tag/html/" title="HTML" rel="tag">HTML</a>, <a href="http://xguiden.dk/tag/image/" title="image" rel="tag">image</a>, <a href="http://xguiden.dk/tag/images/" title="images" rel="tag">images</a>, <a href="http://xguiden.dk/tag/ip/" title="IP" rel="tag">IP</a>, <a href="http://xguiden.dk/tag/java/" title="Java" rel="tag">Java</a>, <a href="http://xguiden.dk/tag/javascript/" title="JavaScript" rel="tag">JavaScript</a>, <a href="http://xguiden.dk/tag/lp/" title="LP" rel="tag">LP</a>, <a href="http://xguiden.dk/tag/meta/" title="META" rel="tag">META</a>, <a href="http://xguiden.dk/tag/over/" title="Over" rel="tag">Over</a>, <a href="http://xguiden.dk/tag/reference/" title="reference" rel="tag">reference</a>, <a href="http://xguiden.dk/tag/script/" title="script" rel="tag">script</a>, <a href="http://xguiden.dk/tag/source/" title="Source" rel="tag">Source</a>, <a href="http://xguiden.dk/tag/standard/" title="standard" rel="tag">standard</a>, <a href="http://xguiden.dk/tag/start/" title="Start" rel="tag">Start</a>, <a href="http://xguiden.dk/tag/sten/" title="Sten" rel="tag">Sten</a>, <a href="http://xguiden.dk/tag/switch/" title="switch" rel="tag">switch</a>, <a href="http://xguiden.dk/tag/table/" title="table" rel="tag">table</a>, <a href="http://xguiden.dk/tag/text/" title="text" rel="tag">text</a>, <a href="http://xguiden.dk/tag/tutorial/" title="tutorial" rel="tag">tutorial</a><br />

	<h4>Related posts</h4>
	<ul class="st-related-posts">
	<li><a href="http://xguiden.dk/2010/02/13/how-to-make-a-css-sprite-powered-menu/" title="How to Make a CSS Sprite Powered Menu (13/02/2010)">How to Make a CSS Sprite Powered Menu</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/02/16/how-to-build-an-unobtrusive-login-system-in-rails/" title="How to Build an Unobtrusive Login System in Rails (16/02/2010)">How to Build an Unobtrusive Login System in Rails</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/02/15/how-to-code-up-a-web-design-from-psd-to-html/" title="How to Code up a Web Design from PSD to HTML (15/02/2010)">How to Code up a Web Design from PSD to HTML</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/02/13/animate-panning-slideshow-with-jquery/" title="Animate Panning Slideshow with jQuery (13/02/2010)">Animate Panning Slideshow with jQuery</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/02/13/protect-your-flash-files-from-decompilers-by-using-encryption/" title="Protect Your Flash Files From Decompilers by Using Encryption (13/02/2010)">Protect Your Flash Files From Decompilers by Using Encryption</a> (0)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://xguiden.dk/2010/02/25/coding-your-first-jquery-ui-plugin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Make your MooTools Code Shorter, Faster, and Stronger</title>
		<link>http://xguiden.dk/2010/02/18/make-your-mootools-code-shorter-faster-and-stronger/</link>
		<comments>http://xguiden.dk/2010/02/18/make-your-mootools-code-shorter-faster-and-stronger/#comments</comments>
		<pubDate>Thu, 18 Feb 2010 11:09:12 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Engelske guides]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[avi]]></category>
		<category><![CDATA[counter]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[GET]]></category>
		<category><![CDATA[Gitter]]></category>
		<category><![CDATA[Header]]></category>
		<category><![CDATA[help]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[input]]></category>
		<category><![CDATA[internet]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[IP]]></category>
		<category><![CDATA[iso]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[LP]]></category>
		<category><![CDATA[Mod]]></category>
		<category><![CDATA[Mount]]></category>
		<category><![CDATA[Outline]]></category>
		<category><![CDATA[Over]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[POST]]></category>
		<category><![CDATA[reference]]></category>
		<category><![CDATA[rewrite]]></category>
		<category><![CDATA[Sand]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[Source]]></category>
		<category><![CDATA[standard]]></category>
		<category><![CDATA[Start]]></category>
		<category><![CDATA[Sten]]></category>
		<category><![CDATA[switch]]></category>
		<category><![CDATA[system]]></category>
		<category><![CDATA[table]]></category>
		<category><![CDATA[tag]]></category>
		<category><![CDATA[text]]></category>
		<category><![CDATA[Tweening]]></category>
		<category><![CDATA[URL]]></category>

		<guid isPermaLink="false">http://xguiden.dk/?p=5142</guid>
		<description><![CDATA[MooTools is one of the most flexible, modular, and well written JavaScript frameworks available. So many people use it but many of them don’t optimize their code. This post will provide you with fifteen simple tips for making your MooTools code shorter, faster, and stronger.
 
1. Create Your Own MooTools Build or Pull From Google AJAX [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://mootools.net/">MooTools</a> is one of the most flexible, modular, and well written JavaScript frameworks available. So many people use it but many of them don’t optimize their code. This post will provide you with fifteen simple tips for making your MooTools code shorter, faster, and stronger.</p>
<p><span> </span></p>
<h3>1. Create Your Own MooTools Build or Pull From Google AJAX Libraries</h3>
<p>One of the great advantages to using MooTools is that it’s incredibly modular. What does that mean?<br />
Almost nothing is required unless you need it. The advantage of MooTools’ modularity is that your<br />
limited, custom MooTools build can keep your JavaScript load time short.</p>
<p><img src="http://net.tutsplus.com/builder.jpg" alt="MooTools Core Builder" /></p>
<p>Want to create a custom MooTools build for your next project? Follow these steps:</p>
<ul>
<li>Go to <a href="http://mootools.net/core">http://mootools.net/core</a> (and/or <a href="http://mootools.net/more">http://mootools.net/more</a> if you’d like additional plugins)</li>
<li>Select the plugins of your choosing. Don’t worry about accounting for dependencies — the plugin builder does that for you!</li>
<li>Select the compression option of your choosing — the YUI Compressor will provide the you with the smallest possible build of MooTools</li>
</ul>
<p>That’s it! Sometimes, however, your project requires the entire MooTools Core library. In that case, your website can save itself thousands<br />
of requests per day by using the Google AJAX Libraries complete build of MooTools. You may do this two ways:</p>
<pre>&lt;script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/mootools/1.2.4/mootools-yui-compressed.js"&gt;&lt;/script&gt;</pre>
<p>This first method simply includes MooTools into the page per normal. The second method allows more functionality and performance:</p>
<pre>&lt;script src="http://www.google.com/jsapi"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;
google.load("mootools", "1.2.4"); //older versions also available
&lt;/script&gt;</pre>
<p>What’s great about using the Google AJAX Libraries API is that if another website uses the AJAX Library API, that version of MooTools is already cached<br />
within their browser and the site will load faster!</p>
<h3>2. Use jQuery and MooTools Together</h3>
<p>While it’s best to stick to one library in a given page to avoid a bunch of overhead, sometimes you can’t avoid needing multiple frameworks.<br />
Luckily MooTools can coexist with any non-prototype-based JavaScript frameworks. Here’s how you can use jQuery and MooTools in the same page:</p>
<pre>&lt;!-- jquery gets the "$" method --&gt;
&lt;script type="text/javascript" src="jquery-1.4.js" /&gt;
&lt;!-- mootools doesn't steal the "$" method; instead, document.id will be used --&gt;
&lt;script type="text/javascript" src="mootools.js" /&gt;
&lt;!-- lets use them --&gt;
&lt;script type="text/javascript"&gt;
//with jquery, grab all links, make then red
$('a').css('color','red');
//with mootools, get the content div, set it's background color to pink
document.id('content').setStyle('background','pink');
//with mootools, get the content div, set it's background color to pink
//this time, we'll give mootools the "$" method
(function($) {
	$('content').setStyle('background','pink');
})(document.id);
&lt;/script&gt;</pre>
<p>Thanks to <a href="http://mootools.net/blog/2009/06/22/the-dollar-safe-mode/">MooTools’ Dollar Safe Mode</a>, MooTools no longer assumes the “$” method if it’s already taken!</p>
<h3>3. Save Elements and Element Collections</h3>
<p>Developers often need to collect one element or a collection of elements. For example, you may need to grab all A elements within the page, change their color, and create tooltips from them.</p>
<pre>//grab links, change color */
$$('#footer a').setStyle('color','#f00');
//make links tooltips
var tippers = new Tips($$('#footer a'));</pre>
<p>The code above is grossly inefficient. Why query the DOM twice (with $$) if you can collect all of the elements once? Let’s make this more efficient:</p>
<pre>//"save" links into a variable
var links = $$('#footer a');
//grab links, change color */
links.setStyle('color','#f00');
//make links tooltips
var tippers = new Tips(links);</pre>
<p>You could make this even shorter, but it’s not as readable:</p>
<pre>var tippers = new Tips($$('#footer a').setStyle('color','#f00'));</pre>
<p>Readability is important, so I wouldn’t recommend coding this way if you work with a team.</p>
<h3>4. Use Element Methods on Element Collections</h3>
<p>Cycling through an array of elements is not unique to any JavaScript framework:</p>
<pre>//for every link...
$$('a').each(function(a) {
	//add link nudging to the element
	a.addEvents({
		mouseenter: function() { //animate to the right
			if(!a.retrieve('oPad')) { a.store('oPad',a.getStyle('padding-left')); }
			a.tween('padding-left',30);
		},
		mouseleave: function() { //animate back to the left
			a.tween('padding-left',a.retrieve('oPad'));
		}
	});
});</pre>
<p>What many developers aren’t aware that Element collections have the same methods as Elements,<br />
so there’s no need to cycle through them — simply apply the desired functionality to the collection:</p>
<pre>$$('a').addEvents({
	mouseenter: function() { //animate to the right
		if(!this.retrieve('oPad')) { this.store('oPad',this.getStyle('padding-left')); }
		this.tween('padding-left',30);
	},
	mouseleave: function() { //animate back to the left
		this.tween('padding-left',this.retrieve('oPad'));
	}
});</pre>
<p>Note that the “this” keyword is used to reference the “current” element within the collection, not the collection itself.</p>
<h3>5. Use MooTools Alias</h3>
<p>MooTools’ “alias” method allows you to rename or alias an existing method. Take the following snippet of code which is currently in the MooTools Core source:</p>
<pre>Array.alias('forEach', 'each');</pre>
<p>The above code lets you call the “each” method instead of “forEach”. Using “each” is more readable, a quiet standard between most JavaScript frameworks, and<br />
it even saves you a few bytes in your code. If you prefer to give MooTools’ Native or Class methods a custom name, feel free to!</p>
<p>For example, the Element Class’ method for removing an Element form the DOM is:</p>
<pre>$('myElement').dispose();</pre>
<p>Suppose your web app is about a given topic and you’d like to stay within that terminology for your code. Here are a few examples:</p>
<pre>Element.alias('dispose','can'); //career site?
Element.alias('dispose','shank'); //prison site?</pre>
<p>Whatever your reasons are for calling a method by a different name, just don’t be afraid to do so!</p>
<h3>6. Create Custom Pseudo Selectors</h3>
<p>Accessing a collection of Elements in the DOM is a core responsibility of any JavaScript framework. Unfortunately it can also be taxing and<br />
the pseudo selectors you want aren’t always available. Luckily MooTools allows you to easily implement your own pseudo selectors! Let’s<br />
create a pseudo selector named “disabled” that returns an element if it’s disabled.</p>
<pre>//grab disabled elements
Selectors.Pseudo.disabled = function() {
	return this.disabled;
}

//how you use it
var disabledInputs = $$('input:disabled');</pre>
<p>Simply add your selector to the Selectors.Pseudo object. If the new pseudo’s function returns “true”, the element is a match and will be returned.</p>
<p>Defining you own pseudo selectors is a great way to take control of your selectors!</p>
<h3>7. Implement Methods on Existing Objects</h3>
<p>MooTools’ philosophy is that it’s acceptable, even encouraged, to modify Native (String, Function, Number, etc.) prototypes when needed.<br />
Implementing new methods on these Natives will empower them even more. Let’s create a String method that will turn any string of text into<br />
“tweet” format (add links for @reply’s, links, etc.):</p>
<pre>String.implement({
	toTweet: function() {
		 return this.replace(/(https?:\/\/\S+)/gi,'&lt;a href="$1"&gt;$1&lt;/a&gt;').replace(/(^|\s)@(\w+)/g,'$1&lt;a href="http://twitter.com/$2"&gt;@$2&lt;/a&gt;').replace(/(^|\s)#(\w+)/g,'$1&lt;a href="http://search.twitter.com/search?q=%23$2"&gt;#$2&lt;/a&gt;');
	}
});</pre>
<p>Now you can call “toTweet” on any string and you’ll get the string back as a “tweet”. Here are a few examples:</p>
<pre>//set an element's html to a tweet value
var el = $('myElement');
el.set('html',el.get('html').toTweet()); //sets the element's html to a linked, tweet value.

//alert the tweeted value
alert('Yo @NetTuts, check out my #MooTools website: http://davidwalsh.name'.toTweet());
//alerts:  Yo &lt;a href="http://twitter.com/nettuts"&gt;@NetTuts&lt;/a&gt;, check out my &lt;a href="http://search.twitter.com/search?q=%23MooTools"&gt;MooTools&lt;/a&gt; website: &lt;a href="http://davidwalsh.name"&gt;http://davidwalsh.name&lt;/a&gt;</pre>
<p>Implementing custom methods on Objects strengthens every existing and future instance of that object.</p>
<h3>8. Extend Existing Classes</h3>
<p>MooTools’ OOP philosophy allows for a super-powerful inheritance model. Extending existing classes<br />
allows you to avoid repeating code, empower existing objects, and leverage existing functionality.<br />
MooTools Core, More, and your custom classes extend existing functionality. Consider the Request class:</p>
<pre>var Request = new Class({

	Implements: [Chain, Events, Options],

	options: {/*
		onRequest: $empty,
		onComplete: $empty,
		onCancel: $empty,
		onSuccess: $empty,
		onFailure: $empty,
		onException: $empty,*/
		url: '',
		data: '',
		headers: {
			'X-Requested-With': 'XMLHttpRequest',
			'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
		},
		async: true,
		format: false,
		method: 'post',
		link: 'ignore',
		isSuccess: null,
		emulation: true,
		urlEncoded: true,
		encoding: 'utf-8',
		evalScripts: false,
		evalResponse: false,
		noCache: false
	},

	initialize: function(options){
		this.xhr = new Browser.Request();
		this.setOptions(options);
		this.options.isSuccess = this.options.isSuccess || this.isSuccess;
		this.headers = new Hash(this.options.headers);
	},

	onStateChange: function(){
		if (this.xhr.readyState != 4 || !this.running) return;
		this.running = false;
		this.status = 0;
		$try(function(){
			this.status = this.xhr.status;
		}.bind(this));
		this.xhr.onreadystatechange = $empty;
		if (this.options.isSuccess.call(this, this.status)){
			this.response = {text: this.xhr.responseText, xml: this.xhr.responseXML};
			this.success(this.response.text, this.response.xml);
		} else {
			this.response = {text: null, xml: null};
			this.failure();
		}
	},

	isSuccess: function(){
		return ((this.status &gt;= 200) &amp;&amp; (this.status &lt; 300));
	},

	processScripts: function(text){
		if (this.options.evalResponse || (/(ecma|java)script/).test(this.getHeader('Content-type'))) return $exec(text);
		return text.stripScripts(this.options.evalScripts);
	},

	success: function(text, xml){
		this.onSuccess(this.processScripts(text), xml);
	},

	onSuccess: function(){
		this.fireEvent('complete', arguments).fireEvent('success', arguments).callChain();
	},

	failure: function(){
		this.onFailure();
	},

	onFailure: function(){
		this.fireEvent('complete').fireEvent('failure', this.xhr);
	},

	setHeader: function(name, value){
		this.headers.set(name, value);
		return this;
	},

	getHeader: function(name){
		return $try(function(){
			return this.xhr.getResponseHeader(name);
		}.bind(this));
	},

	check: function(){
		if (!this.running) return true;
		switch (this.options.link){
			case 'cancel': this.cancel(); return true;
			case 'chain': this.chain(this.caller.bind(this, arguments)); return false;
		}
		return false;
	},

	send: function(options){
		if (!this.check(options)) return this;
		this.running = true;

		var type = $type(options);
		if (type == 'string' || type == 'element') options = {data: options};

		var old = this.options;
		options = $extend({data: old.data, url: old.url, method: old.method}, options);
		var data = options.data, url = String(options.url), method = options.method.toLowerCase();

		switch ($type(data)){
			case 'element': data = document.id(data).toQueryString(); break;
			case 'object': case 'hash': data = Hash.toQueryString(data);
		}

		if (this.options.format){
			var format = 'format=' + this.options.format;
			data = (data) ? format + '&amp;' + data : format;
		}

		if (this.options.emulation &amp;&amp; !['get', 'post'].contains(method)){
			var _method = '_method=' + method;
			data = (data) ? _method + '&amp;' + data : _method;
			method = 'post';
		}

		if (this.options.urlEncoded &amp;&amp; method == 'post'){
			var encoding = (this.options.encoding) ? '; charset=' + this.options.encoding : '';
			this.headers.set('Content-type', 'application/x-www-form-urlencoded' + encoding);
		}

		if (this.options.noCache){
			var noCache = 'noCache=' + new Date().getTime();
			data = (data) ? noCache + '&amp;' + data : noCache;
		}

		var trimPosition = url.lastIndexOf('/');
		if (trimPosition &gt; -1 &amp;&amp; (trimPosition = url.indexOf('#')) &gt; -1) url = url.substr(0, trimPosition);

		if (data &amp;&amp; method == 'get'){
			url = url + (url.contains('?') ? '&amp;' : '?') + data;
			data = null;
		}

		this.xhr.open(method.toUpperCase(), url, this.options.async);

		this.xhr.onreadystatechange = this.onStateChange.bind(this);

		this.headers.each(function(value, key){
			try {
				this.xhr.setRequestHeader(key, value);
			} catch (e){
				this.fireEvent('exception', [key, value]);
			}
		}, this);

		this.fireEvent('request');
		this.xhr.send(data);
		if (!this.options.async) this.onStateChange();
		return this;
	},

	cancel: function(){
		if (!this.running) return this;
		this.running = false;
		this.xhr.abort();
		this.xhr.onreadystatechange = $empty;
		this.xhr = new Browser.Request();
		this.fireEvent('cancel');
		return this;
	}

});</pre>
<p>Then consider Request.JSONP, which extends Request:</p>
<pre>Request.JSON = new Class({

	Extends: Request,

	options: {
		secure: true
	},

	initialize: function(options){
		this.parent(options);
		this.headers.extend({'Accept': 'application/json', 'X-Request': 'JSON'});
	},

	success: function(text){
		this.response.json = JSON.decode(text, this.options.secure);
		this.onSuccess(this.response.json, text);
	}

});</pre>
<p>You see how small the Request.JSONP class is? By adding “Extends: Request”, the Request.JSONP class gets all<br />
of the Request Class’ methods. Essentially, this small snippet of code becomes a powerhouse because it extends<br />
Request. You can even add extensions to extensions. Now consider Request.JSONP and then <a href="http://net.tutsplus.com">Scott Kyle’s</a> Request.Twitter<br />
class:</p>
<pre>//Request.JSONP
/*
---

script: Request.JSONP.js

description: Defines Request.JSONP, a class for cross domain JavaScript via script injection.

license: MIT-style license

authors:
- Aaron Newton
- Guillermo Rauch

requires:
- core:1.2.4/Element
- core:1.2.4/Request
- /Log

provides: [Request.JSONP]

...
*/

Request.JSONP = new Class({

	Implements: [Chain, Events, Options, Log],

	options: {/*
		onRetry: $empty(intRetries),
		onRequest: $empty(scriptElement),
		onComplete: $empty(data),
		onSuccess: $empty(data),
		onCancel: $empty(),
		log: false,
		*/
		url: '',
		data: {},
		retries: 0,
		timeout: 0,
		link: 'ignore',
		callbackKey: 'callback',
		injectScript: document.head
	},

	initialize: function(options){
		this.setOptions(options);
		if (this.options.log) this.enableLog();
		this.running = false;
		this.requests = 0;
		this.triesRemaining = [];
	},

	check: function(){
		if (!this.running) return true;
		switch (this.options.link){
			case 'cancel': this.cancel(); return true;
			case 'chain': this.chain(this.caller.bind(this, arguments)); return false;
		}
		return false;
	},

	send: function(options){
		if (!$chk(arguments[1]) &amp;&amp; !this.check(options)) return this;

		var type = $type(options),
				old = this.options,
				index = $chk(arguments[1]) ? arguments[1] : this.requests++;
		if (type == 'string' || type == 'element') options = {data: options};

		options = $extend({data: old.data, url: old.url}, options);

		if (!$chk(this.triesRemaining[index])) this.triesRemaining[index] = this.options.retries;
		var remaining = this.triesRemaining[index];

		(function(){
			var script = this.getScript(options);
			this.log('JSONP retrieving script with url: ' + script.get('src'));
			this.fireEvent('request', script);
			this.running = true;

			(function(){
				if (remaining){
					this.triesRemaining[index] = remaining - 1;
					if (script){
						script.destroy();
						this.send(options, index).fireEvent('retry', this.triesRemaining[index]);
					}
				} else if(script &amp;&amp; this.options.timeout){
					script.destroy();
					this.cancel().fireEvent('failure');
				}
			}).delay(this.options.timeout, this);
		}).delay(Browser.Engine.trident ? 50 : 0, this);
		return this;
	},

	cancel: function(){
		if (!this.running) return this;
		this.running = false;
		this.fireEvent('cancel');
		return this;
	},

	getScript: function(options){
		var index = Request.JSONP.counter,
				data;
		Request.JSONP.counter++;

		switch ($type(options.data)){
			case 'element': data = document.id(options.data).toQueryString(); break;
			case 'object': case 'hash': data = Hash.toQueryString(options.data);
		}

		var src = options.url +
			 (options.url.test('\\?') ? '&amp;' :'?') +
			 (options.callbackKey || this.options.callbackKey) +
			 '=Request.JSONP.request_map.request_'+ index +
			 (data ? '&amp;' + data : '');
		if (src.length &gt; 2083) this.log('JSONP '+ src +' will fail in Internet Explorer, which enforces a 2083 bytes length limit on URIs');

		var script = new Element('script', {type: 'text/javascript', src: src});
		Request.JSONP.request_map['request_' + index] = function(){ this.success(arguments, script); }.bind(this);
		return script.inject(this.options.injectScript);
	},

	success: function(args, script){
		if (script) script.destroy();
		this.running = false;
		this.log('JSONP successfully retrieved: ', args);
		this.fireEvent('complete', args).fireEvent('success', args).callChain();
	}

});

Request.JSONP.counter = 0;
Request.JSONP.request_map = {};</pre>
<p>…and now Request.Twitter:</p>
<pre>Request.Twitter = new Class({

	Extends: Request.JSONP,

	options: {
	  linkify: true,
	  url: 'http://twitter.com/statuses/user_timeline/{term}.json',
	  data: {
	    count: 5
	  }
	},

	initialize: function(term, options){
	  this.parent(options);
	  this.options.url = this.options.url.substitute({term: term});
	},

	success: function(data, script){
	  if (this.options.linkify) data.each(function(tweet){
	    tweet.text = this.linkify(tweet.text);
	  }, this);

	  // keep subsequent calls newer
	  if (data[0]) this.options.data.since_id = data[0].id;

	  this.parent(data, script);
	},

	linkify: function(text){
	  // modified from TwitterGitter by David Walsh (davidwalsh.name)
	  // courtesy of Jeremy Parrish (rrish.org)
	  return text.replace(/(https?:\/\/[\w\-:;?&amp;=+.%#\/]+)/gi, '&lt;a href="$1"&gt;$1&lt;/a&gt;')
	             .replace(/(^|\W)@(\w+)/g, '$1&lt;a href="http://twitter.com/$2"&gt;@$2&lt;/a&gt;')
	             .replace(/(^|\W)#(\w+)/g, '$1#&lt;a href="http://search.twitter.com/search?q=%23$2"&gt;$2&lt;/a&gt;');
	}

});</pre>
<p>You see how a waterfall effect of extending objects can make the smallest of classes an absolute beast of a class?<br />
Experiment with MooTools’ inheritance model and don’t repeat code!</p>
<h3>9. Create Custom Events</h3>
<p>I’ve already explained how flexible the MooTools selector engine is, the class system is, and how modular the framework is.<br />
Why would you expect anything different from MooTools’ event system? Creating custom events within MooTools is as simple<br />
as it gets. Here’s a basic outline of your MooTools custom event:</p>
<pre>Element.Events.altClick = {
	base: 'click', //the "base" event
	condition: function(event) {
		return event.alt; // alt key?
	},
	onAdd: function() {
		//do something when the event is added
	},
	onRemove: function() {
		//do something when the event is removed
	}
};</pre>
<p>Here’s a great example of a custom event — listening for “alt” and “click” at the same time:</p>
<pre>//alt click
Element.Events.altClick = {
	base: 'click',
	condition: function(event) {
		return event.alt; // alt key?
	}
};

//usage
$(document.body).addEvent('altClick',function() {
	alert('You alt-clicked me!');
});</pre>
<p>Or you can simply define a custom event so that a specific function executes any time that type of event is assigned.<br />
In my next example, any time a click event is assigned to an element, that element’s cursor will be automatically changed<br />
to the “pointer” cursor.</p>
<pre>/* update cursor on add/remove click event */
Element.Events.click = {
	base:'click',
	onAdd: function() {
		if(this.setStyle) {
			this.store('original-cursor',this.getStyle('cursor'));
			this.setStyle('cursor','pointer');
		}
	},
	onRemove: function() {
		if(this.setStyle) {
			this.setStyle('cursor',this.retrieve('original-cursor'));
		}
	}
};</pre>
<p>You’ll notice that if the click event is removed, the original cursor will be restored.</p>
<h3>10. jQuery-Style Events</h3>
<p>While the MooTools event sytax is different from jQuery’s, it doesn’t have to be! With a minimal amount of<br />
javascript you can make MooTools’ event syntax reflect jQuery’s.</p>
<p>MooTools holds all of its events in the Element.NativeElements object:</p>
<pre>Element.NativeEvents = {
	click: 2, dblclick: 2, mouseup: 2, mousedown: 2, contextmenu: 2, //mouse buttons
	mousewheel: 2, DOMMouseScroll: 2, //mouse wheel
	mouseover: 2, mouseout: 2, mousemove: 2, selectstart: 2, selectend: 2, //mouse movement
	keydown: 2, keypress: 2, keyup: 2, //keyboard
	focus: 2, blur: 2, change: 2, reset: 2, select: 2, submit: 2, //form elements
	load: 1, unload: 1, beforeunload: 2, resize: 1, move: 1, DOMContentLoaded: 1, readystatechange: 1, //window
	error: 1, abort: 1, scroll: 1 //misc
};</pre>
<p>Essentially all you need to do is cycle through each element type and implement a method on the Element class, named like the event type,<br />
that simulates what addEvent does:</p>
<pre>//hash the element.natives so you can do stuff with it
var hash = new Hash(Element.NativeEvents);
//remove items that need to be replaced, add their replacements
hash.erase('mouseover').erase('mouseout').erase('DOMMouseScroll');
hash.include('mouseenter',1).include('mouseleave',1);
//initialize this
var eventHash = new Hash({});
//for every event type, add to the hash
hash.getKeys().each(function(event){
	eventHash[event] = function(fn) {
		this.addEvent(event,fn);
		return this;
	};
});
//make it happen
Element.implement(eventHash);</pre>
<p>Now you can listen for events like:</p>
<pre>$('myElement').click(function() {
	//do stuff
});</pre>
<h3>11. Add Events During Element Creation</h3>
<p>If you have experience coding with MooTools, at some point you’ve no doubt created an element and subsequently added events to it:</p>
<pre>var myElement = new Element('a',{
	href: 'mypage.php',
	text: 'Click here!'
});

myElement.addEvent('click',function(e) {
	//stop the event
	if(e) e.stop();
	//do stuff
});</pre>
<p>There’s nothing wrong with the above, per say, but you could just add those events during element creation:</p>
<pre>var myElement = new Element('a',{
	href: 'mypage.php',
	text: 'Click here!',
	events: {
		click: function() {
			//stop the event
			if(e) e.stop();
			//do stuff
		}
	}
});</pre>
<h3>12. Implement Events Within Classes</h3>
<p>Extending classes was discussed in tip #8 above. Now lets explore the *implement* functionality within MooTools classes.<br />
What’s the difference? MooTools contributor Mark Obcena says it best in his article titled<br />
<a href="http://keetology.com/blog/2009/10/27/up-the-moo-herd-iv-theres-a-class-for-this">Up The Moo Herd IV: There’s A Class For This</a>:</p>
<blockquote><p>MooTools has two built-in mutators: Extends and Implements. The Extends mutator takes the class name passed on to it and makes the new class inherit directly from it, while Implements takes the class (or classes) passed and adds their methods to the new class (or mixes them in—thus mixin).</p></blockquote>
<p>With the difference between extending and implementing, lets get back to it. Implementing events within your MooTools classes<br />
can make your classes much more flexible. Consider the following simple Overlay class:</p>
<pre>var Overlay = new Class({

	Implements: [Options,Events],

	options:  {
		id: 'overlay',
		color: '#000',
		duration: 500,
		opacity: 0.5,
		zIndex: 5000
	},

	initialize: function(container,options) {
		this.setOptions(options);
		this.container = document.id(container);
		this.overlay = new Element('div',{
			id: this.options.id,
			opacity: 0,
			styles: {
				position: 'absolute',
				background: this.options.color,
				left: 0,
				top: 0,
				'z-index': this.options.zIndex
			},
		}).inject(this.container);
		this.tween = new Fx.Tween(this.overlay,{
			duration: this.options.duration,
			link: 'cancel',
			property: 'opacity',
			onStart: function() {
				this.overlay.setStyles({
					width: '100%',
					height: this.container.getScrollSize().y
				});
			}.bind(this)
		});
	},
	open: function() {
		this.tween.start(this.options.opacity);
		return this;
	},
	close: function() {
		this.tween.start(0);
		return this;
	}
});</pre>
<p>Sure the class does what it’s supposed to but it isn’t nearly as flexible it could be. Now lets implement<br />
onClick, onClose, onHide, onOpen, and onShow events:</p>
<pre>var Overlay = new Class({

	Implements: [Options,Events],  // EVENTS IMPLEMENTED HERE!

	options:  {
		id: 'overlay',
		color: '#000',
		duration: 500,
		opacity: 0.5,
		zIndex: 5000/*,
		onClick: $empty,
		onClose: $empty,
		onHide: $empty,
		onOpen: $empty,
		onShow: $empty
		*/
	},

	initialize: function(container,options) {
		this.setOptions(options);
		this.container = document.id(container);
		this.overlay = new Element('div',{
			id: this.options.id,
			opacity: 0,
			styles: {
				position: 'absolute',
				background: this.options.color,
				left: 0,
				top: 0,
				'z-index': this.options.zIndex
			},
			events: {
				click: function() {    // CLICK EVENT
					this.fireEvent('click');
				}.bind(this)
			}
		}).inject(this.container);
		this.tween = new Fx.Tween(this.overlay,{
			duration: this.options.duration,
			link: 'cancel',
			property: 'opacity',
			onStart: function() {
				this.overlay.setStyles({
					width: '100%',
					height: this.container.getScrollSize().y
				});
			}.bind(this),
			onComplete: function() {
				this.fireEvent(this.overlay.get('opacity') == this.options.opacity ? 'show' : 'hide');  // SHOW OR HIDE EVENT
			}.bind(this)
		});
	},
	open: function() {
		this.fireEvent('open');  // OPEN EVENT
		this.tween.start(this.options.opacity);
		return this;
	},
	close: function() {
		this.fireEvent('close');  // CLOSE EVENT
		this.tween.start(0);
		return this;
	}
});</pre>
<p>What’s great about adding events to a class is that events allow your to give more options and trigger functionality when<br />
our class methods execute. In the above example, you can execute any functionality when the overlay opens, closes, shows, hides, or gets clicked.<br />
Essentially you added two tiny snippets of code to the class:</p>
<pre>Implements: [Events]</pre>
<p>…and the following wherever you’d like an event to be signaled…</p>
<pre>this.fireEvent('someEvent',[argument1, argument2]);</pre>
<p>So how can you control these events when you create an instance of the class? Add them in the options like this:</p>
<pre>var overlay = new Overlay({
	onClick: function() {
		this.hide();
	},
	onOpen: function() {
		alert('Thank you for opening!');
	}
});</pre>
<p>You’d be hard pressed to find a class that wouldn’t benefit from implementing events!</p>
<h3>13. Use Event Delegation</h3>
<p>Event delegation is the process of adding an event to a parent for all of its children instead of assigning the<br />
event to each individual child. The advantage of event delegation is that you may add child elements to the<br />
parent element without needing to assign the event to that new element. If you choose to remove the event,<br />
you need only remove it from one element.</p>
<p>So, instead of:</p>
<pre>$$('a').addEvent('click',function() {
	//do stuff -- individually assigned
});</pre>
<p>…you do this:</p>
<pre>$('myContainer').addEvent('click:relay(a)',function() {
	//assigned to the parent of all A elements (in this case, #myContainer), to listen to A element click event
})/</pre>
<p>Don’t let the “:relay()” pseudo-syntax fool you; Element.Delegation rewrites the event methods to accommodate for :relay.</p>
<h3>14. Use Class.toElement</h3>
<p>One hidden gem within MooTools’ Class is the Class.toElement method. Class.toElement plays a small role but can help you out<br />
when it comes to accessing the primary element within a class, especially if you don’t know what that element is otherwise.<br />
Implementing toElement on your class is easy:</p>
<pre>var myClass = new Class({

	Implements: [Options],

	initialize: function(container,options) {
		this.container = $(container);
	},

	toElement: function() {
		return this.container;
	}
});</pre>
<p>Once you have toElement defined, you can use your class just like an element:</p>
<pre>var myInstance = new MyClass('myElement');
myInstance.setStyle('color','#f00').set('html','This is my element!');</pre>
<p>Look at that — a class virtually manipulated by Element methods.</p>
<h3>15. “return this” Within Methods For Chainability</h3>
<p>So we’ve all seen how the JavaScript frameworks allow you to chain the hell out of methods. Chaining looks like this:</p>
<pre>$('myElement').setStyles('color','#f00').set('html','Click Here').fade('out').addClass('cssClass').addEvent('click',function(e) {
	if(e) e.stop();
	alert('Clicked'!);
});</pre>
<p>Holy chaining Batman! Want your classes to chain forever? No problem — all you need to do is return “this”:</p>
<pre>var myClass = new Class({

	//options, initialize, implements, etc.

	doSomething: function() {
		//do a whole bunch of functionality here and...
		return this;
	},
	doAnotherThing: function() {
		//do a whole bunch of functionality here and...
		return this;
	},
	doYetAnotherThing: function() {
		//do a whole bunch of functionality here and...
		return this.
	}
});</pre>
<p>Since you placed “return this” in each method, now you can do:</p>
<pre>var klass = new myClass();
klass.doSomething().doAnotherThing().doYetAnotherThing();</pre>
<p>Make sure to return “this” wherever it makes sense. Doing so can make your Class much easier to work with and your code will be shorter!</p>
<h3>BONUS! 16. Use Fx Shortcuts on Elements</h3>
<p>MooTools effects are unarguably the smoothest of any JavaScript framework. The Fx library also provides loads of control through numerous options.<br />
Lets take a look at a basic Tween which fades an element to 50%:</p>
<pre>var myTween = new Fx.Tween('myElement',{
	duration: 500,
	fps: 200,
	//a bunch of options here
});
//fade to 50%
$('myElement').addEvent('click',function() {
	myTween.start('opacity',0.5);
});</pre>
<p>Did you know you didn’t need to type out all of this? You could use element shortcuts like:</p>
<pre>$('myElement').fade(0.5); //fading: Fx.Tween
$('myElement').tween('width',300); //tweening: Fx.Tween
$('myElement').morph({
	width: 200,
	height: 300
}); //morph:  Fx.Morph</pre>
<p>The above snippets, of course, rely on you wanting to use the default options. You can actually set custom options for these shortcut methods per element:</p>
<pre>$('myElement').set('tween',{ duration:500, fps: 200 }).tween('width',300);</pre>
<p>Save your self a few bytes by using Fx shortcuts!</p>
<h3>MooTools FTW!</h3>
<p>Hopefully I’ve given you some tips to improve your MooTools JavaScript code, making it shorter, faster, and stronger. Have some of your own tips to share?<br />
Place them in the comments below!</p>
<p><img src="http://feeds.feedburner.com/~r/nettuts/~4/zf6K2myv5JM" alt="" width="1" height="1" /></p>

	Tags: <a href="http://xguiden.dk/tag/ajax/" title="AJAX" rel="tag">AJAX</a>, <a href="http://xguiden.dk/tag/avi/" title="avi" rel="tag">avi</a>, <a href="http://xguiden.dk/tag/counter/" title="counter" rel="tag">counter</a>, <a href="http://xguiden.dk/tag/css/" title="CSS" rel="tag">CSS</a>, <a href="http://xguiden.dk/tag/get/" title="GET" rel="tag">GET</a>, <a href="http://xguiden.dk/tag/gitter/" title="Gitter" rel="tag">Gitter</a>, <a href="http://xguiden.dk/tag/header/" title="Header" rel="tag">Header</a>, <a href="http://xguiden.dk/tag/help/" title="help" rel="tag">help</a>, <a href="http://xguiden.dk/tag/html/" title="HTML" rel="tag">HTML</a>, <a href="http://xguiden.dk/tag/input/" title="input" rel="tag">input</a>, <a href="http://xguiden.dk/tag/internet/" title="internet" rel="tag">internet</a>, <a href="http://xguiden.dk/tag/internet-explorer/" title="Internet Explorer" rel="tag">Internet Explorer</a>, <a href="http://xguiden.dk/tag/ip/" title="IP" rel="tag">IP</a>, <a href="http://xguiden.dk/tag/iso/" title="iso" rel="tag">iso</a>, <a href="http://xguiden.dk/tag/java/" title="Java" rel="tag">Java</a>, <a href="http://xguiden.dk/tag/javascript/" title="JavaScript" rel="tag">JavaScript</a>, <a href="http://xguiden.dk/tag/lp/" title="LP" rel="tag">LP</a>, <a href="http://xguiden.dk/tag/mod/" title="Mod" rel="tag">Mod</a>, <a href="http://xguiden.dk/tag/mount/" title="Mount" rel="tag">Mount</a>, <a href="http://xguiden.dk/tag/outline/" title="Outline" rel="tag">Outline</a>, <a href="http://xguiden.dk/tag/over/" title="Over" rel="tag">Over</a>, <a href="http://xguiden.dk/tag/php/" title="php" rel="tag">php</a>, <a href="http://xguiden.dk/tag/post/" title="POST" rel="tag">POST</a>, <a href="http://xguiden.dk/tag/reference/" title="reference" rel="tag">reference</a>, <a href="http://xguiden.dk/tag/rewrite/" title="rewrite" rel="tag">rewrite</a>, <a href="http://xguiden.dk/tag/sand/" title="Sand" rel="tag">Sand</a>, <a href="http://xguiden.dk/tag/script/" title="script" rel="tag">script</a>, <a href="http://xguiden.dk/tag/source/" title="Source" rel="tag">Source</a>, <a href="http://xguiden.dk/tag/standard/" title="standard" rel="tag">standard</a>, <a href="http://xguiden.dk/tag/start/" title="Start" rel="tag">Start</a>, <a href="http://xguiden.dk/tag/sten/" title="Sten" rel="tag">Sten</a>, <a href="http://xguiden.dk/tag/switch/" title="switch" rel="tag">switch</a>, <a href="http://xguiden.dk/tag/system/" title="system" rel="tag">system</a>, <a href="http://xguiden.dk/tag/table/" title="table" rel="tag">table</a>, <a href="http://xguiden.dk/tag/tag/" title="tag" rel="tag">tag</a>, <a href="http://xguiden.dk/tag/text/" title="text" rel="tag">text</a>, <a href="http://xguiden.dk/tag/tweening/" title="Tweening" rel="tag">Tweening</a>, <a href="http://xguiden.dk/tag/url/" title="URL" rel="tag">URL</a><br />

	<h4>Related posts</h4>
	<ul class="st-related-posts">
	<li><a href="http://xguiden.dk/2010/02/13/protect-your-flash-files-from-decompilers-by-using-encryption/" title="Protect Your Flash Files From Decompilers by Using Encryption (13/02/2010)">Protect Your Flash Files From Decompilers by Using Encryption</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/03/03/how-we%e2%80%99ll-be-building-websites-in-5-years-html5-and-css3-layout/" title="How We’ll be Building Websites in 5 years: HTML5 and CSS3 layout (03/03/2010)">How We’ll be Building Websites in 5 years: HTML5 and CSS3 layout</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/02/13/how-to-make-a-css-sprite-powered-menu/" title="How to Make a CSS Sprite Powered Menu (13/02/2010)">How to Make a CSS Sprite Powered Menu</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/02/16/how-to-build-an-unobtrusive-login-system-in-rails/" title="How to Build an Unobtrusive Login System in Rails (16/02/2010)">How to Build an Unobtrusive Login System in Rails</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/03/08/design-and-code-a-cool-iphone-app-website-in-html5/" title="Design and Code a Cool iPhone App Website in HTML5 (08/03/2010)">Design and Code a Cool iPhone App Website in HTML5</a> (0)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://xguiden.dk/2010/02/18/make-your-mootools-code-shorter-faster-and-stronger/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to Build an Unobtrusive Login System in Rails</title>
		<link>http://xguiden.dk/2010/02/16/how-to-build-an-unobtrusive-login-system-in-rails/</link>
		<comments>http://xguiden.dk/2010/02/16/how-to-build-an-unobtrusive-login-system-in-rails/#comments</comments>
		<pubDate>Tue, 16 Feb 2010 18:37:12 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Engelske guides]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[CD]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[fil]]></category>
		<category><![CDATA[fix]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[GET]]></category>
		<category><![CDATA[guide]]></category>
		<category><![CDATA[help]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[IP]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[login]]></category>
		<category><![CDATA[LP]]></category>
		<category><![CDATA[Mod]]></category>
		<category><![CDATA[OSX]]></category>
		<category><![CDATA[Over]]></category>
		<category><![CDATA[png]]></category>
		<category><![CDATA[POST]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[Server]]></category>
		<category><![CDATA[Session]]></category>
		<category><![CDATA[Source]]></category>
		<category><![CDATA[standard]]></category>
		<category><![CDATA[Start]]></category>
		<category><![CDATA[Sten]]></category>
		<category><![CDATA[system]]></category>
		<category><![CDATA[table]]></category>
		<category><![CDATA[tag]]></category>
		<category><![CDATA[tags]]></category>
		<category><![CDATA[text]]></category>
		<category><![CDATA[URL]]></category>
		<category><![CDATA[valid]]></category>

		<guid isPermaLink="false">http://xguiden.dk/?p=5091</guid>
		<description><![CDATA[An unobtrusive login system is one that gets out of the user’s way. It will make your application nicer and more polished. This article will guide you through the process of setting up user logins, then ajaxifying the process by moving the form into a modal box that communicates with the server. Additionally, this article [...]]]></description>
			<content:encoded><![CDATA[<p>An unobtrusive login system is one that gets out of the user’s way. It will make your application nicer and more polished. This article will guide you through the process of setting up user logins, then ajaxifying the process by moving the form into a modal box that communicates with the server. Additionally, this article will show you how to create the setup using jQuery and Prototype so you can choose your favorite library. This article assumes that you have experience with Rails and jQuery or Prototype.</p>
<p><span> </span></p>
<div><a href="http://github.com/Adman65/Unobtrusive-Login/"><img src="http://net.tutsplus.com/wp-content/themes/nettuts/site_images/button_src_nm.jpg" alt="" /></a><a href="http://nettuts-unobtrusive-login.heroku.com/"><img src="http://net.tutsplus.com/wp-content/themes/nettuts/site_images/button_demo_nm.jpg" alt="" /></a></div>
<p>You can use Adman65/nettuts for a successful login. Be sure to use bad credentials so you can see how everything works.</p>
<h3>What We’re Making</h3>
<div><a href="http://nettuts-unobtrusive-login.heroku.com/"><br />
<img src="http://nettuts.s3.cdn.plus.org/568_login/login4.png" alt="Final Project" /><br />
</a></div>
<h3>Getting Started</h3>
<p>We’re going to start by creating a dummy application that has a public and private page. The root url is the public page. There’s a login link on the public page. If the user logs in successfully, they’re redirected to the private page. If not, they’re redirected back to the login form. The private page shows the user name. We’ll use this as the starting point for ajaxifying the site.</p>
<p>The first step is using the rails command to generate a new application, then install and setup up authlogic.</p>
<pre>$ cd into-a-directory
$ rails unobtrusive-login
</pre>
<p>Add authlogic.</p>
<pre># /config/environment.rb
config.gem 'authlogic'
</pre>
<p>Now install the gems.</p>
<pre>$ sudo gem install gemcutter
$ sudo gem tumble
$ sudo rake gems:install
</pre>
<p>Next create a user model and add the required authlogic columns to the migration.</p>
<pre>$ ./script/generate model User
exists  app/models/
exists  test/unit/
exists  test/fixtures/
create  app/models/user.rb
create  test/unit/user_test.rb
create  test/fixtures/users.yml
create  db/migrate
create  db/migrate/20100102082657_create_users.rb
</pre>
<p>Now, add the columns to the new migration.</p>
<pre>class CreateUsers &lt; ActiveRecord::Migration
  def self.up
    create_table :users do |t|
      t.string    :login,               :null =&gt; false
      t.string    :crypted_password,    :null =&gt; false
      t.string    :password_salt,       :null =&gt; false
      t.string    :persistence_token,   :null =&gt; false
      t.timestamps
    end
  end

  def self.down
    drop_table :users
  end
end
</pre>
<p>Migrate the database.</p>
<pre>$ rake db:migrate
</pre>
<p>Include authlogic in the user model.</p>
<pre># /app/models/user.rb
class User &lt; ActiveRecord::Base
  acts_as_authentic
end
</pre>
<p>Now we can create a user. Since this is a demo app, web based functionality for signing up isn’t required. So open up the console and create a user:</p>
<pre>$ ./script/console
&gt;&gt; me = User.create(:login =&gt; 'Adman65', :password =&gt; 'nettuts', :password_confirmation =&gt; 'nettuts')
</pre>
<p>Now we have a user in the system, but we have no way to login or logout. We need to create the models, controllers, and views for this. Authlogic has its own class for tracking logins. We can use the generator for that:</p>
<pre># create the user session
$ ./script/generate UserSession
</pre>
<p>Next we need to generate the controller that will login/logout users. You can create sessions just like any other resource in Rails.</p>
<pre># create the session controller
$ ./script/generate controller UserSessions
</pre>
<p>Now set its contents to:</p>
<pre># /app/controllers/user_sessions_controller.rb
class UserSessionsController &lt; ApplicationController
  def new
    @user_session = UserSession.new
  end

  def create
    @user_session = UserSession.new(params[:user_session])
    if @user_session.save
      flash[:notice] = "Login successful!"
      redirect_back_or_default user_path
    else
      render :action =&gt; :new
    end
  end
end
</pre>
<p>It looks exactly the same as a controller that was generated via scaffolding. Now create the users controller which has public and private content. Generate a users controller. Inside the controller we’ll use a before filter to limit access to the private areas. The index action is public and show is private.</p>
<pre># create the users controller
$ ./script/generate controller users
</pre>
<p>Update its contents:</p>
<pre># /app/controllers/users_controller.rb
class UsersController &lt; ApplicationController
  before_filter :login_required, <img class="wp-smiley" src="http://net.tutsplus.cdn.plus.org/wp-includes/images/smilies/icon_surprised.gif" alt=":o" /> nly =&gt; :show

  def index
  end

  def show
    @user = current_user
  end

  private
  def login_required
    unless current_user
      flash[:error] = 'You must be logged in to view this page.'
      redirect_to new_user_session_path
    end
  end
end
</pre>
<p>You should notice that current_user is an undefined method at this point. Define these methods in ApplicationController. Open up application_controller.rb and update its contents:</p>
<pre># application controller
class ApplicationController &lt; ActionController::Base
  helper :all # include all helpers, all the time
  protect_from_forgery # See ActionController::RequestForgeryProtection for details

  # From authlogic
  filter_parameter_logging :password, :password_confirmation
  helper_method :current_user_session, :current_user

  private
  def current_user_session
    @current_user_session ||= UserSession.find
  end

  def current_user
    @current_user ||= current_user_session &amp;&amp; current_user_session.user
  end
end
</pre>
<p>At this point the models and controllers are complete, but views aren’t. We need to create views for a login form and the public and private content. We’ll use the nifty-generators gem to create a basic layout.</p>
<pre>$ sudo gem install nifty-generators
$ ./script/generate nifty_layout
</pre>
<p>Time to create the login form. We’re going to use a partial for this because in the future we’ll use the partial to render just the login form in the modal box. Here’s the code to create the login form. It’s exactly the same as if you were creating a blog post or any other model.</p>
<pre># create the login views
# /app/views/user_sessions/_form.html.erb
&lt;% form_for(@user_session, :url =&gt; user_session_path) do |form| %&gt;
  &lt;%= form.error_messages %&gt;

  &lt;p&gt;
    &lt;%= form.label :login %&gt;
    &lt;%= form.text_field :login %&gt;
  &lt;/p&gt;

  &lt;p&gt;
    &lt;%= form.label :password %&gt;
    &lt;%= form.password_field :password %&gt;
  &lt;/p&gt;

  &lt;%= form.submit 'Login' %&gt;
&lt;% end %&gt;
</pre>
<p>Render the partial in the new view:</p>
<pre># /app/views/user_sessions/new.html.erb
&lt;% title 'Login Please' %&gt;
&lt;%= render :partial =&gt; 'form' %&gt;
</pre>
<p>Create some basic pages for the public and private content. The index action shows public content and show displays private content.</p>
<pre># create the dummy public page
# /app/views/users/index.html.erb
&lt;% title 'Unobtrusive Login' %&gt;

&lt;p&gt;Public Facing Content&lt;/p&gt;

&lt;%= link_to 'Login', new_user_session_path %&gt;
</pre>
<p>And for the private page:</p>
<pre># create the dummy private page
# /app/views/users/show.html.erb
&lt;% title 'Welcome' %&gt;
&lt;h2&gt;Hello &lt;%=h @user.login %&gt;&lt;/h2&gt;

&lt;%= link_to 'Logout', user_session_path, :method =&gt; :delete %&gt;
</pre>
<p>Delete the file /public/index.html and start the server. You can now log in and logout of the application.</p>
<pre>$ ./script/server
</pre>
<p>Here are some screenshots of the demo application. The first one is the public page.</p>
<div><img id="publicpage" src="http://nettuts.s3.cdn.plus.org/568_login/login1.png" alt="Public Page" /></div>
<p>Now the login form</p>
<div><img id="loginpage" src="http://nettuts.s3.cdn.plus.org/568_login/login2.png" alt="Login Page" /></div>
<p>And the private page</p>
<div><img id="privatepage" src="http://nettuts.s3.cdn.plus.org/568_login/login3.png" alt="Private Page" /></div>
<p>And finally, access denied when you try to visit http://localhost:3000/user</p>
<div><img id="accessdenied" src="http://nettuts.s3.cdn.plus.org/568_login/login4.png" alt="Access Denied" /></div>
<h3>The AJAX Login Process</h3>
<p>Before continuing, we need to understand how the server and browser are going to work together to complete this process. We know that we’ll need to use some JavaScript for the modal box and the server to validate logins. Let’s be clear on how this is going to work. The user clicks the login link, then a modal box appears with the login form. The user fills in the form and is either redirected to the private page, or the modal box is refreshed with a new login form. The next question is how do you refresh the modal box or tell the browser what to do after the user submits the form? Rails has respond_to blocks. With respond_to, you can tell the controller to render different content if the user requested XML, HTML, JavaScript, YAML etc. So when the user submits the form, the server can return some JavaScript to execute in the browser. We’ll use this render a new form or a redirect. Before diving any deeper, let’s go over the process in order.</p>
<ol>
<li>User goes to the public page</li>
<li>User clicks the login link</li>
<li>Modal box appears</li>
<li>User fills in the form</li>
<li>Form is submitted to the server</li>
<li>Server returns JavaScript for execution</li>
<li>Browser executes the JavaScript which either redirects or updates the modal box.</li>
</ol>
<p>That’s the high level. Here’s the low level implementation.</p>
<ol>
<li>User visits the public page</li>
<li>The public page has some JavaScript that runs when the DOM is ready that attaches JavaScript to the login link. That javscript does an XMLHTTPRequest (XHR from now on) to the server for some JavaScript. The JavaScript sets the modal box’s content to the form HTML. The JavaScript also does something very important. It binds the form’s submit action to an XHR with POST data to the form’s action. This allows the user to keep filling the login form in inside the modal box.</li>
<li>Modal box now has the form and required JavaScript</li>
<li>User clicks ‘Login’</li>
<li>The submit() function is called which does a POST XHR to the form’s action with its data.</li>
<li>Server either generates the JavaScript for the form or the redirect</li>
<li>Browser receives the JavaScript and executes it. The browser will either update the modal box, or redirect the user through window.location.</li>
</ol>
<h2>Taking a Peak at the AJAX Ready Controller</h2>
<p>Let’s take a look at the new structure for the UserSessions controller.</p>
<pre>class UserSessionsController &lt; ApplicationController
  layout :choose_layout

  def new
    @user_session = UserSession.new
  end

  def create
    @user_session = UserSession.new(params[:user_session])

    if @user_session.save
      respond_to do |wants|
        wants.html { redirect_to user_path(@user_session.user) }
        wants.js { render :action =&gt; :redirect } # JavaScript to do the redirect
      end
    else
      respond_to do |wants|
        wants.html { render :new }
        wants.js # defaults to create.js.erb
      end
    end
  end

  private
  def choose_layout
    (request.xhr?) ? nil : 'application'
  end
end
</pre>
<p>As you can see the structure is different. Inside the if save, else conditional, respond_to is used to render the correct content. want.xx where xx is a content type. By default Prototype and jQuery request text/JavaScript. This corresponds to wants.js. We’re about ready to get started on the AJAX part. We won’t use any plugins except ones for modal boxes. We’ll use Facebox for jQuery and ModalBox for Prototype.</p>
<h3>Prototype</h3>
<p>Rails has built in support for Prototype. The Rail’s JavaScript helpers are Ruby functions that generate JavaScript that use Prototype. This technique is known as RJS (Ruby JavaScript). One example is remote_form_for which works like the standard for_for adds some JS bound to onsubmit that submits to the form to its action using its method with its data. I won’t use RJS in this article since I want to demonstrate vanilla JS. I think by using pure JS and eliminating the JS helpers the article will be more approachable by less experienced developers. That being said, you could easily accomplish these steps using RJS/Prototype helpers if you choose.</p>
<p>Adding Prototype to the application is very easy. When you use the rails command, it creates the Prototype and scriptaculous files in /public/JavaScripts. Including them is easy. Open up /app/views/layouts/application.erb and add this line inside the head tag:</p>
<pre>&lt;%= JavaScript_include_tag :defaults %&gt;
</pre>
<p>JavaScript_include_tag creates script tags for default files in /public/JavaScripts, most importantly prototype.js, effects.js, and application.js. effects.js is scriptaculous. application.js is a file you can use to keep application specific JS. Now we need a modal box plugin. We’re going to use <a href="http://okonet.ru/projects/modalbox/">this</a>. Its a very nice modal box plugin inspired by OSX. The source is hosted on GitHub, so you’ll have to clone and move the files in your project directory. For example:</p>
<pre>$ cd code
$ git clone git://github.com/okonet/modalbox.git
$ cd modalbox
# move the files in the correct directories.
# move modalbox.css into /public/stylesheets
# move modalbox.js into /public/JavaScripts
# move spinner.gif into /public/images
</pre>
<p>Now include the stylesheets and JavaScript in your application.</p>
<pre>  &lt;%= stylesheet_link_tag ‘application’ %&gt;
  &lt;%= stylesheet_link_tag ‘modalbox’ %&gt;
  &lt;%= JavaScript_include_tag :defaults %&gt;
  &lt;%= JavaScript_include_tag ‘modalbox’%&gt;</pre>
<p>Now let’s get our login link to open a modalbox. In order to do this we need to add some JavaScript that runs when the DOM is ready that attaches the modalbox to our link. When the user clicks the login link, the browser will do a GET to /user_sessions/new which contains the login form. The login link uses the #login-link selector. Update the login link to use the new id in /app/views/users/index.html.erb. Modify the link_to function like this:</p>
<pre>&lt;%= link_to 'Login', new_user_session_path, :id =&gt; 'login-link' %&gt;
</pre>
<p>That gives us a#login-link. Now for the JavaScript to attach a modalbox. Add this JS in /public/JavaScripts/application.js</p>
<pre>document.observe('dom:loaded', function() {
    $('login-link').observe('click', function(event) {
        event.stop();
        Modalbox.show(this.href,
            {title: 'Login',
            width: 500}
        );
    });
})
</pre>
<p>There’s some simple JS for when the user clicks the link a modal box opens up with the link’s href. Refer to the modalbox documentation if you’d like more customization. Here’s a screenshot:</p>
<div><img id="initialmodalbox" src="http://nettuts.s3.cdn.plus.org/568_login/prototype/step1.png" alt="Initial Modalbox" /></div>
<p>Notice that inside the modal box looks very similar to our standard page. Rails is using our application layout for all HTML responses. Since our XHR’s want HTML fragments, it make sense to render without layouts. Refer back to the example controller. I introduced a method for determining the layout. Add that to UserSessionsController to disable layout for XHR’s.</p>
<pre>class UserSessionsController &lt; ApplicationController
  layout :choose_layout

  def new
    @user_session = UserSession.new
  end

  def create
    @user_session = UserSession.new(params[:user_session])
    if @user_session.save
      flash[:notice] = "Login successful!"
      redirect_to user_path
    else
      render :action =&gt; :new
    end
  end

  def destroy
    current_user_session.destroy
    flash[:notice] = "Logout successful!"
    redirect_to root_path
  end

  private
  def choose_layout
    (request.xhr?) ? nil : 'application'
  end
end
</pre>
<p>Refresh the page and click the link you should get something like this:</p>
<div><img id="withoutlayout" src="http://nettuts.s3.cdn.plus.org/568_login/prototype/step1-1.png" alt="Without Layout" /></div>
<p>Fill in the form and see what happens. If you fill in the from with bad info, you’re redirected outside the modal box. If you login correctly you’re redirected normally. According the requirements the user should be able to fill out the form over and over again inside the modal box until they login correctly. How can we accomplish this? As described before we need to use AJAX to submit data to the server, then use JavaScript to update the modal box with the form or do a redirection. We know that the modalbox does a GET for HTML. After displaying the initial modalbox, we need to write JS that makes the form submits itself AJAX style. This allows the form to submit itself inside the modal box. Simply adding this code after the modal box is called won’t work because the XHR might not have finished. We need to use Modalbox’s afterLoad callback. Here’s the new code:</p>
<pre>document.observe('dom:loaded', function() {
    $('login-link').observe('click', function(event) {
        event.stop();
        Modalbox.show(this.href,
            {title: 'Login',
            width: 500,
            afterLoad: function() {
                $('new_user_session').observe('submit', function(event) {
                    event.stop();
                    this.request();
                })
            }}
        );
    });
})
</pre>
<p>Form#request is a convenience method for serializing and submitting the form via an Ajax.Request to the URL of the form’s action attribute—which is exactly what we want. Now you can fill in the form inside the modal without it closing. The client side is now complete. What about the server side? The client is submitting a POST wanting JS back. The server needs to decide to either return JavaScript to update the form or render a redirect. In the UserSessionsController we’ll use respond_to to handle the JS request and a conditional to return the correct JS. Let’s begin by handling the failed login case. The server needs to return JS that updates the form, and tells the new form to submit over ajax. We’ll place this template in /app/views/users_sessions/create.js.erb. Here’s the structure for the new create action:</p>
<pre>def create
  @user_session = UserSession.new(params[:user_session])
  if @user_session.save
    flash[:notice] = "Login successful!"
    redirect_to user_path
  else
    respond_to do |wants|
      wants.html { render :new }
      wants.js # create.js.erb
    end
  end
end
</pre>
<p>Now let’s fill in create.js.erb:</p>
<pre>$('MB_content').update("&lt;%= escape_JavaScript(render :partial =&gt; 'form') %&gt;");
Modalbox.resizeToContent();
$('new_user_session').observe('submit', function(event) {
    event.stop();
    this.request();
});
</pre>
<p>First we update the content to include the new form. Then we resize the modal box. Next we ajaxify the form just as before. Voilla, you can fill in the form as many times as you want.</p>
<div><img id="badinfo" src="http://nettuts.s3.cdn.plus.org/568_login/prototype/step2.png" alt="Bad Info" /></div>
<div><img id="updatedform" src="http://nettuts.s3.cdn.plus.org/568_login/prototype/step2-1.png" alt="Updated Form" /></div>
<p>Next we need to handle the redirection case. Create a new file in /app/views/users_sessions/redirect.js.erb:</p>
<pre>  window.location=”&lt;%= user_path %&gt;”;
</pre>
<p>Now, update the create action to handle the redirection process:</p>
<pre>def create
  @user_session = UserSession.new(params[:user_session])
  if @user_session.save
    respond_to do |wants|
      wants.html do
        flash[:notice] = "Login successful!"
        redirect_to user_path
      end

      wants.js { render :redirect }
    end
  else
    respond_to do |wants|
      wants.html { render :new }
      wants.js # create.js.erb
    end
  end
end
</pre>
<p>And that’s it! Now try login with correct credentials and you’re redirected to the private page. For further learning, try to add a spinner and notification telling the user the form is submitting or they’re being redirect. The application still works if the user has JavaScript disabled too.</p>
<h1>jQuery</h1>
<p>Since I’ve already covered the Prototype process, so I won’t go into the same detail as before. Instead, I will move quickly describing the alternate JavaScript to add to the application. The jQuery vesion will have the exact same structure as the Prototype version. All we need to change is what’s in application.js, create.js.erb, and the JavaScript/css includes.</p>
<p>First thing we need to do is download <a href="http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js">jQuery</a> and <a href="http://famspam.com/facebox/releases/facebox-1.2.tar.gz">Facebox</a>. Move jQuery into /public/JavaScripts as jquery.js. For facebox move the images into /public/images/, stylesheets into /public/stylesheets, and finally the JS into /public/JavaScripts. Now update /app/views/layouts/application.html.erb to reflect the changes:</p>
<pre>&lt;head&gt;
  &lt;title&gt;&lt;%= h(yield(:title) || "Untitled") %&gt;&lt;/title&gt;
  &lt;%= stylesheet_link_tag 'facebox' %&gt;
  &lt;%= stylesheet_link_tag 'application' %&gt;
  &lt;%= JavaScript_include_tag 'jquery' %&gt;
  &lt;%= JavaScript_include_tag 'facebox' %&gt;
  &lt;%= JavaScript_include_tag 'application' %&gt;
&lt;/head&gt;
</pre>
<p>Facebox comes with a default stylesheet which assumes you have your images in /facebox. You’ll need to update these selectors in facebox.css like so:</p>
<pre>#facebox .b {
  background:url(/images/b.png);
}

#facebox .tl {
  background:url(/images/tl.png);
}

#facebox .tr {
  background:url(/images/tr.png);
}

#facebox .bl {
  background:url(/images/bl.png);
}

#facebox .br {
  background:url(/images/br.png);
}
</pre>
<p>Now we attach facebox to the login link. Open up /public/JavaScripts/application.js and use this:</p>
<pre>$(document).ready(function() {
    $('#login-link').facebox({
        loadingImage : '/images/loading.gif',
    closeImage   : '/images/closelabel.gif',
    });
});
</pre>
<p>I override the default settings for the images to reflect the new image path. Start the sever and head over to the index page. You should see a nice facebox with the login form:</p>
<div><img id="facebox" src="http://nettuts.s3.cdn.plus.org/568_login/jquery/step1.png" alt="Facebox" /></div>
<p>Next thing we have to do is set the form to submit itself via AJAX. Just like before, we’ll have to use callbacks to execute code after the modal box is ready. We’ll use jQuery’s post method for the XHR request. Facebox has an after reveal hook we can use. application.js:</p>
<pre>$(document).ready(function() {
    $('#login-link').facebox({
        loadingImage : '/images/loading.gif',
        closeImage   : '/images/closelabel.gif',
    });

    $(document).bind('reveal.facebox', function() {
        $('#new_user_session').submit(function() {
            $.post(this.action, $(this).serialize(), null, "script");
            return false;
        });
    });
});
</pre>
<p>Updating create.js.erb should be easy enough. We have to update the facebox’s contents and re-ajaxify the form. Here’s the code:</p>
<pre>$('#facebox .content').html("&lt;%= escape_JavaScript(render :partial =&gt; 'form') %&gt;");
$('#new_user_session').submit(function() {
    $.post(this.action, $(this).serialize(), null, "script");
    return false;
});
</pre>
<p>And that’s it! Here’s the final product:</p>
<div><img id="loggingin" src="http://nettuts.s3.cdn.plus.org/568_login/jquery/step2.png" alt="Logging In" /></div>
<div><img id="badlogin" src="http://nettuts.s3.cdn.plus.org/568_login/jquery/step2-1.png" alt="Bad Login" /></div>
<div><img id="redirected" src="http://nettuts.s3.cdn.plus.org/568_login/jquery/step2-2.png" alt="Redirected" /></div>
<p><img src="http://feeds.feedburner.com/~r/nettuts/~4/snw0jxkP2Kk" alt="" width="1" height="1" /></p>

	Tags: <a href="http://xguiden.dk/tag/ajax/" title="AJAX" rel="tag">AJAX</a>, <a href="http://xguiden.dk/tag/cd/" title="CD" rel="tag">CD</a>, <a href="http://xguiden.dk/tag/css/" title="CSS" rel="tag">CSS</a>, <a href="http://xguiden.dk/tag/database/" title="database" rel="tag">database</a>, <a href="http://xguiden.dk/tag/fil/" title="fil" rel="tag">fil</a>, <a href="http://xguiden.dk/tag/fix/" title="fix" rel="tag">fix</a>, <a href="http://xguiden.dk/tag/flash/" title="Flash" rel="tag">Flash</a>, <a href="http://xguiden.dk/tag/get/" title="GET" rel="tag">GET</a>, <a href="http://xguiden.dk/tag/guide/" title="guide" rel="tag">guide</a>, <a href="http://xguiden.dk/tag/help/" title="help" rel="tag">help</a>, <a href="http://xguiden.dk/tag/html/" title="HTML" rel="tag">HTML</a>, <a href="http://xguiden.dk/tag/image/" title="image" rel="tag">image</a>, <a href="http://xguiden.dk/tag/images/" title="images" rel="tag">images</a>, <a href="http://xguiden.dk/tag/ip/" title="IP" rel="tag">IP</a>, <a href="http://xguiden.dk/tag/java/" title="Java" rel="tag">Java</a>, <a href="http://xguiden.dk/tag/javascript/" title="JavaScript" rel="tag">JavaScript</a>, <a href="http://xguiden.dk/tag/login/" title="login" rel="tag">login</a>, <a href="http://xguiden.dk/tag/lp/" title="LP" rel="tag">LP</a>, <a href="http://xguiden.dk/tag/mod/" title="Mod" rel="tag">Mod</a>, <a href="http://xguiden.dk/tag/osx/" title="OSX" rel="tag">OSX</a>, <a href="http://xguiden.dk/tag/over/" title="Over" rel="tag">Over</a>, <a href="http://xguiden.dk/tag/png/" title="png" rel="tag">png</a>, <a href="http://xguiden.dk/tag/post/" title="POST" rel="tag">POST</a>, <a href="http://xguiden.dk/tag/script/" title="script" rel="tag">script</a>, <a href="http://xguiden.dk/tag/server/" title="Server" rel="tag">Server</a>, <a href="http://xguiden.dk/tag/session/" title="Session" rel="tag">Session</a>, <a href="http://xguiden.dk/tag/source/" title="Source" rel="tag">Source</a>, <a href="http://xguiden.dk/tag/standard/" title="standard" rel="tag">standard</a>, <a href="http://xguiden.dk/tag/start/" title="Start" rel="tag">Start</a>, <a href="http://xguiden.dk/tag/sten/" title="Sten" rel="tag">Sten</a>, <a href="http://xguiden.dk/tag/system/" title="system" rel="tag">system</a>, <a href="http://xguiden.dk/tag/table/" title="table" rel="tag">table</a>, <a href="http://xguiden.dk/tag/tag/" title="tag" rel="tag">tag</a>, <a href="http://xguiden.dk/tag/tags/" title="tags" rel="tag">tags</a>, <a href="http://xguiden.dk/tag/text/" title="text" rel="tag">text</a>, <a href="http://xguiden.dk/tag/url/" title="URL" rel="tag">URL</a>, <a href="http://xguiden.dk/tag/valid/" title="valid" rel="tag">valid</a><br />

	<h4>Related posts</h4>
	<ul class="st-related-posts">
	<li><a href="http://xguiden.dk/2010/02/15/how-to-code-up-a-web-design-from-psd-to-html/" title="How to Code up a Web Design from PSD to HTML (15/02/2010)">How to Code up a Web Design from PSD to HTML</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/02/13/ajax-enabled-sticky-notes-with-php-and-jquery/" title="AJAX-enabled Sticky Notes With PHP and jQuery (13/02/2010)">AJAX-enabled Sticky Notes With PHP and jQuery</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/02/13/jquery-ajax-validation-contact-form-with-modal-slide-in-transition/" title="jQuery AJAX Validation Contact Form with Modal + Slide-in Transition (13/02/2010)">jQuery AJAX Validation Contact Form with Modal + Slide-in Transition</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/02/13/protect-your-flash-files-from-decompilers-by-using-encryption/" title="Protect Your Flash Files From Decompilers by Using Encryption (13/02/2010)">Protect Your Flash Files From Decompilers by Using Encryption</a> (0)</li>
	<li><a href="http://xguiden.dk/2010/02/25/php-and-mysql-file-download-counter/" title="PHP and MySQL File Download Counter (25/02/2010)">PHP and MySQL File Download Counter</a> (0)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://xguiden.dk/2010/02/16/how-to-build-an-unobtrusive-login-system-in-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
