Sunteți pe pagina 1din 139

10 Tips for developing with jQuery in Notepad++

SEP05 20116 COMMENTSWRITTEN BY JQUERY4U

Notepad++ had always been my favourite free editor for coding with JavaScript ever since I can remember. Here are some tips I have picked up while developing with Notepad++.

1. Quick compare code using Notepad++


This feature is great for finding out quickly what code changes have occurred between files. First open the two files next to each other in the Notepad++ Editor (or copy and paste into a new file for quick compare). Then with the first file selected press ALT+D or click from the menu Plugins > Compare > Compare

If the files match you will get a popup saying Files Match. Otherwise if the differences appear in a right hand pane highlighted so you can easily double click these to view the code.

Then to get rid of the compare window press CTRL+ALT+D or click from the menu Plugins > Compare > Clear Results You can also view horizontally if you prefer! Simple right click on the divider column and click

2. Useful keyboard shortcuts in Notepad++


Just a few quick keyboard shortcuts that I use when developing.

1. F11 Switch code to full screen without top menus. To switch back simply press F11 again. F12 does the same thing but not in full screen. 2. CTRL+D quick copy paste current line to line below. 3. CTRL+Q Quickly comment out lines of jQuery code. Press CTRL+Q again to uncomment. 4. SHIFT + right arrow Quick select characters. 5. CTRL + SHIFT + right arrow Quick select words. 6. Triple left click Quick select whole line. 7. CTRL+A Quick select whole document. 8. ALT+F2 Quick Google search. 9. ALT+0 Quick collape all code into blocks. To unfold code blocks press SHIFT+ALT+0

More Keyboard Shortcuts

3. Useful free plugins for Notepad++


There are heaps of free Notepad++ plugins available that do awesome things from simple spell checkers and color pickers to FTP synchs and Directory Searches. Here are some of my favs:

TextFX Lots of very useful features such as code cleanup, neaten, minify etc. One of the first, one of the best.

Multi Clipboard MultiClipboard plugin implements multiple (10) text buffers that is filled up via copying and/or cutting of text.

Switched Simply switch between any associated files, which is extremely useful if you have some of your excerpts set up with hot keys.

Colorpicker This plugin can decode the colour of a pixel on a palette and paste its RGB into the editor.

SearchInFiles Allows a user to find files that have a lot of excessive information piled deep within the code itself.

To install the plugins simply download the .dll files and extract them into the folderApp\Notepad++\plugins.

Wiki Directory of Notepad++ Plugins Sourceforge Download List

4. Minify your code using Notepad++


Pretty useful feature to quickly minify your jQuery code. Simply do the following:

Edit > Blank Operations > Trim Header and Trailing Space Edit > Blank Operations > Remove Unnecessary Blank and EOL

Also see: Other ways to minify/hide your JavaScript code.

5. Neat up your code using Notepad++

Previously I have posted on how to making your jQuery code pretty using Notepad++. Simple select from the main menu TextFX > TextFX Edit > Reindent C++ Code.

However, I have found an awesome online tool called Javascript unpacker and beautifier. This tool actually makes your JS source code look nice and pretty and was worth a mention.

6. TortoiseSVN plugin for Notepad++

Make sure TortoiseSVN is installed and youve installed the latest version of Notepad++. The plugin comes in the form of a zipped, dll. Simply unzip the dll and place it in the Notepad++ plugins directory. For a typical install, it will be located here: C:\Program Files\Notepad++\plugins. Next time you launch Notepad++, the plugin will automatically be loaded. The plugin should work under Windows XP, Vista, and 7. Both 32 bit and 64 bit operating systems are supported. If you find any bugs on these systems or others, drop a comment and Ill see if I can address them. Ive noticed that sometimes Notepad++s auto-updater thinks the plugin needs to be updated. This usually results in a new version being overwritten by version 1.0. If you update to 1.1 or 1.2, do not use Notepad++s auto-update feature when it prompts you for this plugin.

Download

7. The Notepad++ Wiki

Stuck on something technical in Notepad++? Dont stress out just visit the Notepad++ wiki and there might be something on there to help solve your problem.

Notepad++ Wiki

8. Set language to JavaScript in Notepad++


Dont forget to change the language your coding in so that the built in Syntax highlighter can work its magic!

9. Delete Line Numbers


Sometimes when copying code from other websites we end up with stupid line numbers and have to manually remove them in order to use the code. Notepad++ to the rescue! TextFX > TextFX Tools > Delete Line Numbers or First word

10. Word Wrap


Useful if you like coding with all of your code visible on screen and hate scrollbars (i know i do!). Simply click the word wrap button or select from the main menu View > Word Wrap.

11. Quick Copy Filename, Filepath

Just one more tip which is a huge time saver. Right click on file header (tab) > click full filepath to clipboard

Conclusion
Thats it! Hope you have learnt something new with Notepad++ to assist with your future jQuery developments. If you know of any more that I have missed please post a comment.

Get Notepad++ for Free

Solutions to Common jQuery Errors


SEP22

2011 4 COMMENTSWRITTEN BY JQUERY4U

Lets face it, nobody is perfect! Everyone makes mistakes now and then and jQuery is the same although they have an excellent bug fixing team who are fixing up errors and enhancing jQuery around the clock errors may appear from time to time. In light of this and the fact that Ive been developing with jQuery for quite a while now and every now and then an error will show in the Firebug Console and I have to Google it. I thought I would share some of the most common errors so that when you encounter them you might have some idea of how to solve the puzzle.

Error: jquery.1.4.2.js error a is null"

Possible Causes
double click code to edit/copy

1 2 3

a is null [Break On This Error] a))();else c.error("Invalid JSON: "+a)...(d)if(i)for(f in a){if(b.apply(a[f], jquery....min.js (line 29)

I was thinking it might have something to do with this line failing because there was no matches.
double click code to edit/copy

$.each(rawData.match(secureQueryRegex), function(index, currentQuery)

Then, I was thinking it may have been the size of data as it was 69,443 characters long

Possible Solutions
But I eventually found out it was bad characters inside the data string (which was grabbed directly from HTML). See cleanHTML() function to remove bad characters form HTML.
double click code to edit/copy

rawData =

rawData.replace(/[^<>a-zA-Z 0-9]+/g,'');

/* clean up for match() statement */

Specific Versions
Seen in 1.4.2

Error: SyntaxError: invalid object initializer

Possible Causes
Object declaration syntax error.
double click code to edit/copy

1 2 3 4
OR

$.getScript( { 'http://www.domain.com/js/preview.js' });

double click code to edit/copy

1 2 3

$("div").css( { padding:'0',

4 5
});

margin,'4px'

Possible Solutions
Remove the brackets the getScript() function can be called with just the url. The same applies to any other object declaration or function call with an object that doesnt accept one.
double click code to edit/copy

$.getScript('http://www.domain.com/js/preview.js');

Change the comma to a semi colon.


double click code to edit/copy

1 2 3 4 5 6

$("div").css( $("div").css( { padding: '0', margin: '4px' });

Specific Versions
Seen in 1.4.2

Error: uncaught exception: Syntax error, unrecognized expression: [object HTMLLIElement]

Possible Causes
This seems like a jQuery selector error. It seems to appear more frequently in v1.4.2 or earlier so try updating to the latest version of jQuery.

double click code to edit/copy

$(this+' a').css(

double click code to edit/copy

var req = $("input[@name=required]").val();

Possible Solutions
Not sure but take a look at your selectors and make sure they work properly. Try including the full jQuery versions first to get better error info on what might be causing the problem. @ is old selector syntax.
double click code to edit/copy

var req = $("input[name=required]").val();

Specific Versions
Seen in 1.4.2

Error: SyntaxError: missing ) after argument list

Possible Causes
Missing off closing brackets or curly braces.
double click code to edit/copy

})(jQuery

Possible Solutions
double click code to edit/copy

})(jQuery);

Specific Versions
Seen in 1.4.2

Error: SyntaxError: missing : after property id

Possible Causes
This is a repeat of the object initialize error but its caused by Using curly brackets when they are not needed.
double click code to edit/copy

1
$.getScript(

2 3 4 5 6 7

{ 'http://www.domain.com/js/preview.js', function(data, textStatus){ console.log(data); //data returned console.log(textStatus); //success console.log('Load was performed.'); });

Possible Solutions
double click code to edit/copy

1
$.getScript('http://www.domain.com/js/preview.js', function(data, textStatus)

2 3 4 5 6 7
);

{ console.log(data); //data returned console.log(textStatus); //success console.log('Load was performed.'); }

Specific Versions
Seen in 1.4.2

Error: TypeError: jsSrcRegex.exec(v) is null


Possible Causes
Caused by double exec on same regex OR caused by invalid html jsSrcRegex.exec(v) is null.
double click code to edit/copy

1 2

console.log(jsSrcRegex.exec(v)); console.log(jsSrcRegex.exec(v)[1]);

Possible Solutions
Check the html first:
double click code to edit/copy

1 2 3
OR

if(jsSrcRegex.exec(html)){ console.dir(jsSrcRegex.exec(html)[1]); }

Use recompile the regex:


double click code to edit/copy

1 2 3

console.log(jsSrcRegex.exec(v)); jsSrcRegex.compile(); console.log(jsSrcRegex.exec(v)[1]);

Specific Versions
n/a

Error: XML descendants internal method called on incompatiable object

Possible Causes
Double full stop in jQuery chain commands.
double click code to edit/copy

$('.'+inElem)..removeClass('mouseover').addClass('selected');

Possible Solutions
To fix simply remove the double full stop.

Specific Versions
n/a

Error: undetermined string literal


You may have seen this one before! :)

Possible Causes
Many possible causes: could be that you put code where a selector should be or multiple line strings or wrong string format (bad characters) or angle brackets etc.

Possible Solutions
See jQuery Undetermined String Literal Error for a very detailed explanation on this error!

Specific Versions
n/a

Error: Syntax Error: Unrecognized Expression

Possible Causes
Missing attribute name in selector.
double click code to edit/copy

$('input["depDate"]').val(departureDate);

Possible Solutions
Add in the name attribute (or id, class etc) into the selector.
double click code to edit/copy

$('input[name="depDate"]').val(departureDate);

Specific Versions
n/a

Error: SyntaxError: syntax error

(click image to enlarge)

Possible Causes
Well, this error is very generic and there might be a number of reasons why is happens but in this example you can clearly see it was caused by an extra + in the jQuery selector.
double click code to edit/copy

$('.itemColumn'+currentColNum+).append(v);

Possible Solutions
Unfortunately, on this one youve just got to carefully check through your syntax and make sure you dont have any mistakes. Try using something like jshint or another js checker to assist.
double click code to edit/copy

$('.itemColumn'+currentColNum).append(v);

Specific Versions
n/a

Error: (d || ).split is not a function

Possible Causes
Sorry, I found this error and took a screenshot but cant remember how i got it! I think it might be a live image hover bug in jQuery 1.4.2 but not sure. Here is something bug 862 similar which i found (it was logged 5 years ago aha). Sometimes you see a similar error which reads jquery error d is undefined or such which I saw a few times in jQuery 1.5.

Possible Solutions
Update to latest version of jQuery.

Specific Versions
Seen in 1.4.2

After seeing all those errors, heres something to cheer you up!

Or you can see more errors and bugs on the Official jQuery Bug Tracker.

If you find any errors please leave a comment with the error and solution and i will add it to the list! Cheers!

10 JavaScript Shorthand Coding Techniques


JUL20 201112 COMMENTSWRITTEN BY JQUERY4U

This really is a must read for any JavaScript based developer. I have made this post as a vital source of reference for learning shorthand JavaScript coding techniques. I have shown you the longhanded versions as well to give some coding perspective.

Step 1 Learn the JavaScript shorthand techniques. Step 2 Save valuable coding time by keeping your code to a minimum. Step 3 Impress your colleagues with your awesome coding skills.

Its as easy as steps 1,2,3. Here they are.

1. If true else Shorthand


This is a great code saver for when you want to do something if the test is true, else do something else by using the ternary operator.

Longhand:
double click code to edit/copy

var big; if (x > 10) {

2 3 4 5 6 7

big = true; } else { big = false; }

Shorthand:
double click code to edit/copy

var big = (x > 10) ? true : false;

If you rely on some of the weak typing characteristics of JavaScript, this can also achieve more concise code. For example, you could reduce the preceding code fragment to this:
double click code to edit/copy

1 2 3 4 5 6

var big = (x > 10); //further nested example x = 3; var big = (x > 10) ? "greater 10" : (x < 5) ? "less 5" : "between 5 and 10"; console.log(big); //"less 5"

2. Null, Undefined, Empty Checks Shorthand


When creating new variables sometimes you want to check if the variable your referencing for its value isnt null or undefined. I would say this is a very common check for JavaScript coders. Longhand:
double click code to edit/copy

1 2 3

if (variable1 !== null || variable1 !== undefined || variable1 !== '') { var variable2 = variable1; }

Shorthand:
double click code to edit/copy

var variable2 = variable1

|| '';

Dont believe me? Test it yourself (paste into Firebug and click run):
double click code to edit/copy

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

//null value example var variable1 = null; var variable2 = variable1 || ''; console.log(variable2); //output: '' (an empty string) //undefined value example var variable1 = undefined; var variable2 = variable1 || ''; console.log(variable2); //output: '' (an empty string) //normal value example var variable1 = 'hi there'; var variable2 = variable1 || ''; console.log(variable2); //output: 'hi there'

3. Object Array Notation Shorthand


Useful way of declaring small arrays on one line. Longhand:
double click code to edit/copy

1 2 3 4

var a = new Array(); a[0] = "myString1"; a[1] = "myString2"; a[2] = "myString3";

Shorthand:
double click code to edit/copy

var a = ["myString1", "myString2", "myString3"];

4. Associative Array Notation Shorthand

The old school way of setting up an array was to create a named array and then add each named element one by one. A quicker and more readable way is to add the elements at the same time using the object literal notation. Longhand:
double click code to edit/copy

1 2 3 4 5

var skillSet = new Array(); skillSet['Document language'] = 'HTML5'; skillSet['Styling language'] = 'CSS3'; skillSet['Javascript library'] = 'jQuery'; skillSet['Other'] = 'Usability and accessibility';

Shorthand:
double click code to edit/copy

1 2 3 4 5 6

var skillSet = { 'Document language' : 'HTML5', 'Styling language' : 'CSS3', 'Javascript library' : 'jQuery', 'Other' : 'Usability and accessibility' };

Dont forget to omit the final comma otherwise certain browsers will complain (not naming any names, IE).

5. Declaring variables Shorthand


It is sometimes good practice to including variable assignments at the beginning of your functions. This shorthand method can save you lots of time and space when declaring multiple variables at the same time. longhand:
double click code to edit/copy

1 2 3

var x; var y; var z = 3;

shorthand:
double click code to edit/copy

var x, y, z=3;

6. Assignment Operators Shorthand


Assignment operators are used to assign values to JavaScript variables and no doubt you use arithmetic everyday without thinking (no matter what programming language you use Java, PHP, C++ its essentially the same principle). Longhand:
double click code to edit/copy

1 2 3

x=x+1; minusCount = minusCount - 1; y=y*10;

Shorthand:
double click code to edit/copy

1 2 3

x++; minusCount --; y*=10;

Other shorthand operators, given that x=10 and y=5, the table below explains the assignment operators:
double click code to edit/copy

1 2 3 4 5

x x x x x

+= -= *= /= %=

y y y y y

//result //result //result //result //result

x=15 x=5 x=50 x=2 x=0

7. Regex Object Shorthand


In Javascript, a Regex object can be called like a function like so:
double click code to edit/copy

/test/("is test in here")

As opposed to the more verbose(but sometimes more appropriate in cases that you are reusing the Regex).

Longhand:
double click code to edit/copy

1 2 3

searchText = "padding 1234 rocket str austin TX 78704 more padding" /\d+.+\n{0,2}.+\s+[A-Z]{2}\s+\d{5}/m(searchText) //returns: ["1234 rocket str austin TX 78704"]

Shorthand:
double click code to edit/copy

1 2 3

var re = new RegExp(/\d+.+\n{0,2}.+\s+[A-Z]{2}\s+\d{5}/m); re.exec(searchText); //returns: ["1234 rocket str austin TX 78704"]

8. If Presence Shorthand
This might be trivial, but worth a mention. When doing if checks assignment operators can sometimes be ommited. Longhand:
double click code to edit/copy

if (likeJavaScript == true)

Shorthand:
double click code to edit/copy

if (likeJavaScript)

Here is another example. If a is NOT equal to true, then do something. Longhand:


double click code to edit/copy

1 2 3 4

var a; if ( a != true ) { // do something... }

Shorthand:
double click code to edit/copy

1 2 3

var a; if ( !a ) { // do something... }

9. Function Variable Arguments Shorthand


Object literal shorthand can take a little getting used to, but seasoned developers usually prefer it over a series of nested functions and variables. You can argue which technique is shorter, but I enjoy using object literal notation as a clean substitute to functions as constructors. Longhand:
double click code to edit/copy

1 2 3 4

function myFunction( myString, myNumber, myObject, myArray, myBoolean ) { // do something... } myFunction( "String", 1, [], {}, true );

Shorthand (looks long but only because I have console.logs in there!):


double click code to edit/copy

1 2 3 4 5 6 7

function myFunction() { console.log( arguments.length ); // Returns 5 for ( i = 0; i < arguments.length; i++ ) { console.log( typeof arguments[i] ); // Returns string, number, object, object, boolean } } myFunction( "String", 1, [], {}, true );

10. JavaScript foreach Loop Shorthand


This little tip is really useful if you want plain JavaScript and hence cant use the awesomejQuery.each. Longhand:
double click code to edit/copy

for (var i = 0; i < allImgs.length; i++)

Shorthand:
double click code to edit/copy

for(var i in allImgs)

11. charAt() Shorthand


You can use the eval() function to do this but this bracket notation shorthand technique is much cleaner than an evaluation, and you will win the praise of colleagues who once scoffed at your amateur coding abilities! Longhand:
double click code to edit/copy

"myString".charAt(0);

Shorthand:
double click code to edit/copy

"myString"[0]; // Returns 'm'

12. Suggest one?


I really do love these and would love to find more, please leave a comment!

jQuery Tutorials for Designers


Feb 29, 2008 Tutorials css, javascript

1,008

This article contains 10 visual tutorials intended for web designers and newbies on how to apply Javascript effects with jQuery. In case you don't know about jQuery, it is a "write less,

do more" Javascript library. It has many Ajax and Javascript features that allow you to enhance user experience and semantic coding. Since these tutorials are focused on jQuery, I'm not going to get into the details of the CSS.

Note: the version used in this article is jQuery 1.2.3 VIEWjQuery Demos DOWNLOADDemo ZIP

How jQuery works?


First you need to download a copy of jQuery and insert it in your html page (preferably within the <head> tag). Then you need to write functions to tell jQuery what to do. The diagram below explains the detail how jQuery work:

How to get the element?


Writing jQuery function is relatively easy (thanks to the wonderful documentation). The key point you have to learn is how to get the exact element that you want to apply the effects. $("#header") = get the element with id="header" $("h3") = get all <h3> element $("div#content .photo") = get all element with class="photo" nested in the <div id="content"> $("ul li") = get all <li> element nested in all <ul> $("ul li:first") = get only the first <li> element of the <ul>

1. Simple slide panel


Let's start by doing a simple slide panel. You've probably seen a lot of this, where you click on a link and a panel slide up/down. (view demo)

When an elment with class="btn-slide" is clicked, it will slideToggle (up/down) the <div id="panel"> element and then toggle a CSS class="active" to the <a class="btn-slide"> element. The .active class will toggle the background position of the arrow image (by CSS).

$(document).ready(function(){

$(".btn-slide").click(function(){

$("#panel").slideToggle("slow");

$(this).toggleClass("active");

});

});

2. Simple disappearing effect


This sample will show you how to make something disappear when an image button is clicked. (view demo)

When the <img class="delete"> is clicked, it will find its parent element <div class="pane"> and animate its opacity=hide with slow speed.

$(document).ready(function(){

$(".pane .delete").click(function(){

$(this).parents(".pane").animate({ opacity: "hide" }, "slow");

});

});

3 Chain-able transition effects


Now let's see the power of jQuery's chainability. With just several lines of code, I can make the box fly around with scaling and fading transition. (view demo)

Line 1: when the <a class="run"> is clicked Line 2: animate the <div id="box"> opacity=0.1, left property until it reaches 400px, with speed 1200 (milliseconds) Line 3: then opacity=0.4, top=160px, height=20, width=20, with speed "slow" Line 4: then opacity=1, left=0, height=100, width=100, with speed "slow" Line 5: then opacity=1, left=0, height=100, width=100, with speed "slow" Line 6: then top=0, with speed "fast" Line 7: then slideUp (default speed = "normal") Line 8: then slideDown, with speed "slow" Line 9: return false will prevent the browser jump to the link anchor

$(document).ready(function(){

$(".run").click(function(){

$("#box").animate({opacity: "0.1", left: "+=400"}, 1200)

.animate({opacity: "0.4", top: "+=160", height: "20", width: "20"}, "slow")

.animate({opacity: "1", left: "0", height: "100", width: "100"}, "slow")

.animate({top: "0"}, "fast")

.slideUp()

.slideDown("slow")

return false;

});

});

4a. Accordion #1
Here is a sample of accordion. (view demo)

The first line will add a CSS class "active" to the first <H3> element within the <div class="accordion"> (the "active" class will shift the background position of the arrow icon). The second line will hide all the <p> element that is not the first within the <div class="accordion">. When the <h3> element is clicked, it will slideToggle the next <p> and slideUp all its siblings, then toggle the class="active".

$(document).ready(function(){

$(".accordion h3:first").addClass("active");

$(".accordion p:not(:first)").hide();

$(".accordion h3").click(function(){

$(this).next("p").slideToggle("slow")

.siblings("p:visible").slideUp("slow");

$(this).toggleClass("active");

$(this).siblings("h3").removeClass("active");

});

});

4b. Accordion #2
This example is very similar to accordion#1, but it will let you specify which panel to open as default. (view demo) In the CSS stylesheet, set .accordion p to display:none. Now suppose you want to open the third panel as default. You can write as $(".accordion2 p").eq(2).show(); (eq = equal). Note that the indexing starts at zero.

$(document).ready(function(){

$(".accordion2 h3").eq(2).addClass("active");

$(".accordion2 p").eq(2).show();

$(".accordion2 h3").click(function(){

$(this).next("p").slideToggle("slow")

.siblings("p:visible").slideUp("slow");

$(this).toggleClass("active");

$(this).siblings("h3").removeClass("active");

});

});

5a. Animated hover effect #1


This example will create a nice animated hover effect with fade in/out. (view demo)

When the menu link is mouseovered, it will find the next <em> and animate its opacity and top position.

$(document).ready(function(){

$(".menu a").hover(function() {

$(this).next("em").animate({opacity: "show", top: "-75"}, "slow");

}, function() {

$(this).next("em").animate({opacity: "hide", top: "-85"}, "fast");

});

});

5b. Animated hover effect #2


This example will get the menu linktitle attribute, store it in a variable, and then append to the <em> tag. (view demo)

The first line will append an empty <em> to the menu <a> element. When the link is mouseovered, it will get thetitle attribute, store it in a variable "hoverText", and then set the <em> text content with the hoverText's value.

$(document).ready(function(){

$(".menu2 a").append("<em></em>");

$(".menu2 a").hover(function() {

$(this).find("em").animate({opacity: "show", top: "-75"}, "slow");

var hoverText = $(this).attr("title");

$(this).find("em").text(hoverText);

}, function() {

$(this).find("em").animate({opacity: "hide", top: "-85"}, "fast");

});

});

6. Entire block clickable


This example will show you how to make the entire block element clickable as seen on my Best Web Gallery's sidebar tabs. (view demo)

Suppose you have a <ul> list with class="pane-list" and you want to make the nested<li> clickable (entire block). You can assign the click function to ".pane-list li"; and when it is clicked, the function will find the <a> element and redirect the browser location to its href attribute value.

$(document).ready(function(){

$(".pane-list li").click(function(){

window.location=$(this).find("a").attr("href"); return false;

});

});

7. Collapsible panels
Let's combine the techniques from the previous examples and create a serie of collapsible panels (similar to the Gmail inbox panels). Notice I also used the same technique on Web Designer Wall comment list and Next2Friends message inbox? (viewdemo)

First line: hide all <div class="message_body"> after the first one. Second line: hide all <li> element after the 5th Third part: when the <p class="message_head"> is clicked, slideToggle the next <div class="message_body"> Fourth part: when the <a class="collpase_all_message"> button is clicked, slideUp all <div class="message_body"> Fifth part: when the <a class="show_all_message"> is clicked, hide this, show <a class="show_recent_only">, and slideDown all <li> after the fifth one. Sixth part: when the <a class="show_recent_only"> is clicked, hide this, show <a class="show_all_message">, and slideUp all <li> after the 5th.

$(document).ready(function(){

//hide message_body after the first one

$(".message_list .message_body:gt(0)").hide();

//hide message li after the 5th

$(".message_list li:gt(4)").hide();

//toggle message_body

$(".message_head").click(function(){

$(this).next(".message_body").slideToggle(500)

return false;

});

//collapse all messages

$(".collpase_all_message").click(function(){

$(".message_body").slideUp(500)

return false;

});

//show all messages

$(".show_all_message").click(function(){

$(this).hide()

$(".show_recent_only").show()

$(".message_list li:gt(4)").slideDown()

return false;

});

//show recent messages only

$(".show_recent_only").click(function(){

$(this).hide()

$(".show_all_message").show()

$(".message_list li:gt(4)").slideUp()

return false;

});

});

8. Imitating the WordPress Comment Backend


I think most of you have probably seen the WordPress Ajax comment management backend. Well, let's imitate it with jQuery. In order to animate the background color, you need include the Color Animations plugin. (view demo)

First line: will add "alt" class to even <div class="pane"> (to assign the grey background on every other <div >) Second part: when <a class="btn-delete"> is clicked, alert a message, and then animate the backgroundColor and opacity of <div class="pane"> Third part: when <a class="btn-unapprove"> is clicked, first animate the backgroundColor of <div class="pane"> to yellow, then white, and addClass "spam" Fourth part: when <a class="btn-approve"> is clicked, first animate the backgroundColor of <div class="pane"> to green, then white, and removeClass "spam" Fifth part: when <a class="btn-spam"> is clicked, animate the backgroundColor to red and opacity ="hide"

//don't forget to include the Color Animations plugin

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

$(document).ready(function(){

$(".pane:even").addClass("alt");

$(".pane .btn-delete").click(function(){

alert("This comment will be deleted!");

$(this).parents(".pane").animate({ backgroundColor: "#fbc7c7" }, "fast")

.animate({ opacity: "hide" }, "slow")

return false;

});

$(".pane .btn-unapprove").click(function(){

$(this).parents(".pane").animate({ backgroundColor: "#fff568" }, "fast")

.animate({ backgroundColor: "#ffffff" }, "slow")

.addClass("spam")

return false;

});

$(".pane .btn-approve").click(function(){

$(this).parents(".pane").animate({ backgroundColor: "#dafda5" }, "fast")

.animate({ backgroundColor: "#ffffff" }, "slow")

.removeClass("spam")

return false;

});

$(".pane .btn-spam").click(function(){

$(this).parents(".pane").animate({ backgroundColor: "#fbc7c7" }, "fast")

.animate({ opacity: "hide" }, "slow")

return false;

});

});

9. Image replacement gallery


Suppose you have a portfolio where you want to showcase multi images without jumping to another page, you can load the JPG into the target element. (view demo)

First append an empty <em> to H2. When a link within the <p class=thumbs> is clicked: - store its href attribute into a variable "largePath" - store its title attribute into a variable "largeAlt" - replace the <img id="largeImg"> scr attribute with the variable "largePath" and replace the alt attribute with the variable "largeAlt" - Set the em content (within the h2) with the variable largeAlt (plus the brackets)

$(document).ready(function(){

$("h2").append('<em></em>')

$(".thumbs a").click(function(){

var largePath = $(this).attr("href");

var largeAlt = $(this).attr("title");

$("#largeImg").attr({ src: largePath, alt: largeAlt });

$("h2 em").html(" (" + largeAlt + ")"); return false;

});

});

10. Styling different link types


With most modern browsers, styling the link selector is very easy. For example, to style the link to .pdf file, you can simply use the following CSS rule: a[href $='.pdf'] { ... }. Unfortunately, IE 6 doesn't support this (this is another reason why we hate IE!). To get around this, you can do it with jQuery. (view demo)

The first three lines should be very straight foward. They just a CSS class to the <a>element according to their href attribute. The second part will get all <a> element that does not have "http://www.webdesignerwall.com" and/or does not start with "#" in the hrefattribute, then addClass "external" and set target= "_blank".

$(document).ready(function(){

$("a[@href$=pdf]").addClass("pdf");

$("a[@href$=zip]").addClass("zip");

$("a[@href$=psd]").addClass("psd");

$("a:not([@href*=http://www.webdesignerwall.com])").not("[href^=#]")

.addClass("external")

.attr({ target: "_blank" });

});

1. The Markup
Our portfolio is nothing more than a simple unordered list:
view plaincopy to clipboardprint?

1. <ul id="portfolio"> 2. <li><a href="#"><img src="images/a-list-apart.png" alt="" height="115" width="200" />A List Apart</a></li> 3. <li><a href="#"><img src="images/apple.png" alt="" height="115" width="200" />Apple</a></li> 4. <li><a href="#"><img src="images/cnn.png" alt="" height="115" width="200" />CNN</a></li> 5. <li><a href="#"><img src="images/digg.png" alt="" height="115" width="200" />Digg</a></li> 6. <li><a href="#"><img src="images/espn.png" alt="" height="115" width="200" />ESPN</a></li> 7. <li><a href="#"><img src="images/facebook.png" alt="" height="115" width="200" />Facebook</a></li> 8. <li><a href="#"><img src="images/google.png" alt="" height="115" width="200" />Google</a></li> 9. <li><a href="#"><img src="images/netflix.png" alt="" height="115" width="200" />Netflix</a></li> 10. <li><a href="#"><img src="images/nettuts.png" alt="" height="115" width="200" />NETTUTS</a></li> 11. <li><a href="#"><img src="images/twitter.png" alt="" height="115" width="200" />Twitter</a></li> 12. <li><a href="#"><img src="images/white-house.png" alt="" height="115" width="200" />White House</a></li> 13. <li><a href="#"><img src="images/youtube.png" alt="" height="115" width="200" />YouTube</a></li> 14. </ul>

Note: I was by no means a part of creating these wonderful sites; I am just using them as examples.

2. Categorizing the Portfolio


We are going to assume that our portfolio can be broken down into 5 categories: Design

Development CMS Integration Information Architecture

In order to use the categories we have defined, we will convert them to lowercase and replace all spaces with hyphens: Design = design Development = development CMS = cms Integration = integration Information Architecture = information-architecture We are going to assume that each portfolio item could be in one or many categories, so we are going to randomly add our newly created categories as classes to the list items:
view plaincopy to clipboardprint?

1. <ul id="portfolio"> 2. <li class="cms integration"> 3. <a href="#"><img src="images/a-list-apart.png" alt="" height="115" width="200" />A List Apart</a> 4. </li> 5. <li class="integration design"> 6. <a href="#"><img src="images/apple.png" alt="" height="115" width="200" />Apple</a> 7. </li> 8. <li class="design development"> 9. <a href="#"><img src="images/cnn.png" alt="" height="115" width="200" />CNN</a> 10. </li> 11. <li class="cms"> 12. <a href="#"><img src="images/digg.png" alt="" height="115" width="200" />Digg</a> 13. </li> 14. <li class="design cms integration"> 15. <a href="#"><img src="images/espn.png" alt="" height="115" width="200" />ESPN</a> 16. </li> 17. <li class="design integration"> 18. <a href="#"><img src="images/facebook.png" alt="" height="115" width="200" />Facebook</a> 19. </li> 20. <li class="cms information-architecture"> 21. <a href="#"><img src="images/google.png" alt="" height="115" width="200" />Google</a> 22. </li> 23. <li class="integration development"> 24. <a href="#"><img src="images/netflix.png" alt="" height="115" width="200" />Netflix</a> 25. </li> 26. <li class="information-architecture"> 27. <a href="#"><img src="images/nettuts.png" alt="" height="115" width="200" />NETTUTS</a> 28. </li> 29. <li class="design information-architecture cms"> 30. <a href="#"><img src="images/twitter.png" alt="" height="115" width="200" />Twitter</a> 31. </li> 32. <li class="development"> 33. <a href="#"><img src="images/white-house.png" alt="" height="115" width="200" />White House</a> 34. </li> 35. <li class="cms design"> 36. <a href="#"><img src="images/youtube.png" alt="" height="115" width="200" />YouTube</a> 37. </li> 38. </ul>

Adding Category Navigation


Now that we have the portfolio pieces in place, we are going to need some way to navigate through them. Another unordered list should do:
view plaincopy to clipboardprint?

1.

<ul id="filter">

2. 3. 4. 5. 6. 7. 8.

<li class="current"><a href="#">All</a></li> <li><a href="#">Design</a></li> <li><a href="#">Development</a></li> <li><a href="#">CMS</a></li> <li><a href="#">Integration</a></li> <li><a href="#">Information Architecture</a></li> </ul>

Since I want the default view of the portfolio to show All items, I have assigned a class of current to the first list item. You will probably look at that and question me on the accessibility of this example. My thought is that you have 3 options to solve that problem. 1. When creating a portfolio like this, there is a strong probability that it will be database driven. Thus, you should be able to create a separate page for each category. So if a user does not have JavaScript enabled, they can go to the separate page with the filtered portfolio. 2. You can use a similar technique from my last tutorial: setting a parameter in the url. 3. You could always just write in the navigation with JavaScript before the portfolio items:
view plaincopy to clipboardprint?

1. 2.

3.

$(document).ready(function() { $('ul#portfolio').before('<ul id="filter"><li class="current"><a href="#">All</a></li><li><a href="#">Design</a ></li><li><a href="#">Development</a></li><li><a href="#">CMS</a></li><li><a href="#">Integration</a></li> <li><a href="#">Information Architecture</a></li></ul>'); });

Ok, youve got my notes on accessibility, so dont criticize me for not thinking about it.

3. The CSS
This tutorial is not meant to be about CSS, so Im going to run through the CSS pretty quickly. I always start with some basic styles as a sort-of framework, so Im not going to go over those styles right now. These styles basically just act as a reset and define some styling for basic elements. To start, I just want to display the categories across the top horizontally with a border between each:
view plaincopy to clipboardprint?

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.

ul#filter { float: left; font-size: 16px; list-style: none; margin-left: 0; width: 100%; } ul#filter li { border-right: 1px solid #dedede; float: left; line-height: 16px; margin-right: 10px; padding-right: 10px; }

Next, I want to remove the border from the last list item (in browsers that support it) and change the display of the links:
view plaincopy to clipboardprint?

1. 2.

ul#filter li:last-child { border-right: none; margin-right: 0; padding-right: 0; } ul#filter a { color: #999; text-decoration: none; }

I also want to make sure and differentiate the currently selected category:
view plaincopy to clipboardprint?

1. 2.

ul#filter li.current a, ul#filter a:hover { text-decoration: underline; } ul#filter li.current a { color: #333; font-weight: bold; }

Ok, now that we have the category navigation styled, lets focus on the actual layout of the portfolio. Lets plan on floating 3 list items next to each other with a border around each one:
view plaincopy to clipboardprint?

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.

ul#portfolio { float: left; list-style: none; margin-left: 0; width: 672px; } ul#portfolio li { border: 1px solid #dedede; float: left; margin: 0 10px 10px 0; padding: 5px; width: 202px; }

Now, we just need to add some basic styling for the images and links:
view plaincopy to clipboardprint?

1. 2. 3.

ul#portfolio a { display: block; width: 100%; } ul#portfolio a:hover { text-decoration: none; } ul#portfolio img { border: 1px solid #dedede; display: block; padding-bottom: 5px; }

Compensating for Internet Explorer 6


Of course, lett not forget about our friend IE6. Once you start clicking through some of the filters, the layout gets a little crazy.

From what I can tell, it is the dreaded IE Double Margin bug. I tried applying display: inline to the list items once they are filtered, but that didnt seem to fix it. So my best solution was to just halve the right margin:
view plaincopy to clipboardprint?

1.

ul#portfolio li { margin-right: 5px; }

We are of course only going to serve this IE6 specific stylesheet using conditional comments:
view plaincopy to clipboardprint?

1. 2. 3.

<!--[if lt IE 7]> <link href="stylesheets/screen-ie6.css" type="text/css" rel="stylesheet" media="screen,projection" /> <![endif]-->

Yeah, it doesnt look as good, but you know what: I dont care. If you are using IE6, you deserve it.

4. The jQuery

Ok, now that we have the markup and CSS all done, lett get to the important part of this tutorial: the JavaScript. We are going to start by including the latest version of jQuery in the head of our document.
view plaincopy to clipboardprint?

1.

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

Next, we want to execute our code once the document is loaded.


view plaincopy to clipboardprint?

1. 2. 3.

$(document).ready(function() { });

Now, we dont want to do anything until one of our categories is clicked. We also want to make sure that we do not follow the href value of the link, so we need to return false:
view plaincopy to clipboardprint?

1. 2. 3.

$('ul#filter a').click(function() { return false; });

Once a category link is clicked, I want to do a couple of things: remove the outline on the clicked link, remove the class of current on the list item that has it, and add the class of current on the parent of the clicked link:
view plaincopy to clipboardprint?

1. 2. 3.

$(this).css('outline','none'); $('ul#filter .current').removeClass('current'); $(this).parent().addClass('current');

Next, we want to get the text inside of the clicked link, convert it to lowercase, and replace any spaces with hyphens (just like before when we were creating the category classes):
view plaincopy to clipboardprint?

1.

var filterVal = $(this).text().toLowerCase().replace(' ','-');

The first case of the script is when the All link is clicked. When that is clicked, we want to show all of the portfolio items and remove the class of hidden:
view plaincopy to clipboardprint?

1. 2. 3.

if(filterVal == 'all') { $('ul#portfolio li.hidden').fadeIn('slow').removeClass('hidden'); }

Otherwise, one of the actual categories were clicked. So we want to go through each portfolio item and check to see if it has the class that equals the value of the category clicked. If it does not have the class, we want to fade out the list item and add a class of hidden. It it does have the class, we want to fade it in and remove the class of hidden:
view plaincopy to clipboardprint?

1. 2. 3. 4. 5. 6. 7. 8. 9.

else { $('ul#portfolio li').each(function() { if(!$(this).hasClass(filterVal)) { $(this).fadeOut('normal').addClass('hidden'); } else { $(this).fadeIn('slow').removeClass('hidden'); } }); }

The Finished Script


Lets take a look at the entire script:
view plaincopy to clipboardprint?

1. $(document).ready(function() { 2. $('ul#filter a').click(function() { 3. $(this).css('outline','none'); 4. $('ul#filter .current').removeClass('current'); 5. $(this).parent().addClass('current'); 6. 7. var filterVal = $(this).text().toLowerCase().replace(' ','-'); 8. 9. if(filterVal == 'all') { 10. $('ul#portfolio li.hidden').fadeIn('slow').removeClass('hidden'); 11. } else { 12. $('ul#portfolio li').each(function() { 13. if(!$(this).hasClass(filterVal)) { 14. $(this).fadeOut('normal').addClass('hidden'); 15. } else { 16. $(this).fadeIn('slow').removeClass('hidden'); 17. } 18. }); 19. } 20. 21. return false; 22. }); 23. });

Some people may not like the effect, but I think it looks pretty cool how they all kind of dance around. This is definitely not the only way to accomplish something like this, and it could easily be built on to do other things. This technique is actually evolved from the coding that I did for my companys portfolio.

5. One Quick Note


You may have noticed that I was adding and removing the class of hidden on the items as I was toggling the visibility. While I didnt end up doing anything with the class, I try and make it a habit to add and remove classes to denote the state they are in. You may not use it immediately, but it can provide a hook for you do stuff with in the future. Subscribe to the NETTUTS RSS Feed for more daily web development tuts and articles.

Useful and Handy jQuery Tips and Tricks



css-html javascript tips

25 Mar 2009 46 113127

advertise here

When I start learning jQuery, I always look for a best way to implement a code. Or sometimes, look for the simplest solution among the rest, though it's not the elegant way to do it, but it's easy to understand. So, now, I'm gonna show you my favourite collection of jQuery tips and tricks

1. jQuery cheatsheets
First of all, it's good to have a cheatsheet as a reference. I found 3 of them online:

jQuery Cheatsheet from ColorCharge

jQuery Cheatsheet from Gscottolson WebBlog

jQuery Cheatsheet from From Far East WebBlog

2. jQuery $(document).ready shorthand


This is a great tip! Instead of doing this

1 2 3

$(document).ready(function() { //write your code here }

You can also do this, both are the same!

1 2 3

$(function(){ //write your code here });

3. Open in new window


Target attribute is not valid in STRICT W3C standard. Thus, we need to use REL and a bit of jQuery code to dynamically create the attribute to avoid validation error. This is one of my favourite codes. It's so simple and does the job well.

1 1

$('a[rel=external]').attr('target','_blank'); <a href="http://www.queness.com" rel="external">Queness in new window</a>

4. Make the entire LI clickable


This trick is very useful when you're using UL list to make a menu. What it does is, when you click on the LI area (outside of the link), it will search for the url in the anchor tag and execute the link:

$("ul li").click(function(){

2 3 4 1 2 3 4 5

//get the url from href attribute and launch the url window.location=$(this).find("a").attr("href"); return false; });

<ul> <li><a href="home">home</a></li> <li><a href="home">about</a></li> <li><a href="home">contact</a></li> </ul>

5. Switch to different CSS style sheets


You want to have different design for your website. You can use this to switch to different CSS Style Sheets:

1 2 3 4 1 2 3 4 5

$("a.cssSwitcher").click(function() { //swicth the LINK REL attribute with the value in A REL attribute $('link[rel=stylesheet]').attr('href' , $(this).attr('rel')); }); <link rel="stylesheet" href="default.css" type="text/css"> ...... <a href="#" class="cssSwitcher" rel="default.css">Default Theme</a> <a href="#" class="cssSwitcher" rel="red.css">Red Theme</a> <a href="#" class="cssSwitcher" rel="blue.css">Blue Theme</a>

6. Disable right click


Some of us might want to disable right click, or want to create our own context menu for the website, this is how we can detect right click:

1 2 3 4 5 6

$(document).bind("contextmenu",function(e){ //you can enter your code here, e.g a menu list

//cancel the default context menu return false; });

7. Get mouse cursor x and y axis


This script will display the x and y value - the coordinate of the mouse pointer.

1 2 3 4 1

$().mousemove(function(e){ //display the x and y axis values inside the P element $('p').html("X Axis : " + e.pageX + " | Y Axis " + e.pageY); }); <p></p>

8. Prevent default behaviour


Assuming we have a long page, and we have a link similar to below that is used for other purposes other than a hyperlink. If you clicked on it, it will bring you to the top of your page. The reason of this behavior is because of the # symbol. To solve this problem, we need to cancel the default behavior by doing this:

1 2 3 4 5 6

$('#close').click(function(e){ e.preventDefault(); });

/* OR */

7 8 9 1

$('#close').click(function(){ return false; }); <a href="#" id="close"></a>

9. Back to top button/link


A handy back to top button/link using jQuery with scroll to plugin. I like the scroll to top effect, you can test it by pressing the button below this page. You'll know what I meant : ) Get jQuery scrollTo plugin

1 2 3 1 2 3 4

$('#top').click(function() { $(document).scrollTo(0,500); } <script type="text/javascript" src="js/jquery.scrollTo-min.js"></script> ...... <a id="top" style="cursor:hand;cursor:pointer"> Back to top

10. Columns of equal height


I think this script is quite useful. I haven't have a chance to use it yet. It's more on design. If you want columns have the same height, this function will answer your request. Inspired by CSSNewbie

1 2 3 4 5 6

$(document).ready(function() { setHeight('.col'); });

//global variable, this will store the highest height value var maxHeight = 0;

7 8 9 10 11 12 13 14
//Store the highest value //Loop all the col col.each(function() { function setHeight(col) { //Get all the element with class = col col = $(col);

15 16 17 18 19 20 21 22 } 23 1 2 3 4 5
});

if($(this).height() > maxHeight) { maxHeight = $(this).height();; }

//Set the height col.height(maxHeight);

<div class="col" style="border:1px solid">Column One<br/> With Two Line<br/> And the height is different<br/><br/> </div> <div class="col" style="border:1px solid">Column Two<br/><br/></div>

11. Write our own selector


This is a more advance trick. I didnt know about this until I saw it from this website illuminatikarate.com.

1
//extend the jQuery functionality

2 3 4 5 6 7 8 9 10 11 12 13

$.extend($.expr[':'], {

//name of your special selector moreThanAThousand : function (a){ //Matching element return parseInt($(a).html()) > 1000; } });

$(document).ready(function() { $('td:moreThanAThousand').css('background-color', '#ff0000'); });

14 1 2 3 4 5 6 7 8 9
<table> <tbody> <tr><td>1400</td><td>700</td><td>400</td></tr> <tr><td>2500</td><td>600</td><td>100</td></tr> <tr><td>100</td><td>1100</td><td>900</td></tr> <tr><td>2600</td><td>1100</td><td>1200</td></tr> </tbody> </table> <table></table>

12. Font resizing

This is one of the famous facilities on a webpage - able to let user increase the font size. I modified the script fromshopdev.co.uk. Now, you'll be able to put in ID, Classes or HTML elements that you want the font to be adjustable into an array.

1 2 3 4 5 6 7 8 9 10

$(document).ready(function(){

//ID, class and tag element that font size is adjustable in this array //Put in html or body if you want the font of the entire page adjustable var section = new Array('span','.section2'); section = section.join(',');

// Reset Font Size var originalFontSize = $(section).css('font-size'); $(".resetFont").click(function(){ $(section).css('font-size', originalFontSize);

11 12 13 14 15 16 17 18 19 20

}); // Increase Font Size $(".increaseFont").click(function(){ var currentFontSize = $(section).css('font-size'); var currentFontSizeNum = parseFloat(currentFontSize, 10); var newFontSize = currentFontSizeNum*1.2; $(section).css('font-size', newFontSize); return false; });

// Decrease Font Size

21 22 23

$(".decreaseFont").click(function(){ var currentFontSize = $(section).css('font-size'); var currentFontSizeNum = parseFloat(currentFontSize, 10);

24 25 26 27
}); });

var newFontSize = currentFontSizeNum*0.8; $(section).css('font-size', newFontSize); return false;

28 29 30 1 2 3 4 5 6 7 8
<span>Font size can be changed in this section</span> <div class="section1">This won't be affected</div> <div class="section2">This one is adjustable too!</div> <a class="increaseFont">+</a> | <a class="decreaseFont">-</a> | <a class="resetFont">=</a>

MORE TIPS AND TRICKS ARE WANTED!


I will keep updating this post, so you can bookmark it. I hope this list will able to help you, I have modified some of the scripts to become more flexible. If you have some tips and tricks that you want to share with us. Please leave a comment. : ) Thanks!

AdvertisementBy

using our 70-667 and sun certification e-book facility, you can carry your 642-832

dumps prep solutions anywhere along with you. The 642-813 and 70-270 tutorial are also accessible with free downloadable feature.

Introduction

Update 17 Dec 2009: I have created a new version of this image slide show. It's more efficient, clean and simple. Please visit: jQuery Photo Slide Show with Slick Caption Tutorial Revisited I will no longer provide support for this old tutorial Image Slide Show is one of the famous components in web design and development. A lot of the websites display news headlines in an image slide show to attract viewers attention, of course, with caption/excerpt. No doubt about it, this is a clever method not only to gain attentions, but it also makes the website more alive (not too static, dull). Before we start, check out this industry-leading, unrivaled email security and anti-spam appliance hardware -Anti spam for Exchange. So, here we go again, I separated my codes into 3 sections: html, css and javascript and I will explain how it works in each section.
Advertisement

1. HTML
My ultimate objective is - to keep the html as simple as possible. So, the final product is as following. The first image has a class called "show". Class show has higher z-index, so image with this class will display on top, thus image with this class will always display on top of the rest. The second thing you need to know is the DIV with "caption" class. It has the highest z-index. That DIV will be used to display the caption. The caption is retrieve from the REL attribute in the img element. You can put html element in the REL attribute. Be aware of extra padding and margin of the html elements you used. (eg h1, p). Have a look at the html code:

1 2 3 4 5 6 7 8

<div id="gallery">

<a href="#" class="show">

<img src="images/flowing-rock.jpg" alt="Flowing Rock" alt="" title="" width="580" heig html element inside the REL attribute."/></a> </a>

<a href="#">

<img src="images/grass-blades.jpg" alt="Grass Blades" alt="" title="" width="580"

9 10 11 12 13 14 15

Blades</h3>description"/> </a>

...... ...... ......

<div class="caption"><div class="content"></div></div>

16 17 18

</div> <div class="clear"></div>

2. CSS
In this section, I declared a container #gallery for this image slide show. The CSS for this tutorial is pretty straight foward, the most importance thing is the z-index. You have to make sure the "show" class z-index is lower than the "caption" z-index. body{ font-family:arial }

1 2 3 4

.clear {

5
clear:both

6 7 8 9 10

#gallery { position:relative; height:360px

11 12 13 14

} #gallery a { float:left; position:absolute; }

15 16
#gallery a img {

17 18 19 20 21 22 23 24 25 26 27
} }

border:none;

#gallery a.show { z-index:500

#gallery .caption { z-index:600; background-color:#000; color:#ffffff; height:100px;

28 29 30 31 32 33 34 35
} }

width:100%; position:absolute; bottom:0;

#gallery .caption .content { margin:5px

36 37 38 39 40
} #gallery .caption .content h3 { margin:0; padding:0; color:#1DCCEF;

41 42 43 44 45

3. Javascript
Finally, the Javascript code. I have added comments in each line to explain what it does. My concept for this image slide show:
Hide all the images Display the first image and caption Find the image with "show" class, and grab the next image using next() method Add "show" class to next image Animate the image (fadeout the current image, fadein next image) And, it repeats above steps over and over again

1 2 3 4 5

$(document).ready(function() {

//Execute the slideShow slideShow();

6 7 8 9 10 11 12

});

function slideShow() {

//Set the opacity of all images to 0 $('#gallery a').css({opacity: 0.0});

//Get the first image and display it (set it to full opacity)

13
$('#gallery a:first').css({opacity: 1.0});

14 15 16 17 18 19 20 21 22 23 24 25 26 27
} //Get the caption of the first image from REL attribute and display it $('#gallery .content').html($('#gallery a:first').find('img').attr('rel')) .animate({opacity: 0.7}, 400); //Resize the width of the caption according to the image width $('#gallery .caption').css({width: $('#gallery a').find('img').css('width')}); //Set the caption background to semi-transparent $('#gallery .caption').css({opacity: 0.7});

//Call the gallery function to run the slideshow, 6000 = change to next image afte setInterval('gallery()',6000);

28 29 30
function gallery() {

31 32 33 34 35 36 37 38 39 40 41 42 43 44

//if no IMGs have the show class, grab the first image var current = ($('#gallery a.show')?

$('#gallery a.show') : $('#gallery a:first'))

//Get next image, if it reached the end of the slideshow, rotate it back to the fi

var next = ((current.next().length) ? ((current.next().hasClass('caption'))? $('#ga a:first'));

//Get next image caption var caption = next.find('img').attr('rel');

//Set the fade in effect for the next image, show class has higher z-index next.css({opacity: 0.0}) .addClass('show') .animate({opacity: 1.0}, 1000);

//Hide the current image

45 46 47 48 49 50 51
});

current.animate({opacity: 0.0}, 1000) .removeClass('show');

//Set the opacity to 0 and height to 1px

$('#gallery .caption').animate({opacity: 0.0}, { queue:false, duration:0 }).animat

//Animate the caption, opacity to 0.7 and heigth to 100px, a slide up effect

52
$('#gallery .caption').animate({opacity: 0.7},100 ).animate({height: '100px'},500

53 54 55
//Display the content $('#gallery .content').html(caption);

56 57 58 59 60
}

Conclusion
Finally, you will have a nice and simple jQuery image slide show with a semi-transparent caption. Make sure you check out the demo and download the source code to play with it. Last but not least, I need your support :) If you like this article, please help me to promote it by adding this post into your bookmark. Or you can subscribe to my RSS for more posts. Thanks!

Update
14-4-2009: Fixed caption problem. Thanks to one of the readers kpastore. Update 17 Dec 2009: I have created a new version of this image slide show. It's more efficient, clean and simple. Please visit: jQuery Photo Slide Show with Slick Caption Tutorial Revisited I will no longer provide support for this old tutorial

Tutorials\ JavaScript & AJAX \Rating: 1 2

3 4 5

Create a Cool Animated Navigation with CSS and jQuery


Joash Xu on May 18th 2008 with 129 comments Animation and visual feedback are great ways to assist a user in navigating and interacting with a website. While traditionally Adobes Flash was the goto for anything animated, these days with the magic of javascript we can avoid Flash altogether. Today were going to build a really cool animated navigation menu using just CSS and jQuery.

Demo and Source Code

Overview
The menu were building can be seen in the screenshot below. You can also see the final working version here.

Im going to break this tutorial up into five sections as follows: Rough sketch

Creating Resources Writing down the HTML Writing down the CSS Creating the animation using jQuery

Step 1 : Rough Sketch


First of all let us see what we need to do here.

So heres a rough idea of what we should do: We will split the page into 4 parts, header, navigation and content header and the rest of content

The header area will be simple <div> container The navigation area will be split into several <div> container matching the menu item.

Now most of the time we use <ul><li> container but since every menu item is unique, I do not see the advantages of using <ul><li> so I am going to use <div> container instead. The content will be a simple <div> container So to summarize it
view plaincopy to clipboardprint?

1. 2. 3. 4. 5. 6. 7. 8. 9. 10.

<!-- header section--> <div id="header"></div> <!-- navigation section--> <div id="navigation" class="container"> <div><a href="#">home</a></div> <div><a href="#">about</a></div> <div><a href="#">services</a></div> <div><a href="#">solutions</a></div> <div><a href="#">contact</a></div>

11. 12. 13. 14. 15. 16. 17.

</div> <!-- container section--> <div class="container"> <div id="content-title"></div> <!-- rest of the content --> </div>

It might help to show the directory structure Im. The directory structure is as follows:

Step 2: Resources
I assume you have basic knowledge in dealing with Photoshop, so I will not give too detail instruction on creating the resources. There are several things we need to create. Header background

Content Title Navigation Background stripe Note that if you wish to skip this step you can download the full zip of files at the end of the tutorial and extract my copies! Okay, lets create the header background. Open up Photoshop and create a 1181 px canvas, or you can create it larger and then crop the image. Create a layer and give it a linear gradient with Foreground to Background preset for 171px, this will be the main gradient. Create another layer and give it a linear gradient with Foreground to Transparent preset for about 10px at the bottom of the first layer for some shadow effect. Here is what it should look like, it is 100181 px that I later crop to 1181 px.

Save this as hdr-bkg.png in our img folder. Next, we will create the content title. Again, open up Photoshop and create 934284 px. Create Rounded Rectangle using the appropriate tool, select the created shape, create a new layer, add a gradient and give it some drop shadow. Then we will have something like this:

Save this as content-title.png in img folder. Now let us create the resources needed by the navigation. We need two sets of navigation and a white box. The white box is simple. Just create a rounded rectangle of about 98px x 58px and paint it with white. Ensure the background is transparent.

Save this as white.jpg in img folder. For the navigation item, open your Photoshop and create a 490px x 58px document. Create a rounded rectangular with about 98px x 58px and put some text in it. We will need two copy of each text. I applied a little drop shadow on each text, this of course is optional. You can choose your own colors to put here.

Now simply duplicate this layer along the horizontal line. Apply different colors and text.

Save this as nav.jpg in img folder. Finally, for the background stripe I have simply used an online tool called the Stripe Generator. The output looks like this:

You can see my settings here. Of course you could just create the stripe yourself in Photoshop, but why not use a neat little web tool instead :-)

Step 3: HTML code


Now lets jot down our HTML.
view plaincopy to clipboardprint?

1. 2. 3. 4. 5. 6.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>slick animated menu</title> <!--our CSS file--> <link rel="stylesheet" href="css/main.css" type="text/css" />

7. <!--jQuery library--> 8. <script type="text/javascript" src="js/jquery.js" ></script> 9. <!--jQuery plugin, well get to this later--> 10. <script type="text/javascript" src="js/jquery-bp.js" ></script> 11. <!--Our animation script--> 12. <script type="text/javascript" src="js/navigation.js" ></script> 13. </head> 14. <body> 15. <div id="header"></div> 16. <div id="navigation" class="container"> 17. <div id="home"><a href="home">home</a></div> 18. <div id="about"><a href="about">about</a></div> 19. <div id="services"><a href="services">services</a></div> 20. <div id="solutions"><a href="solutions">solutions</a></div> 21. <div id="contact"><a href="contact">contact</a></div> 22. </div> 23. <div class="container"> 24. <div class="content"> 25. <div id="content-title"></div> 26. <!-- the rest of the content--> 27. </div> 28. </div> 29. </body>

This is prety much according to our gameplan explained on Step 1. I have added a link to a main.css file that is yet to be created and I have also added some references to some javascript files. Since every navigation item is unique I have given each item an ID. We will still need some common style to each of the menu items, this will make it easy for us to manage the style in later stages. We will also have a white box on top of every navigation item appear, when we hover over the menu or a menu item is being selected, so we will need another <div> container for that. The final HTML will look like this:
view plaincopy to clipboardprint?

1.

2. 3. 4. 5. 6. <link rel="stylesheet" href="css/main.css" type="text/css" /> 7. 8. <script type="text/javascript" src="js/jquery.js" ></script> 9. <script type="text/javascript" src="js/jquery-bp.js" ></script> 10. <script type="text/javascript" src="js/navigation.js" ></script> 11. </head> 12. <body> 13. <div id="header"></div> 14. <div id="navigation" class="container"> 15. <div id="home" class="pri-nav"><div><a href="home">home</a></div></div> 16. <div id="about" class="pri-nav"><div><a href="about">about</a></div></div> 17. <div id="services" class="pri-nav"><div><a href="services">services</a></div></div> 18. <div id="solutions" class="pri-nav"><div><a href="solutions">solutions</a></div></div> 19. <div id="contact" class="pri-nav"><div><a href="contact">contact</a></div></div> 20. </div> 21. <div class="container"> 22. <div class="content">

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>slick animated menu</title>

23. <div id="content-title"></div> 24. <!-- the rest of the content--> 25. </div> 26. </div> 27. </body>

Save this as index.html. Up to this point we have this as our HTML page:

Step 4: CSS
Let us apply some basic style to the Web page. We will start by defining the background and adding a header area.
view plaincopy to clipboardprint?

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.

body { background: url(../img/body-bkg.jpg) repeat scroll; margin: 0; padding: 0; } .containe r{ margin: 0pt auto; width:950px; } #header { background: url(../img/hdr-bkg.jpg) repeat-x scroll; height:181px; }

Save this as main.css in css folder. Now we have something that looks like:

Now lets add style to each of the menu items. Remember we want the white box at the top each of menu item, so the position must be set to absolute. Append the following style in our main.css file.
view plaincopy to clipboardprint?

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53.

#navigation{ height:60px; } #home, #home div, #about, #about div, #services , #services div, #solutions, #solutions div, #contact, #contact div { height:80px; position:absolute; width:97px; float:left; } #home, #about, #services, #solutions, #contact{ background-image: url(../img/nav.jpg); background-attachment: scroll; background-repeat: no-repeat; top:171px; } #home{ background-position: 0px -25px; margin-left:6px; } #about{ background-position: -98px -25px; margin-left:105px; } #services{ background-position: -196px -25px; margin-left:204px; } #solutions{ background-position: -294px -25px; margin-left:303px; } #contact{ background-position: -392px -25px; margin-left:402px; } #home div, #about div, #services div, #solutions div, #contact div { background-image: url(../img/white.jpg); background-attachment: scroll; background-repeat: no-repeat; background-position: 0px -60px; }

Now we have :

One problem, the <a href> link appears on top of the menu items, lets remove that with a huge text indent effectively taking it off the screen. Add this to our style sheet.
view plaincopy to clipboardprint?

1. 2. 3. 4. 5.

.pri-nav a{ display:block; text-decoration:none; text-indent:-30000px; }

Now it will look like this:

Weve still got one problem, we would like the navigation menu to appear below the header shadow. We can achieve that by modifying our header style.
view plaincopy to clipboardprint?

1. 2. 3. 4. 5. 6. 7. 8. 9.

#header{ background: url(../img/hdr-bkg.jpg) repeat-x scroll; height:181px; position:absolute; z-index :100; /* ensure the header is on top of navigation area */ top: 0px; left:0px; width:100%; }

Now because we used a .png file with transparency, it should look like this:

Perfect! Lets add the content so we can get to our animation script.
view plaincopy to clipboardprint?

1. 2. 3. 4.

.content{ margin-top:160px; }

5. #content-title{ 6. background: url(../img/content.jpg) no-repeat scroll; 7. height:323px; 8. position:absolute; 9. width:100%; 10. }

Step 5: Animation script


First lets download the latest jQuery script and place it in the js folder. The animation is basically a background position style manipulation. Unfortunately jQuery has bug in animating background position style. But worry not! Alexander Farkas has created a plugin that solves this problem. Download the file and rename it to jquery-bp.js and store it in the js folder. There is something we need to understand before proceeding. I quote from the plugin documentation:

Due to some browser bugs (i.e. Firefox, you have to set your (initial) backgroundposition inline: <div style=background-position: 10px 20px></div> - Of course you can achieve this with JavaScript (jQuery), too: $(#background).css({backgroundPosition: 10px 20px});
Okay now that we understand that, lets start. We will set the backgroud position style for every item in the beginning of our script.
view plaincopy to clipboardprint?

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.

// id for each of our menu items var nav = [ '#home', '#about', '#services', '#solutions', '#contact' ]; $(document).ready(function(){ setBkgPos(); }); function setBkgPos() { for ( i = 0; i < nav.length; i++ ){ $(nav[i]).css({backgroundPosition: i*(-98) + 'px -25px'}); $(nav[i] + ' div').css({ backgroundPosition: '0px -60px'}); } }

Save this as 'navigation.js' in 'js' folder. Now we will bind 3 events to each of the menu items. We can do this by invoking the bind function.
view plaincopy to clipboardprint?

1. $(document).ready(function(){ 2. setBkgPos(); 3. 4. // bind the event to function here 5. for ( i = 0; i < nav.length; i++ ) { 6. $(nav[i]).bind( 'mouseover', mMouseOver ); 7. $(nav[i]).bind( 'mouseout', mMouseOut ); 8. $(nav[i]).bind( 'click', mClick ); 9. } 10. });

Whenever a user hovers over the navigation item our script will call mMouseOver function. When the user hovers out of the navigation item our script will call mMouseOut function. And when the user clicks on the navigation item, our script will call mClick function.

Step 5.1: Mouse over


Lets create a story board for our mouse over animation. On 'Mouse Over': Change the navigation menu image (glow) and change the cursor to pointer.

The navigation will move up a bit. The white box will move down. The white box and the navigation menu will both down. The navigation menu and the white box will move up to its final position. And change the navigation menu image to its original state.

Okay lets add these functions below the previous script:


view plaincopy to clipboardprint?

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.

function _getHPos( id ) { for ( i = 0; i < nav.length; i++ ){ if ( '#' + id == nav[i] ){ return i*(-98); } } return 0; } function mMouseOver(e) { $(this) // stop any animation that took place before this .stop() // step 1. change the image file and change the cursor .css({backgroundImage: 'url('+site_url+'img/nav-over.jpg)',cursor: 'pointer'}) // step.2 move up the navigation item a bit .animate({ backgroundPosition:'(' + _getHPos( this.id ) +'px -30px}'},"fast",

20. // this section will be executed after the step.2 is done 21. function(){ 22. $(this) 23. .children() 24. // step. 3 move the white box down 25. .animate({backgroundPosition:'(0px -40px)'},20) 26. // step 4. move the white box down 27. .animate({backgroundPosition:'(0px -20px)'},"fast"); 28. $(this) 29. // step 4. move the navigation item down 30. .animate({backgroundPosition:'(' + _getHPos( this.id ) +'px 50px)'},"fast") 31. // step 5. move the navigation item to its final position 32. .animate({backgroundPosition:'(' + _getHPos( this.id ) +'px 25px)'},"fast"); 33. // store the parent element id for later usage 34. var parent = this; 35. $(this) 36. .children() 37. // step 5. move the white box to its final position 38. .animate( {backgroundPosition:'(0px -45px)'},"fast", 39. // this section will be executed after the step.2 is done 40. function(){ 41. // step.6 change the image to its original image 42. $(parent).css({backgroundImage: 'url(img/nav.jpg)'}); 43. }); 44. }); 45. } 46.

I need to explain several things here: 1. The _getHPos is use to adjust the horizontal background position navigation for each item. For example, the Home item background will start from 0, the About horizontal background position starts from -98px, and so on. 2. Also notice that early in the function we invoke the stop function. We do this to ensure whatever animation was running before the mouse over event has stopped. Why? We will add another animation later on for the mouse out event. Now let us suppose the user hover over an item and then quickly move the mouse pointer some place else and again quickly hover over the same item. If we do not stop the animation before each event, there will be a delay because some part of the animation will be queued or even worse the animation will become inconsistent and annoy the user.

Step 5.2: Mouse out


Now that is done. Let's create "story board" for the 'mouse out' event On 'Mouse Out': Move down the navigation item.

Move the white box down. Move the navigation up. Move the navigation item up to its original position. Move the white box to its original position ( invisible ).

Return the cursor to normal.

The code:
view plaincopy to clipboardprint?

1. function mMouseOut(e) 2. { 3. $(this) 4. // stop any animation that took place before this 5. .stop() 6. // step.1 move down navigation item 7. .animate({backgroundPosition:'(' + _getHPos( this.id ) +'px 40px )'}, "fast", 8. // this section will be executed after the step.1 is done 9. function(){ 10. // step.2 white box move really fast 11. $(this).children().animate({backgroundPosition:'(0px 70px)'}, "fast"); 12. // step 3. move navigation item up 13. $(this).animate( {backgroundPosition:'(' + _getHPos( this.id ) +'px -40px)'}, "fast", 14. // this section will be executed after the step.3 is done 15. function(){ 16. // step 4. move navigation item ot its original position 17. $(this).animate( {backgroundPosition:'(' + _getHPos( this.id ) +'px -25px)'}, "fast", 18. // this section will be executed after the step.4 is done 19. function(){ 20. // move white box to its original position, ready for next animation 21. $(this).children().css({ backgroundPosition:'0px -60px'}); 22. }) 23. }) 24. }) 25. .css({backgroundImage: 'url(img/nav.jpg)', cursor: ''}); 26. }

Step 5.3: Click


Almost there! Now we need to handle when a user click on the navigation item.
view plaincopy to clipboardprint?

1. 2. 3. 4.

function mClick(e) { location.href = this.id; }

Of course you can point to wherever location you see fit here. This particular function will direct your browser to [current_url]/[navigation_id] so for home it will be [current_url]/home, for about it will be [current_url]/about and so on.

Step 5.4: Current page indicator


Of course we need an indicator when we are already on a page. For that we need another CSS class. We will call that class active. For instance if we are now at 'home' the HTML file will become:
view plaincopy to clipboardprint?

1.

<div id="home" class="pri-nav active"><div><a href="home">home</a></div></div>

Or if we are at 'about' it will become:


view plaincopy to clipboardprint?

1.

<div id="about" class="pri-nav active"><div><a href="about">about</a></div></div>

and so on. So now the idea is after a page is loaded our script will check to see which navigation item has the active class. We then apply an animation effect. And we need to ensure any other events ( mouseover, mouseout, click) will not cause any animation effect on this 'active' item. For that we need to change our code a bit. Here is the complete code after the changes:
view plaincopy to clipboardprint?

1. var site_url = ''; 2. var nav = [ '#home', '#about', '#services', '#solutions', '#contact' ]; 3. 4. $(document).ready(function(){ 5. setBkgPos(); 6. 7. for ( i = 0; i < nav.length; i++ ) { 8. $(nav[i]).bind( 'mouseover', mMouseOver ); 9. $(nav[i]).bind( 'mouseout', mMouseOut ); 10. $(nav[i]).bind( 'click', mClick ); 11. } 12. 13. for ( i = 0; i < nav.length; i++ ) { 14. // element with active class will start animation 15. if ( $(nav[i]).get(0).className.indexOf('active') >= 0 ){ 16. $(nav[i]) 17. .animate({ backgroundPosition:'(' + _getHPos( nav[i] ) +'px -30px}'},"fast", 18. function(){ 19. $(this) 20. .children() 21. .animate({backgroundPosition:'(0px -40px)'},20) 22. .animate({backgroundPosition:'(0px -20px)'},"fast"); 23. $(this) 24. .animate({backgroundPosition:'(' + _getHPos( nav[i] ) +'px 50px)'},"fast") 25. .animate({backgroundPosition:'(' + _getHPos( nav[i] ) +'px 25px)'},"fast"); 26. var parent = this; 27. $(this) 28. .children() 29. .animate( {backgroundPosition:'(0px -45px)'},"fast", 30. function(){ 31. $(parent).animate({backgroundPosition:'(' + _getHPos( parent.id ) +'px 25px)'},"fast"); 32. $(parent).css({backgroundImage: 'url(img/nav.jpg)'});

33. }); 34. }); 35. break; 36. } 37. } 38. });

Finished!
And with that we have our entire nifty little menu. Download a ZIP of the Site View a Demo!

Learning jQuery: Fading Menu Replacing Content


by: Chris Coyier Apr92008

30
The more I learn about jQuery, the more natural it feels. Probably because of how closely tied to CSS it is. From a design perspective, the syntax for jQuery is:

"When I do this, make the CSS do this."


The more common slogan is:

Find something, do something.


...which is also awesome. So now instead of thinking about CSS as page layout and a way to style your page when it loads, you can use in animation and change it on-the-fly to react to events that happen on your page. Take for example a menu. You can take the "click" event that happens when clicking on a menu to do lots of stuff.
I'm considering this article deprecated. I have an updated article here, which covers this same type of material only with more features, updated technology, and better practices.

This example page has three menu items and three content areas: home, about, and contact. By default, the home button is selected, meaning that it's menu graphic is at full opacity and it's content area is shown:
#home { display: block; padding: 30px; } #home-button { opacity: 1.0; border-bottom: 1px solid black; }

By default, the other menu items are faded and their content areas are hidden, like so:
#about { display: none; padding: 30px; } #about-button { opacity: 0.5; border-bottom: 1px solid black; }

With jQuery, we can listen for that click event and then act accordingly. This is what we want to happen:

Fade IN the menu item being clicked on. Fade OUT all other menu items. DISPLAY the corresponding content area. HIDE all other content areas.

Since the home button is active by default, let's look at the jQuery javascript for the about button:
<script type="text/javascript" src="js/jquery.js"></script> <script type="text/javascript"> $(document).ready(function(){ $("#about-button").click(function(){ $(this).animate({

opacity: 1.0, borderWidth: 5 }, 600 ); $("#home") .css({ display: "none" }); $("#about") .css({ display: "block" }); $("#contact") .css({ display: "none" }); $("#home-button").animate({ opacity: 0.5, borderWidth: 1 }, 600 ); $("#contact-button").animate({ opacity: 0.5, borderWidth: 1 }, 600 ); }); }); </script>

Your complete javascript code would have similar chunks for all three buttons. As I've mentioned before, I'm just learning here, so there is likely to be a way smarter way of writing this, but these are the basics and they work. UPDATE: This is way smarter:
$("#page-wrap div.button").click(function(){ $clicked = $(this); // if the button is not already "transformed" AND is not animated if ($clicked.css("opacity") != "1" && $clicked.is(":not(animated)")) { $clicked.animate({ opacity: 1, borderWidth: 5 }, 600 ); // each button div MUST have a "xx-button" and the target div must have an id "xx" var idToLoad = $clicked.attr("id").split('-'); //we search trough the content for the visible div and we fade it out $("#content").find("div:visible").fadeOut("fast", function(){ //once the fade out is completed, we start to fade in the right div $(this).parent().find("#"+idToLoad[0]).fadeIn(); }) } //we reset the other buttons to default style

$clicked.siblings(".button").animate({ opacity: 0.5, borderWidth: 1 }, 600 ); });

Again, new article with a newer/better demo is here. Previous Blog Post: Links of Interest

Invoicing for FreelancersStart saving time and looking professional with a FREE account from FreshBooks.

Easy + Powerful EcommerceFoxyCart was built to integrate, regardless of your tools or CMS. Find out more.

Subscribe to The Thread

1.

Adrian
04/09/2008

Nice Chris. In FF 2 the cursor is default on hover though. Maybe a quick cursor:pointer can be thrown into the CSS.

2.

b0li
04/09/2008

i like jQuery cheers mate

3.

Flavia
04/09/2008

This is truly nice, Chris. Now Ive got to come up with a new project to experiment with jQuery. And its your fault. and I thank you in uppercase for this :)

4.

Romz
04/09/2008

Hello Chris, Maybe a better way to perform your animation : $(document).ready(function(){ $(#page-wrap div.button).click(function(){ if($(this).css(opacity) != 1) { $(this).actualBtn.animate({ opacity: 1, borderWidth: 5 }, 600 ); } $(this).siblings().animate({ opacity: 0.5, borderWidth: 1 }, 600 ); }); });

You probably have to do some enhancements to filter the showed content div but its not a big deal for you I guess. If you want, Ill do it

5.

David Sparks
04/09/2008

Sweet. Im in the process of learning jQuery myself so glad youre doing some here

6.

David Walsh
04/09/2008

Nice work Chris. My only suggestion would be to speed up the duration. Awesome though!

Tutorials\ JavaScript & AJAX \Rating: 1 2 3 4 5

Creating a Dynamic Poll with jQuery and PHP


Jonathan Rudenberg on Jul 23rd 2008 with 254 comments Tutorial Details
Programs: CSS, PHP, JavaScript Difficulty: Intermediate Completion Time: 1-2 hours

When you combine some neat functionality courtesy of PHP with the cleverness of jQuery you can produce some pretty cool results. In this tutorial well create a poll using PHP and XHTML, then make use of some jQuery Ajax effects to eliminate the need for a page refresh, and to give it a nice little bit of animation. 1. HTML 2. PHP 1. Introduction 2. poll_default() 3. poll_submit() 4. poll_return_results() 5. poll_ajax() 3. CSS 4. Javascript 1. Introduction 2. formProcess() 3. loadResults() 4. animateResults()

HTML
Lets get our <head> set up:
view plaincopy to clipboardprint?

1. 2. 3. 4.

<link href="style.css" rel="stylesheet" type="text/css" /> <script src="jquery.js" type="text/javascript" charset="utf-8"></script> <script src="jquery.cookie.js" type="text/javascript" charset="utf-8"></script> <script src="poll.js" type="text/javascript" charset="utf-8"></script>

style.css will hold the CSS markup. jquery.js is the base jQuery library. jquery.cookie.js is a plugin by Klaus Hartl to add cookie manipulation to jQuery. poll.js will have the Javascript that makes the poll dynamic. Next, well create a simple poll form:

view plaincopy to clipboardprint?

1. <div id="poll-container"> 2. <h3>Poll</h3> 3. <form id='poll' action="poll.php" method="post" accept-charset="utf-8"> 4. <p>Pick your favorite Javascript framework:</p> 5. <p><input type="radio" name="poll" value="opt1" id="opt1" /><label for='opt1'>&nbsp;jQuery</label><br /> 6. <input type="radio" name="poll" value="opt2" id="opt2" /><label for='opt2'>&nbsp;Ext JS</label><br /> 7. <input type="radio" name="poll" value="opt3" id="opt3" /><label for='opt3'>&nbsp;Dojo</label><br /> 8. <input type="radio" name="poll" value="opt4" id="opt4" /><label for='opt4'>&nbsp;Prototype</label><br /> 9. <input type="radio" name="poll" value="opt5" id="opt5" /><label for='opt5'>&nbsp;YUI</label><br /> 10. <input type="radio" name="poll" value="opt6" id="opt6" /><label for='opt6'>&nbsp;mootools</label><br /><br /> 11. <input type="submit" value="Vote &rarr;" /></p> 12. </form> 13. </div>

This form will be processed by the PHP for now, and when we get the Javascript running, by jQuery. The PHP and Javascript are designed to pull the option ID from the value tag. &nbsp; is just a HTML entity encoded space, and &rarr; is an arrow: .

PHP
Introduction
If Javascript is disabled, the PHP will: 1. Take GET/POST requests from the form 2. Set/check a cookie 3. Make sure the request is from a unique IP 4. Store the vote in a flat file DB 5. Return the results included with a HTML file If Javascript is enabled, the PHP will: 1. Take GET/POST requests from the Javascript 2. Make sure the request is from a unique IP 3. Store the vote in a flat file DB

4. Return the results as JSON For the flat file DB we will be using a package written by Luke Plant. First, we need an array with the names and IDs of the poll options:
view plaincopy to clipboardprint?

1. 2. 3. 4. 5. 6. 7.

<?php $options[1] = 'jQuery'; $options[2] = 'Ext JS'; $options[3] = 'Dojo'; $options[4] = 'Prototype'; $options[5] = 'YUI'; $options[6] = 'mootools';

The flatfile package uses numbers for the column identifiers, so lets set some constants to convert those to names:
view plaincopy to clipboardprint?

1. 2. 3.

define('OPT_ID', 0); define('OPT_TITLE', 1); define('OPT_VOTES', 2);

When the form is submitted, PHP needs to know what file to insert the results into and return, so we set another constant:
view plaincopy to clipboardprint?

1.

define('HTML_FILE', 'index.html');

We need to include flatfile.php and initialize a database object:


view plaincopy to clipboardprint?

1. 2.

require_once('flatfile.php'); $db = new Flatfile();

The flat files are just text files stored in the data directory:
view plaincopy to clipboardprint?

1. 2. 3.

$db->datadir = 'data/'; define('VOTE_DB', 'votes.txt'); define('IP_DB', 'ips.txt');

If we get a request with the poll parameter, its the static form, so we process it. If the request has a vote parameter in it, its a Ajax request. Otherwise, we just return the HTML_FILE.
view plaincopy to clipboardprint?

1. 2. 3. 4. 5. 6. 7. 8. 9.

if ($_GET['poll'] || $_POST['poll']) { poll_submit(); } else if ($_GET['vote'] || $_POST['vote']) { poll_ajax(); } else { poll_default(); }

poll_default()
view plaincopy to clipboardprint?

1. 2. 3. 4.

function poll_default() { global $db; $ip_result = $db->selectUnique(IP_DB, 0, $_SERVER['REMOTE_ADDR']);

5. 6. if (!isset($_COOKIE['vote_id']) && empty($ip_result)) { 7. print file_get_contents(HTML_FILE); 8. } 9. else { 10. poll_return_results($_COOKIE['vote_id']); 11. } 12. }

poll_default() processes requests directly to the script with no valid GET/POST requests. The global line makes the $db object available in the functions scope. The script tracks unique IPs to make sure you can only vote once, so we do a query to check whether it is in the DB:
view plaincopy to clipboardprint?

1.

$ip_result = $db->selectUnique(IP_DB, 0, $_SERVER['REMOTE_ADDR']);

If we dont have a cookie and the IP query comes up empty, the client hasnt voted yet, so we can just send the HTML file which contains the form. Otherwise, we just send the results:
view plaincopy to clipboardprint?

1. 2. 3. 4. 5. 6.

if (!isset($_COOKIE['vote_id']) && empty($ip_result)) { print file_get_contents(HTML_FILE); } else { poll_return_results($_COOKIE['vote_id']); }

poll_submit()
view plaincopy to clipboardprint?

1. function poll_submit() { 2. global $db; 3. global $options; 4. 5. $id = $_GET['poll'] || $_POST['poll']; 6. $id = str_replace("opt", '', $id); 7. 8. $ip_result = $db->selectUnique(IP_DB, 0, $_SERVER['REMOTE_ADDR']); 9. 10. if (!isset($_COOKIE['vote_id']) && empty($ip_result)) { 11. $row = $db->selectUnique(VOTE_DB, OPT_ID, $id); 12. if (!empty($row)) { 13. $ip[0] = $_SERVER['REMOTE_ADDR']; 14. $db->insert(IP_DB, $ip); 15. 16. setcookie("vote_id", $id, time()+31556926); 17. 18. $new_votes = $row[OPT_VOTES]+1; 19. $db>updateSetWhere(VOTE_DB, array(OPT_VOTES => $new_votes), new SimpleWhereClause(OPT_ID, '=', $id)); 20. 21. poll_return_results($id); 22. } 23. else if ($options[$id]) { 24. $ip[0] = $_SERVER['REMOTE_ADDR']; 25. $db->insert(IP_DB, $ip); 26. 27. setcookie("vote_id", $id, time()+31556926); 28. 29. $new_row[OPT_ID] = $id;

30. $new_row[OPT_TITLE] = $options[$id]; 31. $new_row[OPT_VOTES] = 1; 32. $db->insert(VOTE_DB, $new_row); 33. 34. poll_return_results($id); 35. } 36. } 37. else { 38. poll_return_results($id); 39. } 40. }

poll_submit() takes the form submission, checks if the client has already voted, and then updates the DB with the vote. These lines get the selected options ID, and set $id to it:
view plaincopy to clipboardprint?

1. 2.

$id = $_GET['poll'] || $_POST['poll']; $id = str_replace("opt", '', $id);

We need to check whether the option is in the DB yet:


view plaincopy to clipboardprint?

1.

$row = $db->selectUnique(VOTE_DB, OPT_ID, $id);

If it is in the DB (result not empty), we need to run an updateSetWhere(). If it isnt we need to do aninsert():
view plaincopy to clipboardprint?

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.

if (!empty($row)) { $new_votes = $row[OPT_VOTES]+1; $db->updateSetWhere(VOTE_DB, array(OPT_VOTES => $new_votes), new SimpleWhereClause(OPT_ID, '=', $id)); poll_return_results($id); } else if ($options[$id]) { $new_row[OPT_ID] = $id; $new_row[OPT_TITLE] = $options[$id]; $new_row[OPT_VOTES] = 1; $db->insert(VOTE_DB, $new_row); poll_return_results($id); }

Either way, we need to insert the IP into the DB, and set a cookie (expires in one year):
view plaincopy to clipboardprint?

1. 2. 3. 4.

$ip[0] = $_SERVER['REMOTE_ADDR']; $db->insert(IP_DB, $ip); setcookie("vote_id", $id, time()+31556926);

poll_return_results()
view plaincopy to clipboardprint?

1. 2. 3. 4. 5. 6. 7. 8.

function poll_return_results($id = NULL) { global $db; $html = file_get_contents(HTML_FILE); $results_html = "<div id='poll-container'><div id='poll-results'><h3>Poll Results</h3>\n<dl class='graph'>\n"; $rows = $db->selectWhere(VOTE_DB, new SimpleWhereClause(OPT_ID, "!=", 0), -1,

9. 10. 11. 12. 13. 14. 15. 16. 17. 18.

new OrderBy(OPT_VOTES, DESCENDING, INTEGER_COMPARISON)); foreach ($rows as $row) { $total_votes = $row[OPT_VOTES]+$total_votes; } foreach ($rows as $row) { $percent = round(($row[OPT_VOTES]/$total_votes)*100); if (!$row[OPT_ID] == $id) { $results_html .= "<dt class='bar-title'>". $row[OPT_TITLE] ."</dt><dd class='barcontainer'><div id='bar". $row[OPT_ID] ."'style='width:$percent%;'>&nbsp;</div><strong>$percent%</strong></dd>\n";

19. 20. 21.

} else { $results_html .= "<dt class='bar-title'>". $row[OPT_TITLE] ."</dt><dd class='barcontainer'><div id='bar". $row[OPT_ID] ."' style='width:$percent%;backgroundcolor:#0066cc;'>&nbsp;</div><strong>$percent%</strong></dd>\n"; 22. } 23. } 24. 25. $results_html .= "</dl><p>Total Votes: ". $total_votes ."</p></div></div>\n"; 26. 27. $results_regex = '/<div id="poll-container">(.*?)<\/div>/s'; 28. $return_html = preg_replace($results_regex, $results_html, $html); 29. print $return_html; 30. }

poll_return_results() generates the poll results, takes the HTML file, replaces the form with the results, and returns the file to the client. First, lets grab the HTML file and set $html to it:
view plaincopy to clipboardprint?

1.

$html = file_get_contents(HTML_FILE);

Next, we start the results HTML structure:


view plaincopy to clipboardprint?

1.

$results_html = "<div id='poll-container'><div id='poll-results'><h3>Poll Results</h3>\n<dl class='graph'>\n";

To create the results HTML we need to get all the rows (options) from the DB sorted by number of votes:
view plaincopy to clipboardprint?

1. 2. 3.

$rows = $db->selectWhere(VOTE_DB, new SimpleWhereClause(OPT_ID, "!=", 0), -1, new OrderBy(OPT_VOTES, DESCENDING, INTEGER_COMPARISON));

We also need the total votes to calculate percentages:


view plaincopy to clipboardprint?

1. 2. 3.

foreach ($rows as $row) { $total_votes = $row[OPT_VOTES]+$total_votes; }

Next, we calculate the percentage of votes the current option has:


view plaincopy to clipboardprint?

1. 2.

foreach ($rows as $row) { $percent = round(($row[OPT_VOTES]/$total_votes)*100);

The HTML for the results will be a definition list (<dl>) styled with CSS to create bar graphs:
view plaincopy to clipboardprint?

1.

$results_html .= "<dt class='bar-title'>". $row[OPT_TITLE] ."</dt><dd class='barcontainer'><div id='bar". $row[OPT_ID] ."'style='width:$percent%;'>&nbsp;</div><strong>$percent%</strong></dd>\n";

Also, we should check if the current option is the one the client voted for, and change the color:
view plaincopy to clipboardprint?

1. 2. 3. 4. 5.

if (!$row[OPT_ID] == $id) { } else { $results_html .= "<dt class='bar-title'>". $row[OPT_TITLE] ."</dt><dd class='barcontainer'><div id='bar". $row[OPT_ID] ."' style='width:$percent%;backgroundcolor:#0066cc;'>&nbsp;</div><strong>$percent%</strong></dd>\n"; }

6.

Here, we add a total vote count and close the html tags:
view plaincopy to clipboardprint?

1.

$results_html .= "</dl><p>Total Votes: ". $total_votes ."</p></div></div>\n";

This is a regex that finds the poll-container <div>:


view plaincopy to clipboardprint?

1.

$results_regex = '/<div id="poll-container">(.*?)<\/div>/s';

The last step in this function is to replace the poll form with the results using the regex, and return the result:
view plaincopy to clipboardprint?

1. 2.

$return_html = preg_replace($results_regex, $results_html, $html); print $return_html;

poll_ajax()
view plaincopy to clipboardprint?

1. function poll_ajax() { 2. global $db; 3. global $options; 4. 5. $id = $_GET['vote'] || $_POST['vote']; 6. 7. $ip_result = $db->selectUnique(IP_DB, 0, $_SERVER['REMOTE_ADDR']); 8. 9. if (empty($ip_result)) { 10. $ip[0] = $_SERVER['REMOTE_ADDR']; 11. $db->insert(IP_DB, $ip); 12. 13. if ($id != 'none') { 14. $row = $db->selectUnique(VOTE_DB, OPT_ID, $id); 15. if (!empty($row)) { 16. $new_votes = $row[OPT_VOTES]+1; 17. 18. $db>updateSetWhere(VOTE_DB, array(OPT_VOTES => $new_votes), new SimpleWhereClause(OPT_ID, '=', $id)); 19. } 20. else if ($options[$id]) { 21. $new_row[OPT_ID] = $id; 22. $new_row[OPT_TITLE] = $options[$id]; 23. $new_row[OPT_VOTES] = 1; 24. $db->insert(VOTE_DB, $new_row); 25. } 26. } 27. } 28.

29.

$rows = $db->selectWhere(VOTE_DB, new SimpleWhereClause(OPT_ID, "!=", 0), 1, new OrderBy(OPT_VOTES, DESCENDING, INTEGER_COMPARISON)); 30. print json_encode($rows); 31. }

poll_ajax() takes a request from the Javascript, adds the vote to the DB, and returns the results as JSON. There are a few lines of code that are different from poll_submit(). The first checks if the Javascript just wants the results, and no vote should be counted:
view plaincopy to clipboardprint?

1.

if ($id != 'none')

The other two lines select the whole DB and return it as JSON:
view plaincopy to clipboardprint?

1. 2.

$rows = $db->selectWhere(VOTE_DB, new SimpleWhereClause(OPT_ID, "!=", 0), 1, new OrderBy(OPT_VOTES, DESCENDING, INTEGER_COMPARISON)); print json_encode($rows);

CSS
view plaincopy to clipboardprint?

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33.

.graph { width: 250px; position: relative; rightright: 30px; } .bar-title { position: relative; float: left; width: 104px; line-height: 20px; margin-right: 17px; font-weight: bold; text-align: rightright; } .bar-container { position: relative; float: left; width: 110px; height: 10px; margin: 0px 0px 15px; } .bar-container div { background-color:#cc4400; height: 20px; } .bar-container strong { position: absolute; rightright: -32px; top: 0px; overflow: hidden; } #poll-results p {

34. text-align: center; 35. }

This CSS styles the results returned by the PHP or Javascript. .graph styles the container for the bars, titles and percentages. The width will be different for each site. .bar-title styles the titles for the bar graphs. .bar-container styles the individual bar and percentage containers .bar-container div styles the div that the bar is applied to. To create the bars, a percentage widthis set with PHP or Javascript. .bar-container strong styles the percentage. #poll-results p styles the total votes.

Javascript
Introduction
The Javascript will intercept the submit button, send the vote with Ajax, and animate the results. First, some global variables. You should recognize the first three from the PHP. votedID stores the ID of the option the client voted for.
view plaincopy to clipboardprint?

1. 2. 3. 4. 5.

var OPT_ID = 0; var OPT_TITLE = 1; var OPT_VOTES = 2; var votedID;

Now we need a jQuery ready function which runs when the page loads:
view plaincopy to clipboardprint?

1.

$(document).ready(function(){

Inside that function we register the handler for the vote button which will run formProcess when it is triggered:
view plaincopy to clipboardprint?

1.

$("#poll").submit(formProcess);

We also need to check if the results <div> exists, and animate the results if it does:
view plaincopy to clipboardprint?

1. 2. 3.

if ($("#poll-results").length > 0 ) { animateResults(); }

If we have a cookie we should jump straight to generating the results because the user has already voted. To do that we need to get rid of the poll form, get the id from the cookie, grab the results from the PHP and pass them to loadResults().
view plaincopy to clipboardprint?

1. 2. 3. 4. 5.

if ($.cookie('vote_id')) $("#poll-container").empty(); votedID = $.cookie('vote_id'); $.getJSON("poll.php?vote=none",loadResults); }

formProcess()
view plaincopy to clipboardprint?

1. function formProcess(event){ 2. event.preventDefault(); 3. 4. var id = $("input[@name='poll']:checked").attr("value"); 5. id = id.replace("opt",''); 6. 7. $("#poll-container").fadeOut("slow",function(){ 8. $(this).empty(); 9. 10. votedID = id; 11. $.getJSON("poll.php?vote="+id,loadResults); 12. 13. $.cookie('vote_id', id, {expires: 365}); 14. }); 15. }

formProcess() is called by the submit event which passes it an event object. It prevents the form from doing a normal submit, checks/sets the cookies, runs an Ajax submit instead, then calls loadResults() to convert the results to HTML. First, we need to prevent the default action (submitting the form):
1. event.preventDefault();

Next, we get the ID from the currently selected option:


view plaincopy to clipboardprint?

1. 2.

var id = $("input[@name='poll']:checked").attr("value"); id = id.replace("opt",'');

input[@name='poll']:checked is a jQuery selector that selects a <input> with an attribute ofname='poll' that is checked. attr("value") gets the value of the object which in our case is optn wheren is the ID of the option. Now that we have the ID, we can process it. To start, we fade out the poll form, and setup an anonymous function as a callback that is run when the fade is complete. Animations dont pause the script, so weird things happen if you dont do it this way.
view plaincopy to clipboardprint?

1.

$("#poll-container").fadeOut("slow",function(){

After it has faded out we can delete the form from the DOM using empty():
view plaincopy to clipboardprint?

1.

$(this).empty();

In this case, $(this) is jQuery shorthand for the DOM element that the fade was applied to. jQuery has some other shortcut functions, including $.getJSON() which does GET request for a JSON object. When we have the object, we call loadResults() with it:
view plaincopy to clipboardprint?

1.

$.getJSON("poll.php?vote="+id,loadResults);

The last thing to do is set the cookie:

view plaincopy to clipboardprint?

1.

$.cookie('vote_id', id, {expires: 365});

loadResults()
view plaincopy to clipboardprint?

1. function loadResults(data) { 2. var total_votes = 0; 3. var percent; 4. 5. for (id in data) { 6. total_votes = total_votes+parseInt(data[id][OPT_VOTES]); 7. } 8. 9. var results_html = "<div id='poll-results'><h3>Poll Results</h3>\n<dl class='graph'>\n"; 10. for (id in data) { 11. percent = Math.round((parseInt(data[id][OPT_VOTES])/parseInt(total_votes))*100); 12. if (data[id][OPT_ID] !== votedID) { 13. results_html = results_html+"<dt class='bar-title'>"+data[id][OPT_TITLE]+"</dt><dd class='barcontainer'><div id='bar"+data[id][OPT_ID]+"'style='width:0%;'>&nbsp;</div><strong>"+percent+"%</strong></dd>\n"; 14. } else { 15. results_html = results_html+"<dt class='bar-title'>"+data[id][OPT_TITLE]+"</dt><dd class='barcontainer'><div id='bar"+data[id][OPT_ID]+"'style='width:0%;backgroundcolor:#0066cc;'>&nbsp;</div><strong>"+percent+"%</strong></dd>\n"; 16. } 17. } 18. 19. results_html = results_html+"</dl><p>Total Votes: "+total_votes+"</p></div>\n"; 20. 21. $("#poll-container").append(results_html).fadeIn("slow",function(){ 22. animateResults();}); 23. }

loadResults() is called by $.getJSON() and is passed a JSON object containing the results DB. It is pretty much the same as its PHP counterpart poll_return_results() with a few exceptions. The first difference is that we set the width on all the bars to 0% because we will be animating them. The other difference is that we are using a jQuery append() instead of regex to show the results. After the results fade in, the function calls animateResults().

animateResults()
view plaincopy to clipboardprint?

1. 2. 3. 4. 5. 6. 7.

function animateResults(){ $("#poll-results div").each(function(){ var percentage = $(this).next().text(); $(this).css({width: "0%"}).animate({ width: percentage}, 'slow'); }); }

animateResults() iterates through each of the bars and animates the width property based on the percentage. each() is a jQuery function that iterates through each element that is selected:
view plaincopy to clipboardprint?

1.

$("#poll-results div").each(function(){

First, we set the percentage to the text of the element next to the bar which is the <strong> containing the percentage.

view plaincopy to clipboardprint?

1.

var percentage = $(this).next().text();

Then we make sure the width is set to 0%, and animate it:
view plaincopy to clipboardprint?

1. 2.

$(this).css({width: "0%"}).animate({ width: percentage}, 'slow');

Tags: jQuery

Enjoyed this Post? Subscribe to our RSS Feed, Follow us on Twitteror simply recommend us to friends and colleagues!

By Jonathan Rudenberg Rollover to read this author's bio or click through to see a full list of posts by this author.

Plus Premium

Premium Members
Source Files, Bonus Tutorials & More for all relevant Tuts+ sites in one subscription. Join Now
Sign In

Add Comment

Discussion 254 Comments


Comment Page 8 of 8 1 ... 6 7 8

1.

bungabunga
December 15, 2010 at 7:54 am

If you use a PHP version < 5.2 then you should move the json_encode() function definition at the beginning of the script poll.php.
REPLY

2.

Richard
January 13, 2011 at 11:51 am

Hi.. Yes, even the demo is not working. Heres a fix that worked for me. 1. Edit poll.php Replace: $id = $_GET['vote'] || $_POST['vote']; With: $id = isset($_GET['vote']) ? $_GET['vote'] : $_POST['vote']; and Replace: $id = $_GET['poll'] || $_POST['poll']; With: $id = isset($_GET['poll']) ? $_GET['poll'] : $_POST['poll']; 2. After editing the 2 lines in the poll.php file, make sure: - Delete the cookies in your browser - Delete your IP in /data/ips.txt 3. Make sure you have R/W permission on the data/ folder You can see the working poll here -> http://www.explorephilippines.org near the bottom of the home page.

REPLY

fano
December 10, 2011 at 12:54 pm

Had the common ips.txt updates but vote.txt wont issue. In addition to Richards tweaks, I added a closing ?> tag in poll.php and set both text files permissions to: 644 and voila! Hope that can help.

Tutorials\ JavaScript & AJAX \Rating: 1 2 3 4 5

How To Create An Amazing jQuery Style Switcher


James Padolsey on Aug 26th 2008 with 113 comments In this tutorial I will be showing you how to create a style switcher using jQuery and PHP. The end result will be an unobtrusive & entirely degradable dynamic style switcher which will be quick and easy to implement.

Step 1: The HTML


First, we need to create our basic HTML file and save it as index.php:
view plaincopy to clipboardprint?

1.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1strict.dtd"> 2. <html xmlns="http://www.w3.org/1999/xhtml"> 3. <head> 4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5. <title>Style Switcher</title> 6. <?php 7. // Checks for, and assigns cookie to local variable: 8. if(!empty($_COOKIE['style'])) $style = $_COOKIE['style']; 9. // If no cookie is present then set style as "day" (default): 10. else $style = 'day'; 11. ?> 12. 13. <!-- StyleSheet --> 14. <link id="stylesheet" type="text/css" href="css/<?php echo $style ?>.css" rel="stylesheet" /> 15. 16. <!-- jQuery --> 17. <script type="text/javascript" src="js/jquery.js"></script> 18. 19. <!-- Our plugin --> 20. <script type="text/javascript" src="js/styleswitcher.jquery.js"></script> 21. 22. </head> 23. <body> 24. <div id="container"> 25. <h1>Style-Switcher Example</h1> 26. <ul id="nav"> 27. <li><a href="#">Home</a></li> 28. <li><a href="#">About</a></li> 29. <li><a href="#">Services</a></li> 30. <li><a href="#">Products</a></li> 31. <li><a href="#">Links</a></li> 32. <li><a href="#">Contact</a></li> 33. </ul> 34. <div id="banner"></div> 35. <div id="content"> 36. <h2>NETTUTS Tutorial Example</h2> 37. <p>Page content...</p> 38. </div> 39. <div id="foot"> 40. <p>Footer stuff...</p> 41. </div> 42. 43. <!-- StyleSheet selection: --> 44. <div id="style-switcher"> 45. <h4>Choose your style:</h4> 46. <ul> 47. <li id="day"><a href="style-switcher.php?style=day">Day</a></li>

48. <li id="night"><a href="style-switcher.php?style=night">Night</a></li> 49. </ul> 50. </div> 51. 52. </div> 53. 54. <script type="text/javascript"> 55. $('#style-switcher a').styleSwitcher(); // Calling the plugin... 56. </script> 57. 58. </body> 59. </html>

Youll see that there is some PHP up there just below the title attribute in the head. Its very simple all it does is check for a cookie called style if it exists then it assigns it to the local variable (also called style) and if the cookie doesnt exist, it assigns the default theme (day) to the $style variable. This variable is then echoed out within the href attribute of the link element (href="css/<?php echo $style ?>.css"). Youll see that the style-switcher div is included above in our HTML. There is no need to add this using JavaScript because the method were using will allow the style-switcher to work when JavaScript is disabled. The two links (night & day) take the user to a file called style-switcher.php with an appended query string specifying the corresponding theme (e.g. href="styleswitcher.php?style=day"). Ive also called the a jQuery plugin called styleSwitcher. This has not been developed yet (well, it will have by the time you read this), so hold on! We will be writing this plugin in step 4 of this tutorial.

Step 2: The CSS


Now, we need to create a couple of CSS StyleSheets for our HTML. Ive decided to create just two StyleSheets one will have the theme of Day and the other will have the theme of Night and Ive named them appropriately. (day.css & night.css)

The Day theme:

The Night theme:

Its best to start with one style and then copy across all the selectors to the alternative StyleSheet and then all that needs changing are the various CSS rules and declarations. Obviously you can have as many StyleSheets as you want but in this tutorial were using two for illustrative purposes. Plus night and day go well together as a duo!

day.css:
view plaincopy to clipboardprint?

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.

#dummy-element{width:2px;} /* Necessary to check if StyleSheet has loaded */ /* Quick Reset */ body,ul,ol,li,img,form,p,h1,h2,h3,h4,h5,h6,blockquote { margin: 0; padding: 0; border: none; list-style: none; font-weight: normal; } /* General / Header */ body {background: #98beeb url(../img/day-body-bg.jpg) repeat-x; } #container { width: 60%; margin: 0 auto; min-width: 400px;

18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78.

max-width: 800px; position: relative; } h1 { text-align: left; text-transform: uppercase; color: white; font-size: 1.4em; padding: 45px 30px 10px 30px; } /* Navigation */ #nav { padding: 5px 5px 0 0; overflow: hidden; } #nav li {display: inline;} #nav a { float: left; color: #6195ce; font-weight: bold; text-decoration: none; padding: 3px 6px; margin-left: 5px; background: white; } #nav a:hover {color: #2c5a8c;} /* Banner */ #banner { height: 125px; background: url(../img/day-banner.jpg) center; border: 5px solid white; clear: both; } /* Content Area */ #content { border: 10px solid white; background: white; color: #2c5a8c; margin: 5px 0; } #content a {font-weight: bold;} #content a:hover {text-decoration: underline;} h2 { padding: 0.3em 0; font-size: 1.4em; } p {padding: 0.3em 0;} /* Footer */ #foot { background: white; color: #1f3a57; text-align: center; border: 10px solid white; clear: both; } #foot a { text-decoration: none;

79. font-weight: bold; 80. color: #2c5a8c; 81. } 82. #foot a:hover {text-decoration: underline;} 83. 84. /* Style-Switcher */ 85. #style-switcher { 86. position: absolute; 87. width: 100%; 88. top: 0; 89. left: 0; 90. rightright: 0; 91. height: 34px; 92. background: #79a3cc url(../img/day-ss-bg.jpg); 93. border-bottom: 1px solid white; 94. } 95. #style-switcher ul { 96. border-right: 1px solid white; 97. float: rightright; 98. } 99. #style-switcher h4 { 100. display: inline; 101. color: #153c67; 102. font-weight: bold; 103. line-height: 34px; 104. padding: 0 10px; 105. float: left; 106. border-left: 1px solid white; 107. } 108. #style-switcher li {display: inline;} 109. #style-switcher li a { 110. float: left; 111. line-height: 26px; 112. color: white; 113. background: #90a6bb; 114. text-decoration: none; 115. padding: 0 13px; 116. display: inline; 117. margin: 4px 4px 4px 0; 118. } 119. #style-switcher li a:hover {background: #3a5a7c;}

night.css:
view plaincopy to clipboardprint?

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.

#dummy-element{width:2px;} /* Necessary to check if StyleSheet has loaded */ /* Quick Reset */ body,ul,ol,li,img,form,p,h1,h2,h3,h4,h5,h6,blockquote { margin: 0; padding: 0; border: none; list-style: none; font-weight: normal; } /* General / Header */ body { font-family: Calibri,"Arial Narrow",Arial,Sans-Serif; background: #072952 url(../img/night-body-bg.jpg) repeat-x; }

17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77.

#container { width: 60%; margin: 0 auto; min-width: 400px; max-width: 800px; position: relative; } h1 { text-align: left; text-transform: uppercase; color: white; font-size: 1.4em; padding: 45px 30px 10px 30px; font-family: "Times New Roman", Times, serif; } /* Navigation */ #nav { padding: 5px 5px 0 0; overflow: hidden; } #nav li {display: inline;} #nav a { float: left; color: #010e2e; font-weight: bold; text-decoration: none; padding: 8px 6px 3px 6px; font-size: 0.8em; text-transform: uppercase; font-weight: 700; margin-left: 5px; background: white url(../img/night-nav-bg2.jpg) repeat-x; } #nav a:hover {color: #2c5a8c;} /* Banner */ #banner { height: 125px; background: url(../img/night-banner.jpg) center; border: 5px solid white; clear: both; } /* Content Area */ #content { color: white; margin: 20px 0; padding: 5px 0; border-top: 4px double white; border-bottom: 4px double white; font-family: "Times New Roman", Times, serif; } #content a {font-weight: bold;} #content a:hover {text-decoration: underline;} h2 { padding: 0.3em 0; font-size: 1.4em; } p {padding: 0.3em 0;}

78. /* Footer */ 79. #foot { 80. color: white; 81. font-size: 0.8em; 82. clear: both; 83. } 84. #foot p { 85. text-align: center; 86. padding: 0; 87. } 88. #foot a { 89. text-decoration: none; 90. font-weight: bold; 91. color: white; 92. } 93. #foot a:hover {text-decoration: underline;} 94. 95. /* Style-Switcher */ 96. #style-switcher { 97. position: absolute; 98. width: 100%; 99. top: 0; 100. left: 0; 101. rightright: 0; 102. height: 34px; 103. } 104. #style-switcher ul {float: left;} 105. #style-switcher h4 { 106. display: inline; 107. color: white; 108. font-weight: bold; 109. line-height: 34px; 110. padding: 0 10px; 111. float: left; 112. } 113. #style-switcher li {display: inline;} 114. #style-switcher li a { 115. float: left; 116. line-height: 34px; 117. color: white; 118. text-decoration: none; 119. padding: 0 4px; 120. margin-left: 5px; 121. display: inline; 122. } 123. #style-switcher li a:hover { 124. background: white; 125. color: #13181c; 126. background: white url(../img/night-ss-bg.jpg) repeat-x left bottombottom; 127. }

This is not really a CSS tutorial so I wont be delving into any of the above, but if you have any questions then please feel free to ask them in the comments section. And yes, I know that min-width is not supported in older browsers! ;)

Step 3: style-switcher.php

This is where we write the core functionality of the style switcher. It is actually just a few lines of very basic PHP code. You should create a new file called style-switcher.php and copy the following into it:
view plaincopy to clipboardprint?

1. 2. 3. 4. 5. 6. 7. 8. 9.

<?php $style = $_GET['style']; setcookie("style", $style, time()+604800); // 604800 = amount of seconds in one week if(isset($_GET['js'])) { echo $style; } else { header("Location: ".$_SERVER['HTTP_REFERER']); } ?>

So, what the above code does is assign the style GET variable to a local $style variable. In other words it will take the value of the style property within the query string (styleswitcher.php?style=day). It then sets a cookie (for one week) called style we will be able to retrieve this cookie on our main index.php with the code shown in step 1 (remember that little chunk of PHP in the head?). Next, it checks to see if js is appended to the query string. If it is then we know that JavaScript (which we have yet to write) has requested this PHP script. The else condition occurs when a user does not have JavaScript enabled and redirects the user to the referrer (i.e. the page they just came from) this will become clearer once weve written the jQuery stuff!

Step 4: The jQuery stuff


You can, if you want, stop right here! The solution thus far will work perfectly, but as I stated in the intro we are going to make it even cooler with some jQuery awesomeness! Not only are we going to allow the user to change their theme without refreshing the page but we are also going to add a really cool fading effect I mean, what type of jQuery tutorial would this be if there was no fading!?!? Obviously this is all possible without having to create a plugin but I thought it would be a good learning experience for all you, plus it allows us to adapt or transfer the code quickly and easily. First off, lets create a file called styleswitcher.jquery.js. Making a new plugin in jQuery is extremely simple; all it takes is the following code:
view plaincopy to clipboardprint?

1. 2. 3.

jQuery.fn.styleSwitcher = function(){ // The code goes here... }

So, first we want to specify what happens when one of the StyleSheet links are clicked on (those withindiv#style-switcher):
view plaincopy to clipboardprint?

1. 2. 3. 4. 5. 6. 7. 8.

/* "this" refers to each instance of the selected element, * So, if you were to call the plugin like this: * $('a').styleSwitcher(); then the following would occur * when clicking on any anchor within the document: */ $(this).click(function(){ // We're passing this element object through to the

9. // loadStyleSheet function. 10. loadStyleSheet(this); 11. // And then we're returning false. 12. return false; 13. });

loadStyleSheet:
Now we need to write the loadStyleSheet function:
view plaincopy to clipboardprint?

1. function loadStyleSheet(obj) { 2. 3. // Append new div to body: 4. $('body').append('<div id="overlay" />'); 5. 6. // Give body a height of 100% (to fix IE6 issue): 7. $('body').css({height:'100%'}); 8. 9. // Select newly created div and apply some styles: 10. $('#overlay') 11. .css({ 12. display: 'none', 13. position: 'absolute', 14. top:0, 15. left: 0, 16. width: '100%', 17. height: '100%', 18. zIndex: 1000, 19. background: 'black url(img/loading.gif) no-repeat center' 20. }) 21. 22. // Now fade in the div (#overlay): 23. .fadeIn(500,function(){ 24. 25. // The following will happen when the div has finished fading in: 26. 27. // Request PHP script (obj.href) with appended "js" query string item: 28. $.get( obj.href+'&js',function(data){ 29. 30. // Select link element in HEAD of document (#stylesheet) and change href attribute: 31. $('#stylesheet').attr('href','css/' + data + '.css'); 32. 33. // Check if new CSS StyleSheet has loaded: 34. cssDummy.check(function(){ 35. 36. // When StyleSheet has loaded, fade out and remove the #overlay div: 37. $('#overlay').fadeOut(500,function(){ 38. $(this).remove(); 39. }); 40. }); 41. }); 42. }); 43. }

I hope the comments explained it sufficiently. The more attentive of you will have noticed that we are calling a currently undefined function (cssDummy.check()). Dont worry because that is the next step

cssDummy:
We need a way of testing whether a StyleSheet has loaded. If it has loaded then we can make the overlay div disappear, but if it hasnt we have to keep on checking until it does load. I did a bit of searching around the net and found a reliable way of testing such a thing. It involves testing for the computed width of a dummy element. The width of this element will be defined in the CSS and so the computed width of the element will only equal the width defined in the CSS when the StyleSheet has loaded. I hope you now understand why we had to include that #dummy-element rule in each CSS file So, here it is:
view plaincopy to clipboardprint?

1. var cssDummy = { 2. init: function(){ 3. // Appends "dummy-element" div to body: 4. $('<div id="dummy-element" style="display:none" />').appendTo('body'); 5. }, 6. check: function(callback) { 7. 8. // Checks if computed with equals that which is defined in the StyleSheets (2px): 9. if ($('#dummy-element').width()==2) callback(); 10. 11. // If it has not loaded yet then simple re-initiate this 12. // function every 200 milliseconds until it had loaded: 13. else setTimeout(function(){cssDummy.check(callback)}, 200); 14. } 15. }

And, right at the end of our plugin were going to call the cssDummy.init function: cssDummy.init(); Were done! The entire plugin now looks like this:
view plaincopy to clipboardprint?

1. jQuery.fn.styleSwitcher = function(){ 2. $(this).click(function(){ 3. loadStyleSheet(this); 4. return false; 5. }); 6. function loadStyleSheet(obj) { 7. $('body').append('<div id="overlay" />'); 8. $('body').css({height:'100%'}); 9. $('#overlay') 10. .css({ 11. display: 'none', 12. position: 'absolute', 13. top:0, 14. left: 0, 15. width: '100%', 16. height: '100%', 17. zIndex: 1000, 18. background: 'black url(img/loading.gif) no-repeat center' 19. }) 20. .fadeIn(500,function(){ 21. $.get( obj.href+'&js',function(data){ 22. $('#stylesheet').attr('href','css/' + data + '.css'); 23. cssDummy.check(function(){ 24. $('#overlay').fadeOut(500,function(){

25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. }

$(this).remove(); }); }); }); }); } var cssDummy = { init: function(){ $('<div id="dummy-element" style="display:none" />').appendTo('body'); }, check: function(callback) { if ($('#dummy-element').width()==2) callback(); else setTimeout(function(){cssDummy.check(callback)}, 200); } } cssDummy.init();

We can now call the jQuery plugin like this: $('#style-switcher a').styleSwitcher();

Finished!
If youre not sure about the file structure then download the src files to have a look. I hope you enjoyed reading through this tutorial. As always, if you have any questions feel free to ask them below! If you enjoyed this posting, please Digg it!

0digg

15 Days Of jQuery
Examples and tutorials to help you learn JQuery

About the Author Content For Your Site Subscribe Subscribe Success Email Policy

Search

Style Sheet Switcheroo

02JUN
Posted by Jack as Tutorials

The first time I saw a style sheet switcher I was either reading A List Apart or Simple Bits, both excellent sites you should visit if you are serious about design.

Since then, Ive seen many different methods for allowing a visitor to switch a stylesheet with a click of a mouse. But recently I came across a short example of how to do it with jQuery. I want to show you this example and walk you through it because it not only gives another fine example of the short code you can write with jQuery but also too illustrate some of the more advanced features of the jQuery javascript library.

First, The Code


$(document).ready(function() { $('.styleswitch').click(function() { switchStylestyle(this.getAttribute("rel")); return false; }); var c = readCookie('style'); if (c) switchStylestyle(c); }); function switchStylestyle(styleName) { $('link[@rel*=style]').each(function(i) { this.disabled = true; if (this.getAttribute('title') == styleName) this.disabled = false; }); createCookie('style', styleName, 365); }
What Ive left out of the demonstration are the functions youll see later for creating and reading the cookies.

Familiar Ground
$(document).ready(function() { $('.styleswitch').click(function()
The beginning of the code tells jQuery As soon as possible, get all elements with the class name of styleswitch and fire off a function when the element is clicked. So far so good. When these chosen elements are clicked the switchStylestyle function will be called. So thats where we turn our attention next.

What In The World?


The first time I really looked closely at this I was stumped:

$('link[@rel*=style]').each(function(i) {

After searching the web and coming up empty handed I contacted John Resig, the creator of jQuery, and asked him for some hints. He directed me to some pages on the jQuery site that explain some of the more advanced ways that jQuery can be used to find and manipulate elements on a page. If you read the short explanations and examples here youll soon see that this mysterious line of code tells jQuery Find all link elements with a rel attribute containing the string style. Huh? Lets look at how we would create a page with one main stylesheet and two alternate ones:

<link rel="stylesheet" type="text/css" href="styles1.css" title="styles1" media="screen" /> <link rel="alternate stylesheet" type="text/css" href="styles2.css" title="styles2" media="screen" /> <link rel="alternate stylesheet" type="text/css" href="styles3.css" title="styles3" media="screen" />
Notice how all of the links to the stylesheets have a rel attribute with stylesomewhere between the quotation marks. So, in short, this code is telling jQuery to target all of the stylesheet links in the page.

What Next?
The each() function loops through each of the stylesheet links and performs the operations spelled out in the next few lines of code:

this.disabled = true; if (this.getAttribute('title') == styleName) this.disabled = false;


Disable every stylesheet link but then un-disable any link where the title attribute is the same as the value passed to the switchStylestyle function Thats a mouthful too, but its really not that tough. What were doing is matching the rel attribute of the links on our page (the clickable links for switching the stylesheets) with the title attribute of the stylesheets (and alternates) available to us. When one of the clickable links is clicked, a function is called, which finds all the stylesheets, disables all of them, and then turns one back on the one where the title of the stylesheet link matches the rel attribute of the link clicked. Whew!

Full Code and Demos


Since Kelvin Luck already created the code, no need for me to replicate it here.

Demo Code I wont link directly to the zip, since thats sometimes seen as rude. Go to this page and at the bottom is a link to the zip.

Compare to Other Code


I believe ol Kelvin got his inspiration from this site where youll see that to do this without jQuery is a little bit more complicated and you dont get all the benefits of Kelvins code namely the long term memory of stylesheet chosen. [tags]jQuery, javascript, DOM, cookie, stylesheet, css, alternate stylesheets[/tags]

36 Responses 1. Sam
June 18th, 2006 at 6:51 pm

1
Thanks for taking time to post these examples. Heres my 2-cents on further code reduction: Replace this.disabled = true; if (this.getAttribute(title) == styleName) this.disabled = false; With this.disabled = this.getAttribute(title) != styleName;

2. v
June 19th, 2006 at 7:53 pm

2
Doesnt work in Safari.

3. joon
October 23rd, 2006 at 11:30 am

3
Is $(document).ready(function().. absolutely necessary in this case? In Safari the default style sheet is rendered for a split second then the chosen style is loaded on each page load. If its possible, let the browser execute as its being read. Me (big noob) has to test it out. Thanks for the tutorials.!

4. nic
April 3rd, 2007 at 7:50 pm

4
How would you modify this code to load a specific style sheet based on an attribute in the ? Ive been mucking around in the code and Ive gotten totally confused. Thanks for all the tutorials, youve gotten me hooked on jquery.

5. nic
April 3rd, 2007 at 7:51 pm

its supposed to say based on an attribute in the body tag.

6. Jack
April 4th, 2007 at 11:49 am

6
Should be easy enough, just grab the class or attribute of the body tag, and pop that into the mix. This is an untested quickie based on an id: $(body).each(function(){ switchStylestyle(this.id); }); But I also think that you can perform the same or similar without the use of javascript by putting a class name and/or id in the body tag of your document, and then putting the appropriate rules in your css body#one p { color: black; } body#two p { color: red;}

7. nic
April 4th, 2007 at 7:32 pm

7
Jack, Thanks for the example, thats exactly what I needed. Ive been doing the tutorials on jQuery and I literally know 200% more than when I wrote that first question. The problem Im trying to solve is that we want to have an individual style for multiple users on the same set of pages. For example two people visit page Cranberry, if user A came from page Apple they would have the Apple style loaded, and if user B came from page Banana they would have the Banana style loaded. If someone visited Cranberry straight up they would see the default theme. We already had this system in place using an onLoad script, but I wanted to switch over to jQuery.

8. Mike
April 26th, 2007 at 12:42 pm

8
Oops, forgot to mention one thing. In the line that generates the random number: var randNum = Math.floor(Math.random() * 4); Change the number you are multiplying by, in this case 4, to the number of alternate stylesheets you have listed, or one more than the last title number. In my case I have 4 alternate stylesheets numbered 0 through 3, so I multiply by 4.

p 1 Lets start with the necessities

Create a new folder in your wp-content/themes/ folder, and name it whatever you want to name the skin were about to make. Make 2 new files in this new folder, one called index.php and the other style.css. We are going to start off with some basic wordpress code. This base code is what I start off with every time I create a full wordpress skin, because it includes most of the necessary information. Ive kept it in here because you might want to develop this into a full skin. I also use a default stylesheet for my themes, so copy this code snippet into your style.css, and edit the content respectively. The stylesheet is reled in with the line:
view plaincopy to clipboardprint?

1.

<link rel="stylesheet" href="<?php bloginfo('stylesheet_url'); ?>" type="text/css" media="screen" />

Youll also need 2 JavaScript files, one being a copy of jQuery and an empty .js file called myTheme.js. Dont forget to rel these in with this in your head element:
view plaincopy to clipboardprint?

1. 2.

<script type="text/javascript" src="<?php bloginfo('template_directory'); ?>/jquery-1.2.6.min.js"></script> <script type="text/javascript" src="<?php bloginfo('template_directory'); ?>/myTheme.js"></script>

Dont forget to change the name of the jQuery rel if youre using a different package to me, which you most likely are. myTheme.js must come under the jQuery link, not above. Note: jQuery 1.2.6 is also packaged with WordPress 2.2 and above, so if you dont want to download it, you can find it in wp-includes/js/jquery/jquery.js. To include THIS jQuery document, use this instead of the jQuery rel above. Youll still need myTheme.js though!
view plaincopy to clipboardprint?

1.

<script type="text/javascript" src="<?php bloginfo('url'); ?>/wp-includes/js/jquery.js"></script>

Step 2 The PHP/Wordpress/XHTML code.


Once youve selected and activated your new theme, open index.php with your favourite editor, and lets get coding!

Here is all the XHTML/PHP/Wordpress code we need to set out the content and the metadata for each post. Paste or type it inbetween the html open and close tags. I will explain it bit by bit below!
view plaincopy to clipboardprint?

1. <div id="wrapper"> 2. <?php if(have_posts()) : ?><?php while(have_posts()) : the_post(); ?> 3. 4. <div class="post"> 5. 6. <div class="left"> 7. <p class="postmetadata"> 8. <strong>Post Details</strong><br /> 9. Posted: <em><?php the_time('l, jS F, Y'); ?></em> 10. at <em><?php the_time('g:i a'); ?></em>.<br /> 11. Written by: <em><?php the_author(); ?>.</em><br /> 12. Number of comments: <em><?php the_comments_number('none', '1', '%'); ?></em>.<br /> 13. Posted in: <em><?php the_category(', '); ?></em>. 14. </p> 15. </div><!-- end div.left --> 16. 17. <div class="right"> 18. <h2><?php the_title(); ?></h2> 19. <div class="entry"> 20. <?php the_content('more...'); ?> 21. </div><<!-- end div.entry --> 22. </div><!-- end div.right --> 23. 24. </div><!-- end div.post --> 25. 26. <?php endwhile; ?> 27. <?php endif; ?> 28. </div><!-- end div#wrapper -->

Divs
view plaincopy to clipboardprint?

1.

<div id="wrapper">

The wrapper div basically wraps the whole thing so we can lay it out nicely later on. All divs are pretty self explanitory, and I have also commented in the ends of the divs, so Ill skip them while explaining. In short, Ive wrapped everything accordingly so its easy to style. the .left div is the left column, the .right div is the right column, the .entry div is the post entry, so on and so forth. Ive used classes within the loop, as if there are more than one posts, the ids would back up and create a validation error.

The famous WordPress Loop.


view plaincopy to clipboardprint?

1.

<?php if(have_posts()) : ?><?php while(have_posts()) : the_post(); ?>

If you dont get what this is, go back to wordpress school. It basically loops through the databases information in respect to the calls made within the loop. If you ask for the title, the loop will look into the database for the title for you.

The Posts MetaData.


view plaincopy to clipboardprint?

1. 2. 3.

<p class="postmetadata"> <strong>Post Details</strong><br /> Posted: <em><?php the_time('l, jS F, Y'); ?></em> at <em><?php the_time('g:i a'); ?></em>.<br />

4. 5. 6. 7.

Written by: <em><?php the_author(); ?>.</em><br /> Number of comments: <em><?php comments_number('none', '1', '%'); ?></em>.<br /> Posted in: <em><?php the_category(', '); ?></em>. </p>

Now for the nitty gritty stuff. Everything above contains the information that we want to display about the post. In respective order, we ask for; Date and Time We ask for the date in the format of l, jS F, Y (e.g. Sunday, 8th June, 2008), and the time in the format of g:i a (e.g. 4:45 pm). Ive used the_time(); twice, because if we use the_date();to ask for the date, it will only show it once per day. If you posted numerous posts on the same day, the date wouldnt show once per post, but once on the first post of the day. Author This is self explanitory, we are simply asking for the author of the post. Comments Number This calls for the number of comments on a post. If the post has no comments, it will return the value none. If it has one, it will return the value 1, and, yep you guessed it! If it has more than one, it will return a value like 21 or 6, all depending on how many comments the post has. Category the_category(); asks the database for the categories that a post have been assigned to. Thanks to wordpress, we dont have to worry about using an extensive and raw php foreach loop, as the (, ); seperates the categories with a comma for us. Thanks WordPress!

The Content.
view plaincopy to clipboardprint?

1. 2. 3. 4.

<h2><?php the_title(); ?></h2> <div class="entry"> <?php the_content('more...'); ?> </div><<!-- end div.entry -->

Does it get more self explanitory than that? We ask for the title (wrapped in a h2 element so we can style it accordingly), and the content (wrapped in a .entry div so that all content is nested in its own div for easy styling and access too.). more in brackets are for when you use the <! more > tag in the wordpress post editor.

Come on The loop end!


view plaincopy to clipboardprint?

1. 2.

<?php endwhile; ?> <?php endif; ?>

You code bunnies should get this Its the basic loop again! It closes off the loop so that only the contained functions within the loop are executed over and over.

Step 3 The CSS: Layout.


Phew! Youve braved all the wordpress code we need for this tutorial! Well done! It should look something ugly like this:

Note: I have used content from my own local server (which happens to be from my own blog) as filler content, so your content wont reflect mine. Now that weve got all the xhtml and php functions out of the way, we can move onto making it look pretty with css! Joy! Open up style.css once again with your favourite editor, and if you havent already, paste this code into it. But you should have done that anyway, because otherwise you wouldnt have been able to activate the theme! In this tutorial, I utilise the beauty of csss float and clear to float the post details (or metadata, whatever you want to call it), and the content side by side, and one post after the other. Here is the basic layout code: (NOTE: This will NOT make your page pretty JUST yet.)
view plaincopy to clipboardprint?

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.

/*-----LAYOUT-----*/ #wrapper{ width: 600px; margin: 0 auto; } .post{ clear: both; width: 600px; } .post .left{ width: 180px;

14. float: left; 15. padding-right: 20px; 16. } 17. 18. .post .rightright{ 19. width: 400px; 20. float: rightright; 21. padding: 0 25px 20px; 22. }

Simple: #wrapper These attributes place everything we have in the middle our page, and at 600px wide. #post the posts may accidentally ride up next to a poorly floated previous post, or one that doesnt have enough content because were using floats. The clear attribute makes sure that its pushed all the way to the bottom of the previous element, no matter what. .left and .right divs These are floated left and right respectively, because this is what makes them go side by side! If we didnt set the widths of the divs though, this technique wouldnt work. Ive made the post details column slightly slimmer than the content column, because we want more attention and more space for the content (considering there is less content in the post details column). Ive done my math, and made sure that the total width adds up to 600 so both columns fit nicely into the parent .post div:180px+20px(padding, so we have some spacing)+400px=600px Yay! Now, lets make it pretty looking!

Step 4 The CSS: Styling.


So weve got the skeleton layout down pat, but it still looks kinda ugly:

This is when we use the true power of our cascading stylesheets. Copy or type the following into your style.css underneath the previous Layout code:
view plaincopy to clipboardprint?

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24.

/*-----STYLES-----*/ body{ font: 75%/18px Georgia, "Times New Roman", Times, serif; background-color: #e4e4e4; } a{ color: #006082; text-decoration: none; } .post .left{ text-align: rightright; color: #898989; } .post .left p.postmetadata strong{ display: block; text-transform: uppercase; } .rightright{ background-color: #fff;

25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41.

min-height: 150px; } .entry{ color: #3c3c3c; } .entry p img{ padding: 0 10px 7px 0; float: left; } a.more-link{ display: block; padding-top: 10px; text-transform: uppercase; }

The Breakdown.
This is a handful of code to process, and it might all look daunting, but its actually really simple! Because majority of you are probably adequate at CSS, Ill be quick and snappy through this part. body Here it is that we set the standard text/font size, and the background colour a Makes all links look pretty.

.post .left Change the colour of the text to a grey shade, and align the paragraphs to the right. .post .left. p.postmetadata strong Makes the Post Details stand out by capitalising it, and changes the strong element to a block element to line up the post details with the content paragraphs. .right This is a little confusing, so Ill explain this in depth. Obviously, the background colour is now white, so that the content jumps off the page. The min-height attribute though, is so that if the post content is actually shorter than the post details, it will not break the continuous white colour down the page. .entry Makes the content text a dark grey. .entry p img gives any images within the content area to breath, and also allows the text to wrap around the

image. a.more-link The more-link class is automatically added by wordpress to single out the more that we added into the_content() function. We turn it capital, so the users assume its not a regular/external link, and give it some space too. That CSS should bring it to look something like this:

Step 5 The jQuery.


So its very important it looks all good without any JavaScript The above compensates for us here. But to create our true newspaper style degrading headers, we need some tasty jQuery! Open up myTheme.js and lets get cracking! What we want to achieve, is something like this (photoshop mockup):

Notice the difference? Were going to increase the size of the first hero posts header, and change the colour also. Then, the second or villain post will be slightly grey with an even smaller size, and the consecutive posts after that will remain a uniform size. Were going to tackle this by adding the classes hero and villain to our first and second .post divs respectively, to which well then style with a little additional CSS. We add the class to the .post divs and not

the h2 elements because we want to change some of the contained content too, for example the size of the content and the additional icon on the more-link in the hero post. Why hero and villain you ask? Because the Villain always comes after the Hero. And its an easy concept to grasp. It sounds complicated, but its actually only 4 lines of (spaced out) code. This all goes into myTheme.js:
view plaincopy to clipboardprint?

1. 2. 3. 4.

$(document).ready(function(){ $(".post:first").addClass("hero"); $(".post:nth-child(2)").addClass("villain"); });

Great! Non-intrusive JavaScript! I love it! It should be in myTheme.js.

Explanation
We have just used a tiny bit of jQuerys incredibly powerful, valuable and versatile selectors. We have now unobtrusively added the classes .hero to the first .post div on the page, and the class .villain to the second .post div on the page. Let me explain how.

view plaincopy to clipboardprint?

1.

$(document).ready(function(){

This is jQuerys super special function of initiating the JavaScript function that is defined after this line. When the $(document) is .ready() initiate the function(){} we are about to define. Using$(document).ready(function(){ is much faster than using the default: window.onload() function, because the window.onload() function waits for the entire document to load. This includes all images, iframes, etc. We only need to wait the the core XHTML document is finished loading to run our script so we use jQuerys special $(document).ready(function(){ to make things go faster, and have less lag between initial browsing time and javascript initiation. Kinda confusing huh? To make it simple, jQuerys method is faster. Remember that.

view plaincopy to clipboardprint?

1.

$(".post:first").addClass("hero");

Yay for powerful selectors! jQuery has an amazing array of selectors, some that are from CSS3, but we can use them now. This line, tells us to get: $() the first .post element: .post:first and add the class hero: .addClass(hero) to it. We can now style this in CSS, yet we still havent touched or changed the XHTML code of the .post div in any way.

view plaincopy to clipboardprint?

1.

$(".post:nth-child(2)").addClass("villain");

More super strong selectors! jQuery not only lets us select the :first element of a kind, but also lets us select any number of the elements! Using :nth-child(#) we can select any type of the element we want on a page. If we wanted the 30th <p> on the page, the markup would be $(p:nth-child(30)). Simple to understand? jQuerys selectors arent limited to numbers though! There are many many more selectors that let you chose the exact element you need. You can view them by visiting the selector section on the jQuery docs.

Step 6 The jQuery CSS.


Great. With all that out of the way, we can now focus on the visual side of things. No more explaining needed, lets delve into the CSS. Add or type this at the very bottom of style.css in the myTheme folder. For the more-link to work, download this arrow from the famfamfam silk icon pack, and place it in the a new folder images within the myTheme folder.
view plaincopy to clipboardprint?

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45.

/*-----jQUERY-----*/ .hero .left p.postmetadata{ margin-top: 30px; } .hero .left p.postmetadata strong{ margin-bottom: 20px; } .hero .rightright h2{ font-size: 46px; font-style: italic; font-weight: normal; margin-bottom: 0.5em; } .hero .rightright p{ font-size: 14px; } .hero a.more-link{ background: url(images/arrow_right.png) no-repeat rightright bottombottom; float: left; padding-right: 20px; } .villain .left p.postmetadata{ margin-top: 20px; } .villain .left p.postmetadata strong{ margin-bottom: 15px; } .villain .rightright h2{ font-size: 32px; font-weight: normal; color: #747474; } .villain .rightright p img{ float: rightright; padding: 0 0 7px 10px; }

Explanation
You should all be pretty adequate now with CSS, so Ill do a very quick run through of this new CSS.

This is the CSS that changes the look of the .hero post. .hero .left p.postmetadata We push it down a bit so its in line with our new header size. .hero .left p.postmetadata strong We push everything under the bolded post details down so its in line with the content text. .hero .right h2 This makes our hero header stand out. We make it bigger, and italicise it. .hero .right p Increase the font size of our hero content. .hero a.more-link Add the little green arrow from the famfamfam silk pack. And also, the CSS that changes the .villain post.

.villain .left p.postmetadata Does the same as the hero postmetadata, pushes it down. .villain .left p.postmetadata strong Does the same as the hero postmetadata alignement. .villain .right h2 Here we make the villain header grey, un-bolded and a little larger than the uniform posts. .villain .right p img The villain image has to stand out, right? We just float it to the right (so the text wraps around it) and change the padding accordingly.

Wrap Up
Well done! In this tutorial weve covered a basic method to spruce up our wordpress content using jQuerys selectors! They are not exclusive to jQuery however. Youll find all of these selectors in CSS3 (when all browsers support that!). We just love jQuery because they bring them to us now. Here is our final product.

Tags: jQuery

Enjoyed this Post? Subscribe to our RSS Feed, Follow us on Twitteror simply recommend us to friends and colleagues!

By Harley Rollover to read this author's bio or click through to see a full list of posts by this author.

Plus Premium

Premium Members
Source Files, Bonus Tutorials & More for all relevant Tuts+ sites in one subscription. Join Now
Sign In

Add Comment

Discussion 41 Comments
Comment Page 2 of 2 1 2

1.

Philo
July 18, 2008 at 12:44 am

Nice tutorial! :)
REPLY

Mass
October 10, 2009 at 1:06 am

Really
REPLY

2.

Ben Griffiths

July 18, 2008 at 1:30 am

This is really inventive I always imagine using jquery for an animation or ajax, never for anything like this. Thanks :)
REPLY

3.

Andrei Constantin
July 18, 2008 at 1:53 am

very nice, thanks a lot


REPLY

4.

Alistair
July 18, 2008 at 1:57

S-ar putea să vă placă și