Get last.fm Top Weekly Artist Chart to your Web site with PHP
<
I enjoy to play with json and xml files but did not use simplexml before. Dean Harris has a great script that pulls top tracks from last.fm. I needed one that is gonna pull the weekly chart. Changed his script a bit and here is the result.
Source Code
// Set up the required variables first
$method = "user.getweeklyartistchart"; //Enter method. Visit http://www.last.fm/api for more methods
$username = "username"; // Enter your username here
$apikey = "api key"; // Enter your API Key here. Visit http://www.last.fm/api/account if you dont have one
$limit = 5; //Enter the number of artist will be displayed
// Construct the URL, and feed it through SimpleXML
$feed = simplexml_load_file("http://ws.audioscrobbler.com/2.0/?method=".$method."&user=".$username."&api_key=".$apikey);
//Get Artists
$artist = $feed->weeklyartistchart->artist;
//Print Chart
for($i=0;$i<$limit;$i++){
$a = $artist[$i];
echo "#".($i+1)." - url."'>".$a->name." - ".$a->playcount." plays
";
}
You can also visit http://www.last.fm/tools/charts?subpage=gallery#gallery, generate your chart style and get the list to your website.
]]>
Hosting Git on GitHub and Dreamhost (Mac OS X & Windows)
<
Installing Git on Mac OS X
Installing the latest version of Git on OS X is pretty easy.
- Go to http://code.google.com/p/git-osx-installer/downloads/list and download/install the suitable version for your system (I downloaded git-1.7.3.3-x86_64-leopard.dmg)
Setup GitHub Repository
Username: "goksel" E-mail : "goksel@gmail.com" Project Name: "project" Remote Project Url : "git@github.com:goksel/project.git" Local Project Folder : "/Library/WebServer/Documents/project"
We are ready to setup our Repo:
-
git config --global user.name "Goksel Eryigit" git config --global user.email "goksel@gmail.com" ssh-keygen -t rsa -C "goksel@gmail.com"
-
cat ~/.ssh/id_rsa.pub | pbcopy
- Go to GitHub Account Settings > SSH Public Keys > Add another public key and paste the key you copied to key field.
-
cd /Library/WebServer/Documents git clone git@github.com:goksel/project.git
Setup Dreamhost Git Repository
SSH User: "goksel" Host: "geryit.com" Project Name : "project" Remote Repo Location : "/~/git/project.git" (means "/home/goksel/git/project.git")" Local Repo Location : "/Library/WebServer/Documents/project"
We are ready to setup our Dreamhost Repo:
-
git config --global user.name "Goksel Eryigit" git config --global user.email "goksel@gmail.com" ssh-keygen -t rsa
-
scp ~/.ssh/id_rsa.pub goksel@geryit.com:~/
-
ssh goksel@geryit.com
-
mkdir .ssh cat id_rsa.pub >> .ssh/authorized_keys rm id_rsa.pub chmod go-w ~ chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys eval `ssh-agent` ssh-add
-
mkdir git mkdir git/project.git cd git/project.git git --bare init exit
-
cd /Library/WebServer/Documents git clone ssh://goksel@geryit.com/~/git/project.git
Installing Git on Windows
We will install 3 software to run Git; Msysgit (Basic Git Tool), TortoiseGit (Git Client for Windows) and Putty (Helps us to SSH to Remote)
-
Download and install Msysgit.
-
Download and install TortoiseGit.
-
Download and install Putty (Find Installer Version)
-
Run Git Bash
-
Run these commands:
git config --global user.name "Your Name" git config --global user.email your-github-email@email.com
Now your Git username and email is created on your local.
-
Now run Pageant and Puttygen, generate keys, copy Public Key, save Private Key in Putty Format (ppk) to a safe place and add to Pageant.










GitHub
-
Go to GitHub, create a project, go to Account Settings > SSH Public Keys > Add another public key and paste key into key field and hit Add Key.



-
Go to github.com, get your github remote git url and clone your repo (by right click on local) to your local server with tortoisegit




Git on Dreamhost
There are two connection ways that you can setup your repository on Dreamhost: Html (WebDav) and SSH
WebDav
Webdav allows more then one user to push to the same repo but also slow.
There are two great posts that will help you to setup your repo:
http://priodev.blogspot.com/2010/02/hosting-your-git-repository-on.html and http://www.travisberry.com/2009/11/running-a-git-repo-on-dreamhost
SSH
I give the commands that will help you a lot. My SSH username is “goksel”, Remote Host is “geryit.com” and I will run my Remote Repo at “~/git/project.git” so I SSH with Git Bash (or Terminal) and :
ssh-keygen -t rsa scp ~/.ssh/id_rsa.pub goksel@geryit.com:~/ ssh goksel@geryit.com mkdir .ssh cat id_rsa.pub >> .ssh/authorized_keys rm id_rsa.pub chmod go-w ~ chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys eval `ssh-agent` ssh-add
mkdir git mkdir git/project.git cd git/project.git git --bare init exit
git clone ssh://goksel@geryit.com/~/git/project.git
You must see a project folder on your local server after clone command.
If you want your changes to be deployed on a live site you should play with hook files (On remote, under project.git/hooks)
Some very helpful posts
https://github.com/multitheftauto/multitheftauto/wiki/how-to-use-tortoisegit
http://wiki.dreamhost.com/Git
http://craigjolicoeur.com/blog/hosting-git-repositories-on-dreamhost
http://priodev.blogspot.com/2010/02/hosting-your-git-repository-on.html
http://www.travisberry.com/2009/11/running-a-git-repo-on-dreamhost/
http://chosencollective.com/technology/using-git-hooks-push-live-website
http://effectif.com/nesta/publishing-articles-with-git
If you want to run an SVN Repo on Dreamhost please visit https://goxel.wordpress.com/wp-content/uploads/2010/12/tortoisegit41.png2010/07/auto-update-svn-on-dream-host/
]]>
Pure CSS3 box-shadow page curl effect
<

<ul class="box"> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> </ul>
ul.box {
margin: 0;
padding: 0; }
ul.box li {
list-style-type: none;
margin: 0 30px 30px 0;
padding: 0;
width: 250px;
height: 150px;
border: 1px solid #efefef;
position: relative;
float: left;
background: #ffffff; /* old browsers */
background: -moz-linear-gradient(top, #ffffff 0%, #e5e5e5 100%); /* firefox */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ffffff), color-stop(100%,#e5e5e5)); /* webkit */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#e5e5e5',GradientType=0 ); /* ie */
-webkit-box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.3);
-moz-box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.3); }
ul.box li:after {
z-index: -1;
position: absolute;
background: transparent;
width: 70%;
height: 55%;
content: '';
right: 10px;
bottom: 10px;
-webkit-transform: skew(15deg) rotate(5deg);
-webkit-box-shadow: 8px 12px 10px rgba(0, 0, 0, 0.3);
-moz-transform: skew(15deg) rotate(5deg);
-moz-box-shadow: 8px 12px 10px rgba(0, 0, 0, 0.3); }
ul.box li:before {
z-index: -2;
position: absolute;
background: transparent;
width: 70%;
height: 55%;
content: '';
left: 10px;
bottom: 10px;
-webkit-transform: skew(-15deg) rotate(-5deg);
-webkit-box-shadow: -8px 12px 10px rgba(0, 0, 0, 0.3);
-moz-transform: skew(-15deg) rotate(-5deg);
-moz-box-shadow: -8px 12px 10px rgba(0, 0, 0, 0.3); }
Handcoded in Coda with love by Matt Hamm www.matthamm.com
thanks to www.ballyhooblog.com for the inspiration.
]]>
Writing Efficient CSS for use in the Mozilla UI
<
Post Source
Table of contents
-
1. How the style system breaks up rules
- 1.1. ID Rules
- 1.2. Class Rules
- 1.3. Tag Rules
- 1.4. Universal Rules
- 2. How the Style System Matches Rules
-
3. Guidelines for Efficient CSS
- 3.1. Avoid Universal Rules
- 3.2. Don’t qualify ID Rules with tag names or classes
- 3.3. Don’t qualify Class Rules with tag names
- 3.4. Use the most specific category possible
- 3.5. Avoid the descendant selector
- 3.6. Tag Category rules should never contain a child selector
- 3.7. Question all usages of the child selector
- 3.8. Rely on inheritance
- 3.9. Use -moz-image-region!
- 4. Original Document Information
This document provides guidelines for optimizing CSS code for use in the Mozilla UI.
The first section is a general discussion of how the Mozilla style system categorizes rules. The following sections contain guidelines for writing rules that take advantage of Mozilla’s style system implementation.
How the style system breaks up rules
The style system breaks rules up into four primary categories:
- ID Rules
- Class Rules
- Tag Rules
- Universal Rules
It is critical to understand these categories, as they are the fundamental building blocks of rule matching.
I use the term key selector in the paragraphs that follow. The key selector is the last part of the selector (the part that matches the element being matched, rather than its ancestors).
For example, in the rule…
a img, div > p, h1 + [title] {…}
…the key selectors are
,
img
, and
p
.
[title]
ID Rules
The first category consists of those rules that have an
selector as their key selector.
ID
Example
button#backButton {…} /* This is an ID-categorized rule */
#urlBar[type="autocomplete"] {…} /* This is an ID-categorized rule */
treeitem > treerow > treecell#myCell:active {…} /* This is an ID-categorized rule */
Class Rules
If a rule has a
specified as its key selector, then it falls into this category.
class
Example
button.toolbarButton {…} /* A class-based rule */
.fancyText {…} /* A class-based rule */
menuitem > .menu-left[checked="true"] {…} /* A class-based rule */
Tag Rules
If no
or
class
is specified as the key selector, the next candidate is the tag category. If a rule has a tag specified as its key selector, then the rule falls into this category.
ID
Example
td {…} /* A tag-based rule */
treeitem > treerow {…} /* A tag-based rule */
input[type="checkbox"] {…} /* A tag-based rule */
Universal Rules
All other rules fall into this category.
Example
[hidden="true"] {…} /* A universal rule */
* {…} /* A universal rule */
tree > [collapsed="true"] {…} /* A universal rule */
How the Style System Matches Rules
The style system matches rules by starting with the key selector, then moving to the left (looking for any ancestors in the rule’s selector). As long as the selector’s subtree continues to check out, the style system continues moving to the left until it either matches the rule, or abandons because of a mismatch.
The most fundamental concept to learn is this rule filtering. The categories exist in order to filter out irrelevant rules (so the style system doesn’t waste time trying to match them).
This is the key to dramatically increasing performance. The fewer rules required to check for a given element, the faster style resolution will be.
For example, if an element has an ID, then only ID rules that match the element’s ID will be checked. Only Class Rules for a class found on the element will be checked. Only Tag Rules that match the tag will be checked. Universal Rules will always be checked.
Guidelines for Efficient CSS
Avoid Universal Rules
Make sure a rule doesn’t end up in the universal category!
Don’t qualify ID Rules with tag names or classes
If a rule has an ID selector as its key selector, don’t add the tag name to the rule. Since IDs are unique, adding a tag name would slow down the matching process needlessly.
class
of an element dynamically in order to apply different styles in different situations, but the same
class
is going to be shared with other elements.
- BAD
-
button#backButton {…}
- BAD
-
.menu-left#newMenuIcon {…}
- GOOD
-
#backButton {…}
- GOOD
-
#newMenuIcon {…}
Don’t qualify Class Rules with tag names
The previous concept also applies here. All class names are unique.
One convention you can use is to include the tag name in the class name. However, this may cost some flexibility; if design changes are made to the tag, the class names must be changed as well. (It’s best to choose strictly semantic names, as such flexibility is one of the aims of separate stylesheets.)
- BAD
-
treecell.indented {…}
- GOOD
-
.treecell-indented {…}
- BEST
-
.hierarchy-deep {…}
Use the most specific category possible
The single biggest cause of slowdown is too many rules in the Tag Category. By adding
es to our elements, we can further subdivide these rules into Class Categories, which eliminates time spent trying to match rules for a given tag.
class
- BAD
-
treeitem[mailfolder="true"] > treerow > treecell {…}
- GOOD
-
.treecell-mailfolder {…}
Avoid the descendant selector
The descendant selector is the most expensive selector in CSS. It is dreadfully expensive—especially if the selector is in the Tag or Universal Category.
Frequently, what is really desired is the child selector. Using the descendant selector is banned in User Interface CSS without the explicit approval of your skin’s module owner.
- BAD
-
treehead treerow treecell {…}
- BETTER, BUT STILL BAD (see next guideline)
-
treehead > treerow > treecell {…}
Tag Category rules should never contain a child selector
Avoid using the child selector with Tag Category rules. This will dramatically lengthen the match time (especially if the rule is likely to be matched) for all occurrences of that element.
- BAD
-
treehead > treerow > treecell {…}
- GOOD
-
.treecell-header {…}
Question all usages of the child selector
Exercise caution when using the child selector. Avoid it if you can.
In particular, the child selector is frequently used with RDF trees and menus like so:
- BAD
-
treeitem[IsImapServer="true"] > treerow > .tree-folderpane-icon {…}
Remember that REF attributes can be duplicated in a template! Take advantage of this. Duplicate RDF properties on child XUL elements in order to change them based on the attribute.
- GOOD
-
.tree-folderpane-icon[IsImapServer="true"] {…}
Rely on inheritance
Learn which properties inherit, and allow them to do so!
For example, XUL widgets are explicitly set up such that a parent’s
or
list-style-image
rules will filter down to anonymous content. It’s not necessary to waste time on rules that talk directly to anonymous content.
font
- BAD
-
#bookmarkMenuItem > .menu-left { list-style-image: url(blah) }
- GOOD
-
#bookmarkMenuItem { list-style-image: url(blah) }
In the above example, the desire to style anonymous content (without leveraging the inheritance of
) resulted in a rule that was in the Class Category, when the rule should have ended up in the ID Category—the most specific category of all!
list-style-image
Remember: Elements all have the same classes—especially anonymous content!
The above “bad” rule forces every menu’s icons to be tested for containment within the bookmarks menu item. Since there are many menus, this is extraordinarily expensive. Instead, the “good” rule limits the testing to the bookmarks menu.
Use
-moz-image-region
!
-moz-image-region
Putting a bunch of images into a single image file and selecting them with
-moz-image-region
performs significantly better than putting each image into its own file.
Original Document Information
- Author: David Hyatt
- Last Updated Date: 2000-04-21
- Original Document URL: http://www.mozilla.org/xpfe/goodcss.html
]]>
Custom Snippets in Aptana 3
<

Aptana Snippets
There are some very useful snippets in Aptana like auto building Html tags (Type “div” and hit “Tab” then Aptana will generate “<div id=”name”></div>” for you) but most amazing thing is its very easy to create your own snippets.
If you are using “console.log()” function a lot like me then writing a snippet for this function will save a lot of time for you.
To add a “console.log()” shortcut key
- Create a new project and go to project folder (where your “.project” is found)
- Download bundles.zip
- Extract the zip content to the root of your project folder. The folder hierarchy :

- And restart Aptana 3.
- Now open an Html file, select a text and hit “Shift+Command+.”
require 'ruble'
with_defaults :scope => 'text.html,source.js,source.php source.php.embedded.block.html', :input => :none, :output => :insert_as_snippet do |bundle|
command 'console.log()' do |cmd|
cmd.key_binding = 'M1+M2+.'
cmd.input = :selection
cmd.invoke do |context|
selection = ENV['TM_SELECTED_TEXT'] || ''
if selection.length > 0
"console.log(${1:#{selection}})"
else
"console.log($0)"
end
end
end
end
Visit https://aptanastudio.tenderapp.com/faqs/your-aptana-studio-installation/adding-a-new-snippet and https://aptanastudio.tenderapp.com/faqs/scripting-aptana-studio/ruble-programming-guide for more
]]>
Firebug 1.6 is Released with Many Fixes and Improvements
<
Firebug 1.6.0
The Firebug Working Group proudly announces the availability of Firebug 1.6.0!
We have implemented a lot of new features that are summarized on our wiki in section Firebug 1.6 release notes. Please go over the summary and let us know if you need any additional information.
We have been working hard, but a lot of things wouldn’t be possible without contributions from developers, translators and also designers. See our wiki that lists all our active contributors.
Stability of Firebug has been improved, some memory leaks caught and so, we can declare Firebug 1.6 as the best release ever.
We are focusing on quality and continuously extending our list of automated tests. We run these tests to verify every release and publishing all test results online. Any Firebug users can also run the automated test suite on local machines and upload the results so, we can collect information about stability from various environments.
Firebug 1.6.0 has been uploaded on addons.mozilla.org and your Firefox should ask you for update soon. According to our past experience some issues can sneak through all the alpha and beta releases so, we expect some minor updates in the next few weeks.
Firebug 1.6.0 is for Firefox 3.6 and we are currently working on Firebug 1.7 and focusing on compatibility with Firefox 4.0. It should be available early next year. See known issues with Firefox 4.0.
Beta testers using releases from getfirebug.com will be also automatically asked to update.
Overview of Firebug 1.6
Firebug 1.6 supports Firefox 3.6
Console and Command Line
- Command line available on all panels
- New API for the console object: console.table()
- Console allows to filter its content
- Improved auto-completion now the best of all
- Logging of cut/copy/paste events
- Support for XPath console logging
- Descriptive background colors for console messages
HTML
- Support for expand All through a context menu or by pressing ‘*’
- When copying XPath, namespace is included (if any)
- Improved display of iframes
- DOCTYPE is now also displayed
- Scrollable Breadcrumbs
- Better keyboard navigation
CSS
- Better search match highlighting
- SVG CSS autocomplete
- Support for copying CSS declarations
- Folding for computed styles
- Auto-completion for “!important”
Script
- Disabling break on next error
- The stack panel now displays argument names and values + support for expanding/collapsing
- Script Panel shows nicer message when it is inactive during page load
- Improved presentation of the scope chain in the Script panel Watch side panel
- Save and restore breakpoints across Firefox sessions
- Script panel file list has auto scroll button and shows filtering text
DOM
- Show the prototype, constructor, and __proto__ properties of objects
- localStorage and sessionStorage now also displayed
- Better search match highlighting
Net
- BF Cache reads are also reported
- MozAfterPaint events displayed in the timeline
- SVG pretty print in the net panel
- Better search match highlighting
Toolbars and Menus
- Back and Forward arrows
- Scrolling Panels tab Bar
- New option to use en-US locale
Miscellaneous
- First Run Page now displayed when new Firebug version is installed
- TestBot result page displaying results from automated testing
- Known issue page
- Visual indication for search field not finding any matches
- Support for private browsing mode
- Filterable file location menus
- Locale updates + one new language
- New Firebug icon
- Editor configurations improvements
]]>
Create a Multi-step Register Form with jQuery
<
Post Source
In this tutorial we will see how to create a simple multi-step signup form using CSS3 and
jQuery. To spice up things a bit, we will include progress bar with the form, so the users
will be able to see the percentage of form completion.
You can take a look at the working demo if you click on the image below:
We will create four steps in our form:
1. username and password fields
2. first and last name and email address
3. age, gender and country
4. summary
HTML Code
First thing to do is to create the html structure. We need a box container with four divs,
one for each step. The basic HTML code is the following:
<div id="container">
<form action="#" method="post">
<div id="first_step">
<div id="second_step">
<div id="third_step">
<div id="fourth_step">
</form>
</div>
Inside each box container we will put the fields and a simple helpfull label. You can see
the code inside the first box in the code below:
<!-- #first_step -->
<div id="first_step">
<h1>SIGN UP FOR A FREE <span>WEBEXP18</span> ACCOUNT</h1>
<div class="form">
<input type="text" name="username" id="username" value="username" />
<label for="username">At least 4 characters. Uppercase letters, lowercase letters and
numbers only.</label>
<input type="password" name="password" id="password" value="password" />
<label for="password">At least 4 characters. Use a mix of upper and lowercase for a
strong password.</label>
<input type="password" name="cpassword" id="cpassword" value="password" />
<label for="cpassword">If your passwords aren’t equal, you won’t be able to continue
with signup.</label>
</div> <!-- clearfix --><div class="clear"></div><!-- /clearfix
-->
<input class="submit" type="submit" name="submit_first" id="submit_first" value="" />
</div> <!-- clearfix --><div class="clear"></div><!-- /clearfix
-->
We have used three input fields: username, password and confirm password and at the end of
the box, an input submit for the next step. The other boxes work in the same way.
At the end of the container box you can see a simple progress bar. This is the necessary
code:
<div id="progress_bar">
<div id="progress"></div>
<div id="progress_text">0% Complete</div>
</div>
The complete HTML code is the following:
<div id="container">
<form action="#" method="post">
<!-- #first_step -->
<div id="first_step">
<h1>SIGN UP FOR A FREE <span>WEBEXP18</span> ACCOUNT</h1>
<div class="form">
<input type="text" name="username" id="username" value="username" />
<label for="username">At least 4 characters. Uppercase letters, lowercase
letters and numbers only.</label>
<input type="password" name="password" id="password" value="password" />
<label for="password">At least 4 characters. Use a mix of upper and
lowercase for a strong password.</label>
<input type="password" name="cpassword" id="cpassword" value="password"
/>
<label for="cpassword">If your passwords aren’t equal, you won’t be able
to continue with signup.</label>
</div> <!-- clearfix --><div
class="clear"></div><!-- /clearfix -->
<input class="submit" type="submit" name="submit_first" id="submit_first"
value="" />
</div> <!-- clearfix --><div class="clear"></div><!--
/clearfix -->
<!-- #second_step -->
<div id="second_step">
<h1>SIGN UP FOR A FREE <span>WEBEXP18</span> ACCOUNT</h1>
<div class="form">
<input type="text" name="firstname" id="firstname" value="first name" />
<label for="firstname">Your First Name. </label>
<input type="text" name="lastname" id="lastname" value="last name" />
<label for="lastname">Your Last Name. </label>
<input type="text" name="email" id="email" value="email address" />
<label for="email">Your email address. We send important administration
notices to this address</label>
</div> <!-- clearfix --><div
class="clear"></div><!-- /clearfix -->
<input class="submit" type="submit" name="submit_second" id="submit_second"
value="" />
</div> <!-- clearfix --><div class="clear"></div><!--
/clearfix -->
<!-- #third_step -->
<div id="third_step">
<h1>SIGN UP FOR A FREE <span>WEBEXP18</span> ACCOUNT</h1>
<div class="form">
<select id="age" name="age">
<option> 0 - 17</option>
<option>18 - 25</option>
<option>26 - 40</option>
<option>40+</option>
</select>
<label for="age">Your age range. </label> <!-- clearfix
--><div class="clear"></div><!-- /clearfix -->
<select id="gender" name="gender">
<option>Male</option>
<option>Female</option>
</select>
<label for="gender">Your Gender. </label> <!-- clearfix
--><div class="clear"></div><!-- /clearfix -->
<select id="country" name="country">
<option>United States</option>
<option>United Kingdom</option>
<option>Canada</option>
<option>Serbia</option>
<option>Italy</option>
</select>
<label for="country">Your country. </label> <!-- clearfix
--><div class="clear"></div><!-- /clearfix -->
</div> <!-- clearfix --><div
class="clear"></div><!-- /clearfix -->
<input class="submit" type="submit" name="submit_third" id="submit_third"
value="" />
</div> <!-- clearfix --><div class="clear"></div><!--
/clearfix -->
<!-- #fourth_step -->
<div id="fourth_step">
<h1>SIGN UP FOR A FREE <span>WEBEXP18</span> ACCOUNT</h1>
<div class="form">
<h2>Summary</h2>
<table>
<tr><td>Username</td><td></td></tr>
<tr><td>Password</td><td></td></tr>
<tr><td>Email</td><td></td></tr>
<tr><td>Name</td><td></td></tr>
<tr><td>Age</td><td></td></tr>
<tr><td>Gender</td><td></td></tr>
<tr><td>Country</td><td></td></tr>
</table>
</div> <!-- clearfix --><div
class="clear"></div><!-- /clearfix -->
<input class="send submit" type="submit" name="submit_fourth" id="submit_fourth"
value="" />
</div>
</form>
</div>
<div id="progress_bar">
<div id="progress"></div>
<div id="progress_text">0% Complete</div>
</div>
As you can see, in the fourth step the table is empty. We fill it with the information
entered by the users using jQuery.
CSS Code
Now we need to add the style on the form. First, we use the @fontface rule for using a
custom font. Ive used the Cantarell
font. The complete CSS Code is listed below:
/* CSS Reset (Eric Meyer) */
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{border:0;outline:0;font-size:100%;vertical-align:baseline;background:transparent;margin:0;padding:0}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}:focus{outline:0}ins{text-decoration:none}del{text-decoration:line-through}table{border-collapse:collapse;border-spacing:0}
@font-face {
font-family: 'Cantarell';
src: url(../fonts/Cantarell-Regular.eot);
src: local('Cantarell'), url('../fonts/Cantarell-Regular.ttf') format('truetype');
}
body {
background-color: #f9f9f9;
color: #222;
font-family: Cantarell, Verdana, sans-serif;
font-size: 12px;
}
input[type="submit"]::-moz-focus-inner, input[type="button"]::-moz-focus-inner { border : none; }
input[type="submit"]:focus, input[type="button"]:focus { outline : none; }
.clear { clear: both; }
#container {
background: url('../images/container.png') no-repeat;
width: 754px;
height: 370px;
margin: 20px auto;
padding: 50px 0;
overflow: hidden;
position: relative;
}
#container #first_step, #second_step, #third_step, #fourth_step { display: none; }
#container #first_step { display: block; }
#container .form { margin: 66px 72px 0 72px; }
#container h1, #container h2 {
font-size: Cantarell, Verdana, sans-serif;
text-align: center;
font-size: 24px;
text-shadow: 1px 1px 2px #222;
}
#container h1 span { color: #a90329; }
#container h2 {
color: #888;
font-size: 20px;
text-align: left;
text-shadow: none;
}
#container table {
margin: 20px 40px;
font-size: 14px;
font-weight: bold;
}
#container table td {
padding: 5px 10px;
}
#container table td:nth-child(2) {
color: #a90329;
}
#container input, #container select {
background: url('../images/input.png') no-repeat;
color: #888;
border: 1px solid #ccc;
font-family: Cantarell, Verdana, sans-serif;
font-weight: bold;
font-size: 15px;
width: 300px;
height: 35px;
padding: 0 25px;
margin: 20px 0;
float: left;
border-radius: 6px;
-moz-border-radius: 6px;
-webkit-border-radius: 6px;
}
#container input.submit {
background: url('../images/button.png') no-repeat;
border: none;
cursor: pointer;
width: 85px;
height: 38px;
position: relative;
bottom: 2px;
left: 655px;
}
#container input.submit:focus { border: none; }
#container input.send{ background: url('../images/send.png') no-repeat; }
#container input.error { border: 1px solid red; }
#container input.valid { border: 1px solid #1FFF00; }
#container input:focus, #container select:focus {
border: 1px solid #a90329;
color: #a90329;
}
#container select { padding: 5px 0 5px 25px; }
#container option { padding: 0 15px; }
#container label {
color: #666;
font-size: 12px;
font-weight: bold;
line-height: 14px;
float: right;
margin: 23px -25px;
width: 270px;
}
#progress_bar {
background: url('../images/progress_bar.png') no-repeat;
width: 339px;
height: 24px;
margin: 0 auto;
position: relative;
}
#progress {
background: url('../images/progress.png') repeat-x;
width: 0px;
height: 23px;
border-radius: 20px;
-webkit-border-radius: 20px;
-moz-border-radius: 20px;
}
#progress_text {
position: relative;
line-height: 21px;
text-align: center;
font-weight: bold;
color: white;
text-shadow: 1px 1px 2px #222;
width: 339px;
height: 24px;
top: -23px;
left: 0;
}
jQuery Code
Were going to use jQuery for:
– slide the steps
– check if the data are valid
– change the completion percentage of progress bar
We need load jQuery library inside the page and then to use two plugins:
– jQuery UI,
the most famous plugin used to extend the jQuery functionality.
– jQuery
inputfocus, my jQuery plugin used to manage focus and blur events of the form.
Our jQuery code is listed below:
$(function(){
//original field values
var field_values = {
//id : value
'username' : 'username',
'password' : 'password',
'cpassword' : 'password',
'firstname' : 'first name',
'lastname' : 'last name',
'email' : 'email address'
};
//inputfocus
$('input#username').inputfocus({ value: field_values['username'] });
$('input#password').inputfocus({ value: field_values['password'] });
$('input#cpassword').inputfocus({ value: field_values['cpassword'] });
$('input#lastname').inputfocus({ value: field_values['lastname'] });
$('input#firstname').inputfocus({ value: field_values['firstname'] });
$('input#email').inputfocus({ value: field_values['email'] });
//reset progress bar
$('#progress').css('width','0');
$('#progress_text').html('0% Complete');
//first_step
$('form').submit(function(){ return false; });
$('#submit_first').click(function(){
//remove classes
$('#first_step input').removeClass('error').removeClass('valid');
//ckeck if inputs aren't empty
var fields = $('#first_step input[type=text], #first_step input[type=password]');
var error = 0;
fields.each(function(){
var value = $(this).val();
if( value.length<4 || value==field_values[$(this).attr('id')] ) {
$(this).addClass('error');
$(this).effect("shake", { times:3 }, 50);
error++;
} else {
$(this).addClass('valid');
}
});
if(!error) {
if( $('#password').val() != $('#cpassword').val() ) {
$('#first_step input[type=password]').each(function(){
$(this).removeClass('valid').addClass('error');
$(this).effect("shake", { times:3 }, 50);
});
return false;
} else {
//update progress bar
$('#progress_text').html('33% Complete');
$('#progress').css('width','113px');
//slide steps
$('#first_step').slideUp();
$('#second_step').slideDown();
}
} else return false;
});
$('#submit_second').click(function(){
//remove classes
$('#second_step input').removeClass('error').removeClass('valid');
var emailPattern = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,4}$/;
var fields = $('#second_step input[type=text]');
var error = 0;
fields.each(function(){
var value = $(this).val();
if( value.length<1 || value==field_values[$(this).attr('id')] || (
$(this).attr('id')=='email' && !emailPattern.test(value) ) ) {
$(this).addClass('error');
$(this).effect("shake", { times:3 }, 50);
error++;
} else {
$(this).addClass('valid');
}
});
if(!error) {
//update progress bar
$('#progress_text').html('66% Complete');
$('#progress').css('width','226px');
//slide steps
$('#second_step').slideUp();
$('#third_step').slideDown();
} else return false;
});
$('#submit_third').click(function(){
//update progress bar
$('#progress_text').html('100% Complete');
$('#progress').css('width','339px');
//prepare the fourth step
var fields = new Array(
$('#username').val(),
$('#password').val(),
$('#email').val(),
$('#firstname').val() + ' ' + $('#lastname').val(),
$('#age').val(),
$('#gender').val(),
$('#country').val()
);
var tr = $('#fourth_step tr');
tr.each(function(){
//alert( fields[$(this).index()] )
$(this).children('td:nth-child(2)').html(fields[$(this).index()]);
});
//slide steps
$('#third_step').slideUp();
$('#fourth_step').slideDown();
});
$('#submit_fourth').click(function(){
//send information to server
alert('Data sent');
});
});
The code from row 3 to 20 activate the inputfocus plugin to each input
field. The code from row 27 to 64 check the validity of the data entered by the user (if
username and password length is greather than 4 characters, if the password and confirm
password fields are equal), then update the progress bar value and then slide to second
step.
The code from row 71 to 100 check the data integrity for the second step (if first and last
name arent empty and if the email address is valid). The rest is similar to the previous
code.
Conclusions and Download
We have seen how simple its to create a multistep signup form. This is only an example so I
omitted some features as back button, and more others. Anyway the example is ready to use
and it needs only to change the form action with the link of your php file used to store
data and to edit the jQuery line 125 to: $(form).submit();. You can also decide to
use an AJAX calls to send the informations to server, and again its very easy to implement.
To see form in action click on the image below:
and if you like the final result download form files using the below button.
]]>
Create a Simple Image Preloader Jquery Plugin
<
Post Source
Download Source FilesSee the Demo
How often do you find that images in a website load gracefully; the kind where a loading icon first appears, and the image then fades in, once loaded? This technique can greatly boost the performance of your website. If you’re not already familiar with this method, you’re in luck! Today, we’ll create a preloader plugin for your projects. Intrigued? Let’s get started!
Step 1:
Setting Up Your Workspace
First, we are going to setup the project folder for this tutorial. We’ll need:
- Our main HTML file
- CSS folder for our stylesheet and loading icon ( in ‘i’ folder)
- JS folder for jQuery and our plugin
- IMAGES
Step 2:
The HTML
We’re going to start off with the HTML code.
<DOCTYPE html>
<html>
<head>
<meta charset=utf-8" />
<title>Image Preloader</title>
<script type="text/javascript" src="js/jquery-1.4.4.min.js"></script>
<script type="text/javascript" src="js/jquery.preloader.js"></script>
<link rel="stylesheet" href="css/preloader.css" type="text/css" />
</head>
<body>
<div id="container">
<h2>Preloader - Load images with style</h2>
<ul id="gallery" class="clearfix">
<li><p><a href="#"><img src="images/1.jpg" /></a></p></li>
<li><p><a href="#"><img src="images/2.jpg" /></a></p> </li>
<li><p><a href="#"><img src="images/3.jpg" /></a></p> </li>
<li><p><a href="#"><img src="images/4.jpg" /></a></p></li>
<li><p><a href="#"><img src="images/5.jpg" /></a></p> </li>
<li><p><a href="#"><img src="images/6.jpg" /></a></p> </li>
<li><p><a href="#"><img src="images/7.jpg" /></a></p> </li>
<li><p><a href="#"><img src="images/8.jpg" /></a></p> </li>
<li><p><a href="#"><img src="images/9.jpg" /></a></p> </li>
</ul>
</div>
Nothing fancy here: just plain HTML code for a simple gallery. We have imported jQuery, our plugin jquery.preloader.js
(currently blank), and our preloader’s stylesheet. To finish up, we’ll add an unordered list, which will contain list items as images wrapped by an anchor tag (usually done in a website for opening a lightbox or linking to a site).
Note that the extra
p
tag wrapping each anchor is used for the purpose of styling the image; they are not explicitly required.
Step 3:
The CSS
Now, we’re going to create a preloader.css
stylesheet in the css
folder, and, inside that, create a subfolder i
in which we will keep our preloader icon. Preloaders.net
have a nice collection of loading icons that you can choose from. Add the following code to your stylesheet:
* { margin:0; padding:0; }
body { background:url(i/bg.jpg); }
#container { width:960px; margin:0px auto; }
h2 { font-weight:100; text-shadow:#ffffff 1px 1px 0px; text-align:center; padding:20px; font-size:32px; color:#555555; border-bottom:1px dashed #ccc; margin-bottom:30px; font-family: Georgia, "Times New Roman", Times, serif ; }
First, we have created a 960px
centered container, and have added a background to the page. Additionally, we’ve added some basic styling to the title ( h2
tag ).
Styling the Gallery
Next, we’ll style the gallery and, while we are at it, throw in some CSS3 goodness.
#gallery {
list-style:none;
}
#gallery li {
background:#e8e8e8;
float:left;
display:block;
border:1px solid #d7d7d7;
-moz-border-radius:4px;
-webkit-border-radius:4px;
border-radius:4px;
-webkit-box-shadow:1px 1px 6px #ddd;
-moz-box-shadow:1px 1px 6px #ddd;
box-shadow:1px 1px 6px #ddd;
margin:15px 56px;
padding:0;
}
#gallery li p {
border:1px solid #fff;
-moz-border-radius:4px;
-webkit-border-radius:4px;
border-radius:4px;
margin:0;
padding:7px;
}
#gallery li a {
display:block;
color:#fff;
text-decoration:none;
padding:0;
}
#gallery img {
width:315px;
height:210px;
margin:0;
padding:0;
}
At this point, our gallery should look like so:

Setting up the Preloader Class
Let’s create a preloader
class that will be responsible for showing the loading icon, while images are loading.
.preloader {
background:url(i/89.gif) center center no-repeat #ffffff;
display:inline-block;
}
The preloader element’s display
property must be set to block
or inline block; otherwise, the loading icon won’t show.
Step 4:
Writing the Plugin
Let’s begin by creating the plugin structure and options.
Allowing for customization options makes a plugin far more flexible for the user.
We start off with the base structure:
$.fn.preloader = function(options){
var defaults = {
delay:200,
preload_parent:"a",
check_timer:300,
ondone:function(){ },
oneachload:function(image){ },
fadein:500
};
// variables declaration and precaching images and parent container
var options = $.extend(defaults, options),
}
Our Options
-
delay
– Successive delay between fading in images -
preload_parent
– Add preload class to the parent mentioned. If not found, the image is wrapped within an anchor tag -
ondone
– Callback to be executed when all the images are loaded -
oneachload
– Called when each image is loaded with image as the parameter -
fadein
– Fade in animation duration
Step 5:
Variables
Next, we declare and precache the variables that we will be using in the rest of the plugin.
var defaults = {
delay:200,
preload_parent:"a",
check_timer:300,
ondone:function(){ },
oneachload:function(image){ },
fadein:500
};
// variables declaration and precaching images and parent container
var options = $.extend(defaults, options),
root = $(this),
images = root.find("img").css( {"visibility":"hidden", opacity:0} ),
timer,
counter = 0,
i=0 ,
checkFlag = [],
delaySum = options.delay;
First, we precache the root element (always a best practice), then find the images (also making them hidden), and finally declare the variables which will be explained in greater detail as we counter them.
There are two things worth noting here: you might initially think the easiest solution is to hide the images, and then fade them in, rather than jumping through all of this code. However, the problem is that, if we hide the images, the browser marks the space they used to occupy as empty, and thus the layout, itself, is messed up when they’re eventually faded in. Okay, well what if we used opacity
to “show” and “hide” the images? That’s a better practice, though, some versions of IE doesn’t like this method.
Step 6:
Adding Preloader Class
We now will iterate over each image element, and check if its parent is the one mentioned in the option. If so, we add our preloader class to it; else, we wrap the image within an anchor tag with a class of preloader.
images.each(function(){
var $this = $(this);
if( $this.parent( options.preload_parent ).length==0 ) {
$this.wrap("<a class='preloader' />");
} else {
$this.parent().addClass("preloader");
}
checkFlag[i++] = false;
});
images = $.makeArray(images);
Here, we are using an array checkFlag, and are setting each array’s item value to false. Its use will be made clear as you move along.
Step 7:
Bringing it All Together
We’ll now implement what actually happens behind the scenes. There is a boolean
property, called complete, associated with the image object. When the image has been loaded completely, this boolean is set to true. So, we keep checking this property for each image, and, if it is indeed set to true, we fade in that image.
We can use the setInterval
function to continuously determine whether the images have been loaded or not. This is where the check_timer
option comes in: it maps directly to our timer’s frequency.
An image also has an onload
event associated with it; you’re probably wondering why we aren’t using it. The reason is because some browsers don’t work well with that event; as such, we’re skipping it. We need a solution that works like a charm across all browsers. We start off with:
init = function(){
timer = setInterval(function(){}
},options.check_timer);
timer
is the variable which will reference the timer. This is needed in order to eventually stop the timer. This function is declared along with all the variables.
Checking Each Image
We’ll iterate through the array and check each image’s complete
property to determine whether it has finished downloading. If it has been downloaded, we will set it to visible and fade in slowly. When the animation has ended, we remove the preloader class from its parent.
for(i=0; i<images.length; i++) {
if(images[i].complete == true) {
$(images[i]).css("visibility","visible")
.delay(delaySum)
.animate({opacity:1}, options.fadein, function(){
$(this)
.parent()
.removeClass("preloader");
});
}
}
There’s a tiny issue here: the timer will continue to check — even after
the images have all been loaded.To counter this, we’ll add a counter variable, and increment it after each image has been loaded. This way, we can check if the counter variable is equal to the size of the images array. If that’s the case, we stop.
timer = setInterval(function(){
if(counter>=checkFlag.length) {
clearInterval(timer);
options.ondone();
return;
}
for( i=0; i<images.length; i++) {
if(images[i].complete==true) {
$(images[i])
.css("visibility","visible")
.delay(delaySum)
.animate({opacity:1}, options.fadein, function(){
$(this)
.parent()
.removeClass("preloader");
});
counter++;
}
}
},options.check_timer)
However, there’s another small issue now. Our timer may stop earlier than expected; if one image has been loaded, its complete
property has been set to true
and the counter thus increments by 1. Now, when the loop runs the next time, the image is already loaded, the complete
property is set totrue, and, thus, the loop will run twice! To overcome this problem, we use the checkFlag
array. When an image is loaded, we will set checkFlag
to true, and set the condition for the counter to increment only on the condition that the checkFlag
value is false. So counter is incremented only once: when an image is loaded for the first time.
timer = setInterval(function () {
if (counter & gt; = checkFlag.length) {
clearInterval(timer);
options.ondone();
return;
}
for (i = 0; i & lt; images.length; i++) {
if (images[i].complete == true) {
if (checkFlag[i] == false) {
checkFlag[i] = true;
options.oneachload(images[i]);
counter++;
delaySum = delaySum + options.delay;
}
$(images[i]).css("visibility", "visible").delay(delaySum).animate({
opacity: 1
}, options.fadein, function () {
$(this).parent().removeClass("preloader");
});
}
}
}, options.check_timer);
Note that we call the ondone
function when the counter flag is greater than the array’s length – i.e. when all the images are loaded. When the counter is incremented, oneachload
is called with the current image passed as the parameter.
Step 8:
The Easy Part
Finally, in this step, we call the init();
function at the end of the plugin.
init(); // called at the last line of plugin
That’s all; we have made a fully working preloading plugin, and its size is less than 2kb. Still, one problem remains: the loading icon image is loaded randomly. We don’t want that. In the next section we will take care of that.
Step 9:
Going the Extra Mile
To fix the problem mentioned above, we’ll load the icon first, and then call the init
function. But the loading icon is a background image, so we inject it as an image in the page, while keeping it hidden. When it loads, we call the init
function. We’re essentially preloading the icon itself.
var icon = jQuery("<img />", {
id: 'loadingicon',
src: 'css/i/89.gif'
}).hide().appendTo("body");
timer = setInterval(function () {
if (icon[0].complete == true) {
clearInterval(timer);
init();
icon.remove();
return;
}
}, 100);
First we create an image object with an id
of loadingicon, and a source
pointing to the path of the loading icon. Then, we append it the body
and initially hide it. Lastly, we set the interval to check if the icon has been loaded or not. If it has, we kill the timer, and start preloading the images. Don’t forget to remove that icon too!
Conclusion
With that last step, we’re done! This functionality works in all browsers, just as expected, and degrades gracefully. Just be sure set the preloader element’s display
property to block
or inline-block. It is now ready to be used in your projects. Thanks for reading!
]]>
Three Great Books For Practicing Javascript
<
I was looking for a book to improve my javascript skills without using a library and finally found the best book : JavaScript Patterns by Stoyan Stefanov (O’Reilly Media/Yahoo! Press)
About the book
What’s the best approach for developing an application with JavaScript? This book helps you answer that question with numerous JavaScript coding patterns and best practices. If you’re an experienced developer looking to solve problems related to objects, functions, inheritance, and other language-specific categories, the abstractions and code templates in this guide are ideal — whether you’re writing a client-side, server-side, or desktop application with JavaScript. Author Stoyan Stefanov includes several examples for each pattern as well as practical advice for implementing them.
The Other Books on My List
]]>
Like this comparison!
]]>



