<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4356457360167243215</id><updated>2011-07-29T17:54:06.052+10:00</updated><category term='resize'/><category term='images'/><category term='flash'/><category term='calendar'/><category term='discussion'/><category term='replacement'/><category term='plug-ins'/><category term='User Voice'/><category term='flot'/><category term='icons'/><category term='news'/><category term='free'/><category term='commercial'/><category term='stylesheet'/><category term='on'/><category term='UI'/><category term='projects'/><category term='art'/><category term='analytics'/><category term='uservoice'/><category term='open source'/><category term='selectable'/><category term='draggable'/><category term='chrome'/><category term='PHPMailer'/><category term='google docs'/><category term='firefox'/><category term='submit'/><category term='RSS'/><category term='css'/><category term='js'/><category term='tips'/><category term='sales'/><category term='apps'/><category term='function'/><category term='255 characters'/><category term='video'/><category term='TCPDF'/><category term='authorize'/><category term='work'/><category term='variables'/><category term='sort'/><category term='aspect ratio'/><category term='multiple'/><category term='sites'/><category term='asp'/><category term='weather'/><category term='MSSQL'/><category term='table'/><category term='business'/><category term='jQuery'/><category term='select'/><category term='mysql'/><category term='toggle'/><category term='sortable'/><category term='arrays'/><category term='security'/><category term='web devlopment'/><category term='selected'/><category term='example'/><category term='information'/><category term='Gmail'/><category term='sydphp'/><category term='more'/><category term='SSO'/><category term='links'/><category term='IIS'/><category term='teams'/><category term='scrollTop'/><category term='wordpress'/><category term='pdf'/><category term='industry'/><category term='employment'/><category term='trac'/><category term='personal development'/><category term='tutorials'/><category term='sign'/><category term='opinion'/><category term='software'/><category term='flickr'/><category term='1.4'/><category term='color'/><category term='large'/><category term='marketing'/><category term='design'/><category term='version control'/><category term='CDN'/><category term='beginning'/><category term='widget'/><category term='remove'/><category term='svn'/><category term='google'/><category term='subversion'/><category term='articles'/><category term='resizer'/><category term='mail'/><category term='Twitter'/><category term='podcast'/><category term='javascript'/><category term='inline'/><category term='hooks'/><category term='apple'/><category term='manipulation'/><category term='IT'/><category term='iconset'/><category term='AJAX'/><category term='change'/><category term='option'/><category term='christmas'/><category term='explorer'/><category term='input'/><category term='video player'/><category term='graphs'/><category term='advertising'/><category term='dump'/><category term='youtube'/><category term='paragraph'/><category term='graph'/><category term='conference'/><category term='form'/><category term='jQuery-UI'/><category term='tortoisesvn'/><category term='addons'/><category term='download'/><category term='social networking'/><category term='SMTP'/><category term='zebra'/><category term='plugin'/><category term='browser'/><category term='graphing'/><category term='script'/><category term='forms'/><category term='windows'/><category term='animate'/><category term='image'/><category term='firewall'/><category term='JSON'/><category term='menu'/><category term='learning'/><category term='usability'/><category term='repository'/><category term='authorization'/><category term='elements'/><category term='branching'/><category term='extensions'/><category term='POP3'/><category term='wallpaper'/><category term='php'/><category term='livequery'/><category term='tutorial'/><category term='jQuery 1.4'/><category term='games'/><category term='single'/><category term='LEGO'/><category term='size'/><category term='careers'/><category term='font'/><category term='post'/><category term='context'/><category term='API'/><category term='databases'/><category term='pagination'/><category term='add-ons'/><category term='minify'/><category term='manipulating'/><category term='search'/><category term='tablesorter'/><category term='microsoft'/><category term='index'/><category term='standards'/><category term='IE'/><category term='tagging'/><category term='sqlsrv'/><category term='social media'/><category term='inline editing'/><category term='cheatsheet'/><category term='droppable'/><category term='data'/><category term='less'/><category term='beginner'/><title type='text'>myphpetc</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.myphpetc.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>93</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-944990820501167563</id><published>2011-05-12T20:12:00.000+10:00</published><updated>2011-05-14T06:50:43.279+10:00</updated><title type='text'>Please help beta test my new site areatags.com</title><content type='html'>I am working on a new project which allows for collabarative editing of places, activities and events.&lt;br /&gt;&lt;br /&gt;If you could take some time out to have a look at the site, test the login functionality and send me some feedback would be appreciated.&lt;br /&gt;&lt;br /&gt;You can send feedback to info at the below domain:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://areatags.com"&gt;http://areatags.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Much appreciated!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-944990820501167563?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/944990820501167563/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=944990820501167563' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/944990820501167563'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/944990820501167563'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2011/05/please-help-beta-test-my-new-site.html' title='Please help beta test my new site areatags.com'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-4327198414982640418</id><published>2011-02-04T10:06:00.000+11:00</published><updated>2011-02-04T10:06:45.614+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='discussion'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><category scheme='http://www.blogger.com/atom/ns#' term='articles'/><title type='text'>Security questions</title><content type='html'>How secure are security questions if several sites are using the same emergency security questions?&lt;br /&gt;&lt;br /&gt;How many people could get your bank details, hotmail account or anything else with the combination of your email address and the answers to your emergency questions?&lt;br /&gt;&lt;br /&gt;This site I just visited goes one step above scary and asks you to provide 5 separate questions with answers, anyone else seen these questions before?&lt;br /&gt;&lt;br /&gt;My bank actually asks two of these five questions for me to approve transactions.&lt;br /&gt;&lt;br /&gt;Anyone else starting to feel these secret questions are not so secret once every second site you visit on the net starts asking the same questions.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_ifZvVaqCHro/TUs0zm_uAjI/AAAAAAAAAB0/P-SPcZuuYuI/s1600/secure.jpg" imageanchor="1" style="clear:left; float:left;margin-right:1em; margin-bottom:1em"&gt;&lt;img border="0" height="320" width="230" src="http://2.bp.blogspot.com/_ifZvVaqCHro/TUs0zm_uAjI/AAAAAAAAAB0/P-SPcZuuYuI/s320/secure.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-4327198414982640418?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/4327198414982640418/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=4327198414982640418' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/4327198414982640418'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/4327198414982640418'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2011/02/security-questions.html' title='Security questions'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_ifZvVaqCHro/TUs0zm_uAjI/AAAAAAAAAB0/P-SPcZuuYuI/s72-c/secure.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-4698336012595017822</id><published>2010-10-19T18:45:00.001+11:00</published><updated>2010-10-19T18:46:52.767+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='marketing'/><category scheme='http://www.blogger.com/atom/ns#' term='sales'/><category scheme='http://www.blogger.com/atom/ns#' term='articles'/><title type='text'>How not to win customers with your sales site</title><content type='html'>I'm currently in the middle of purchasing something on the internet. Easy you might think, unless the thing that you need to buy is for your business or enterprise. Years ago sites like Amazon and eBay revolutionised the way we bought on the internet and made it easy to purchase goods in a way that worked for the consumer. Why did these sites become king? Not because of what they were selling, but how they were selling. It's the experience that matters. Why head to an online store that only shows part of their catalogue, requires you to sign up to use trivial parts of the site or has poor payment integration.&lt;br /&gt;&lt;span id="summary-area"&gt; &lt;br /&gt;Unfortunately the same revolution hasn't happened for enterprise. B2B purchases are a nightmare obstacle course. Want to see our product overview video?... give me your name, number and email address and then we'll let you see. Want to know how much it costs?... give me your number and I'll call you. Want to contact a human?... our sales staff will be glad to have a chat and then call you every week for the next two months.&lt;br /&gt;&lt;br /&gt;Most B2B business with an online presence are still stuck in the past, still trying to bug people so they can exist off the bottom 2%, the suckers. Their sites, no matter how elaborate are set up to solicit phone calls. Just like companies that cold call customers, it's just another form of spam and unfortunately, some people fall for it. After all they don't really have a choice.&lt;br /&gt;&lt;br /&gt;So how can you improve your sales site? What should you change so that you are fishing for the 98% and not the bottom 2% that fall into the trap? Below are my suggestions for improving your B2B site to make it more customer friendly.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;1. Don't hide your sales pitch.&lt;br /&gt;Your home page might have drawn me in, but what are you providing beyond your flashy splash page? Do you have white papers, product overviews and videos detailing your products? Don't make me have to sign up for them. If your product is worth knowing make sure it can be known by the world. If you have some product videos host them on Youtube, who knows who might stumble across them. And don't hide your sales pitch behind jargon I can't understand. If I want a HR solution with payroll integration, tell me that's what you have and don't make me have to call to find out.&lt;br /&gt;&lt;br /&gt;2. Be contactable in a way that is non-creepy.&lt;br /&gt;Someone you don't know who calls you once a week to ask you what you are doing... that's a stalker. If I have a quick question about your product I don't want to call you because I know by looking at your website your first question is going to be: what is your name, what is your company, what is your position, what is your phone number? If I want to ask a quick question I prefer to send you an email, because I just want an answer to a single question. I don't want to be sold on your product just yet. Teach your call centre staff to answer emails if that's what it takes. &lt;br /&gt;&lt;br /&gt;3. Give me a price&lt;br /&gt;If I'm comparing 10 companies all with good looking web sites that are full of marketing fluff there's one good way to tell you apart: give me a price. If you can't tell me the price per license for enterprise for x users then I can only believe that you are hiding behind your product and it can't be that good if you can't tell me the price up front. Tiered pricing and support is fine, but be upfront. Don't leave me guessing that I pay a premium just because of my name and reputation.&lt;br /&gt;&lt;br /&gt;The success of your sales site on the internet will depend on how well you can build a relationship with your audience. If you are full of jargon and fishing for my number you are not out there trying to reach out to your customers. eBay and Amazon are about trust and their relationship with their customers, make your sales site with the same idea in mind. Educate your customers, teach them why your product is better, provide them with tools to honestly compare and allow them to reach out to you.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-4698336012595017822?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/4698336012595017822/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=4698336012595017822' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/4698336012595017822'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/4698336012595017822'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2010/10/how-not-to-win-customers-with-your.html' title='How not to win customers with your sales site'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-6003455329165495991</id><published>2010-10-18T20:23:00.002+11:00</published><updated>2010-10-18T20:28:39.202+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tutorials'/><category scheme='http://www.blogger.com/atom/ns#' term='animate'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>Great jQuery text silhouette animation</title><content type='html'>Going over some jQuery plugins today I came across this effect in a banner on &lt;a href="http://artimore.com/?p=8"&gt;this site&lt;/a&gt; that I thought was pretty cool. Btw, the plugin on that page is quite nice and will be even better after a few more releases (worth checking out as an aside).&lt;br /&gt;&lt;span id="summary-area"&gt; &lt;br /&gt;The main idea is to have some black text on a white background (colors can change to taste) and then an image is animated over the top of the text which is the same color as the background (white) but with a transparent background. So that when the image passes over the text it creates a cool silhouette effect.&lt;br /&gt;&lt;br /&gt;You can &lt;a href="https://sites.google.com/site/myphpetc/Home/backwords.zip?attredirects=0&amp;d=1"&gt;download the code here&lt;/a&gt;. You can see a working example in the &lt;a href="http://artimore.com/?p=8"&gt;site mentioned above&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;img src='https://sites.google.com/site/myphpetc/Home/backwords.jpg' /&gt;&lt;br /&gt;&lt;br /&gt;As per the site linked above I also use 3 images to enhance the effect.&lt;br /&gt;&lt;br /&gt;This could definitely be implemented a lot better (using multiple images to create a continuous stream as it currently stops after a period of time and some way to make the text selectable), but I'll leave that to you.&lt;br /&gt;&lt;br /&gt;This effect is not something that would work on every site (think blinking text), but for some arty or monochromatic schemes I can see this fitting right in.&lt;br /&gt;&lt;br /&gt;The code is quite straight forward:&lt;br /&gt;&lt;br /&gt;&lt;pre class="pre_code"&gt;&amp;lt;div id="text_cont"&amp;gt;&lt;br /&gt;   Some text&lt;br /&gt;   &amp;lt;div id=\&amp;#039;cross_img\&amp;#039;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;   &amp;lt;div id=\&amp;#039;cross_img2\&amp;#039;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;   &amp;lt;div id=\&amp;#039;cross_img3\&amp;#039;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Start with my text and three images.&lt;br /&gt;&lt;br /&gt;Here is part of the css, you see the div with a white background and black text. Each of my images is almost identical, I offset them slightly using different top and left positions. Also in the jQuery I provide different speeds for the animation to try and create an overlapping effect.&lt;br /&gt;&lt;pre class="pre_code"&gt;#text_cont {&lt;br /&gt; background: white;&lt;br /&gt; color:black;&lt;br /&gt; font-size:120px;&lt;br /&gt; font-weight:bold;&lt;br /&gt; position:relative;&lt;br /&gt; overflow:hidden;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;#cross_img {&lt;br /&gt; position:absolute;&lt;br /&gt; top:0px;&lt;br /&gt; left:0px;&lt;br /&gt; width:1800px;&lt;br /&gt; display:block;&lt;br /&gt; height:500px;&lt;br /&gt; background: url("../images/demo1.gif");&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here is the javascript:&lt;br /&gt;&lt;pre class="pre_code"&gt;$(document).ready(function(){&lt;br /&gt; $("#cross_img").animate({"left": -1800}, 150000);&lt;br /&gt; $("#cross_img2").animate({"left": -1800}, 120000);&lt;br /&gt; $("#cross_img3").animate({"left": -1800}, 90000);&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You can see the different speeds as mentioned previously.&lt;br /&gt;&lt;br /&gt;Hope you like it. If you use it anywhere I'd like to check it out.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-6003455329165495991?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/6003455329165495991/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=6003455329165495991' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/6003455329165495991'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/6003455329165495991'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2010/10/great-jquery-text-sillhoutte-animation.html' title='Great jQuery text silhouette animation'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-8295701644523328109</id><published>2010-10-15T16:52:00.001+11:00</published><updated>2010-10-15T16:54:04.208+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tutorials'/><category scheme='http://www.blogger.com/atom/ns#' term='scrollTop'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>jQuery scrolling page with autogenerated index</title><content type='html'>In my previous article I wrote about scrollTop and how to get working for your sites. If you haven't had a chance to read it yet and you are not too familiar with scrollTop I suggest you check it out as I will use the techniques from that article in building the example in this tutorial.&lt;br /&gt;&lt;br /&gt;What I am going to build today is made up of two parts: an index section and a document section. The index section will list titles in the document and will be built on the fly using jQuery. Clicking on one of the titles in the index will smoothly scroll down to the selected section.&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;&lt;a href='http://comp345.awardspace.com/scrollpage/index.html'&gt;Here is a live demo&lt;/a&gt; and you can download the code &lt;a href='https://sites.google.com/site/myphpetc/Home/scrollpage.zip'&gt;from here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;How to create the index section:&lt;br /&gt;To begin with we want to loop over all of the titles in our text. In my example I am going to have all of my titles as h2 elements. I am going to use jQuery to loop over all of our h2 elements using the &lt;a href='http://api.jquery.com/each/'&gt;each function&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;pre class="pre_code"&gt;$("#our_book h2").each(function(index, elem) {&lt;br /&gt; }); &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Next we need to add an element to the index for each of our titles. I have chosen to have each of these as links.&lt;br /&gt;&lt;br /&gt;&lt;pre class="pre_code"&gt;$("#our_book h2").each(function(index, elem) {&lt;br /&gt;  $("#our_index").append("&lt;a href='#' style='display:block;margin-bottom:8px;overflow:hidden;'&gt;" + $(elem).html() + "&lt;/a&gt;");&lt;br /&gt; });&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So each link has now been added to the "#our_index" div, now we need to bind a click event to each of these links. Let's have a look at the code:&lt;br /&gt;&lt;br /&gt;&lt;pre class="pre_code"&gt;$("#our_index a").click(function() {&lt;br /&gt;  var idx = $("#our_index a").index(this);&lt;br /&gt;  $("#our_book").stop(true).animate({scrollTop: ($("#our_book").scrollTop() + $("#our_book h2:eq(" + idx + ")").position().top)}, {duration: 1500, queue: false});&lt;br /&gt;  return false;&lt;br /&gt; }); &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;To start off we need to get the index of link being clicked. As each link has been added in order that it appears in the "#our_book" section, the index of the link will match the index of the h2 element in the "#our_book" section.&lt;br /&gt;&lt;br /&gt;Next we call the stop function on "#our_book", this is done so that when someone clicks multiple links rapidly it doesn't fill up the queue and all animations (on this element) are stopped immediately.&lt;br /&gt;&lt;br /&gt;Following we chain on the animate method and we want to scroll to the position of our matching h2 element. To calculate its position we first add the current scroll position  of "#our_book" by calling scrollTop. Next we add on the value of the position of the h2 element we are targeting relative to the parent, which is the "#our_book" element. This will give the position of where we need to scroll our "#our_book" element. If this is confusing I suggest checking out my previous post on scrollTop which explains this is further detail.&lt;br /&gt;&lt;br /&gt;The final piece of our code is binding mousedown event to the "#our_book" element. We want to stop all animations if someone tries to scroll or clicks on our "#our_book" element. This is so that we are not fighting with the animation if you are trying to scroll up while it is scrolling down or if someone spots something of interest and they want the animation to stop they can just click.&lt;br /&gt;&lt;br /&gt;This is a small practical example of using scrollTop which could be used in a variety of ways: intructions, TOS, FAQ etc.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-8295701644523328109?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/8295701644523328109/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=8295701644523328109' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/8295701644523328109'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/8295701644523328109'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2010/10/jquery-scrolling-page-with.html' title='jQuery scrolling page with autogenerated index'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-1016046551165685991</id><published>2010-10-14T19:32:00.004+11:00</published><updated>2010-10-14T19:36:29.560+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tutorials'/><category scheme='http://www.blogger.com/atom/ns#' term='scrollTop'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>Smooth scrolling with jQuery scrollTop</title><content type='html'>&lt;script type="text/javascript" src="http://www.google.com/jsapi"&gt;&lt;/script&gt;&lt;script type="text/javascript"&gt; google.load("jquery", "1.4.2");&lt;/script&gt;&lt;br /&gt;&lt;p&gt;I want to have a look at jQuery's scrollTop method; how to work with it and some of it's uses. To begin with if you are not familiar will the scrollTop function have a read over the &lt;a href='http://api.jquery.com/scrollTop/'&gt;API entry&lt;/a&gt;.&lt;/p&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;&lt;p&gt;The scrollTop function can be called on any element, but is only relevant for items that have excess content. What I mean by excess content is that the target element has child elements that would cause the item to scroll, if it had overflow:scroll; set. This is important to note: it is not necessary for an item to have scrollbars in order to use scrollTop. So look at the two following examples, one is a &amp;lt;div&amp;gt; that has scrollbars and excess content, the other is a &amp;lt;div&amp;gt; without scrollbars and excess content; both can be controlled using the scrollTop function.&lt;/p&gt;&lt;br /&gt;&lt;div id="long-para" class="excess_content" style="width:200px;height:400px;overflow:hidden;float:left;"&gt;&lt;p&gt;Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Suspendisse mauris. Fusce accumsan mollis eros. Pellentesque a diam sit amet mi ullamcorper vehicula. Integer adipiscing risus a sem. Nullam quis massa sit amet nibh viverra malesuada. Nunc sem lacus, accumsan quis, faucibus non, congue vel, arcu. Ut scelerisque hendrerit tellus. Integer sagittis. Vivamus a mauris eget arcu gravida tristique. Nunc iaculis mi in ante. Vivamus imperdiet nibh feugiat est.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ut convallis, sem sit amet interdum consectetuer, odio augue aliquam leo, nec dapibus tortor nibh sed augue. Integer eu magna sit amet metus fermentum posuere. Morbi sit amet nulla sed dolor elementum imperdiet. Quisque fermentum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque adipiscing eros ut libero. Ut condimentum mi vel tellus. Suspendisse laoreet. Fusce ut est sed dolor gravida convallis. Morbi vitae ante. Vivamus ultrices luctus nunc. Suspendisse et dolor. Etiam dignissim. Proin malesuada adipiscing lacus. Donec metus. Curabitur gravida.&lt;/p&gt;&lt;p&gt;Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Suspendisse mauris. Fusce accumsan mollis eros. Pellentesque a diam sit amet mi ullamcorper vehicula. Integer adipiscing risus a sem. Nullam quis massa sit amet nibh viverra malesuada. Nunc sem lacus, accumsan quis, faucibus non, congue vel, arcu. Ut scelerisque hendrerit tellus. Integer sagittis. Vivamus a mauris eget arcu gravida tristique. Nunc iaculis mi in ante. Vivamus imperdiet nibh feugiat est.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ut convallis, sem sit amet interdum consectetuer, odio augue aliquam leo, nec dapibus tortor nibh sed augue. Integer eu magna sit amet metus fermentum posuere. Morbi sit amet nulla sed dolor elementum imperdiet. Quisque fermentum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque adipiscing eros ut libero. Ut condimentum mi vel tellus. Suspendisse laoreet. Fusce ut est sed dolor gravida convallis. Morbi vitae ante. Vivamus ultrices luctus nunc. Suspendisse et dolor. Etiam dignissim. Proin malesuada adipiscing lacus. Donec metus. Curabitur gravida.&lt;/p&gt;&lt;p&gt;Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna.&lt;/p&gt;&lt;br /&gt;&lt;p id='scrollhere'&gt;Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Suspendisse mauris. Fusce accumsan mollis eros. Pellentesque a diam sit amet mi ullamcorper vehicula. Integer adipiscing risus a sem. Nullam quis massa sit amet nibh viverra malesuada. Nunc sem lacus, accumsan quis, faucibus non, congue vel, arcu. Ut scelerisque hendrerit tellus. Integer sagittis. Vivamus a mauris eget arcu gravida tristique. Nunc iaculis mi in ante. Vivamus imperdiet nibh feugiat est.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ut convallis, sem sit amet interdum consectetuer, odio augue aliquam leo, nec dapibus tortor nibh sed augue. Integer eu magna sit amet metus fermentum posuere. Morbi sit amet nulla sed dolor elementum imperdiet. Quisque fermentum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque adipiscing eros ut libero. Ut condimentum mi vel tellus. Suspendisse laoreet. Fusce ut est sed dolor gravida convallis. Morbi vitae ante. Vivamus ultrices luctus nunc. Suspendisse et dolor. Etiam dignissim. Proin malesuada adipiscing lacus. Donec metus. Curabitur gravida.&lt;/p&gt;&lt;p&gt;Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Suspendisse mauris. Fusce accumsan mollis eros. Pellentesque a diam sit amet mi ullamcorper vehicula. Integer adipiscing risus a sem. Nullam quis massa sit amet nibh viverra malesuada. Nunc sem lacus, accumsan quis, faucibus non, congue vel, arcu. Ut scelerisque hendrerit tellus. Integer sagittis. Vivamus a mauris eget arcu gravida tristique. Nunc iaculis mi in ante. Vivamus imperdiet nibh feugiat est.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ut convallis, sem sit amet interdum consectetuer, odio augue aliquam leo, nec dapibus tortor nibh sed augue. Integer eu magna sit amet metus fermentum posuere. Morbi sit amet nulla sed dolor elementum imperdiet. Quisque fermentum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque adipiscing eros ut libero. Ut condimentum mi vel tellus. Suspendisse laoreet. Fusce ut est sed dolor gravida convallis. Morbi vitae ante. Vivamus ultrices luctus nunc. Suspendisse et dolor. Etiam dignissim. Proin malesuada adipiscing lacus. Donec metus. Curabitur gravida.&lt;/p&gt;&lt;p&gt;Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Suspendisse mauris. Fusce accumsan mollis eros. Pellentesque a diam sit amet mi ullamcorper vehicula. Integer adipiscing risus a sem. Nullam quis massa sit amet nibh viverra malesuada. Nunc sem lacus, accumsan quis, faucibus non, congue vel, arcu. Ut scelerisque hendrerit tellus. Integer sagittis. Vivamus a mauris eget arcu gravida tristique. Nunc iaculis mi in ante. Vivamus imperdiet nibh feugiat est.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ut convallis, sem sit amet interdum consectetuer, odio augue aliquam leo, nec dapibus tortor nibh sed augue. Integer eu magna sit amet metus fermentum posuere. Morbi sit amet nulla sed dolor elementum imperdiet. Quisque fermentum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque adipiscing eros ut libero. Ut condimentum mi vel tellus. Suspendisse laoreet. Fusce ut est sed dolor gravida convallis. Morbi vitae ante. Vivamus ultrices luctus nunc. Suspendisse et dolor. Etiam dignissim. Proin malesuada adipiscing lacus. Donec metus. Curabitur gravida.&lt;/p&gt;&lt;/div&gt;&lt;div id="long-para2" class="excess_content" style="width:200px;height:400px;overflow:auto;float:left;margin-left:100px;"&gt;&lt;p&gt;Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Suspendisse mauris. Fusce accumsan mollis eros. Pellentesque a diam sit amet mi ullamcorper vehicula. Integer adipiscing risus a sem. Nullam quis massa sit amet nibh viverra malesuada. Nunc sem lacus, accumsan quis, faucibus non, congue vel, arcu. Ut scelerisque hendrerit tellus. Integer sagittis. Vivamus a mauris eget arcu gravida tristique. Nunc iaculis mi in ante. Vivamus imperdiet nibh feugiat est.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ut convallis, sem sit amet interdum consectetuer, odio augue aliquam leo, nec dapibus tortor nibh sed augue. Integer eu magna sit amet metus fermentum posuere. Morbi sit amet nulla sed dolor elementum imperdiet. Quisque fermentum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque adipiscing eros ut libero. Ut condimentum mi vel tellus. Suspendisse laoreet. Fusce ut est sed dolor gravida convallis. Morbi vitae ante. Vivamus ultrices luctus nunc. Suspendisse et dolor. Etiam dignissim. Proin malesuada adipiscing lacus. Donec metus. Curabitur gravida.&lt;/p&gt;&lt;p&gt;Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Suspendisse mauris. Fusce accumsan mollis eros. Pellentesque a diam sit amet mi ullamcorper vehicula. Integer adipiscing risus a sem. Nullam quis massa sit amet nibh viverra malesuada. Nunc sem lacus, accumsan quis, faucibus non, congue vel, arcu. Ut scelerisque hendrerit tellus. Integer sagittis. Vivamus a mauris eget arcu gravida tristique. Nunc iaculis mi in ante. Vivamus imperdiet nibh feugiat est.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ut convallis, sem sit amet interdum consectetuer, odio augue aliquam leo, nec dapibus tortor nibh sed augue. Integer eu magna sit amet metus fermentum posuere. Morbi sit amet nulla sed dolor elementum imperdiet. Quisque fermentum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque adipiscing eros ut libero. Ut condimentum mi vel tellus. Suspendisse laoreet. Fusce ut est sed dolor gravida convallis. Morbi vitae ante. Vivamus ultrices luctus nunc. Suspendisse et dolor. Etiam dignissim. Proin malesuada adipiscing lacus. Donec metus. Curabitur gravida.&lt;/p&gt;&lt;p&gt;Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna.&lt;/p&gt;&lt;br /&gt;&lt;p id='scrollhere'&gt;Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Suspendisse mauris. Fusce accumsan mollis eros. Pellentesque a diam sit amet mi ullamcorper vehicula. Integer adipiscing risus a sem. Nullam quis massa sit amet nibh viverra malesuada. Nunc sem lacus, accumsan quis, faucibus non, congue vel, arcu. Ut scelerisque hendrerit tellus. Integer sagittis. Vivamus a mauris eget arcu gravida tristique. Nunc iaculis mi in ante. Vivamus imperdiet nibh feugiat est.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ut convallis, sem sit amet interdum consectetuer, odio augue aliquam leo, nec dapibus tortor nibh sed augue. Integer eu magna sit amet metus fermentum posuere. Morbi sit amet nulla sed dolor elementum imperdiet. Quisque fermentum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque adipiscing eros ut libero. Ut condimentum mi vel tellus. Suspendisse laoreet. Fusce ut est sed dolor gravida convallis. Morbi vitae ante. Vivamus ultrices luctus nunc. Suspendisse et dolor. Etiam dignissim. Proin malesuada adipiscing lacus. Donec metus. Curabitur gravida.&lt;/p&gt;&lt;p&gt;Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Suspendisse mauris. Fusce accumsan mollis eros. Pellentesque a diam sit amet mi ullamcorper vehicula. Integer adipiscing risus a sem. Nullam quis massa sit amet nibh viverra malesuada. Nunc sem lacus, accumsan quis, faucibus non, congue vel, arcu. Ut scelerisque hendrerit tellus. Integer sagittis. Vivamus a mauris eget arcu gravida tristique. Nunc iaculis mi in ante. Vivamus imperdiet nibh feugiat est.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ut convallis, sem sit amet interdum consectetuer, odio augue aliquam leo, nec dapibus tortor nibh sed augue. Integer eu magna sit amet metus fermentum posuere. Morbi sit amet nulla sed dolor elementum imperdiet. Quisque fermentum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque adipiscing eros ut libero. Ut condimentum mi vel tellus. Suspendisse laoreet. Fusce ut est sed dolor gravida convallis. Morbi vitae ante. Vivamus ultrices luctus nunc. Suspendisse et dolor. Etiam dignissim. Proin malesuada adipiscing lacus. Donec metus. Curabitur gravida.&lt;/p&gt;&lt;p&gt;Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Suspendisse mauris. Fusce accumsan mollis eros. Pellentesque a diam sit amet mi ullamcorper vehicula. Integer adipiscing risus a sem. Nullam quis massa sit amet nibh viverra malesuada. Nunc sem lacus, accumsan quis, faucibus non, congue vel, arcu. Ut scelerisque hendrerit tellus. Integer sagittis. Vivamus a mauris eget arcu gravida tristique. Nunc iaculis mi in ante. Vivamus imperdiet nibh feugiat est.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ut convallis, sem sit amet interdum consectetuer, odio augue aliquam leo, nec dapibus tortor nibh sed augue. Integer eu magna sit amet metus fermentum posuere. Morbi sit amet nulla sed dolor elementum imperdiet. Quisque fermentum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque adipiscing eros ut libero. Ut condimentum mi vel tellus. Suspendisse laoreet. Fusce ut est sed dolor gravida convallis. Morbi vitae ante. Vivamus ultrices luctus nunc. Suspendisse et dolor. Etiam dignissim. Proin malesuada adipiscing lacus. Donec metus. Curabitur gravida.&lt;/p&gt;&lt;/div&gt;&lt;div style='clear:both;'&gt;&lt;/div&gt;&lt;button type="button" style='float:left;' onclick='$("#long-para").scrollTop(200);'&gt;scroll me&lt;/button&gt;&lt;button type="button" style='float:left;margin-left:220px;' onclick='$("#long-para2").scrollTop(200);'&gt;scroll me&lt;/button&gt;&lt;br /&gt;&lt;div style='clear:both;'&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;So for either of these boxes I could call something like $(".excess_content").scrollTop(200); and the content would be scrolled regardless of whether there was a scrollbar or not.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The next thing I want to look at is how to scroll to a particular peice of content. Say we had a paragraph that had the most important text and some users may want to skip immediately to that paragraph. Similar to anchor tags in a page, we can reference an item inside our scrolling div in a similar way and scroll our element to that position.&lt;/p&gt;&lt;p&gt;To begin with I have labelled on of my &amp;lt;p&amp;gt; tags with the id "red_para". This paragraph has some text marked in red, when the button is clicked the element is scrolled immediately to that section.&lt;/p&gt;&lt;br /&gt;&lt;div id="long-para3" class="excess_content" style="width:200px;height:400px;overflow:auto;float:left;position:relative;"&gt;&lt;p&gt;Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Suspendisse mauris. Fusce accumsan mollis eros. Pellentesque a diam sit amet mi ullamcorper vehicula. Integer adipiscing risus a sem. Nullam quis massa sit amet nibh viverra malesuada. Nunc sem lacus, accumsan quis, faucibus non, congue vel, arcu. Ut scelerisque hendrerit tellus. Integer sagittis. Vivamus a mauris eget arcu gravida tristique. Nunc iaculis mi in ante. Vivamus imperdiet nibh feugiat est.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ut convallis, sem sit amet interdum consectetuer, odio augue aliquam leo, nec dapibus tortor nibh sed augue. Integer eu magna sit amet metus fermentum posuere. Morbi sit amet nulla sed dolor elementum imperdiet. Quisque fermentum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque adipiscing eros ut libero. Ut condimentum mi vel tellus. Suspendisse laoreet. Fusce ut est sed dolor gravida convallis. Morbi vitae ante. Vivamus ultrices luctus nunc. Suspendisse et dolor. Etiam dignissim. Proin malesuada adipiscing lacus. Donec metus. Curabitur gravida.&lt;/p&gt;&lt;p&gt;Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Suspendisse mauris. Fusce accumsan mollis eros. Pellentesque a diam sit amet mi ullamcorper vehicula. Integer adipiscing risus a sem. Nullam quis massa sit amet nibh viverra malesuada. Nunc sem lacus, accumsan quis, faucibus non, congue vel, arcu. Ut scelerisque hendrerit tellus. Integer sagittis. Vivamus a mauris eget arcu gravida tristique. Nunc iaculis mi in ante. Vivamus imperdiet nibh feugiat est.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ut convallis, sem sit amet interdum consectetuer, odio augue aliquam leo, nec dapibus tortor nibh sed augue. Integer eu magna sit amet metus fermentum posuere. Morbi sit amet nulla sed dolor elementum imperdiet. Quisque fermentum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque adipiscing eros ut libero. Ut condimentum mi vel tellus. Suspendisse laoreet. Fusce ut est sed dolor gravida convallis. Morbi vitae ante. Vivamus ultrices luctus nunc. Suspendisse et dolor. Etiam dignissim. Proin malesuada adipiscing lacus. Donec metus. Curabitur gravida.&lt;/p&gt;&lt;p&gt;Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna.&lt;/p&gt;&lt;br /&gt;&lt;p id='red_para' style="color:red;"&gt;Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Suspendisse mauris. Fusce accumsan mollis eros. Pellentesque a diam sit amet mi ullamcorper vehicula. Integer adipiscing risus a sem. Nullam quis massa sit amet nibh viverra malesuada. Nunc sem lacus, accumsan quis, faucibus non, congue vel, arcu. Ut scelerisque hendrerit tellus. Integer sagittis. Vivamus a mauris eget arcu gravida tristique. Nunc iaculis mi in ante. Vivamus imperdiet nibh feugiat est.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ut convallis, sem sit amet interdum consectetuer, odio augue aliquam leo, nec dapibus tortor nibh sed augue. Integer eu magna sit amet metus fermentum posuere. Morbi sit amet nulla sed dolor elementum imperdiet. Quisque fermentum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque adipiscing eros ut libero. Ut condimentum mi vel tellus. Suspendisse laoreet. Fusce ut est sed dolor gravida convallis. Morbi vitae ante. Vivamus ultrices luctus nunc. Suspendisse et dolor. Etiam dignissim. Proin malesuada adipiscing lacus. Donec metus. Curabitur gravida.&lt;/p&gt;&lt;p&gt;Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Suspendisse mauris. Fusce accumsan mollis eros. Pellentesque a diam sit amet mi ullamcorper vehicula. Integer adipiscing risus a sem. Nullam quis massa sit amet nibh viverra malesuada. Nunc sem lacus, accumsan quis, faucibus non, congue vel, arcu. Ut scelerisque hendrerit tellus. Integer sagittis. Vivamus a mauris eget arcu gravida tristique. Nunc iaculis mi in ante. Vivamus imperdiet nibh feugiat est.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ut convallis, sem sit amet interdum consectetuer, odio augue aliquam leo, nec dapibus tortor nibh sed augue. Integer eu magna sit amet metus fermentum posuere. Morbi sit amet nulla sed dolor elementum imperdiet. Quisque fermentum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque adipiscing eros ut libero. Ut condimentum mi vel tellus. Suspendisse laoreet. Fusce ut est sed dolor gravida convallis. Morbi vitae ante. Vivamus ultrices luctus nunc. Suspendisse et dolor. Etiam dignissim. Proin malesuada adipiscing lacus. Donec metus. Curabitur gravida.&lt;/p&gt;&lt;p&gt;Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Suspendisse mauris. Fusce accumsan mollis eros. Pellentesque a diam sit amet mi ullamcorper vehicula. Integer adipiscing risus a sem. Nullam quis massa sit amet nibh viverra malesuada. Nunc sem lacus, accumsan quis, faucibus non, congue vel, arcu. Ut scelerisque hendrerit tellus. Integer sagittis. Vivamus a mauris eget arcu gravida tristique. Nunc iaculis mi in ante. Vivamus imperdiet nibh feugiat est.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ut convallis, sem sit amet interdum consectetuer, odio augue aliquam leo, nec dapibus tortor nibh sed augue. Integer eu magna sit amet metus fermentum posuere. Morbi sit amet nulla sed dolor elementum imperdiet. Quisque fermentum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque adipiscing eros ut libero. Ut condimentum mi vel tellus. Suspendisse laoreet. Fusce ut est sed dolor gravida convallis. Morbi vitae ante. Vivamus ultrices luctus nunc. Suspendisse et dolor. Etiam dignissim. Proin malesuada adipiscing lacus. Donec metus. Curabitur gravida.&lt;/p&gt;&lt;/div&gt;&lt;div style='clear:both;'&gt;&lt;/div&gt;&lt;button type="button" onclick='$("#long-para3").scrollTop($("#red_para").position().top);'&gt;scroll me&lt;/button&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;So to scroll to a particular location we call the scrollTop function with the location of the target as the value. It looks like this:&lt;/p&gt;&lt;pre class='pre_code'&gt;onclick='$("#long-para3").scrollTop($("#red_para").position().top);'&lt;br /&gt; &lt;/pre&gt;&lt;p&gt;So to get the location of our #red_para paragraph we call the &lt;a href='http://api.jquery.com/position/'&gt;position function&lt;/a&gt; and use the top value. Position according to the API gets the current coordinates of the element relative to the parent element.&lt;/p&gt;&lt;p&gt;The next thing I want to look at doing is scroll to our section smoothly, currently scrollTop just jumps immediately to the position indicated. With the use of jQuery's animate method we can do this quite easily.&lt;/p&gt;&lt;p&gt;Here's what it looks like:&lt;/p&gt;&lt;pre class='pre_code'&gt;$("long-para4").animate({scrollTop: $("#red_para").position().top},1500);&lt;br /&gt; &lt;/pre&gt;&lt;br /&gt;&lt;div id="long-para4" class="excess_content" style="width:200px;height:400px;overflow:auto;float:left;position:relative;"&gt;&lt;p&gt;Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Suspendisse mauris. Fusce accumsan mollis eros. Pellentesque a diam sit amet mi ullamcorper vehicula. Integer adipiscing risus a sem. Nullam quis massa sit amet nibh viverra malesuada. Nunc sem lacus, accumsan quis, faucibus non, congue vel, arcu. Ut scelerisque hendrerit tellus. Integer sagittis. Vivamus a mauris eget arcu gravida tristique. Nunc iaculis mi in ante. Vivamus imperdiet nibh feugiat est.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ut convallis, sem sit amet interdum consectetuer, odio augue aliquam leo, nec dapibus tortor nibh sed augue. Integer eu magna sit amet metus fermentum posuere. Morbi sit amet nulla sed dolor elementum imperdiet. Quisque fermentum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque adipiscing eros ut libero. Ut condimentum mi vel tellus. Suspendisse laoreet. Fusce ut est sed dolor gravida convallis. Morbi vitae ante. Vivamus ultrices luctus nunc. Suspendisse et dolor. Etiam dignissim. Proin malesuada adipiscing lacus. Donec metus. Curabitur gravida.&lt;/p&gt;&lt;p&gt;Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Suspendisse mauris. Fusce accumsan mollis eros. Pellentesque a diam sit amet mi ullamcorper vehicula. Integer adipiscing risus a sem. Nullam quis massa sit amet nibh viverra malesuada. Nunc sem lacus, accumsan quis, faucibus non, congue vel, arcu. Ut scelerisque hendrerit tellus. Integer sagittis. Vivamus a mauris eget arcu gravida tristique. Nunc iaculis mi in ante. Vivamus imperdiet nibh feugiat est.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ut convallis, sem sit amet interdum consectetuer, odio augue aliquam leo, nec dapibus tortor nibh sed augue. Integer eu magna sit amet metus fermentum posuere. Morbi sit amet nulla sed dolor elementum imperdiet. Quisque fermentum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque adipiscing eros ut libero. Ut condimentum mi vel tellus. Suspendisse laoreet. Fusce ut est sed dolor gravida convallis. Morbi vitae ante. Vivamus ultrices luctus nunc. Suspendisse et dolor. Etiam dignissim. Proin malesuada adipiscing lacus. Donec metus. Curabitur gravida.&lt;/p&gt;&lt;p&gt;Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna.&lt;/p&gt;&lt;br /&gt;&lt;p id='red_para_ani' style="color:red;"&gt;Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Suspendisse mauris. Fusce accumsan mollis eros. Pellentesque a diam sit amet mi ullamcorper vehicula. Integer adipiscing risus a sem. Nullam quis massa sit amet nibh viverra malesuada. Nunc sem lacus, accumsan quis, faucibus non, congue vel, arcu. Ut scelerisque hendrerit tellus. Integer sagittis. Vivamus a mauris eget arcu gravida tristique. Nunc iaculis mi in ante. Vivamus imperdiet nibh feugiat est.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ut convallis, sem sit amet interdum consectetuer, odio augue aliquam leo, nec dapibus tortor nibh sed augue. Integer eu magna sit amet metus fermentum posuere. Morbi sit amet nulla sed dolor elementum imperdiet. Quisque fermentum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque adipiscing eros ut libero. Ut condimentum mi vel tellus. Suspendisse laoreet. Fusce ut est sed dolor gravida convallis. Morbi vitae ante. Vivamus ultrices luctus nunc. Suspendisse et dolor. Etiam dignissim. Proin malesuada adipiscing lacus. Donec metus. Curabitur gravida.&lt;/p&gt;&lt;p&gt;Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Suspendisse mauris. Fusce accumsan mollis eros. Pellentesque a diam sit amet mi ullamcorper vehicula. Integer adipiscing risus a sem. Nullam quis massa sit amet nibh viverra malesuada. Nunc sem lacus, accumsan quis, faucibus non, congue vel, arcu. Ut scelerisque hendrerit tellus. Integer sagittis. Vivamus a mauris eget arcu gravida tristique. Nunc iaculis mi in ante. Vivamus imperdiet nibh feugiat est.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ut convallis, sem sit amet interdum consectetuer, odio augue aliquam leo, nec dapibus tortor nibh sed augue. Integer eu magna sit amet metus fermentum posuere. Morbi sit amet nulla sed dolor elementum imperdiet. Quisque fermentum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque adipiscing eros ut libero. Ut condimentum mi vel tellus. Suspendisse laoreet. Fusce ut est sed dolor gravida convallis. Morbi vitae ante. Vivamus ultrices luctus nunc. Suspendisse et dolor. Etiam dignissim. Proin malesuada adipiscing lacus. Donec metus. Curabitur gravida.&lt;/p&gt;&lt;p&gt;Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Suspendisse mauris. Fusce accumsan mollis eros. Pellentesque a diam sit amet mi ullamcorper vehicula. Integer adipiscing risus a sem. Nullam quis massa sit amet nibh viverra malesuada. Nunc sem lacus, accumsan quis, faucibus non, congue vel, arcu. Ut scelerisque hendrerit tellus. Integer sagittis. Vivamus a mauris eget arcu gravida tristique. Nunc iaculis mi in ante. Vivamus imperdiet nibh feugiat est.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ut convallis, sem sit amet interdum consectetuer, odio augue aliquam leo, nec dapibus tortor nibh sed augue. Integer eu magna sit amet metus fermentum posuere. Morbi sit amet nulla sed dolor elementum imperdiet. Quisque fermentum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque adipiscing eros ut libero. Ut condimentum mi vel tellus. Suspendisse laoreet. Fusce ut est sed dolor gravida convallis. Morbi vitae ante. Vivamus ultrices luctus nunc. Suspendisse et dolor. Etiam dignissim. Proin malesuada adipiscing lacus. Donec metus. Curabitur gravida.&lt;/p&gt;&lt;/div&gt;&lt;div style='clear:both;'&gt;&lt;/div&gt;&lt;button type="button" onclick='$("#long-para4").animate({scrollTop: $("#red_para_ani").position().top},1500);'&gt;scroll me&lt;/button&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;If you click the above button or play around with the scrolling and then try and click again you will notice something, the scrolling jumps around. So in my last example I will show you how to correct this issue and ensure that regardless of the scrolling position it will always scroll to the top of the red paragraph.&lt;/p&gt;&lt;p&gt;The problem arises because the position function gives us the position of the paragraph relative to where the parent is currently scrolled. This means that once the scrollbar has been moved it does not return the same value as it does initially. So we need to add the value of the scrollbar onto the position value. Hopefully the code can explain this clearly:&lt;/p&gt;&lt;pre class='pre_code'&gt;$("#long-para5").animate({scrollTop: ($("#long-para5").scrollTop() + $("#red_para_ani2").position().top)},1500);&lt;br /&gt; &lt;/pre&gt;&lt;br /&gt;&lt;div id="long-para5" class="excess_content" style="width:200px;height:400px;overflow:auto;float:left;position:relative;"&gt;&lt;p&gt;Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Suspendisse mauris. Fusce accumsan mollis eros. Pellentesque a diam sit amet mi ullamcorper vehicula. Integer adipiscing risus a sem. Nullam quis massa sit amet nibh viverra malesuada. Nunc sem lacus, accumsan quis, faucibus non, congue vel, arcu. Ut scelerisque hendrerit tellus. Integer sagittis. Vivamus a mauris eget arcu gravida tristique. Nunc iaculis mi in ante. Vivamus imperdiet nibh feugiat est.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ut convallis, sem sit amet interdum consectetuer, odio augue aliquam leo, nec dapibus tortor nibh sed augue. Integer eu magna sit amet metus fermentum posuere. Morbi sit amet nulla sed dolor elementum imperdiet. Quisque fermentum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque adipiscing eros ut libero. Ut condimentum mi vel tellus. Suspendisse laoreet. Fusce ut est sed dolor gravida convallis. Morbi vitae ante. Vivamus ultrices luctus nunc. Suspendisse et dolor. Etiam dignissim. Proin malesuada adipiscing lacus. Donec metus. Curabitur gravida.&lt;/p&gt;&lt;p&gt;Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Suspendisse mauris. Fusce accumsan mollis eros. Pellentesque a diam sit amet mi ullamcorper vehicula. Integer adipiscing risus a sem. Nullam quis massa sit amet nibh viverra malesuada. Nunc sem lacus, accumsan quis, faucibus non, congue vel, arcu. Ut scelerisque hendrerit tellus. Integer sagittis. Vivamus a mauris eget arcu gravida tristique. Nunc iaculis mi in ante. Vivamus imperdiet nibh feugiat est.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ut convallis, sem sit amet interdum consectetuer, odio augue aliquam leo, nec dapibus tortor nibh sed augue. Integer eu magna sit amet metus fermentum posuere. Morbi sit amet nulla sed dolor elementum imperdiet. Quisque fermentum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque adipiscing eros ut libero. Ut condimentum mi vel tellus. Suspendisse laoreet. Fusce ut est sed dolor gravida convallis. Morbi vitae ante. Vivamus ultrices luctus nunc. Suspendisse et dolor. Etiam dignissim. Proin malesuada adipiscing lacus. Donec metus. Curabitur gravida.&lt;/p&gt;&lt;p&gt;Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna.&lt;/p&gt;&lt;br /&gt;&lt;p id='red_para_ani2' style="color:red;"&gt;Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Suspendisse mauris. Fusce accumsan mollis eros. Pellentesque a diam sit amet mi ullamcorper vehicula. Integer adipiscing risus a sem. Nullam quis massa sit amet nibh viverra malesuada. Nunc sem lacus, accumsan quis, faucibus non, congue vel, arcu. Ut scelerisque hendrerit tellus. Integer sagittis. Vivamus a mauris eget arcu gravida tristique. Nunc iaculis mi in ante. Vivamus imperdiet nibh feugiat est.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ut convallis, sem sit amet interdum consectetuer, odio augue aliquam leo, nec dapibus tortor nibh sed augue. Integer eu magna sit amet metus fermentum posuere. Morbi sit amet nulla sed dolor elementum imperdiet. Quisque fermentum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque adipiscing eros ut libero. Ut condimentum mi vel tellus. Suspendisse laoreet. Fusce ut est sed dolor gravida convallis. Morbi vitae ante. Vivamus ultrices luctus nunc. Suspendisse et dolor. Etiam dignissim. Proin malesuada adipiscing lacus. Donec metus. Curabitur gravida.&lt;/p&gt;&lt;p&gt;Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Suspendisse mauris. Fusce accumsan mollis eros. Pellentesque a diam sit amet mi ullamcorper vehicula. Integer adipiscing risus a sem. Nullam quis massa sit amet nibh viverra malesuada. Nunc sem lacus, accumsan quis, faucibus non, congue vel, arcu. Ut scelerisque hendrerit tellus. Integer sagittis. Vivamus a mauris eget arcu gravida tristique. Nunc iaculis mi in ante. Vivamus imperdiet nibh feugiat est.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ut convallis, sem sit amet interdum consectetuer, odio augue aliquam leo, nec dapibus tortor nibh sed augue. Integer eu magna sit amet metus fermentum posuere. Morbi sit amet nulla sed dolor elementum imperdiet. Quisque fermentum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque adipiscing eros ut libero. Ut condimentum mi vel tellus. Suspendisse laoreet. Fusce ut est sed dolor gravida convallis. Morbi vitae ante. Vivamus ultrices luctus nunc. Suspendisse et dolor. Etiam dignissim. Proin malesuada adipiscing lacus. Donec metus. Curabitur gravida.&lt;/p&gt;&lt;p&gt;Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus hendrerit. Pellentesque aliquet nibh nec urna. In nisi neque, aliquet vel, dapibus id, mattis vel, nisi. Sed pretium, ligula sollicitudin laoreet viverra, tortor libero sodales leo, eget blandit nunc tortor eu nibh. Nullam mollis. Ut justo. Suspendisse potenti.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Sed egestas, ante et vulputate volutpat, eros pede semper est, vitae luctus metus libero eu augue. Morbi purus libero, faucibus adipiscing, commodo quis, gravida id, est. Sed lectus. Praesent elementum hendrerit tortor. Sed semper lorem at felis. Vestibulum volutpat, lacus a ultrices sagittis, mi neque euismod dui, eu pulvinar nunc sapien ornare nisl. Phasellus pede arcu, dapibus eu, fermentum et, dapibus sed, urna.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Morbi interdum mollis sapien. Sed ac risus. Phasellus lacinia, magna a ullamcorper laoreet, lectus arcu pulvinar risus, vitae facilisis libero dolor a purus. Sed vel lacus. Mauris nibh felis, adipiscing varius, adipiscing in, lacinia vel, tellus. Suspendisse ac urna. Etiam pellentesque mauris ut lectus. Nunc tellus ante, mattis eget, gravida vitae, ultricies ac, leo. Integer leo pede, ornare a, lacinia eu, vulputate vel, nisl.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Suspendisse mauris. Fusce accumsan mollis eros. Pellentesque a diam sit amet mi ullamcorper vehicula. Integer adipiscing risus a sem. Nullam quis massa sit amet nibh viverra malesuada. Nunc sem lacus, accumsan quis, faucibus non, congue vel, arcu. Ut scelerisque hendrerit tellus. Integer sagittis. Vivamus a mauris eget arcu gravida tristique. Nunc iaculis mi in ante. Vivamus imperdiet nibh feugiat est.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ut convallis, sem sit amet interdum consectetuer, odio augue aliquam leo, nec dapibus tortor nibh sed augue. Integer eu magna sit amet metus fermentum posuere. Morbi sit amet nulla sed dolor elementum imperdiet. Quisque fermentum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque adipiscing eros ut libero. Ut condimentum mi vel tellus. Suspendisse laoreet. Fusce ut est sed dolor gravida convallis. Morbi vitae ante. Vivamus ultrices luctus nunc. Suspendisse et dolor. Etiam dignissim. Proin malesuada adipiscing lacus. Donec metus. Curabitur gravida.&lt;/p&gt;&lt;/div&gt;&lt;div style='clear:both;'&gt;&lt;/div&gt;&lt;button type="button" onclick='$("#long-para5").animate({scrollTop: ($("#long-para5").scrollTop() + $("#red_para_ani2").position().top)},1500);'&gt;scroll me&lt;/button&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;This should give you a good introduction to the scrollTop function and how to get it up and running smoothly.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-1016046551165685991?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/1016046551165685991/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=1016046551165685991' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/1016046551165685991'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/1016046551165685991'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2010/10/smooth-scrolling-with-jquery-scrolltop.html' title='Smooth scrolling with jQuery scrollTop'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-2500819871027986279</id><published>2010-10-13T19:02:00.000+11:00</published><updated>2010-10-13T19:02:25.122+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tips'/><category scheme='http://www.blogger.com/atom/ns#' term='articles'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>Be ready to go with pre-setup site folder</title><content type='html'>During my limited spare time I like to have a look around and answer questions on &lt;a href='http://stackoverflow.com/'&gt;Stack Overflow&lt;/a&gt;. Stack Overflow is not just a great place for getting answers to your questions, but is also great for finding out hints and tips about your language of choice just by browsing in a particular category. One of the main ways I browse the site is by searching for &lt;a href='http://stackoverflow.com/search?tab=newest&amp;q=[jquery]%20answers%3a0'&gt;jQuery questions that are unanswered&lt;/a&gt;. This a great opportunity to challenge yourself and stretch your skills by finding an answer to something that hasn't been answered before; good brain exercise.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;What I wanted to share with you today is how I set myself up ready to answer these questions without too much hassle. Quite often someone provides you with very few lines of code and if you had to set up a working environment each time it would be a huge hassle. If I have a spare hour I can usually get through about three or four questions so I need to be able to get up and going on an answer quickly otherwise it's just not worth the effort.&lt;br /&gt;&lt;br /&gt;This is fairly straight forward kind of stuff, but I find it also helps me at work to have on hand when I have small bits of code that I want to try out or when I am stuck working on a particular solution I like to break it down into manageable chunks and work on one section at a time. So, the idea is to have a folder with a bunch files ready to go with all the bits and pieces I need.&lt;br /&gt;&lt;br /&gt;To start with I keep a folder where I have all my previous attempts at other questions and solutions, you never know when you want to go back to one of these. Inside this folder is where I keep my base folder with all of these files. This folder is labeled 'aaa base'; it always sits on top and is easy to find that way. When I begin I just duplicate that folder and it's contents and then rename it to something that I will remember later e.g. if I'm working on an issue with draggables I call it draggable_something.&lt;br /&gt;&lt;br /&gt;Inside this folder are three sub folders: js, css and images. There is also a base html file index.html. The images folder is empty by default.&lt;br /&gt;&lt;br /&gt;Inside the js folder is script.js, a javascript file that contains an empty $(document).ready so that I can quickly add any jQuery / javascript as needed.&lt;br /&gt;&lt;br /&gt;Inside the css folder is styles.css an empty css file. I prefer not to use a reset stylesheet for these exercises as it's useful to have some padding and margins for readability.&lt;br /&gt;&lt;br /&gt;The index.html file looks as follows:&lt;br /&gt;&lt;pre class='pre_code'&gt;&amp;lt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD XHTML 1.0 Transitional//EN&amp;quot; &amp;quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;html xmlns=&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&lt;br /&gt;&amp;lt;title&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html;charset=utf-8&amp;quot; /&amp;gt;&lt;br /&gt;&amp;lt;script src=&amp;quot;http://www.google.com/jsapi&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;script&amp;gt;&lt;br /&gt; google.load(&amp;quot;jquery&amp;quot;, &amp;quot;1.4.2&amp;quot;);&lt;br /&gt; google.load(&amp;quot;jqueryui&amp;quot;, &amp;quot;1.8.4&amp;quot;);&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;./css/styles.css&amp;quot; /&amp;gt;&lt;br /&gt;&amp;lt;link href=&amp;quot;http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.4/themes/start/jquery-ui.css&amp;quot; type=&amp;quot;text/css&amp;quot; rel=&amp;quot;Stylesheet&amp;quot; /&amp;gt;&lt;br /&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;./js/script.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This begins with some of the basics; a DOCTYPE, html, head and body tags and also a reference to the character set.&lt;br /&gt;&lt;br /&gt;Next I load in the latest version of jQuery and jQuery UI using Google's CDN. As well as the start theme stylesheet for jQuery UI.&lt;br /&gt;&lt;br /&gt;The only thing left are the references to out styles.css css file and script.js javascript file.&lt;br /&gt;&lt;br /&gt;This combination allows me to easily load in code snippets from Stack Overflow and test out bits and pieces of my own quite quickly without having to go through the hassle of setting this up, I simply just duplicate and rename the folder each time.&lt;br /&gt;&lt;br /&gt;I have &lt;a href='https://sites.google.com/site/myphpetc/Home/aaabase.zip'&gt;attached my test folder&lt;/a&gt; in a zip for you to use on your own trials, hope it comes in handy.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-2500819871027986279?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/2500819871027986279/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=2500819871027986279' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/2500819871027986279'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/2500819871027986279'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2010/10/be-ready-to-go-with-pre-setup-site.html' title='Be ready to go with pre-setup site folder'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-6051373132157642159</id><published>2010-03-27T14:12:00.007+11:00</published><updated>2010-03-27T14:21:40.830+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='LEGO'/><category scheme='http://www.blogger.com/atom/ns#' term='articles'/><category scheme='http://www.blogger.com/atom/ns#' term='personal development'/><title type='text'>Lessons from LEGO for better software development</title><content type='html'>I love LEGO. I've always loved LEGO. In every design school out there they should be holding it up as the glorious example of marketing that it is. From the smallest offering with a single racecar to the largest of boxed sets, each LEGO set is displayed in accurate detail and glowing colours on the front of the box along with several smaller pictures on the back to demonstrate what fun you can have with your newly purchased bricks. Their packaging has lasted the ages and has changed little in the many years since LEGO became popular.&lt;br /&gt;&lt;br /&gt;Aside from their attraction and the many other joys of owning LEGO, there are lessons to be learned and applied to the world of software development from this humble little brick.&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/BILD_1918.JPG' style="border: 1px solid rgb(204, 204, 204);" /&gt;&lt;br /&gt;&lt;p style='font-size:8pt;color:#444;font-style:italic;'&gt;My son gets his first LEGO set on his 3rd birthday this week.&lt;/p&gt;&lt;br /&gt;&lt;h4&gt;If you want to build a world, start by building a car&lt;/h4&gt;Of all the kids I ever met growing up, even the ones who had parents with bottomless pockets, they still only bought one set at a time. The lesson here is that you buy one set, you play with it, you integrate it, you take it apart and change it around and not until it becomes part of everything else do you move on to the next set. With LEGO even the smallest set can deliver and look great with the rest of your LEGO world.&lt;br /&gt;&lt;br /&gt;So here's what we too often try to do with software: We ask the customer what they want, they want the full package, we market them the full package and we try and deliver them the full package. Month's later we're still trying to build the full package.&lt;br /&gt;&lt;br /&gt;The lesson we can learn from LEGO: First build that racecar, then deliver, play around with it, and when it fits in, then move onto the next step; maybe a gas station, maybe a garage for the LEGO person to park their car in. Build your system in small functioning parts, the benefits are obvious: Spot issues earlier; It makes more sense when integrating new functionality to see how the existing functionality works and view the context; Incremental improvements and incremental changes, when you finish the entire project if you do it incrementally you will deliver something closer to what the user actually wants and will have months of feedback.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Everything is made from something smaller that already exists&lt;/h4&gt;&lt;br /&gt;This should go without saying, but we still as developers continue to reinvent the brick every time we build something. After decades of software development you would think it would be easier, so were are our magic bricks and why is it that you are still hand coding forms for web sites?&lt;br /&gt;&lt;br /&gt;Many frameworks allow you the felixibility of utilising built in APIs for things such as form generation etc. A fully fledged framework may not be the answer every time for the work you are doing. But have you thought about working as a team to put together your own toolbox of functionality that you seem to be writing over and over again. We have a function for building html select elements that can be populated from any array or database table and I've used it again and again and it sits in a utilities class that anyone can use.&lt;br /&gt;&lt;br /&gt;The lesson we can learn from LEGO: Don't build it, customise it. Make use of your existing blocks and you can build something rapidly again and again with the same reusable parts.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;If you've played with one LEGO set you've played with them all&lt;/h4&gt;&lt;br /&gt;The benefits of a system that is familiar and requires little training when newly built are endless and scalable. Think of this when you are designing and writing requirements. If you can make your system seem familiar to your users they will adapt and adopt faster. You should be also working towards having the best in class practices for building your 'familiar' systems; think of the many companies that have a software brand and how familiarity works in their favour.&lt;br /&gt;&lt;br /&gt;The lesson we can learn from LEGO: The instruction booklet you get from LEGO doesn't tell you how to play with your LEGO set, but a very straight forward step by step guide on how to get you up and going. The idea is to show you what you can achieve not how you should use it. You should build your software with familiar steps and controls.&lt;br /&gt;&lt;br /&gt;There are many more lessons we can learn and apply from LEGO, including scalability, reuse, minimalism and familiarity. These lessons are worthy of consideration for your next project.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-6051373132157642159?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/6051373132157642159/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=6051373132157642159' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/6051373132157642159'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/6051373132157642159'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2010/03/lessons-from-lego-for-better-software.html' title='Lessons from LEGO for better software development'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-3426078623885902298</id><published>2010-02-10T17:41:00.001+11:00</published><updated>2010-02-10T17:42:17.711+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tutorials'/><category scheme='http://www.blogger.com/atom/ns#' term='search'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>Build on-the-fly filtering with jQuery</title><content type='html'>This tutorial looks at using jQuery to build on-the-fly filtering for search results to quickly filter out by matching search terms with content and hiding those elements that don't match.&lt;br /&gt;&lt;br /&gt;Recently when jQuery upgraded their API they added a nice on-the-fly filtering feature for filtering by search terms within the API. To get an idea of what I'm talking about you can see the effect &lt;a href='http://api.jquery.com/category/events/'&gt;here&lt;/a&gt; by typing 'bl' into the search jQuery box and you will notice only the entries containing 'bl' are displayed.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;You can download the code for this tutorial &lt;a href='http://sites.google.com/site/myphpetc/Home/search.zip'&gt;here&lt;/a&gt;&lt;br /&gt;You can view a working demo &lt;a href='http://comp345.awardspace.com/search/search.html'&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/search_filter.jpg' style='border:1px solid #CCC;' /&gt;&lt;br /&gt;&lt;br /&gt;This filtering works on both the title and on the content. It is quite easy to build and a nice trick that has multiple applications. Let's have a look at what our HTML will look like for each of our page elements:&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;&amp;lt;div class=&amp;#039;option&amp;#039;&amp;gt;&lt;br /&gt; &amp;lt;div class=&amp;#039;title&amp;#039;&amp;gt;Soccer&amp;lt;/div&amp;gt;&lt;br /&gt; &amp;lt;div class=&amp;#039;description&amp;#039;&amp;gt;A sport played with two teams of eleven players, a round ball and two sets of goals.&amp;lt;/div&amp;gt;&lt;br /&gt; &amp;lt;a href=&amp;#039;#&amp;#039;&amp;gt;more...&amp;lt;/a&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So each element is an 'option' and there is a 'title' and a 'description' section. Fairly straight forward. Now let's look at the javascript behind the functionality:&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;$(&amp;quot;document&amp;quot;).ready(function() {&lt;br /&gt; $(&amp;quot;#search_field&amp;quot;).keyup(function() {&lt;br /&gt;  var terms = $(this).val().toLowerCase();&lt;br /&gt;  if (!terms) {&lt;br /&gt;   $(&amp;quot;.option&amp;quot;).show();&lt;br /&gt;  } else {&lt;br /&gt;   $(&amp;quot;.option&amp;quot;).hide().filter(function() {&lt;br /&gt;    return ($(this).children(&amp;quot;.title&amp;quot;).text().toLowerCase().indexOf(terms) &amp;gt; -1) || ($(this).children(&amp;quot;.description&amp;quot;).text().toLowerCase().indexOf(terms) &amp;gt; -1);&lt;br /&gt;   }).show();&lt;br /&gt;  }&lt;br /&gt; });&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We start by adding the keyup event listener to our #search_field input. Whenever the keyup event occurs we grab the contents of the input and convert to lowercase and store in the terms variable.&lt;br /&gt;&lt;br /&gt;If terms is empty we display all of our pages elements. If it is not empty then we begin by hiding all of the '.option' elements and then we apply a filter function. This function filters out all of the elements that do not contain the terms in the '.title' child element or the '.decription' child element. Those elements that haven't been filtered out are then displayed using show().&lt;br /&gt;&lt;br /&gt;This kind of filtering is really useful when you have a limited number of elements on the page and makes good sense if you want to avoid round trips to the database.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-3426078623885902298?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/3426078623885902298/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=3426078623885902298' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/3426078623885902298'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/3426078623885902298'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2010/02/build-on-fly-filtering-with-jquery.html' title='Build on-the-fly filtering with jQuery'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-2215609739405714132</id><published>2010-02-09T17:44:00.000+11:00</published><updated>2010-02-09T17:44:58.783+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='careers'/><category scheme='http://www.blogger.com/atom/ns#' term='industry'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><category scheme='http://www.blogger.com/atom/ns#' term='articles'/><category scheme='http://www.blogger.com/atom/ns#' term='personal development'/><title type='text'>How to get the best start with an IT career</title><content type='html'>When you are in College / University it is hard to have the far-sightedness to know how your career is going to progress and where you will be in the future. If you are currently studying to work in the IT industry it is a good idea to start thinking about what you are going to do once you graduate and what direction you would like to take. In this post I would like to give you some suggestions on how to make those first few steps into the IT industry. If you have some good suggestions yourself please add them in the comments.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;&lt;span style='font-weight:bold'&gt;What to do before you graduate&lt;/span&gt;&lt;br /&gt;Whatever you do, don't wait until you graduate before you start thinking about what you will do with your qualification. Many of you will be doing a generic IT degree that will prepare you for a range of careers within the industry. Now is the time to find out exactly what area you &lt;span style='font-style:italic;'&gt;want&lt;/span&gt; to work in. If you don't decide early you may find that you are in a job you don't enjoy and in that case your second job will need to be a move sideways to something you do enjoy.&lt;br /&gt;&lt;br /&gt;Once you have found the area you are interested in start learning and I don't just mean your text books. If your area of choice is design start reading about colour, start looking through books about interior decorating or design theory. If it is e-business, research some of the success stories in the industry or some of the more abstract titles on marketing. Read, read, read! Knowledge is king in the IT industry, the more you learn the more valuable you are; not just in terms of financial gain, but in the quality of the work you will deliver.&lt;br /&gt;&lt;br /&gt;Apply your knowledge. Find an open source project on the internet and get to work. Even if you can only work on small sections you will improve. Reach out and connect to others in your industry via social networking and find out how you can help by asking. While I was attending university I asked anyone I knew if they could offer some work experience and after a couple of weeks I was able to help collate and prepare single HTML pages for a company intranet, eventually progessing on to whole sections of their site. You need to reach out, the goal is to get something on your resume other than working at Wendys or generic call centre experience.&lt;br /&gt;&lt;br /&gt;Do as much studying, casual work, volunteer work, work experience and open source project work as you can before you graduate and you will be in a prime position come the time you graduate.&lt;br /&gt;&lt;br /&gt;&lt;span style='font-weight:bold'&gt;What to do once you graduate&lt;/span&gt;&lt;br /&gt;Once you graduate you should have a clear idea of which part of the IT industry you want to work in and hopefully you have put the hard yards in to read and learn some of the skills you will require. &lt;br /&gt;&lt;br /&gt;If you start having a look at employment advertisements you may be dissapointed, most of the jobs you would love to be doing usually require a lot more experience than you have. I would suggest that this is a fact for most people starting out, if you are damn lucky you will be able to find a fantastic first job that not only pays well, but is exactly what you were looking for. The key here is to focus on where you want to be rather than what is available to you now. It is best to think of your first job as a stepping stone to your ideal job. My first job as a programmer was paying much less than I was getting paid at the supermarket I worked at during my studies. The trick is to find a job that will actually get you to where you want to be next.&lt;br /&gt;&lt;br /&gt;The other point I would like to make about your first job; if it is only a stepping stone and there is no progression, do not stay there longer than a year. Work as hard as you possibly can in the first year to add many different skills to your resume and then move to where you want to be. If you are still being paid like a paperboy after a year, you are either not learning enough or your work is not appreciated. Remember, you want to get to the next step and start doing some real work.&lt;br /&gt;&lt;br /&gt;Once you land that all important second job you should be on your way to a positive and rewarding career in the IT industry.&lt;br /&gt;&lt;br /&gt;Just to sumarise:&lt;br /&gt;- Decide early what you want to do, don't wait till you graduate&lt;br /&gt;- Learn as much as you can while you are still studying&lt;br /&gt;- Look for work opportunities either in open source projects or work experience through social connections&lt;br /&gt;- Be content with your first job as long as it steers you in the right direction&lt;br /&gt;- Work hard in your first year so you can be in the job you want in a years time&lt;br /&gt;- Knowledge is king, learn and keep learning&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-2215609739405714132?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/2215609739405714132/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=2215609739405714132' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/2215609739405714132'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/2215609739405714132'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2010/02/how-to-get-best-start-with-it-career.html' title='How to get the best start with an IT career'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-6801626050904908962</id><published>2010-02-03T22:45:00.002+11:00</published><updated>2010-02-03T22:46:08.096+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='social networking'/><category scheme='http://www.blogger.com/atom/ns#' term='opinion'/><category scheme='http://www.blogger.com/atom/ns#' term='articles'/><category scheme='http://www.blogger.com/atom/ns#' term='business'/><title type='text'>How can business reap the benefits of organic social networking?</title><content type='html'>The long term benefits of social networking for enterprise are well known and have already been discussed in detail. There's team building, leveraging your knowledge base, early adoption and cross team discussion to name a few. For a long time there has been two sides of the fence to social networking in business; there are those who do and those that don't. The don't group is made up of several smaller groups; the we don't know how to do it, the we don't want to ruin our reputation or the we don't believe in the benefits groups.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;For a long time I believed that the second group were just poorly educated and if they could see the light (or just give it a try) they would not only be convinced of the benefits, but they could reap the rewards of an open blogging policy. But for larger size outfits this approach is just too unwieldly, the size of the dinosaur is too great and the idea of testing the waters is hard with such a large foot. For smaller sized operations it's not viable to crowd source and hard to find passionate bloggers (even in the IT industry) to write about work in their own free time.&lt;br /&gt;&lt;br /&gt;So how can small and large business still leverage the benefits of social networking outside of company blogging while still reaping the benefits for the business? The solution lies in employee involvement outside of the business. Already employees are connecting via Twitter, Linked In, myspace and other social networking outside of business hours. These organically formed social networking groups and activities can be taken advantage of (with permission) and business wide networking can be seen as an extension of these organic groups.&lt;br /&gt;&lt;br /&gt;Each of these sites has readily available APIs that can be used to link groups and information from each of your employees. The information that each employee is adding online has already been made publicly available. Does your employee already blog? Ask if you can provide their RSS feed to the rest of the company. Are there employees that tweet regularly? Why not have a company wide aggregator of this activity. As with all online activity the good quality links can be pushed higher and the chatter will be ignored. This large amount of activity that is already happening in the public arena could be shared within, and for the better material without.&lt;br /&gt;&lt;br /&gt;Be brave, be passionate about your employees and reach out. Not by sticking your foot in it, but by gently wading in.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-6801626050904908962?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/6801626050904908962/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=6801626050904908962' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/6801626050904908962'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/6801626050904908962'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2010/02/how-can-business-reap-benefits-of.html' title='How can business reap the benefits of organic social networking?'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-6679675372708578934</id><published>2010-02-02T17:42:00.002+11:00</published><updated>2010-02-02T19:46:50.184+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='opinion'/><category scheme='http://www.blogger.com/atom/ns#' term='marketing'/><category scheme='http://www.blogger.com/atom/ns#' term='articles'/><category scheme='http://www.blogger.com/atom/ns#' term='apple'/><title type='text'>Is Apple being too Apple?</title><content type='html'>Many, many years ago I used to work for an Apple Centre and many more years before that I was a child with a love of computers. The first computer my family ever bought was not just any computer, but an &lt;a href='http://en.wikipedia.org/wiki/Apple_IIGS'&gt;Apple IIgs&lt;/a&gt;. You only have to scan over aforementioned wikipedia page to see that it was a lovely piece of Apple engineering. It had it all; audio, graphics (it was all about the graphics in the 80s) a memory expansion slot and the ability to add an internal HD. I'm not bragging here, I'm trying to conjure the picture of a computer lovingly crafted and ahead of its time (think iPod).&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/appleiigs.jpg' style='border:1px solid #ccc;'/&gt;&lt;br /&gt;&lt;span style='font-size:9pt;color#777;'&gt;&lt;div xmlns:cc="http://creativecommons.org/ns#" about="http://www.flickr.com/photos/quagmirez31/3547583644/"&gt;&lt;a rel="cc:attributionURL" href="http://www.flickr.com/photos/quagmirez31/"&gt;http://www.flickr.com/photos/quagmirez31/&lt;/a&gt; / &lt;a rel="license" href="http://creativecommons.org/licenses/by-nd/2.0/"&gt;CC BY-ND 2.0&lt;/a&gt;&lt;/div&gt;&lt;/span&gt;&lt;br /&gt;Apple have sat in this niche for years; before the iPod became top of the Christmas list for young boys and girls, Apple was synonymous with the architecture, graphic arts, production and design industries. They were still producing top notch computers that were ahead of their time in terms of quality, speed and power. So what was the problem, why have Apple been hiding in a cave for so many years and how is possible that they might screw it up again?&lt;br /&gt;&lt;br /&gt;Firstly, during the 90s, Apple had &lt;a href='http://upload.wikimedia.org/wikipedia/en/timeline/39b870e1739017f305486f41fe37a0b1.png'&gt;too many different models on the market&lt;/a&gt; this also included their choice to allow cloned Macs in a revenue raising exercise. Sure customers like choice, but the customer was left with too much choice and were unsure which branch of the Macintosh family was appropriate and regardless of what you bought it was usually superseded by another model within a couple of months.&lt;br /&gt;&lt;br /&gt;Secondly, Apple have always kept a strangle hold on everything they do. Way back when, while I was stuck with the few games that my family could afford at $50 a pop, my friends were swapping disk-loads of games and applications almost daily. We were left with something that was good quality wise, but was useless unless you continued to pay.&lt;br /&gt;&lt;br /&gt;I don't want to go into too much detail in the above two points, because it should be obvious that the trend above is still part of the Apple's mentality today. Make something that is so good everyone will want it and then control the market that surrounds it. Think: iTunes, think app store, think Apple stores. They all look good and they are all flashy, but at the end of the day they are all Apple run and controlled.&lt;br /&gt;&lt;br /&gt;Sure Apple's iTunes and apps are now at a price point that stops people from hesitating before they spend a couple of bucks, but think about what you are getting... who decides what apps you can use on your iPod, who censors what you can use on your iPhone, who decides what you can and can't install on your newly bought iPad? Are you sacrificing good design and quality for a lack of innovation and control? Apple pushes DRM because it's what they have always done. Sure the iTunes/app store is a good concept, but think to yourself, would you be more empowered if you could shop at another store? Would this provide you as a consumer with greater choice and pricing?&lt;br /&gt;&lt;br /&gt;Although the smartphone/handheld industry has been around for a long while it is still finding its place outside of just being a telephone; maybe the equivelant of the personal computer in the mid-80s. How this pans out is anyones guess, but is it possible that someone will cut out some of the quality and sheen and deliver something that is flexible and open and you can install whatever you please, even if it means that your phone crashes occassionally?&lt;br /&gt;&lt;br /&gt;As Apple looks to create new revenue for the future it will be interesting to see if they can maintain their current model. Will they produce another ten "i" products that are essentially different sizes of the same thing with a few slight differences? It's not too hard to imagine because they did it in the 90's. Or can they dig deep and produce products that are not only innovative by design, but also innovative in functionality and value to consumers.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-6679675372708578934?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/6679675372708578934/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=6679675372708578934' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/6679675372708578934'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/6679675372708578934'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2010/02/is-apple-being-too-apple.html' title='Is Apple being too Apple?'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-4465356222816066695</id><published>2010-02-01T22:44:00.002+11:00</published><updated>2010-02-01T22:45:28.300+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='projects'/><category scheme='http://www.blogger.com/atom/ns#' term='industry'/><category scheme='http://www.blogger.com/atom/ns#' term='articles'/><category scheme='http://www.blogger.com/atom/ns#' term='business'/><title type='text'>Before you start coding... stop, take time and compare</title><content type='html'>Many years ago my high school teacher told me about his days as an analyst; whenever he used to go breakfast cereal shopping it used to drive his wife crazy. He would compare everything from box size to amounts of sugar and price per 100 grams. Whatever he did he had to make a comparison. So think for a second what you are working on at this moment... how does it compare? Have you taken the time to compare your solution against anything else?&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;In the IT industry we focus too much on benchmarking a standard set of things before making deliverable; how fast is your site, how many bugs are there left to remove and what will be the cost benefit to the business or to our customer. But, one step that is imperative before you make the first jump is to stop and compare. There are many ways that you can go about doing this, the easiest of them you could call the cereal box test. Take a look at what is on the shelf, what are those ready made solutions that are in the same market as the product you are delivering. Look at all of the features and compare to your own feature set: Is there something missing? Is there something extra that isn't of use now but is imperative to have later on?&lt;br /&gt;&lt;br /&gt;This is more than a custom tailored vs. boxed solution argument, it's about shopping around, even if the your customer isn't shopping anywhere else themsleves. If you've sold your customer on a particular solution ensure that you are giving them the best. Once the deal has been made you can even ask your client for their own ideas. Was there something in other proposals that you didn't offer. Have they heard of some new technology that they thought would be beneficial to the project. Once you are on the other side of the fence it's much easier to ask these kinds of questions and in the end it will pay in the results.&lt;br /&gt;&lt;br /&gt;In every day life we hate to let an opportunity go by, even worse we hate to lose time and money. Don't sell yourself or your clients short, look around, take time and compare. By always looking forward you may miss something good that is sitting just beside you.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-4465356222816066695?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/4465356222816066695/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=4465356222816066695' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/4465356222816066695'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/4465356222816066695'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2010/02/before-you-start-coding-stop-take-time.html' title='Before you start coding... stop, take time and compare'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-503990433615605298</id><published>2010-01-31T21:43:00.001+11:00</published><updated>2010-01-31T21:43:56.842+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wordpress'/><category scheme='http://www.blogger.com/atom/ns#' term='images'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorials'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>Easily add rotating banners to your wordpress site with jQuery</title><content type='html'>Adding a rotating banner to wordpress with jQuery is too easy. The &lt;a href='http://malsup.com/jquery/cycle/'&gt;jQuery cycle plugin&lt;/a&gt; is one of the oldest and the best and comes with a multitude of effects transitions and inculdes next previous and pager options if needed. Even more the plugin includes pause on hover, click to progress and even custom transitions, unleashing the power and versatlity of jQuery.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;I want to show how to do a simple fade out to the next photo style banner which is popular on many sites and works well in the main banner position. It's a good idea to check out some of the examples on the cycle plugin site and find whichever transition suits your needs. Some of the more animated transitions would likely suit your sidebar if you wanted to draw more attention away from the page. I feel something more subtle works better at the top op the page.&lt;br /&gt;&lt;br /&gt;A transitioning image on a recent site that I worked on:&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/ssd_trans.jpg' style='border:1px solid #CCC' /&gt;&lt;br /&gt;&lt;br /&gt;Now there are many sites that teach you to include jQuery using the &lt;a href='http://digwp.com/2009/06/including-jquery-in-wordpress-the-right-way/'&gt;wp_enqueue_script method&lt;/a&gt;. The best way for you to include jQuery on any site is to use &lt;a href='http://www.myphpetc.com/2009/11/google-ajax-libraries-cdn.html'&gt;Google's CDN&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;To do this add the following to your header.php file:&lt;br /&gt;&lt;pre class='pre_code'&gt;&amp;lt;script type=\&amp;quot;text/javascript\&amp;quot; src=\&amp;quot;http://www.google.com/jsapi\&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;script type=\&amp;quot;text/javascript\&amp;quot;&amp;gt;&lt;br /&gt; google.load(\&amp;quot;jquery\&amp;quot;, \&amp;quot;1.4\&amp;quot;);&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Next populate a div on your page with images where you would like your banner to appear:&lt;br /&gt;&lt;pre class='pre_code'&gt;&amp;lt;div id=\&amp;quot;header\&amp;quot;&amp;gt;&lt;br /&gt; &amp;lt;img src=\&amp;quot;&amp;lt;?php bloginfo(\&amp;#039;template_url\&amp;#039;);?&amp;gt;/images/01.jpg\&amp;quot; alt=\&amp;quot;Image 01\&amp;quot; /&amp;gt;&lt;br /&gt; &amp;lt;img src=\&amp;quot;&amp;lt;?php bloginfo(\&amp;#039;template_url\&amp;#039;);?&amp;gt;/images/02.jpg\&amp;quot; alt=\&amp;quot;Image 02\&amp;quot; /&amp;gt;&lt;br /&gt; &amp;lt;img src=\&amp;quot;&amp;lt;?php bloginfo(\&amp;#039;template_url\&amp;#039;);?&amp;gt;/images/03.jpg\&amp;quot; alt=\&amp;quot;Image 03\&amp;quot; /&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Make sure your images have been cropped and adjusted to a reasonable size, with you banner it works well if all the images have the same dimensions.&lt;br /&gt;&lt;br /&gt;Next download and include the cycle plugin in the head after the jQuery include, paying attention to wherever you installed the plugin:&lt;br /&gt;&lt;pre class='pre_code'&gt;&amp;lt;script language=\&amp;quot;javascript\&amp;quot; type=\&amp;quot;text/javascript\&amp;quot; src=\&amp;quot;&amp;lt;?php bloginfo(\&amp;#039;template_directory\&amp;#039;); ?&amp;gt;/js/jquery.cycle.all.min.js\&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The next bit is calling the plugin which is very straight forward:&lt;br /&gt;&lt;pre class='pre_code'&gt;jQuery(document).ready(function(){ &lt;br /&gt; jQuery(\&amp;quot;#header\&amp;quot;).cycle({&lt;br /&gt;  delay:-4000,&lt;br /&gt;  fx: \&amp;#039;fade\&amp;#039;,&lt;br /&gt;  pause: 1,&lt;br /&gt;  timeout:1000,&lt;br /&gt;  speed: 4000&lt;br /&gt; });&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I have set a negative delay so that it doesn't wait to transition for the very first image. I have set the 'fade' effect with a transition speed of 4 seconds and a timeout speed of 1 second which is the length of time between transisitons. The last option is pause which simply pauses the effect while the mouse is over the images.&lt;br /&gt;&lt;br /&gt;It's that easy and with the combined number of transitions you can really add some magic to your wordpress site.&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-503990433615605298?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/503990433615605298/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=503990433615605298' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/503990433615605298'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/503990433615605298'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2010/01/easily-add-rotating-banners-to-your.html' title='Easily add rotating banners to your wordpress site with jQuery'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-4618066354941368787</id><published>2010-01-30T22:04:00.002+11:00</published><updated>2010-01-30T22:07:42.467+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='teams'/><category scheme='http://www.blogger.com/atom/ns#' term='employment'/><category scheme='http://www.blogger.com/atom/ns#' term='industry'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><category scheme='http://www.blogger.com/atom/ns#' term='articles'/><title type='text'>Your next employee, 10 years experience or an avid learner?</title><content type='html'>How do you keep up to date in the IT world?&lt;br /&gt;&lt;br /&gt;Several months ago we did a round of interviews for a new position at our company. We weren't interested in how many years experience a person had, what we wanted was someone who was as passionate about IT as the rest of our team. Our team spends much of our spare time discussing the latest trends in the industry and how we can apply new technologies and methodologies to our work. One question that really stumped most people was 'How do you keep up to date in the IT world?'.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;From the number of people that we interviewed who could not provide a coherent answer to this question, I would assume that very few people regularly spend their time reading blogs, reading online news or even text books for that matter. I would have even accepted an "I check Digg every now and then to see what are the top results". Most of the time we had to prompt people by asking them more directly, such as do you regularly read any blogs or visit any tech sites. But this also yielded few precise answers.&lt;br /&gt;&lt;br /&gt;By the sheer fact that you are reading this post I am likely preaching to the converted. But I would like to say that staying up to date with IT is important and to do that you need to read, read, read. IT is an industry that is constantly trying to justify itself, we have to make time and make money for an organisation in order to exist and hopefully to grow. IT is in constant change which is one of the great things about our industry, but to stay relevant and to keep in touch we must constantly learn.&lt;br /&gt;&lt;br /&gt;So how can we encourage reading outside of the few text books that we bothered to take out of the plastic during your college / university years? Maybe this question, "'How do you keep up to date in the IT world?' should become a standard interview question for all new positions, I know it will be top of the list for me. Should we be taught about it by our teachers when we are at university?&lt;br /&gt;&lt;br /&gt;One of the best things we can do for new starters and for our own teams is to share what you read. Do you encourage learning amongst your staff or your team, do you take time to discuss what you have read in the past week? Maybe you could set up a page on your companies intranet or blog to share your latest thoughts and ideas or send out an email with your top ten links for the week. Take time in your weekly team meetings to find out what each person has learnt while doing their job this week. Foster a team of learners and growers and encourage this trend for anyone who joins your team.&lt;br /&gt;&lt;br /&gt;How you keep up to date is not just about what the individual knows, it is about how the individual will continue to contribute to your teams future. In the end there is not much difference between a basic "programmer" with 2 or 10 years experience. If you can find someone who wants to learn and share and challenge; they will be much more beneficial to your team. But you won't find this person unless you have a team that actively seeks and encourages this kind of person.&lt;br /&gt;&lt;br /&gt;What type of person would you like to add to your team? Someone who has 5+ years experience in this or that language or someone who has their finger on the pulse and is actually interested in what they are doing by constantly learning and constantly improving themselves and their team.&lt;br /&gt;&lt;br /&gt;Be sure to also check out &lt;a href='http://stackoverflow.com/questions/201189/what-do-you-do-to-keep-learning'&gt;this post&lt;/a&gt; for some good ideas on keeping you and your team learning.&lt;br /&gt;&lt;br /&gt;If you have some good ideas on how you or your team keeps up to date with IT leave me a message in the comments below.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-4618066354941368787?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/4618066354941368787/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=4618066354941368787' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/4618066354941368787'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/4618066354941368787'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2010/01/your-next-employee-10-years-experience.html' title='Your next employee, 10 years experience or an avid learner?'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-3938918639448924668</id><published>2010-01-29T19:04:00.000+11:00</published><updated>2010-01-29T19:04:26.376+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tutorials'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><category scheme='http://www.blogger.com/atom/ns#' term='beginning'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><category scheme='http://www.blogger.com/atom/ns#' term='beginner'/><title type='text'>Hints and tips for learning jQuery</title><content type='html'>In this article I want to give some hints and tips for those of you who are just beginning with jQuery. jQuery can seem quite overwhelming at first, there appears to be a lot to cover and the syntax appears quite technical at first. The great thing is, once you have overcome the initial learning period, jQuery syntax is quite readable and will provide you with a fantastic tool with limitless potential.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;I suggest before you begin, you also go over &lt;a href='http://docs.jquery.com/Tutorials'&gt;these tutorials&lt;/a&gt;. They are jQuery's own tutorials and are a good foundation. This tutorial will help you build on these basics and help you go further with jQuery.&lt;br /&gt;&lt;br /&gt;To begin with jQuery is now available via Google's &lt;a href='http://en.wikipedia.org/wiki/Content_delivery_network'&gt;content delivery network&lt;/a&gt; (CDN). This means that you don't need to download anything to begin using jQuery. Here's how you can start a basic page which will load in jQuery via the CDN.&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;&amp;lt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD XHTML 1.0 Transitional//EN&amp;quot; &amp;quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;html xmlns=&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&lt;br /&gt;&amp;lt;title&amp;gt;jQuery test&amp;lt;/title&amp;gt;&lt;br /&gt;&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html;charset=utf-8&amp;quot; /&amp;gt;&lt;br /&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;http://www.google.com/jsapi&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt; google.load(&amp;quot;jquery&amp;quot;, &amp;quot;1.4&amp;quot;);&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This basic page when loaded will contact Google's CDN from wherever you are in the world and include it in your page. So now we have jQuery up and ready.&lt;br /&gt;&lt;br /&gt;The next thing that I suggest you do is to get a copy of &lt;a href='http://getfirebug.com/'&gt;Firebug&lt;/a&gt; for Firefox. There are many similar tools for other browsers, I will leave you to investigate those. Having Firebug (or equivelant) allows us to enter javascript directly and view the results of running those commands. You can see from the screen shot below, when I type in the $ command I get the result function.&lt;br /&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/fire.jpg' style='border:1px solid #CCC;' /&gt;&lt;br /&gt;&lt;br /&gt;Firebug will be your best friend will learning jQuery because it can show the results of your function calls, prevent you from refreshing the browser and using alert messages for feedback and will even show you which elements match your jQuery selectors. Selectors tell jQuery which part of your page a certain function should target.&lt;br /&gt;&lt;br /&gt;So now you should have your page loading jQuery, which we have confirmed by using Firebug and typing in the $ command so let's dive in and start using jQuery.&lt;br /&gt;&lt;br /&gt;The first thing you will want to do to your page is to include a regular javascript file. You need to do this in the head after the section that loads in jQuery. Something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;my_script.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Open up the my_script.js file (or whatever you called it) and we will start with our jQuery code. If you have read any tutorials or had a play with jQuery you will know we need to start by adding in jQuery's document ready function so let's do that:&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;$("document").ready(function() {&lt;br /&gt; // Other code goes here!&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So if we place an alert() inside this function it will alert us when the page is loaded and ready to be accessed with jQuery.&lt;br /&gt;&lt;br /&gt;Besides the above, there is nothing else needed to start using jQuery and working with its awesome functionality. So let's start taking a look at the way the language itself works.&lt;br /&gt;&lt;br /&gt;jQuery has two main types of functions: Those that require a selector and those that don't...&lt;br /&gt;&lt;br /&gt;A jQuery function call with a selector&lt;br /&gt;&lt;pre class='pre_code'&gt;$("#details").hide();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;A jQuery function call without a selector&lt;br /&gt;&lt;pre class='pre_code'&gt;$.ajax("url", {}, function(data) {&lt;br /&gt; });&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So those with a selecter will be in the form $(&amp;lt;&amp;lt;selector&amp;gt;&amp;gt;).&amp;lt;&amp;lt;function&amp;gt;&amp;gt; and those without $.&amp;lt;&amp;lt;function&amp;gt;&amp;gt;. A selector allows us to target a specific element or elements on the page. So we have functions that allow us to target elements and functions that don't need to be targeted, such as AJAX calls.&lt;br /&gt;&lt;br /&gt;We can suggest that the non-selector functions are actually targeted at the entire page, then all functions can be viewed as &amp;lt;&amp;lt;selector&amp;gt;&amp;gt;.&amp;lt;&amp;lt;function&amp;gt;&amp;gt;.&lt;br /&gt;&lt;br /&gt;The function part of the call can be found in the API, a list of all the functions that jQuery currently provides, jQuery has a great &lt;a href='http://api.jquery.com/'&gt;API browser&lt;/a&gt; which you will eventually become familiar with, for now you can have a quick look to see some of the functionality available. You will notice that most of these is written as either .&amp;lt;&amp;lt;function name&amp;gt;&amp;gt; or jQuery.&amp;lt;&amp;lt;function name&amp;gt;&amp;gt;, jQuery.&amp;lt;&amp;lt;function name&amp;gt;&amp;gt; are the non-selector functions we mentioned.&lt;br /&gt;&lt;br /&gt;jQuery selector syntax takes a bit of learning, but here are some basic tips that will get you on your way...&lt;br /&gt;&lt;br /&gt;To start with jQuery selectors are based on &lt;a href='http://www.w3.org/TR/CSS2/selector.html'&gt;CSS selectors&lt;/a&gt;, if you are already familiar with CSS selectors you have a very good head start. So if you want to target all the h3 elements we can just do like this $("h3"). If you want to target all elements of a specific class you can do it this way $(".someclass"). All of the available selectors are available in the &lt;a href='http://api.jquery.com/category/selectors/'&gt;selectors section&lt;/a&gt; of the jQuery API.&lt;br /&gt;&lt;br /&gt;You can chain selectors just like CSS e.g. $(".someclass, h3")&lt;br /&gt;&lt;br /&gt;You can specify all descendants like CSS e.g. $("#specials *")&lt;br /&gt;&lt;br /&gt;jQuery even has special selectors to match child elements and for filtering out certain items from your selection. For now try and familiarise yourself with the basic selectors of class, attribute i.e. input[name='first_name'] and class selectors and build up from there. Just keep in mind, it is not unfamiliar, if you can select it in CSS you can select it using jQuery.&lt;br /&gt;&lt;br /&gt;The best way to get to know selectors is by trying out each of the selectors and the best place to do this is jQuery's site. Go to any page on the jQuery site, open up Firebug and start typing out some selectors. You can start out by trying in $("*") and drill down from there or view the page source and see which elements you would like to try and target.&lt;br /&gt;&lt;br /&gt;The next important thing to know about jQuery is chaining. Most jQuery functions will chain, meaning you don't need to type the selector out multiple times, you can just apply function after function as such;&lt;br /&gt;&lt;br /&gt;&amp;lt;&amp;lt;selector&amp;gt;&amp;gt;.&amp;lt;&amp;lt;function 1&amp;gt;&amp;gt;.&amp;lt;&amp;lt;function 2&amp;gt;&amp;gt;.&amp;lt;&amp;lt;function 3&amp;gt;&amp;gt;... and so on.&lt;br /&gt;&lt;br /&gt;For example:&lt;br /&gt;&lt;pre class='pre_code'&gt;$("#my_div").css("background", "red").addClass("dimensions").toggle();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This will apply each of the three functions to our first selector, as each function is called the result is passed along the chain until it reaches the end.&lt;br /&gt;&lt;br /&gt;So now we know how to write a basic jQuery function call and how to chain. Let's get familiar with the &lt;a href='http://api.jquery.com/'&gt;API&lt;/a&gt;. Looking down the left hand side you will see the main categories of the API; AJAX, Attributes etc. let's look at the main categories in detail.&lt;br /&gt;&lt;br /&gt;AJAX:   Used for making AJAX calls&lt;br /&gt;Attributes:  Used for retrieve/updating/adding/removing attributes  &lt;br /&gt;CSS:   Used for CSS manipulation (add class, remove class, set CSS rule)&lt;br /&gt;Data:   Used for storing extra data on a DOM element&lt;br /&gt;Dimensions:  Getting the size of elements on a page (width, height etc.)&lt;br /&gt;Effects:  Fade in, Fade out, animating and other effects&lt;br /&gt;Events:   Used for handling events such as onclick, mouseover etc.&lt;br /&gt;Forms:   Functions for manipulating forms&lt;br /&gt;Manipulation: Clone items, DOM inserting etc.&lt;br /&gt;Selectors:  A run down on the jQuery selectors and associated functions&lt;br /&gt;Traversing:  Functions for traversing the DOM&lt;br /&gt;&lt;br /&gt;There are several categories I have left out that are also worthwhile but are hard to generalise or only have a few functions. But you can get a good idea from above jQuery's main functionality. Again, have a play with some of the functions using jQuery's site and Firebug. Also if you click through on the function name in the API it will lead you to a lot of details information about each function including a demo of how it works.&lt;br /&gt;&lt;br /&gt;Just in summary, here is a rundown of what we have covered:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Use Google's CDN to load jQuery&lt;/li&gt;&lt;li&gt;Get Firebug so you can see what is going on and to run javascript/jQuery commands without reloading&lt;/li&gt;&lt;li&gt;Use the document ready function to use jQuery when your page loads (you can also use jQuery inside a regular function call)&lt;/li&gt;&lt;li&gt;A basic function is made up of $(&amp;lt;&amp;lt;selector&amp;gt;&amp;gt;).&amp;lt;&amp;lt;function&amp;gt;&amp;gt;&lt;/li&gt;&lt;li&gt;Selectors are based on and in most cases identical to CSS selectors&lt;/li&gt;&lt;li&gt;jQuery's functions can be chained&lt;/li&gt;&lt;li&gt;Get familiar with selectors then get familiar with functions in API&lt;/li&gt;&lt;li&gt;Use Firebug and jQuery's site to test out selectors/functions rather than trying to build things to test yourself&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Hopefully this gives you a leg up when starting out with jQuery. Let me know how you are going by leaving a comment below.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-3938918639448924668?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/3938918639448924668/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=3938918639448924668' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/3938918639448924668'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/3938918639448924668'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2010/01/hints-and-tips-for-learning-jquery.html' title='Hints and tips for learning jQuery'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-8640270322308684832</id><published>2010-01-24T07:38:00.001+11:00</published><updated>2010-01-24T07:40:09.541+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='industry'/><category scheme='http://www.blogger.com/atom/ns#' term='work'/><category scheme='http://www.blogger.com/atom/ns#' term='IT'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='articles'/><title type='text'>Professional trust - delivering more than what the customer sees</title><content type='html'>What makes a person a professional? I would suggest two things; knowledge and experience. You can have knowledge  without experience as in a college graduate and it's possible to have years of experience without learning anything new. As consumers we put a fair bit of faith in professionals, we trust what an auto mechanic says about our car and we must rely on the opinion of a doctor.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;This trust is extended even further, we expect that a professional can do something better than we can do ourselves. If you go to get a haircut you never get specifically what you asked for, the reason for this is the person cutting our hair can see what we can't see ourselves and adjusts accordingly. So this is another special trait of a professional, they have an insight into their subject. When they look at a piece of work they can see when something has been done well and when something has been done poorly. We as a consumer need to extend our trust to relying on a quality piece of work, even when we can't see it ourselves.&lt;br /&gt;&lt;br /&gt;This reminds me of an old episode of the Simpsons. Homer goes to visit his long lost brother who owns and operates a previously successful car design business. Homer's brother asks him to help design their next model car for the "average American". What ensues is an argument between the designers and Homer as to exactly how the car should look. The designers want to inerperate Homer's ideas into something that appears sleek and marketable while Homer just wants something that looks like what he has in his head. In the end, his brother agrees to let Homer build the car in his head and it ends up costing him his business.&lt;br /&gt;&lt;br /&gt;So we see for success, although the customer may always be right, it takes a good quality professional to implement the ideas and not in exactly the same way that the customer expected.&lt;br /&gt;&lt;br /&gt;So how do we apply this to the work we do in the IT industry. If you are on the other side of the fence and you are providing a client with work, you have the client's trust that you are going to deliver a good quality piece of work. In the IT industry we have an even greater level of smokescreen as we hide behind the code we write. The average guy on the street can see a good quality car or can pick out a bad haircut, but your customer has no chance of picking out your poorly written code.&lt;br /&gt;&lt;br /&gt;There is an unfortunate acceptance of well presented, poorly implemented, badly structured, overly cluttered and user-unfriendly code within our industry. I've heard the excuse many times that bugs in design and usability of web applications attributed to "it just works that way and it can't be fixed" which is accepted as the norm. People just expect less of the IT industry because it's apparantly over technical and supposedly unwieldly.&lt;br /&gt;&lt;br /&gt;The general acceptance of poorly written web sites results in people charging excesive amounts in return for something that is below par. Recently an IT colleague of mine recieved some code via another colleague (non-IT) that had been written by an agency. The initial delivery was table based HTML which would have fit well in 1996. After rejecting the code as unusable (it was to be included as part of a larger site), the rework came back and was the same code, but each TD, TR and TABLE element were replace with DIVs. Not only is there one person who still thinks it's acceptable to code this way, but there's a whole damn agency of monkeys who thinks it's fine to deliver this kind of work to a paying customer.&lt;br /&gt;&lt;br /&gt;Delivering poor quality work to a customer who is both accepting and uneducated is not only unprofessional, but it shows a lack of respect for the customer. This trust is given in the hopes that a customer will get not only what they ask for, but also for what they can't see. Are you selling or delivering to your customers a beautiful car with a second-hand engine?&lt;br /&gt;&lt;br /&gt;I wish I knew the source of this quote, I read it somewhere a while back. It said, when you work on a web application for your company, always write it to the highest possible standard. It doesn't matter that nobody will ever look at that piece of code and smile in recognition. What does matter is that you have delivered the best piece of work that you can. It's only by working to the best of your ability that you can continue to go further.&lt;br /&gt;&lt;br /&gt;So don't try to sell your customers or your company short. If you are a professional you will be delivering professional quality work. If you are just using your customers to make a quick buck you won't be doing it for long... I've had too many bad haircuts to know when not to go back.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-8640270322308684832?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/8640270322308684832/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=8640270322308684832' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/8640270322308684832'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/8640270322308684832'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2010/01/professional-trust-delivering-more-than.html' title='Professional trust - delivering more than what the customer sees'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-3085254918367984598</id><published>2010-01-22T17:49:00.001+11:00</published><updated>2010-01-22T20:02:46.681+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='usability'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorials'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>Building great site navigation with jQuery and key listeners</title><content type='html'>Good navigation is essential to any site. Gone are the days when everything should appear above the fold, users now want and expect a rich internet experience from the sites you build. A vital part of this is experience is a good layout and good navigation, especially if there are a large number of elements on the page.&lt;br /&gt;&lt;br /&gt;On top of this it is also worthwhile to consider users with accessability issues and who are constantly stuck with using the tab key to navigate around often poorly designed web pages.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;With jQuery it is possible and easy to improve keyboard site navigation by binding listeners to certain keys. In this post I will go over some of the basics to give you some ideas of how you can challenge your own designs and think about including a more clever way to navigate around the elements on your page.&lt;br /&gt;&lt;br /&gt;In my sample application I will have nine boxes in a 3 x 3 square. Allowing us to navigate left, right, up and down and performing some function when the enter is pressed. My navigation will be indicated by switching the class on the currently selected item.&lt;br /&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/naviga.jpg' style='border:1px solid #CCC;' /&gt;&lt;br /&gt;&lt;br /&gt;A working example of this code can be found &lt;a href='http://comp345.awardspace.com/navigate/index.html'&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You can download the actual code from &lt;a href='http://sites.google.com/site/myphpetc/Home/navigate.zip?attredirects=0&amp;d=0'&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Let's begin by looking at a simple function to getting your site to listen to key presses:&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;$("document").ready(function() {&lt;br /&gt; &lt;br /&gt; $(document).keydown(function(e) {&lt;br /&gt;  switch (e.keyCode) {&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here we have our jQuery document ready function and a document level listener for the keydown event. The last piece is the switch statement which will determine what action is performed whenever a key is pressed. As we are looking at navigating around our site, let's bind some listeners to the arrow keys. Here are the codes that we will need:&lt;br /&gt;&lt;br /&gt;37 Left arrow&lt;br /&gt;38 Up arrow&lt;br /&gt;39 Right arrow&lt;br /&gt;40 Down arrow&lt;br /&gt;&lt;br /&gt;I'm also going to add the enter key (code 13) to perform an action on the currently selected item.&lt;br /&gt;&lt;br /&gt;You can find a full list of keycodes &lt;a href='http://www.cambiaresearch.com/c4/702b8cd1-e5b0-42e6-83ac-25f0306e3e25/Javascript-Char-Codes-Key-Codes.aspx'&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Let's look at some pseudocode to see how our navigation will work:&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;$("document").ready(function() {&lt;br /&gt; &lt;br /&gt; $(document).keydown(function(e) {&lt;br /&gt;  switch (e.keyCode) {&lt;br /&gt;   case 13:&lt;br /&gt;    // Perform some action when enter is placed&lt;br /&gt;    return;&lt;br /&gt;   case 37:&lt;br /&gt;    // Navigate left&lt;br /&gt;    break;&lt;br /&gt;   case 38:&lt;br /&gt;    // Navigate up&lt;br /&gt;    break;&lt;br /&gt;   case 39:&lt;br /&gt;    // Navigate right&lt;br /&gt;    break; &lt;br /&gt;   case 40:&lt;br /&gt;    // Navigate down&lt;br /&gt;    break;   &lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now let's look at the full code to see how it all holds together:&lt;br /&gt;&lt;br /&gt;&lt;pre class="pre_code"&gt;&amp;lt;body&amp;gt;&lt;br /&gt; &amp;lt;div id=&amp;quot;container&amp;quot;&amp;gt;&lt;br /&gt;  &amp;lt;div class=&amp;#039;item&amp;#039;&amp;gt;0&amp;lt;/div&amp;gt;&lt;br /&gt;  &amp;lt;div class=&amp;#039;item&amp;#039;&amp;gt;1&amp;lt;/div&amp;gt;&lt;br /&gt;  &amp;lt;div class=&amp;#039;item&amp;#039;&amp;gt;2&amp;lt;/div&amp;gt;&lt;br /&gt;  &amp;lt;div class=&amp;#039;item&amp;#039;&amp;gt;3&amp;lt;/div&amp;gt;&lt;br /&gt;  &amp;lt;div class=&amp;#039;item&amp;#039;&amp;gt;4&amp;lt;/div&amp;gt;&lt;br /&gt;  &amp;lt;div class=&amp;#039;item&amp;#039;&amp;gt;5&amp;lt;/div&amp;gt;&lt;br /&gt;  &amp;lt;div class=&amp;#039;item&amp;#039;&amp;gt;6&amp;lt;/div&amp;gt;&lt;br /&gt;  &amp;lt;div class=&amp;#039;item&amp;#039;&amp;gt;7&amp;lt;/div&amp;gt;&lt;br /&gt;  &amp;lt;div class=&amp;#039;item&amp;#039;&amp;gt;8&amp;lt;/div&amp;gt;&lt;br /&gt;  &amp;lt;div style=&amp;#039;clear:both;&amp;#039;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt; &amp;lt;/div&amp;gt;&lt;br /&gt; &amp;lt;div style=&amp;#039;clear:both;&amp;#039;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt; &amp;lt;div id=&amp;quot;debug&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We can see our nine boxes all floated left in a containing div and all having the item class. Here is the javascript:&lt;br /&gt;&lt;br /&gt;&lt;pre class="pre_code"&gt;$(&amp;quot;document&amp;quot;).ready(function() {&lt;br /&gt; $(&amp;quot;.item:first&amp;quot;).addClass(&amp;quot;selected&amp;quot;);&lt;br /&gt; &lt;br /&gt; $(document).keydown(function(e) {&lt;br /&gt;  // Current index&lt;br /&gt;  var cur_idx = $(&amp;quot;.item&amp;quot;).index($(&amp;quot;.selected&amp;quot;));&lt;br /&gt;  var max_idx = $(&amp;quot;.item&amp;quot;).length - 1;&lt;br /&gt;  var row_length = 3;&lt;br /&gt;  &lt;br /&gt;  switch (e.keyCode) {&lt;br /&gt;   case 13:&lt;br /&gt;    $(&amp;quot;.item&amp;quot;).eq(cur_idx).effect(&amp;quot;explode&amp;quot;, {}, 500, function() {$(this).remove();});&lt;br /&gt;    $(&amp;quot;.item:first&amp;quot;).addClass(&amp;quot;selected&amp;quot;);&lt;br /&gt;    return;&lt;br /&gt;   case 37:&lt;br /&gt;    // Get index of current item, if 1 then nothing, else move one back&lt;br /&gt;    if (cur_idx == 0) {&lt;br /&gt;     var next_idx = 0;&lt;br /&gt;    } else {&lt;br /&gt;     var next_idx = cur_idx - 1;&lt;br /&gt;    }&lt;br /&gt;    break;&lt;br /&gt;   case 38:&lt;br /&gt;    if ((cur_idx - row_length) &amp;lt;= 0) {&lt;br /&gt;     var next_idx = 0;&lt;br /&gt;    } else {&lt;br /&gt;     var next_idx = (cur_idx - row_length);&lt;br /&gt;    }&lt;br /&gt;    break;&lt;br /&gt;   case 39:&lt;br /&gt;    // Get index of current item, if max then nothing, else move one forward&lt;br /&gt;    if (cur_idx == max_idx) {&lt;br /&gt;     var next_idx = cur_idx;&lt;br /&gt;    } else {&lt;br /&gt;     var next_idx = cur_idx + 1;&lt;br /&gt;    }&lt;br /&gt;    break; &lt;br /&gt;   case 40:&lt;br /&gt;    if ((cur_idx + row_length) &amp;gt;= max_idx) {&lt;br /&gt;     var next_idx = max_idx;&lt;br /&gt;    } else {&lt;br /&gt;     var next_idx = (cur_idx + row_length);&lt;br /&gt;    }&lt;br /&gt;    break;   &lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  if (typeof next_idx != &amp;#039;undefined&amp;#039;) {&lt;br /&gt;   $(&amp;quot;.item.selected&amp;quot;).removeClass(&amp;quot;selected&amp;quot;);&lt;br /&gt;   $(&amp;quot;.item&amp;quot;).eq(next_idx).addClass(&amp;quot;selected&amp;quot;);&lt;br /&gt;  }&lt;br /&gt; }); &lt;br /&gt; &lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We begin by setting the selected class on the first of our boxes.&lt;br /&gt;&lt;br /&gt;Next we set the keydown listener to the document. When the function is called we begin by getting the index of the currently selected item and also the number of items. The row_length variable is used to navigate up and down to the item above or below.&lt;br /&gt;&lt;br /&gt;Next comes our keyCode swtich statement. For each of the arrow keys codes 37, 38, 39 and 40 we calculate whether we are going to go outside the item at index 0 or the last iem and we navigate accordingly by removing the class for the currently selected item and applying it to the item at the next_idx index by using the jquery &lt;a href='http://api.jquery.com/eq/'&gt;eq() function&lt;/a&gt; to target the item at index next_idx.&lt;br /&gt;&lt;br /&gt;If the enter key is pressed (code 13) we call the jQuery UI effect "explode" and then remove the item and reset the selected class back to the first item.&lt;br /&gt;&lt;br /&gt;This is just the tip of the iceburg of what can be achieved using jQuery and key listeners but it should give you a glimpse of the possibilities for building a responsive, interactive web page.&lt;br /&gt;&lt;br /&gt;If you have some good examples of sites with outstanding keyboard navigation share it with us with a comment below.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-3085254918367984598?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/3085254918367984598/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=3085254918367984598' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/3085254918367984598'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/3085254918367984598'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2010/01/building-great-site-navigation-with.html' title='Building great site navigation with jQuery and key listeners'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-8303906724067527691</id><published>2010-01-21T21:39:00.001+11:00</published><updated>2010-01-21T21:39:29.653+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='opinion'/><category scheme='http://www.blogger.com/atom/ns#' term='advertising'/><category scheme='http://www.blogger.com/atom/ns#' term='social media'/><category scheme='http://www.blogger.com/atom/ns#' term='articles'/><title type='text'>Pervasive advertising and digital sharecroppers</title><content type='html'>Does pervasive advertising still work on the internet? As some of the big guys work hard to make a profit from their current business model pervasive advertising has crept onto pages and across screens. We've been led to believe that traditional methods of advertising are dying out; so why the full page ads, auto play video and pop-up like overlay advertisements? The simple answer is pervasive advertising works and still delivers a certain percentage of click throughs that can be depended on and on sold to clients. But internet advertising is a complex beast and one that big companies are struggling to make a profit from.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;Digital &lt;a href='http://www.roughtype.com/archives/2006/12/sharecropping_t.php'&gt;sharecropping&lt;/a&gt; is a dirty word, but in the end who really cares? In Nicholas Carr's own words "What's being concentrated, in other words, is not content but the economic value of content.". But, again, who cares? Part of everyon'es big obsession with Web 2.0 is the celebrity status, if you were at all concerned that Twitter was making big bucks out of onselling your tweets you would blog in your own dark corner of the web. Youtube didn't drag you to their site or link to your video without your permission. So it is reasonable that they should be able to cash in on their traffic. The traffic that is the pitter, patter of millions of satisfied content creators and viewers.&lt;br /&gt;&lt;br /&gt;What is interesting in the past five years of the internet, despite the large volumes of traffic flowing through &lt;a href='http://www.guardian.co.uk/business/2008/may/09/google.youtube'&gt;Youtube&lt;/a&gt;, &lt;a href='http://www.dailyfinance.com/story/media/is-twitter-really-profitable-do-the-math/19293401/'&gt;Twitter&lt;/a&gt; and &lt;a href='http://gawker.com/5137912/why-reality-will-bury-diggs-profit-dreams'&gt;other social sites&lt;/a&gt;, they are still finding it hard to come up with a successful model to compare with that made by the companies fund them (think the cost of buying Youtube to the profit made so far). Digital sharecropping aside, we have received a hell of a lot of joy in return for sharing our meager thoughts and content with these sites.&lt;br /&gt;&lt;br /&gt;Social sites are just like reality TV, some people are willing to participate for free in hopes of celebrity, while a larger company sells advertising on their television network.&lt;br /&gt;&lt;br /&gt;What's interesting to see is the way the big guys have gone about trying to get the best out of their clients advertising dollars. Like this example from &lt;a href='www.yahoo.com'&gt;yahoo&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/yahoo_sports.jpg' style='border:1px solid #CCC;'/&gt;&lt;br /&gt;&lt;br /&gt;Note, I didn't even click on this thing it just pops out at you and engulfs the entire screen. These type of adds are regular on yahoo's site and occasionally clicking on close will either redirect you to the sponsors site or just doesn't respond.&lt;br /&gt;&lt;br /&gt;This next example from &lt;a href='http://www.myspace.com/ween'&gt;myspace&lt;/a&gt; is even better. The only thing worth looking at on myspace is the band pages, and the only thing on those pages is the music player. So clever myspace place the add directly over the music player. After closing an add it is replaced approximately every couple of minutes with a new one.&lt;br /&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/ween_add.jpg' style='border:1px solid #CCC;'/&gt;&lt;br /&gt;&lt;br /&gt;But the most memorable advertisement recently has to go to Digg with their Dragon Age full page advertisement. That caused a storm so big the &lt;a href='http://digg.com/mods/How_to_remove_the_Digg_Dragon_Age_ad'&gt;instructions on how to remove the add&lt;/a&gt; reached the front page of Digg's own site. Have a look at the add below:&lt;br /&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/digg-dragon-age-origins.jpg' style='border:1px solid #CCC;' /&gt;&lt;br /&gt;&lt;br /&gt;The Digg community went crazy with many threatening never to return. As the backlash reverberated around the halls of Digg HQ and at the risk of losing their beloved linkers (farmers?) it prompted &lt;a href='http://about.digg.com/blog/digg-we%E2%80%99re-fixing-annoying-ads'&gt;this response&lt;/a&gt;. With full page adds never to be repeated since.&lt;br /&gt;&lt;br /&gt;I'm sure we won't be seeing the end of pervasive advertising on the internet, but advertising in the internet is different to advertising in the real world. Most people tolerate advertising in return for entertainment. But on the internet, especially where users are giving up some of their own time and effort they are not willing to let the experience be degrade by advertising that interferes with the experience.&lt;br /&gt;&lt;br /&gt;Sure we are willing to be sharecroppers and sure you can have advertising on your site and you can keep your traffic and we'll keep our 15 minutes of fame. By try and interrupt that experience and there might just be a workers strike.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-8303906724067527691?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/8303906724067527691/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=8303906724067527691' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/8303906724067527691'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/8303906724067527691'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2010/01/pervasive-advertising-and-digital.html' title='Pervasive advertising and digital sharecroppers'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-4502783063692886483</id><published>2010-01-21T20:57:00.002+11:00</published><updated>2010-01-21T20:58:31.844+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='AJAX'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorials'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>Save to database via Ajax using jQuery, php, mysql</title><content type='html'>When you start building your very first php + mysql applications you will likely have a loop that looks something like this:&lt;br /&gt;* Display a form&lt;br /&gt;* Submit a form to php page&lt;br /&gt;* Update database&lt;br /&gt;* Return user to form, possibly with success message&lt;br /&gt;&lt;br /&gt;This is a good basic loop and works perfectly fine in very small scale sites or for something like a user sign-up form to a newsletter etc. But as web applications have moved forward and there is a greater focus on more fluid and dynamic applications form processing has also progressed and it is now possible to submit a form without reloading your page.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;Think of the situation where someone has to use your web application to do a large amount of data entry or providing inline editing of a table. You wouldn't want your valuable users to be waiting while the page loads each time.&lt;br /&gt;&lt;br /&gt;This tutorial will show you how you can process your form using Ajax.&lt;br /&gt;&lt;br /&gt;A working version of this functionality can be viewed &lt;a href='http://comp345.awardspace.com/saveajax/aj.html'&gt;here&lt;/a&gt;.&lt;br /&gt;You can download the code for this tutorial &lt;a href='http://sites.google.com/site/myphpetc/Home/save_ajax.zip'&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Our new loop will look like this:&lt;br /&gt;* Display a form to the user&lt;br /&gt;* Validation is performed on the form before submit, displaying an alert dialog if validation fails&lt;br /&gt;* Form details are then sent to a php script via AJAX&lt;br /&gt;* php script attempts to save to database and reports if there were any errors&lt;br /&gt;* page is updated (form reset and success message) if successful or display error if save failed&lt;br /&gt;&lt;br /&gt;To begin with we have a relatively plain HTML form:&lt;br /&gt;&lt;pre class="pre_code"&gt;&amp;lt;form id=&amp;quot;personal_details&amp;quot; action=&amp;quot;process.php&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;&lt;br /&gt; &amp;lt;fieldset&amp;gt;&lt;br /&gt;  &amp;lt;legend&amp;gt;Personal Details&amp;lt;/legend&amp;gt;&lt;br /&gt;  &amp;lt;label for=&amp;quot;name&amp;quot;&amp;gt;Name&amp;lt;/label&amp;gt;&lt;br /&gt;  &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;name&amp;quot;/&amp;gt;&lt;br /&gt;  &amp;lt;label for=&amp;quot;age_range&amp;quot;&amp;gt;Age&amp;lt;/label&amp;gt;&lt;br /&gt;  &amp;lt;select name=&amp;quot;age_range&amp;quot;&amp;gt;&lt;br /&gt;   &amp;lt;option value=&amp;quot;&amp;quot;&amp;gt;Please select an age range&amp;lt;/option&amp;gt;&lt;br /&gt;   &amp;lt;option value=&amp;quot;1&amp;quot;&amp;gt;0-12&amp;lt;/option&amp;gt;&lt;br /&gt;   &amp;lt;option value=&amp;quot;2&amp;quot;&amp;gt;12-16&amp;lt;/option&amp;gt;&lt;br /&gt;   &amp;lt;option value=&amp;quot;3&amp;quot;&amp;gt;16-21&amp;lt;/option&amp;gt;&lt;br /&gt;   &amp;lt;option value=&amp;quot;4&amp;quot;&amp;gt;21-30&amp;lt;/option&amp;gt;&lt;br /&gt;   &amp;lt;option value=&amp;quot;5&amp;quot;&amp;gt;30-50&amp;lt;/option&amp;gt;&lt;br /&gt;   &amp;lt;option value=&amp;quot;6&amp;quot;&amp;gt;50+&amp;lt;/option&amp;gt;&lt;br /&gt;  &amp;lt;/select&amp;gt;&lt;br /&gt;  &amp;lt;label for=&amp;quot;sports&amp;quot;&amp;gt;Please select your favourite sports&amp;lt;/label&amp;gt;&lt;br /&gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;sports[]&amp;quot; value=&amp;quot;soccer&amp;quot; /&amp;gt;&amp;amp;nbsp;Soccer&amp;lt;br /&amp;gt;&lt;br /&gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;sports[]&amp;quot; value=&amp;quot;swimming&amp;quot; /&amp;gt;&amp;amp;nbsp;Swimming&amp;lt;br /&amp;gt;&lt;br /&gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;sports[]&amp;quot; value=&amp;quot;cycling&amp;quot; /&amp;gt;&amp;amp;nbsp;Cycling&amp;lt;br /&amp;gt;&lt;br /&gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;sports[]&amp;quot; value=&amp;quot;kayaking&amp;quot; /&amp;gt;&amp;amp;nbsp;Kayaking&amp;lt;br /&amp;gt;&lt;br /&gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;sports[]&amp;quot; value=&amp;quot;volleyball&amp;quot; /&amp;gt;&amp;amp;nbsp;Volleyball&amp;lt;br /&amp;gt;&lt;br /&gt;  &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;sports[]&amp;quot; value=&amp;quot;basketball&amp;quot; /&amp;gt;&amp;amp;nbsp;Basketball&amp;lt;br /&amp;gt;&lt;br /&gt;  &amp;lt;button type=&amp;quot;button&amp;quot; onclick=&amp;quot;processDetails();&amp;quot;&amp;gt;Submit&amp;lt;/button&amp;gt;&lt;br /&gt;  &amp;lt;div style=&amp;quot;clear:both;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt; &amp;lt;/fieldset&amp;gt;&lt;br /&gt;&amp;lt;/form&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/ajjx.jpg' style='border:1px solid #CCC;' /&gt;&lt;br /&gt;&lt;br /&gt;You can see we have a Submit button that calls the processDetails function. We also set processDetails as the submit function in the jQuery document ready function as such:&lt;br /&gt;&lt;pre class="pre_code"&gt;$("document").ready(function() {&lt;br /&gt; $("#personal_details").submit(function() {&lt;br /&gt;  processDetails();&lt;br /&gt;  return false;&lt;br /&gt; });&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now lets have a look at our processDetails function;&lt;br /&gt;&lt;pre class="pre_code"&gt;function processDetails() {&lt;br /&gt; var errors = &amp;#039;&amp;#039;;&lt;br /&gt; &lt;br /&gt; // Validate name&lt;br /&gt; var name = $(&amp;quot;#personal_details [name=&amp;#039;name&amp;#039;]&amp;quot;).val();&lt;br /&gt; if (!name) {&lt;br /&gt;  errors += &amp;#039; - Please enter a namen&amp;#039;;&lt;br /&gt; }&lt;br /&gt; // Validate age range&lt;br /&gt; var age_range = $(&amp;quot;#personal_details [name=&amp;#039;age_range&amp;#039;]&amp;quot;).val();&lt;br /&gt; if (!age_range) {&lt;br /&gt;  errors += &amp;#039; - Please select and age rangen&amp;#039;;&lt;br /&gt; }&lt;br /&gt; // Validate sports selection&lt;br /&gt; var sports = $(&amp;quot;#personal_details [name=&amp;#039;sports[]&amp;#039;]:checked&amp;quot;).length;&lt;br /&gt; if (!sports) {&lt;br /&gt;  errors += &amp;#039; - Please select your favourite sportsn&amp;#039;;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; if (errors) {&lt;br /&gt;  errors = &amp;#039;The following errors occurred:n&amp;#039; + errors;&lt;br /&gt;  alert(errors);&lt;br /&gt;  return false;&lt;br /&gt; } else {&lt;br /&gt;  // Submit our form via Ajax and then reset the form&lt;br /&gt;  $(&amp;quot;#personal_details&amp;quot;).ajaxSubmit({success:showResult});&lt;br /&gt;  return false;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;processDetails begins with our validating our three form inputs. We basically just check to see if they are set and if they have not been set we display an error message. If no errors are called we submit the form to Ajax by calling the ajaxSubmit function. &lt;a href='http://jquery.malsup.com/form/#ajaxSubmit'&gt;ajaxSubmit&lt;/a&gt; is part of the &lt;a href='http://jquery.malsup.com/form/'&gt;jQuery forms plugin&lt;/a&gt;. This plugin has many great functions that we can use for processing forms. The ajaxSubmit function looks at the form elements action attribute and uses that to submit your form via Ajax so we don't need to worry about serializing and submitting the form manually, it all gets taken care of. I also pass in a success function showResult which will be called on Ajax submit success.&lt;br /&gt;&lt;br /&gt;&lt;pre class="pre_code"&gt;function showResult(data) {&lt;br /&gt; if (data == 'save_failed') {&lt;br /&gt;  alert('Form save failed, please contact your administrator');&lt;br /&gt;  return false;&lt;br /&gt; } else {&lt;br /&gt;  $("#personal_details").clearForm().clearFields().resetForm();&lt;br /&gt;  alert('Form save success');&lt;br /&gt;  return false;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;On success we either display a success or failure alert message. If successful we also clear the form using the form plugins &lt;a href='http://jquery.malsup.com/form/#api'&gt;clearForm, clearFields and resetForm&lt;/a&gt; functions.&lt;br /&gt;&lt;br /&gt;So now anything that happens in our php script is going to happen in the background after it has been called via Ajax.&lt;br /&gt;&lt;br /&gt;In our php file we are going to do the following:&lt;br /&gt;* Retrieve our data from the form post ($_POST)&lt;br /&gt;* Check that we have been provided the amount of data we expected&lt;br /&gt;* Try connecting to the database&lt;br /&gt;* Clean the data from the post to ensure no attacks (please not in this example the cleaning is not extensive, you will need to learn about cleaning variables for database inserts elsewhere)&lt;br /&gt;* Attempt to insert the data into the database&lt;br /&gt;&lt;br /&gt;You will see that when there is an issue anywhere in the script we echo out 'save_failed' so that the javascript function showResult will know that there has been an issue.&lt;br /&gt;&lt;br /&gt;Furthermore with any of the myqsl functions I have appended an @ to the front of the function call, this will supress any error messages given if accessing the database fails.&lt;br /&gt;&lt;br /&gt;Let's have a look at the code:&lt;br /&gt;&lt;pre class='pre_code'&gt;// Retrieve form data&lt;br /&gt;$name = $_POST['name'];&lt;br /&gt;$age_range = $_POST['age_range'];&lt;br /&gt;$sports = $_POST['sports'];&lt;br /&gt;if (!$name || !$age_range || !$sports) {&lt;br /&gt; echo "save_failed";&lt;br /&gt; return;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Convert sports array to a serialized string&lt;br /&gt;$sports_list = serialize($sports);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We begin by retrieving the variables from the post and checking that they have been set.&lt;br /&gt;&lt;br /&gt;Next we attempt to connect to the database, the details of your database will be provided by your host or depending how you have set them on your own personal server:&lt;br /&gt;&lt;pre class='pre_code'&gt;$db = array(&lt;br /&gt; 'host' =&gt; 'host here',&lt;br /&gt; 'login' =&gt; 'username here',&lt;br /&gt; 'password' =&gt; 'password here',&lt;br /&gt; 'database' =&gt; 'database here',&lt;br /&gt;);&lt;br /&gt;$link = @mysql_connect($db['host'], $db['login'], $db['password']);&lt;br /&gt;if (!$link) {&lt;br /&gt; echo "save_failed";&lt;br /&gt; return; &lt;br /&gt;}&lt;br /&gt;mysql_select_db($db['database']);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;As mentioned, you will need to clean your variables to avoid database attacks. Begin by &lt;a href='http://stackoverflow.com/questions/110575/do-htmlspecialchars-and-mysqlrealescapestring-keep-my-php-code-safe-from-injec/110576#110576'&gt;reading this&lt;/a&gt; to get a good idea of what's required. &lt;a href='http://cakephp.org/'&gt;CakePHP&lt;/a&gt; has a very extensive cleaning function built in and is worth looking at if you want to do some further research.&lt;br /&gt;&lt;pre class='pre_code'&gt;// Clean variables before performing insert&lt;br /&gt;$clean_name = mysql_real_escape_string($name);&lt;br /&gt;$clean_age_range = mysql_real_escape_string($age_range);&lt;br /&gt;$clean_sports_list = mysql_real_escape_string($sports_list);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Our last step is doing the actual insert into the database:&lt;br /&gt;&lt;pre class='pre_code'&gt;// Perform insert&lt;br /&gt;$sql = "INSERT INTO details (name, age_range_ID, sports) VALUES ('{$clean_name}', {$clean_age_range}, '{$clean_sports_list}')";&lt;br /&gt;if (@mysql_query($sql, $link)) {&lt;br /&gt; echo "success";&lt;br /&gt; @mysql_close($link);&lt;br /&gt; return;&lt;br /&gt;} else {&lt;br /&gt; echo "save_failed";&lt;br /&gt; @mysql_close($link);&lt;br /&gt; return;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This is fairly straight forward; I try and run the query and then return the appropriate message and lastly close the database connection.&lt;br /&gt;&lt;br /&gt;Hopefully this tutorial gives you some good insight into getting started on adding Ajax database updates to your web applications.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-4502783063692886483?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/4502783063692886483/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=4502783063692886483' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/4502783063692886483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/4502783063692886483'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2010/01/save-to-database-via-ajax-using-jquery.html' title='Save to database via Ajax using jQuery, php, mysql'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-4094953611488830024</id><published>2010-01-15T21:22:00.001+11:00</published><updated>2010-01-15T21:22:35.344+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><category scheme='http://www.blogger.com/atom/ns#' term='articles'/><title type='text'>A shout out to open source and free software</title><content type='html'>Free and open source software is the lifeblood of the internet. You only need to look at the number of servers running open software, the number of sites written in open languages and the ability to be able to download a variety of top quality applications (virus protection, games, video players etc.) to know that; the figures speak for themselves.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;On top of this we have the bloggers, the plug-in developers, the evangelists, the authors, distributors and hosts that all give something away to further the free and open cause. Let's also not forget the end users, they are also important, they purchase the books and manuals, make donations and attend the conferences. It is with great pleasure that you can survey the current software landscape and see the giving of time, knowledge and creativity for the benefit of everyone. For this I want to say a big thank you to everyone on behalf of everyone else.&lt;br /&gt;&lt;br /&gt;As a developer, quite frequently during job interviews you will be asked if you contribute to open source or other online projects. I used to always answer no to this question. Sure everything I touched was built on open and free technology and my whole career depended on the stuff, but I had never gone so far as to actually participate.&lt;br /&gt;&lt;br /&gt;So this is my call to everyone, developer or not, to go out and participate. How? You don't need to write lines of code to help, but you can still contribute. Like the software you're working on? Go out and talk about it, blog about it, write about it in forums, evangelise. Don't know how to write? Buy a manual and support an author, most of the time those people who wrote the book also helped write the code. Still can't think of a way to help, most projects make it quite easy to donate and every bit helps.&lt;br /&gt;&lt;br /&gt;I love &lt;a href='http://www.gimp.org/'&gt;gimp&lt;/a&gt;, I love &lt;a href='http://www.ubuntu.com/'&gt;ubuntu&lt;/a&gt;, I love &lt;a href='http://php.net/index.php'&gt;php&lt;/a&gt; and the list goes on. Go out and spread the love! Take some time out of your own schedule to contribute and don't forget to consider what we now enjoy thanks to open software.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-4094953611488830024?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/4094953611488830024/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=4094953611488830024' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/4094953611488830024'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/4094953611488830024'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2010/01/shout-out-to-open-source-and-free.html' title='A shout out to open source and free software'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-7733113913434712249</id><published>2010-01-14T21:28:00.004+11:00</published><updated>2010-01-14T21:32:11.853+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='opinion'/><category scheme='http://www.blogger.com/atom/ns#' term='web devlopment'/><category scheme='http://www.blogger.com/atom/ns#' term='articles'/><title type='text'>Give up your bad coding habits this new year</title><content type='html'>What bad programming habits do you have? Developers are definitely creatures of habit and we tend to get stuck in our ways. I want to look at some of the bad habits I have picked up over the years and hopefully it will inspire and challenge you to take a look at the way you write code and maybe this new year we can try and change our ways.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;Most of these habits are not so bad (at least that's what I tell myself) that they are going to bring down a whole project, but a good coding practice reaps benefits; saving time, testing, number of bugs in your finalised code and even the sanity of your work mates. Good quality coding can become second nature with practice.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Coding style&lt;/h4&gt;I have to admit, I have the worlds worst hand writing. Beautiful hand writing is developed over years of practice. Your coding style is built up simarly over time, if you don't take time to indent your code, comment, consolidate and refactor as you go it will stay that way. By the time you reach the end of your page and look back at what you've typed you can't be bothered to go back and fix things up. It's like writing a paper and going back and dotting the 'i's once it's finished.&lt;br /&gt;Get in to the habit of correctly styling your code and just like your hand writing your speed will increase over time to the point where you can write presentable, intelligable, clean written code.&lt;br /&gt;Those of us with good coding styles also find it easier to switch styles on request. So if you move to another company or get a new client who requires a certain coding style you can easily adapt your current coding style.&lt;br /&gt;And if your company doesn't have it's own coding style (and you really want to make friends), try and encourage everyone to develop a company standard coding style that raises the bar for everyone.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Not enough testing&lt;/h4&gt;Oh no! Oh FUUUUUUUUU! Not god damn testing. If you're the kind of person who gets violently ill when asked to test your own code then you may be pleasantly surprised to know that the more you test and the earlier you test the less number of times you are going to have to revisit the same piece of code. There's only one thing worse than testing and that's having someone else tell you your code is buggy, so make sure you take the time to test your code.&lt;br /&gt;The best way to do this is to get some idea of how it's going to be used and once it's built go ahead and use it. Everyone writes buggy code, we write code fast because we can, but you can't code perfect. Apps and sites are built using building blocks, but you need to test each page and the site as a whole. Test after each section and test once you've put all the pieces together. You are more likely to find bugs testing like a user rather than testing like a developer so go ahead and click everything, try and break it and then plug those holes. People accept the fact you are going to write buggy code, but they will be surprised if you hand over a well tested piece of work. Remember these guys know how to break it better than we do, that's their job.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Read more&lt;/h4&gt;One of the questions we asked in a recent round of interviews was 'what sites do you like to visit online and how do you keep your skills up to date?'. We were surprised at the number of people who didn't have an answer for this. Members of our team are crazy about the web and the latest news. Reading tech books, blogs and news articles is part of our passion for IT. It's not something we do to keep up to date, it's something we do because we love it.&lt;br /&gt;Even if you're just checking out &lt;a href='http://www.digg.com'&gt;Digg&lt;/a&gt; or looking at a few bugs on &lt;a href='http://stackoverflow.com/'&gt;Stack Overflow&lt;/a&gt;, the more you read the better your skills become. We work in an industry that is always changing and developers are being required more and more to provide clever solutions for a multitude of problems. One of the early pieces of software I worked on was a small java app for a biometric finger scanner and I was hired as a php developer. Broaden your skillset and increase your value, the net is full of clever solutions.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Cut and past code&lt;/h4&gt;Who doesn't cut and paste code; we do it from the one page we are working on to another, from the net or even from old apps into new apps. I do it, we all do it. The problem with cut and past code is context and understanding. You cut and paste code from one area and stick it into another you want to be sure that it's doing exactly what it should be doing. &lt;br /&gt;Good suggestions are ensuring that you relook at the way the code is commented; has the context changed? update the comments. Will you understand why it has been stuck there if you were to look at the same section of code in 3 months time? Try integrating the code by rewriting it, that is, only keep the good bits. If it looks out of place now, imagine what it will look like to someone else who looks at your code.&lt;br /&gt;If you need to search the net for an easy solution to a particular problem, chances are you don't understand the problem yourself enough to write it from scratch. Try and understand code and if you have time and it's a clever solution, try and learn how to write it yourself from scratch.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Programming in one environment delivering in another&lt;/h4&gt;This is one of my current bad habits. Our company standard web browser is IE6, so everything must be delivered and working on IE6. God help me if I had to debug and use web tools on IE6; I can't live without Firebug. But the big issue here is that once it's working in FF it has to be tweaked in IE6, which occassionally doesn't happen (guilty look).&lt;br /&gt;This really goes back to a good personal testing regime, but if you are developing for a particular environment your works not over until you have used and reviewed in that environment. And more than likely you will find more bugs if you use that environment more often. If you have a client who wants you to build for a particular environment or setup, try your hardest to work in that environment or at least do all of your quick and full reviews in that environment. If you code in FF and need to have it working in IE, have IE on the screen next to you, only use FF to fix bugs. Finding bugs saves you time rewriting the same code again.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Trying to code everything in the frontend/backend/database and overreliance on one language&lt;/h4&gt;This can be a real killer. If your coding relies heavily on one methodology or technology your work will suffer. Too much javascript or an overreliance on AJAX? Hate server side technologies and want to do everything in the backend?&lt;br /&gt;Usually sites like these suffer from speed, usability or functionality just doesn't work quite right. Try and get an understanding of how a good working application is put together and find a good balance between front and back. And as always, the number one rule of usability, don't put useless shit into your site.  &lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Comment, Comment and More Comments&lt;/h4&gt;How many times have I looked at code I wrote 4 weeks ago and have no idea why the hell I wrote what's in front of me. It's painful. Commenting is not only useful for yourself, but you should consider it a courtesy. You can also usually tell how good a coder someone is by how good there commenting is. Why? Because commenting is human readable, you can read it a lot faster than code, you can immediately see if someone understands what their code is doing.&lt;br /&gt;Commenting is a quality not a quantity thing, but more often than not it's lacking, so I suggest to aim for slightly over commented rather than commenting where and when you think necessary.&lt;br /&gt;Also as suggested elsewhere, if you touch a piece of code that is already commented, read the code and update the comments. Out of date commenting is just as dangerous as incorrect code.&lt;br /&gt;&lt;br /&gt;If you have any suggestions (or confessions) of coding habits that should be changed in this new year (and decade) let us know in the comments below.&lt;br /&gt;&lt;br /&gt;Have a great new year and happy coding!&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-7733113913434712249?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/7733113913434712249/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=7733113913434712249' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/7733113913434712249'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/7733113913434712249'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2010/01/give-up-your-bad-coding-habit-this-new.html' title='Give up your bad coding habits this new year'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-2677340144843362768</id><published>2010-01-13T18:45:00.003+11:00</published><updated>2010-01-13T18:46:52.606+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='articles'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery 1.4'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>What's in the jQuery 1.4 release</title><content type='html'>Well it's almost here. Just a couple of more sleeps and the official release of jQuery 1.4 is going to happen. I previously posted about what was expected to be included in jQuery 1.4. This post looks at the events surrounding the release and what has been included in jQuery 1.4.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;To begin with you will want to head over to this site: &lt;a href='http://jquery14.com/'&gt;this official site&lt;/a&gt; set up to celebrate the release of jQuery 1.4. It's going to have all the announcements and allows you to subscribe via RSS, email or &lt;a href='http://twitter.com/jquery'&gt;Twitter @jquery&lt;/a&gt; so you won't miss a thing. The site is called 'The 14 Days of jQuery' (plus the two extra days they snuck on the front). you will notice a bunch of links towards the bottom of the site A,B,1,2 etc... which will show you each of the announcements for each day.&lt;br /&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/jq1.jpg' style='border:1px solid #ccc;width:540px;' /&gt;&lt;br /&gt;&lt;br /&gt;At the time of this post day A and B have already passed and there has already been some exciting goodies revealed. To start off with there has been a complete rewrite of the API and it looks awesome (see screenshot below). The API rewrite was done courtesty of &lt;a href='http://www.karlswedberg.com/'&gt;Karl Swedberg&lt;/a&gt; in the process of writing the next version of the jQuery reference guide; it was so good they decided to turn his work into the new API site. So head on over to &lt;a href='http://api.jquery.com/'&gt;api.jquery.com&lt;/a&gt;, which is filled with all new examples and much more detail.&lt;br /&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/jq2.jpg' style='border:1px solid #ccc;width:540px;' /&gt;&lt;br /&gt;&lt;br /&gt;Even better, the new API even includes a section &lt;a href='http://api.jquery.com/category/version/1.4/'&gt;New or Changed in 1.4&lt;/a&gt; so you don't need to go digging around in the API to find out. One thing I did notice, this page didn't mention the changes to live() which are one of the most talked about changes, but when I browsed the &lt;a href='http://api.jquery.com/live/'&gt;API to .live()&lt;/a&gt; it did mention that it has been changed for 1.4. Quote: "As of jQuery 1.4, the .live() method supports custom events as well as &lt;span style='font-weight:bold;'&gt;all JavaScript events&lt;/span&gt;." So I guess they will be updating that later. Which means there must be some more jQuery awesomeness hidden elsewhere that is not included in the New or Changed section so far.&lt;br /&gt;&lt;br /&gt;Now if you are in hot anticipitation of the next release the fun doesn't stop here... If you can't wait till the actual release day, jQuery have released &lt;a href='http://jquery14.com/pre-release-2/jquery-14rc1'&gt;jQuery 1.4rc1&lt;/a&gt; the first release candidate which will become the actual release some point in the next 48 hours. So you can get your hands on the almost complete jQuery 1.4 now and start using it in your projects today. Please note, if you come across any inconsitencies or errors while use the release candidate (or the final release) please head on over to &lt;a href='http://groups.google.com/group/jquery-dev'&gt;jquery-dev&lt;/a&gt; and report the issues your having.&lt;br /&gt;&lt;br /&gt;According to the site: "The final release (along with the full changelog) will occur this Thursday, on January 14th, coinciding with jQuery’s 4th birthday.". So we don't have long to wait.&lt;br /&gt;&lt;br /&gt;The last piece of good news is that they are giving away free ebooks to any who makes a tax-deductable(please refer to your own countries tax laws, I don't know if this applies outside of the US) donation of US $20 or more. Go to the &lt;a href='http://jquery14.com/donate'&gt;donation page&lt;/a&gt; to make your donation and recieve your bonus eBook. The jQuery Project is a non-profit, open source effort, supported by donations and contributions from developers, supporters and professional organizations. Your contributions help fund the continued rapid development and growth of jQuery and the jQuery community.&lt;br /&gt;&lt;br /&gt;The jQuery 1.4 release gaurantees to be a killer, with major speed improvements and new functionality. I'm looking forward to the next 14 days. I also want to say a happy birthday to jQuery and many more to come. And a big thankyou to the developers who have made a tireless effort to get this release out on time.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-2677340144843362768?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/2677340144843362768/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=2677340144843362768' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/2677340144843362768'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/2677340144843362768'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2010/01/whats-in-jquery-14-release.html' title='What&apos;s in the jQuery 1.4 release'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-1100387415981947115</id><published>2010-01-12T20:20:00.001+11:00</published><updated>2010-01-12T20:20:39.375+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='databases'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorials'/><category scheme='http://www.blogger.com/atom/ns#' term='version control'/><category scheme='http://www.blogger.com/atom/ns#' term='articles'/><category scheme='http://www.blogger.com/atom/ns#' term='MSSQL'/><title type='text'>Put your database under version control</title><content type='html'>In this tutorial I want to look at some strategies for including your database as part of your version control strategy.&lt;br /&gt;&lt;br /&gt;Over the years that I have been writing web applications the majority of the sites I have worked on include some sort of database back-end. Whether they be large scale web applications or simply a sign-up for a newsletter, the database is an integral part of the system. It may come as a surprise that it has only been in the most recent of applications that I have started including the database as part of our version control strategy.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;If you haven't started to include your database as part of your version control I would like to point out some of the benefits realised and convince you of why this should also become your habit and part of your regular release cycle or even if it's a single site, part of your site release / update regime.&lt;br /&gt;&lt;br /&gt;Most of you &lt;strike&gt;should be&lt;/strike&gt; are most definitely &lt;a href='http://www.codinghorror.com/blog/archives/001315.html'&gt;backing up your database&lt;/a&gt; regularly, so I won't be covering that area.&lt;br /&gt;&lt;br /&gt;To kick things off I will explain to you how we were previously doing things before our recent changeover to versioning our database. In the not so distant past there were five of us working on different parts of the same app. Each of us were working off of the same database, which meant even if we weren't aware that someone was changing the database, there was a small chance of you finding out incidently that a change was made to the table you were working on (queue scream). We would each work on our separate parts and before Beta release day we would all come together and apply our changes to a clean database that would be used for production once Beta was over. Sounds scary right? It was worse than that; we all kept a text file with aforementioned database changes that could be thousands of lines of stored procedures, triggers and table updates. We did manage to make it work without huge dramas, but it's a terrible way to work.&lt;br /&gt;&lt;br /&gt;You can imagine if someone forgot to add their changes or held off adding changes or their changes needed to be reverted. The exact reason that we have version control for all our files, so why the hell not for your database? Your situation may (or may not) be as bad as what is mentioned above but you can see the benefits of including your database as part of your versioning: who changed it, when was it changed, can we roll back to a previous version, what should be included in this release? All of these things were not being answered before and we also couldn't track the most basic problem 'if something had been changed?'. Our CRM has hundreds of tables and stored procedures (not an exaggeration), it is God damn huge, so it's not an easy task to manually verify if something is changed or missing. You can now start to see a big problem requiring an easy solution.&lt;br /&gt;&lt;br /&gt;We had discussed the problem several times and could not come up with a suitable solution. We wanted something unobtrusive that would be less trouble than what we already had. With any IT team we are always looking for the solution which requires zero effort, has zero loop-holes in case someone forgets to (or is too damn lazy) to do it and is a complete solution to the problem (partial solution = likely fall back to personal methods = half of us do it this way and half of us do it our own way).&lt;br /&gt;&lt;br /&gt;The search for a solution got put onto the shelf (&lt;a href='http://en.wikipedia.org/wiki/Inertia'&gt;inertia&lt;/a&gt;) for some time until I came across a query to generate the CREATE script for any table or stored procedure, after this everything else fell in to place. I'll run you over our steps for keeping our database inside version control:&lt;br /&gt;&lt;br /&gt;Components:&lt;br /&gt;* Database table; each row contains the name, type and script to (re)create our stored procedures or tables.&lt;br /&gt;* Stored procedure; empties the above mentioned table and then repopulates with the current state of our database.&lt;br /&gt;* php script; Calls the stored procedure then retrieves all the rows from the table. Loops over each row then stores (or updates) an invdividual file which is a .sql file with the CREATE statement. These files are stored inside /db/stored_procedures or /db/tables folder.&lt;br /&gt;&lt;br /&gt;Steps:&lt;br /&gt;* Developer makes a change to a table or stored procedure&lt;br /&gt;* Developer finished making any changes to scripts and any other files that will form part of version control commit&lt;br /&gt;* Developer runs the php script above so that database files stored inside the repository are updated&lt;br /&gt;* Developer commits to version control and writes a lovely message for all to see&lt;br /&gt;* Other developers update their repositories and are aware that changes have been made to the database&lt;br /&gt;&lt;br /&gt;All is good, yay! But there is still one small issue, the zero loop-holes, what happens if someone forgets to commit there database changes? This is covered in our release cycle. Whoever is responsible for the release &lt;b&gt;MUST&lt;/b&gt; run the php script and if there are any database changes that have not been committed yet then we have a slight problem. This is usually solved by a bit of finger pointing. We also have an agreed rule, if it doesn't belong to anyone and was written by some phantom menace then we just revert back to the previous version (this hasn't happened yet because I work with such lovely people).&lt;br /&gt;&lt;br /&gt;Hopefully this gives you a good insight into how you can get your database into version control. It is hard for me to provide working examples as there are so many different combinations of databases and scripting languages. I have provided some links below that I used to get our MSSQL database under version control.&lt;br /&gt;&lt;br /&gt;&lt;a href='http://stackoverflow.com/questions/21547/in-mssql-how-do-i-generate-a-create-table-statement-for-a-given-table'&gt;How to generate a CREATE TABLE statement for a given table in SQL server&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;For your stored procedures you can do something like the following:&lt;br /&gt;&lt;pre class='pre_code'&gt;protected function export_storedprocs() {&lt;br /&gt; $sp_dir = $_SERVER[&amp;#039;APPL_PHYSICAL_PATH&amp;#039;] . &amp;#039;dbstored_procs\&amp;#039;;&lt;br /&gt;&lt;br /&gt; // Retrieve all SP names&lt;br /&gt; $strSQL = &amp;quot;SELECT Distinct SO.Name&lt;br /&gt;    FROM sysobjects SO (NOLOCK)&lt;br /&gt;    WHERE SO.Type = &amp;#039;P&amp;#039;&lt;br /&gt;    ORDER BY SO.Name&amp;quot;;&lt;br /&gt; $sps = $this-&amp;gt;fetchrows($strSQL);&lt;br /&gt; &lt;br /&gt; foreach ($sps as $sp) {&lt;br /&gt;  $strSQL = &amp;quot;EXEC sp_helptext {$sp[&amp;#039;Name&amp;#039;]}&amp;quot;;&lt;br /&gt;  $splines = $this-&amp;gt;fetchrows($strSQL);&lt;br /&gt;  if ($splines) {&lt;br /&gt;   $h = fopen($sp_dir . $sp[&amp;#039;Name&amp;#039;] . &amp;quot;.sql&amp;quot;, &amp;quot;w&amp;quot;);&lt;br /&gt;   foreach ($splines as $line) {&lt;br /&gt;    fwrite($h, $line[&amp;#039;Text&amp;#039;]);&lt;br /&gt;   }&lt;br /&gt;   fclose($h);&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; echo &amp;quot;Export complete&amp;quot;;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Also checkout: &lt;a href='http://www.simple-talk.com/sql/database-administration/pop-rivett-and-the-uncontrolled-release/'&gt;worthy reading on the same topic&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-1100387415981947115?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/1100387415981947115/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=1100387415981947115' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/1100387415981947115'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/1100387415981947115'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2010/01/put-your-database-under-version-control.html' title='Put your database under version control'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-4314948399529079318</id><published>2010-01-08T20:08:00.004+11:00</published><updated>2010-01-08T20:32:44.729+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSON'/><category scheme='http://www.blogger.com/atom/ns#' term='flickr'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorials'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>jQuery Galleriffic gallery with Flickr feed</title><content type='html'>This post looks at how you can combine the great look and functionality of the &lt;a href='http://www.twospy.com/galleriffic/'&gt;Galleriffic jQuery photo gallery plugin&lt;/a&gt; with &lt;a href='http://www.flickr.com/'&gt;Flickr&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/galler.jpg' style='border:1px solid #CCC;' /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;Flick has great functionality already for you to share and view your photos, but the one thing that it doesn't provide is custom styling. If you want to combine a particular Flick photo album within a web design or your own blog you can do so relatively easy with the use of Flickr's API and a bit of javascript. Today I will look at grabbing a Flickr feed using JSON and combine that with the fast and fantastic jQuery Galleriffic plugin.&lt;br /&gt;&lt;br /&gt;You can view a working example of this &lt;a href="http://comp345.awardspace.com/galleriffic/example-2.html"&gt;here&lt;/a&gt;. You can download the code &lt;a href='http://sites.google.com/site/myphpetc/Home/galleriffic.zip'&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The Galleriffic plugin is well styled out of the box, but can easily be customised and has all the features you would want: pagination, slideshow and nice transition effects. My main interest in this plugin is that it looks classy and works well with very little customisation.&lt;br /&gt;&lt;br /&gt;I will do a simple example and you can do the rest to integrate it into you site or design. I'm going to base my example on Galleriffic's own example-2.html. Begin by &lt;a href='http://www.twospy.com/galleriffic/'&gt;downloading Gallerific&lt;/a&gt; and you will find all the examples in the root directory. Open up example-2.html and let's begin editing.&lt;br /&gt;&lt;br /&gt;Start by removing all of the li elements except for the first one from the thumbs div, we will be using the remaining li element to clone later on. It should now look something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="pre_code"&gt;&amp;lt;div id=&amp;quot;thumbs&amp;quot; class=&amp;quot;navigation&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;ul class=&amp;quot;thumbs noscript&amp;quot;&amp;gt;&lt;br /&gt;        &amp;lt;li&amp;gt;&lt;br /&gt;            &amp;lt;a class=&amp;quot;thumb&amp;quot; name=&amp;quot;leaf&amp;quot; href=&amp;quot;http://farm4.static.flickr.com/3261/2538183196_8baf9a8015.jpg&amp;quot; title=&amp;quot;Title #0&amp;quot;&amp;gt;&lt;br /&gt;                &amp;lt;img src=&amp;quot;http://farm4.static.flickr.com/3261/2538183196_8baf9a8015_s.jpg&amp;quot; alt=&amp;quot;Title #0&amp;quot; /&amp;gt;&lt;br /&gt;            &amp;lt;/a&amp;gt;&lt;br /&gt;            &amp;lt;div class=&amp;quot;caption&amp;quot;&amp;gt;&lt;br /&gt;                &amp;lt;div class=&amp;quot;download&amp;quot;&amp;gt;&lt;br /&gt;                    &amp;lt;a href=&amp;quot;http://farm4.static.flickr.com/3261/2538183196_8baf9a8015_b.jpg&amp;quot;&amp;gt;Download Original&amp;lt;/a&amp;gt;&lt;br /&gt;                &amp;lt;/div&amp;gt;&lt;br /&gt;                &amp;lt;div class=&amp;quot;image-title&amp;quot;&amp;gt;Title #0&amp;lt;/div&amp;gt;&lt;br /&gt;                &amp;lt;div class=&amp;quot;image-desc&amp;quot;&amp;gt;Description&amp;lt;/div&amp;gt;&lt;br /&gt;                &amp;lt;div class=&amp;quot;image-auth&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;            &amp;lt;/div&amp;gt;&lt;br /&gt;        &amp;lt;/li&amp;gt;&lt;br /&gt;    &amp;lt;/ul&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I also added in the image-auth div so I can give some credit to the authors of the photos used in my example.&lt;br /&gt;&lt;br /&gt;Next we are going to change the document ready function. I'm going to show you the whole thing so you know where I'm coming from. Have a scan over it first and then I will explain what's going on. This is located at the bottom of the page just before the closing body tag.&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;jQuery(document).ready(function($) {&lt;br /&gt;    $.getJSON(&amp;quot;http://api.flickr.com/services/feeds/groups_pool.gne?id=32142572@N00&amp;amp;lang=en-us&amp;amp;format=json&amp;amp;jsoncallback=?&amp;quot;, function(data){&lt;br /&gt;            $.each(data.items, function(i,item){&lt;br /&gt;                var newthumb = $(&amp;quot;ul.thumbs&amp;quot;).children(&amp;quot;li:first&amp;quot;).clone();&lt;br /&gt;                var baseimg = item.media.m;&lt;br /&gt;                &lt;br /&gt;                var thumbimg = baseimg.replace(&amp;quot;_m.jpg&amp;quot;, &amp;quot;_s.jpg&amp;quot;);&lt;br /&gt;                $(newthumb).find(&amp;quot;img&amp;quot;).attr(&amp;quot;src&amp;quot;, thumbimg);&lt;br /&gt;                &lt;br /&gt;                var disimg = baseimg.replace(&amp;quot;_m.jpg&amp;quot;, &amp;quot;.jpg&amp;quot;);&lt;br /&gt;                $(newthumb).find(&amp;quot;.thumb&amp;quot;).attr(&amp;quot;href&amp;quot;, disimg);&lt;br /&gt;                &lt;br /&gt;                var lgeimg = baseimg.replace(&amp;quot;_m.jpg&amp;quot;, &amp;quot;_b.jpg&amp;quot;);&lt;br /&gt;                $(newthumb).find(&amp;quot;.download&amp;quot;).children(&amp;quot;a&amp;quot;).attr(&amp;quot;href&amp;quot;, lgeimg);&lt;br /&gt;                &lt;br /&gt;                var title = item.title;&lt;br /&gt;                var description = item.description;&lt;br /&gt;                &lt;br /&gt;                var desc = $(&amp;quot;&amp;lt;div /&amp;gt;&amp;quot;).append(description);&lt;br /&gt;                if ($(desc).children().size() == 3) {&lt;br /&gt;                    description = $(desc).children(&amp;quot;p:last&amp;quot;).html();&lt;br /&gt;                } else {&lt;br /&gt;                    description = &amp;quot;&amp;quot;;&lt;br /&gt;                }&lt;br /&gt;                &lt;br /&gt;                $(newthumb).find(&amp;quot;.image-title&amp;quot;).empty().html(title);&lt;br /&gt;                $(newthumb).find(&amp;quot;.image-desc&amp;quot;).empty().html(description);&lt;br /&gt;                $(newthumb).find(&amp;quot;.image-auth&amp;quot;).empty().html(item.author);&lt;br /&gt;                &lt;br /&gt;                $(&amp;quot;ul.thumbs&amp;quot;).append(newthumb);&lt;br /&gt;            });    &lt;br /&gt;            &lt;br /&gt;            $(&amp;quot;ul.thumbs&amp;quot;).children(&amp;quot;li:first&amp;quot;).remove();&lt;br /&gt;            &lt;br /&gt;            // Initially set opacity on thumbs and add&lt;br /&gt;            // additional styling for hover effect on thumbs&lt;br /&gt;            var onMouseOutOpacity = 0.67;&lt;br /&gt;            $(&amp;#039;#thumbs ul.thumbs li&amp;#039;).opacityrollover({&lt;br /&gt;                mouseOutOpacity:   onMouseOutOpacity,&lt;br /&gt;                mouseOverOpacity:  1.0,&lt;br /&gt;                fadeSpeed:         &amp;#039;fast&amp;#039;,&lt;br /&gt;                exemptionSelector: &amp;#039;.selected&amp;#039;&lt;br /&gt;            });&lt;br /&gt;            &lt;br /&gt;            // Initialize Advanced Galleriffic Gallery&lt;br /&gt;            var gallery = $(&amp;#039;#thumbs&amp;#039;).galleriffic({&lt;br /&gt;                delay:                     2500,&lt;br /&gt;                numThumbs:                 12,&lt;br /&gt;                preloadAhead:              10,&lt;br /&gt;                enableTopPager:            true,&lt;br /&gt;                enableBottomPager:         true,&lt;br /&gt;                maxPagesToShow:            7,&lt;br /&gt;                imageContainerSel:         &amp;#039;#slideshow&amp;#039;,&lt;br /&gt;                controlsContainerSel:      &amp;#039;#controls&amp;#039;,&lt;br /&gt;                captionContainerSel:       &amp;#039;#caption&amp;#039;,&lt;br /&gt;                loadingContainerSel:       &amp;#039;#loading&amp;#039;,&lt;br /&gt;                renderSSControls:          true,&lt;br /&gt;                renderNavControls:         true,&lt;br /&gt;                playLinkText:              &amp;#039;Play Slideshow&amp;#039;,&lt;br /&gt;                pauseLinkText:             &amp;#039;Pause Slideshow&amp;#039;,&lt;br /&gt;                prevLinkText:              &amp;#039;&amp;amp;lsaquo; Previous Photo&amp;#039;,&lt;br /&gt;                nextLinkText:              &amp;#039;Next Photo &amp;amp;rsaquo;&amp;#039;,&lt;br /&gt;                nextPageLinkText:          &amp;#039;Next &amp;amp;rsaquo;&amp;#039;,&lt;br /&gt;                prevPageLinkText:          &amp;#039;&amp;amp;lsaquo; Prev&amp;#039;,&lt;br /&gt;                enableHistory:             false,&lt;br /&gt;                autoStart:                 false,&lt;br /&gt;                syncTransitions:           true,&lt;br /&gt;                defaultTransitionDuration: 900,&lt;br /&gt;                onSlideChange:             function(prevIndex, nextIndex) {&lt;br /&gt;                    // &amp;#039;this&amp;#039; refers to the gallery, which is an extension of $(&amp;#039;#thumbs&amp;#039;)&lt;br /&gt;                    this.find(&amp;#039;ul.thumbs&amp;#039;).children()&lt;br /&gt;                        .eq(prevIndex).fadeTo(&amp;#039;fast&amp;#039;, onMouseOutOpacity).end()&lt;br /&gt;                        .eq(nextIndex).fadeTo(&amp;#039;fast&amp;#039;, 1.0);&lt;br /&gt;                },&lt;br /&gt;                onPageTransitionOut:       function(callback) {&lt;br /&gt;                    this.fadeTo(&amp;#039;fast&amp;#039;, 0.0, callback);&lt;br /&gt;                },&lt;br /&gt;                onPageTransitionIn:        function() {&lt;br /&gt;                    this.fadeTo(&amp;#039;fast&amp;#039;, 1.0);&lt;br /&gt;                }&lt;br /&gt;            });                        &lt;br /&gt;    });&lt;br /&gt;&lt;br /&gt;    // We only want these styles applied when javascript is enabled&lt;br /&gt;    $(&amp;#039;div.navigation&amp;#039;).css({&amp;#039;width&amp;#039; : &amp;#039;300px&amp;#039;, &amp;#039;float&amp;#039; : &amp;#039;left&amp;#039;});&lt;br /&gt;    $(&amp;#039;div.content&amp;#039;).css(&amp;#039;display&amp;#039;, &amp;#039;block&amp;#039;);&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You will notice that almost everything is now wrapped inside the getJSON call. We need to ensure our pictures are loaded before we call the gallerific function.&lt;br /&gt;&lt;br /&gt;The &lt;a href='http://docs.jquery.com/Ajax/jQuery.getJSON'&gt;getJSON&lt;/a&gt; call is a simple call to the Flickr Feed API. Once you get the hang of what's going on in this tutorial your next step is getting a Flick developer key and using JSON, you can do all sorts of cool things with the &lt;a href='http://www.flickr.com/services/api/'&gt;Flickr API&lt;/a&gt;. For this post I'm just keeping it simple and we will just be using a Group feed.&lt;br /&gt;&lt;br /&gt;The main part of the getJSON call is the URL: http://api.flickr.com/services/feeds/groups_pool.gne?id=32142572@N00&amp;lang=en-us&amp;format=json&amp;jsoncallback=?. It calls the groups_pool services feed and simply passes in the group ID. This can be retrieved easily from any group by going to the group's Flickr page and clicking on the RSS link near the bottom left hand corner of the page. The RSS feed will have an URL similar to this: http://api.flickr.com/services/feeds/groups_discuss.gne?id=1239213@N21&amp;lang=en-us&amp;format=rss_200 and you just grab the value of the id variable.&lt;br /&gt;&lt;br /&gt;The next thing we do is loop over the results:&lt;br /&gt;&lt;br /&gt;&lt;pre class="pre_code"&gt;$.each(data.items, function(i,item){&lt;br /&gt;    var newthumb = $(&amp;quot;ul.thumbs&amp;quot;).children(&amp;quot;li:first&amp;quot;).clone();&lt;br /&gt;    var baseimg = item.media.m;&lt;br /&gt;    &lt;br /&gt;    var thumbimg = baseimg.replace(&amp;quot;_m.jpg&amp;quot;, &amp;quot;_s.jpg&amp;quot;);&lt;br /&gt;    $(newthumb).find(&amp;quot;img&amp;quot;).attr(&amp;quot;src&amp;quot;, thumbimg);&lt;br /&gt;    &lt;br /&gt;    var disimg = baseimg.replace(&amp;quot;_m.jpg&amp;quot;, &amp;quot;.jpg&amp;quot;);&lt;br /&gt;    $(newthumb).find(&amp;quot;.thumb&amp;quot;).attr(&amp;quot;href&amp;quot;, disimg);&lt;br /&gt;    &lt;br /&gt;    var lgeimg = baseimg.replace(&amp;quot;_m.jpg&amp;quot;, &amp;quot;_b.jpg&amp;quot;);&lt;br /&gt;    $(newthumb).find(&amp;quot;.download&amp;quot;).children(&amp;quot;a&amp;quot;).attr(&amp;quot;href&amp;quot;, lgeimg);&lt;br /&gt;    &lt;br /&gt;    var title = item.title;&lt;br /&gt;    var description = item.description;&lt;br /&gt;    &lt;br /&gt;    var desc = $(&amp;quot;&amp;lt;div /&amp;gt;&amp;quot;).append(description);&lt;br /&gt;    if ($(desc).children().size() == 3) {&lt;br /&gt;        description = $(desc).children(&amp;quot;p:last&amp;quot;).html();&lt;br /&gt;    } else {&lt;br /&gt;        description = &amp;quot;&amp;quot;;&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    $(newthumb).find(&amp;quot;.image-title&amp;quot;).empty().html(title);&lt;br /&gt;    $(newthumb).find(&amp;quot;.image-desc&amp;quot;).empty().html(description);&lt;br /&gt;    $(newthumb).find(&amp;quot;.image-auth&amp;quot;).empty().html(item.author);&lt;br /&gt;    &lt;br /&gt;    $(&amp;quot;ul.thumbs&amp;quot;).append(newthumb);&lt;br /&gt;});    &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;data is returned in our callback function to the getJSON call. We then just loop over the data.items. If you want to look at what the feed looks like you can easily read it by &lt;a href='http://api.flickr.com/services/feeds/groups_pool.gne?id=32142572@N00&amp;lang=en-us&amp;format=json'&gt;going here&lt;/a&gt; and just replacing the Group id.&lt;br /&gt;&lt;br /&gt;When we loop over each of the items we begin by cloning our first item in the .thumbs unordered list. We then get the baseimg which is the image source URL passed in from the feed. For each photo you upload to Flickr they have several formats but all have similar URLs so we are going to take advantage of this knowledge and we don't need to manipulate the image we retrieve from Flickr into different sizes e.g.&lt;br /&gt;&lt;br /&gt;An image:             http://farm4.static.flickr.com/3261/2538183196_8baf9a8015.jpg&lt;br /&gt;Image thumbnail:     http://farm4.static.flickr.com/3261/2538183196_8baf9a8015_s.jpg&lt;br /&gt;Big version:         http://farm4.static.flickr.com/3261/2538183196_8baf9a8015_b.jpg&lt;br /&gt;&lt;br /&gt;You can now see they are almost identical. So we are going to build these three image links from the one retrieved in the feed. Our three images are thumbimg, disimg and lgeimg; our thumbnail, display image and large image. We then use jQuery's selectors to replace these URLs in the cloned li element $(newthumb).&lt;br /&gt;&lt;br /&gt;Next we want to get and set the title, description and author. The feed contains a preformated description with it's own thumbnail (who knows why, I guess for convenience). So we check the description HTML to see if it has three sections, if it does then a user description has been entered on Flickr and we grab it, otherwise just leave it blank:&lt;br /&gt;&lt;br /&gt;&lt;pre class="pre_code"&gt;var desc = $(&amp;quot;&amp;lt;div /&amp;gt;&amp;quot;).append(description);&lt;br /&gt;if ($(desc).children().size() == 3) {&lt;br /&gt;    description = $(desc).children(&amp;quot;p:last&amp;quot;).html();&lt;br /&gt;} else {&lt;br /&gt;    description = &amp;quot;&amp;quot;;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In the last step we insert the title, description and author and then append our cloned and updated li element:&lt;br /&gt;&lt;br /&gt;&lt;pre class="pre_code"&gt;$(newthumb).find(&amp;quot;.image-title&amp;quot;).empty().html(title);&lt;br /&gt;$(newthumb).find(&amp;quot;.image-desc&amp;quot;).empty().html(description);&lt;br /&gt;$(newthumb).find(&amp;quot;.image-auth&amp;quot;).empty().html(item.author);&lt;br /&gt;&lt;br /&gt;$(&amp;quot;ul.thumbs&amp;quot;).append(newthumb);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now that all the elements have been looped over and added we have one final thing to do before we proceed to build our gallery, we just need to remove our initial and no longer need first li element:&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;$(&amp;quot;ul.thumbs&amp;quot;).children(&amp;quot;li:first&amp;quot;).remove();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;After this is done we just call the gallerific function as per the initial example and then we're all ready to go.&lt;br /&gt;&lt;br /&gt;There's one small thing that I changed and that's the variable numThumbs which determines how many thumbs are displayed per page.&lt;br /&gt;&lt;br /&gt;One last thing to note is that the Flickr feeds only provide 20 items. If you want to get more from your feeds you will need to get a developer key and use the Flickr API. The public feeds are deliberately restricted to avoid abuse.&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-4314948399529079318?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/4314948399529079318/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=4314948399529079318' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/4314948399529079318'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/4314948399529079318'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2010/01/jquery-gallerific-gallery-with-flickr.html' title='jQuery Galleriffic gallery with Flickr feed'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-5848118595730218385</id><published>2009-12-08T21:41:00.001+11:00</published><updated>2009-12-08T21:41:31.377+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='articles'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>How to get on the jQuery IRC channel</title><content type='html'>This article looks at how to connect to the &lt;a href='http://blog.jquery.com/2007/02/17/the-jquery-irc-channel/'&gt;jQuery IRC channel&lt;/a&gt; via your web browser.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;To connect is straight forward, you can go &lt;a href='http://webchat.freenode.net/'&gt;here&lt;/a&gt;, this will display the following:&lt;br /&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/freenode.jpg' style='border 1px solid #CCC;'/&gt;&lt;br /&gt;&lt;br /&gt;Just enter any nickname and #jQuery as the channel and you are in.&lt;br /&gt;&lt;br /&gt;The jQuery IRC channel is helpful if you want to get something answered quickly, there's plenty of people hanging around who could help, but... make sure you ask something specific and make sure you ask something relevant and you will be sure to get some help.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-5848118595730218385?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/5848118595730218385/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=5848118595730218385' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/5848118595730218385'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/5848118595730218385'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/12/how-to-get-on-jquery-irc-channel.html' title='How to get on the jQuery IRC channel'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-5805185012116961992</id><published>2009-12-08T19:42:00.003+11:00</published><updated>2009-12-08T19:44:44.681+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tutorials'/><category scheme='http://www.blogger.com/atom/ns#' term='animate'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>Cool transitioniong effect between images using jQuery animate</title><content type='html'>This tutorial looks at using jQuery animate to transition from one image to another. jQuery's built in &lt;a href='http://docs.jquery.com/Effects/animate'&gt;animate&lt;/a&gt; function provides a method for easily animating styles such as height, color and position. I will show you a method of toggling backwards an forwards between two images by changing on images dimensions to match the others and by fading one image out to reveal the other.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;You can view a demo of this functionality &lt;a href='http://comp345.awardspace.com/animate/index.html'&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;You can download the code for this tutorial &lt;a href='http://sites.google.com/site/myphpetc/Home/animate.zip'&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/anim.jpg' /&gt;&lt;br /&gt;&lt;br /&gt;Each of the steps should work simultaneously to give a smooth transition from one image to the other. The current image will gradually change width/height while fading out to reveal the other image. The functionality will allow transistioning backwards and forwards between the two images.&lt;br /&gt;&lt;br /&gt;This functionality is a great example of jQuery's animate function and could be applied in a variety of ways. You could extend it to cycle through several images, use it in an online catalog for different views of an item or to make an interesting photo album.&lt;br /&gt;&lt;br /&gt;In our HTML we have a div marked with class .fade_switch, inside that are the two images that will be used to transition between:&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;&amp;lt;div class=&amp;#039;fade_switch&amp;#039; style=&amp;#039;display:block;position:relative;&amp;#039;&amp;gt;&lt;br /&gt; &amp;lt;img src=&amp;#039;./images/green_present.png&amp;#039; /&amp;gt;&lt;br /&gt; &amp;lt;img src=&amp;#039;./images/zim.jpg&amp;#039;/&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This is all the markup that is needed, now let's look at our javascript:&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;$("document").ready(function() {&lt;br /&gt; $(".fade_switch img").each(function() {&lt;br /&gt;  var img = new Image;&lt;br /&gt;  img.src = this.src;&lt;br /&gt;  var my_parent = $(this).parent(".fade_switch");&lt;br /&gt;  &lt;br /&gt;  var my_index = $(my_parent).children().index(this);&lt;br /&gt;  &lt;br /&gt;  var myself = $(this);&lt;br /&gt;  &lt;br /&gt;  $(img).load(function() {&lt;br /&gt;   $(myself).data("start_w", img.width);&lt;br /&gt;   $(myself).data("start_h", img.height);&lt;br /&gt;   if (my_index == 0) {&lt;br /&gt;    $(my_parent).css({"width":img.width, "height":img.height});&lt;br /&gt;   } else {&lt;br /&gt;    $(myself).hide();&lt;br /&gt;   }&lt;br /&gt;  });&lt;br /&gt;  &lt;br /&gt;  $(this).css({"position":"absolute", "top":"0px", "left":"0px"});&lt;br /&gt; });&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We begin by looping over each image belonging to a .fade_switch div. We preload the image and after each image has loaded we store its dimensions by using the &lt;a href='http://docs.jquery.com/Core/data#namevalue'&gt;data function&lt;/a&gt;, this will be used later when we animate back to its original size (this is required by IE).&lt;br /&gt;&lt;br /&gt;Next we check to see if it is the first image of the two, if so we set the parent .fade_switch element to the size of the image. We then hide the other image.&lt;br /&gt;&lt;br /&gt;We finish by setting each image to position absolute, so one image sits in front of the other.&lt;br /&gt;&lt;br /&gt;Then we have the click function for each .fade_switch div:&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;$(".fade_switch").click(function() {&lt;br /&gt;  if (!$(this).is(':animated')) {&lt;br /&gt;   var vis_img = $(this).children(":visible");&lt;br /&gt;   var hid_img = $(this).children(":hidden");&lt;br /&gt;   &lt;br /&gt;   $(vis_img).css("z-Index", "100");&lt;br /&gt;   &lt;br /&gt;   var vis_width = $(vis_img).data("start_w");&lt;br /&gt;   var vis_height = $(vis_img).data("start_h");&lt;br /&gt;   &lt;br /&gt;   var hid_width = $(hid_img).data("start_w");&lt;br /&gt;   var hid_height = $(hid_img).data("start_h");&lt;br /&gt;   &lt;br /&gt;   $(hid_img).css({"z-Index":"1","width":vis_width,"height":vis_height}).show();&lt;br /&gt;   &lt;br /&gt;   &lt;br /&gt;   &lt;br /&gt;   $(vis_img).animate({&lt;br /&gt;    "opacity" : "0",&lt;br /&gt;    "width" : hid_width,&lt;br /&gt;    "height" : hid_height&lt;br /&gt;   }, function() {&lt;br /&gt;    $(this).css("z-Index", "1").hide().css("opacity", "100");&lt;br /&gt;   }); &lt;br /&gt;&lt;br /&gt;   $(hid_img).animate({&lt;br /&gt;    "width" : hid_width,&lt;br /&gt;    "height" : hid_height&lt;br /&gt;   }, function() {&lt;br /&gt;    $(this).css("z-Index", "100");&lt;br /&gt;   });&lt;br /&gt;   &lt;br /&gt;   $(this).animate({&lt;br /&gt;    "width" : hid_width,&lt;br /&gt;    "height" : hid_height&lt;br /&gt;   });&lt;br /&gt;  }&lt;br /&gt; });&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We first check to see that this element is not being currently animated, this is done to stop multiple clicks from screwing things up mid transition. This is done using the &lt;a href='http://docs.jquery.com/Selectors/animated'&gt;:animated selector&lt;/a&gt;: if (!$(this).is(':animated')) {&lt;br /&gt;&lt;br /&gt;We then retrieve the two elements seperately according to whether they are visible or hidden. We set the visible image to have a zIndex of 100 so it sits on top.&lt;br /&gt;&lt;br /&gt;Next we grab the dimensions of each of the images and set the hidden image to have the same dimensions as the visible on, but with zIndex set to 1, then we set it show (it will not appear as it sits behind the other image since it has a zIndex of one and both are absolutely positioned).&lt;br /&gt;&lt;br /&gt;Once this is done we begin the animation. We animate the top image to opacity 0, and to shrink or grow to the behind image. Once it has completely faded and changed its dimensions we set it to zIndex 1 and hide it. We animate the back image to its original width and height and set it to zIndex 100 and we also make sure the parent div also has matching width and height.&lt;br /&gt;&lt;br /&gt;If you have any great transitioning tricks or want to recommend any good tutorials, share them in the comments below.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-5805185012116961992?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/5805185012116961992/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=5805185012116961992' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/5805185012116961992'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/5805185012116961992'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/12/cool-transitioniong-effect-between.html' title='Cool transitioniong effect between images using jQuery animate'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-2862572097517955301</id><published>2009-12-08T17:13:00.003+11:00</published><updated>2009-12-08T17:14:12.606+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tutorials'/><category scheme='http://www.blogger.com/atom/ns#' term='sortable'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery-UI'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><category scheme='http://www.blogger.com/atom/ns#' term='draggable'/><category scheme='http://www.blogger.com/atom/ns#' term='droppable'/><title type='text'>Accessing draggable elements from ui.droppable drop function</title><content type='html'>This post looks at the ui.droppable drop function. We will look at how to access the droppable, the element that has been dropped onto the droppable and how to access it's methods.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;In most cases the droppable views the item being dropped as a draggable, whether it is a ui.sortable or a ui.draggable. To get some understanding of how this works, I came across this section of the &lt;a href='http://jqueryui.pbworks.com/Droppable'&gt;jQuery UI Development and Planning wiki&lt;/a&gt;: "The droppable implementation comes with a global drag &amp; drop manager called $.ui.ddmanager. It tracks the current draggable, has a list of all droppables at all times and its 'drag' function is called during dragging of the draggable (a 'drop' function on mouseup). It then forwards to the actual widget functions of the current intersecting droppable.". This is important to understand as when we access the element after it is dropped it is referenced via ui.draggable.&lt;br /&gt;&lt;br /&gt;Let's take a look at the &lt;a href='http://jqueryui.com/demos/droppable/'&gt; droppable API&lt;/a&gt; and how it explains the drop function for the ui.droppable:&lt;br /&gt;&lt;br /&gt;This event is triggered when an accepted draggable is dropped 'over' (within the tolerance of) this droppable. In the callback, $(this) represents the droppable the draggable is dropped on. ui.draggable represents the draggable.&lt;br /&gt;&lt;br /&gt;Code examples:&lt;br /&gt;&lt;pre class='pre_code'&gt;Supply a callback function to handle the drop event as an init option.&lt;br /&gt;&lt;br /&gt;    $('.selector').droppable({&lt;br /&gt;       drop: function(event, ui) { ... }&lt;br /&gt;    });&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So our drop function has the following signature function(event, ui) and we know that $(this) represents the droppable and ui.draggable represents the draggable.&lt;br /&gt;&lt;br /&gt;So regardless of whether it is a ui.sortable list item or a ui.draggable being dropped on a droppable we can access the element in the following way:&lt;br /&gt;&lt;pre class='pre_code'&gt;$("#target").droppable({&lt;br /&gt; drop: function(event, ui) { &lt;br /&gt;  var element = $(ui.draggable);&lt;br /&gt;  var DOMelement = $(ui.draggable)[0];&lt;br /&gt; }&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You can then manipulate the item in anyway that you like using javascript or jQuery as per usual.&lt;br /&gt;&lt;br /&gt;For a standard UI widget when looking at the file you will notice there are two types of functions; those defined with an underscore such as _clear and _trigger in ui.draggable.js and those that don't have an underscore, such as serialize and toArray in ui.sortable.js. Those with an underscore are like privately scoped functions, you cannot call them outside of the UI widget, the others you can and it is done like this. $("#my_sortable_ul").sortable("toArray");. There are also getters and setters available, examples of which are usually available in the API such as ui.droppable addClasses option which can be retrieved as such:&lt;br /&gt;&lt;pre class='pre_code'&gt;//getter&lt;br /&gt;var addClasses = $('.selector').droppable('option', 'addClasses');&lt;br /&gt;//setter&lt;br /&gt;$('.selector').droppable('option', 'addClasses', false);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So now that we know how to target our element in the drop function and we know which functions are public and how to use setters and getters here is an example of how we can call those functions within the ui.droppable drop function. Note: The sortable and draggable are different in that for sortable list items it is the parent who is the ui.sortable, whereas with the draggable it is the element itself that is the ui.draggable.&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;// Calling functions on a ui.sortable&lt;br /&gt;&lt;br /&gt;drop: function(event, ui) { &lt;br /&gt; var array_values = $(ui.draggable).parent().sortable("toArray");&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;// Calling functions on a ui.draggable&lt;br /&gt;&lt;br /&gt;drop: function(event, ui) { &lt;br /&gt; $(ui.draggable).draggable("destroy");&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;// Accessing getter on a ui.sortable&lt;br /&gt;&lt;br /&gt;drop: function(event, ui) { &lt;br /&gt; var this_opacity = $(ui.draggable).parent().sortable('option', 'opacity');&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;// Accessing getter on a ui.draggable&lt;br /&gt;&lt;br /&gt;drop: function(event, ui) { &lt;br /&gt; var this_cursor = $(ui.draggable).draggable('option', 'cursor');&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;With a sortable once it has been dropped it may be also usefull to access the siblings of the element dropped:&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;// Set the background color on all of the siblings of the dropped element to red&lt;br /&gt;&lt;br /&gt;drop: function(event, ui) { &lt;br /&gt; $(ui.draggable).siblings().css("background", "red");&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Using &lt;a href='http://docs.jquery.com/Traversing/andSelf'&gt;andSelf&lt;/a&gt; you can manipulate the siblings as well as the dropped element:&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;// Set the text color of all of the elements including the dropped element to blue&lt;br /&gt;&lt;br /&gt;drop: function(event, ui) { &lt;br /&gt; $(ui.draggable).siblings().andSelf().css("color", "blue");&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;jQuery widgets are extremely well designed and have layers of complexity that require a bit of digging. The are very simple to use, but with a bit of research you can get a great amount out of them. Hopefully this tutorial will help you understand UI widgets in a bit more detail.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-2862572097517955301?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/2862572097517955301/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=2862572097517955301' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/2862572097517955301'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/2862572097517955301'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/12/accessing-draggable-elements-from.html' title='Accessing draggable elements from ui.droppable drop function'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-6345169612292842547</id><published>2009-12-07T21:48:00.003+11:00</published><updated>2009-12-07T21:51:58.049+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='forms'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorials'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>Using jQuery with forms - part 5 (Traversing)</title><content type='html'>This is the fifth in a series of tutorials on using jQuery to manipulate forms. In this series I will be looking at parts of the jQuery API reference in detail. In this tutorial I will be looking at forms and jQuery &lt;a href='http://docs.jquery.com/Traversing'&gt;Traversing&lt;/a&gt;.&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;&lt;h3&gt;Filtering&lt;/h3&gt;&lt;br /&gt;&lt;div style='width:520px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Traversing/eq#index'&gt;eq(index)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Matches the element from a group at a particular index&lt;/p&gt;&lt;pre class='pre_code'&gt;// Set the second radio element with name foods to checked&lt;br /&gt;$("#my_form radio[name='foods']:eq(2)").attr('checked', 'checked');&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style='width:520px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Traversing/filter#expr'&gt;filter(expr)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Removes elements from a group that do not match the expression&lt;/p&gt;&lt;pre class='pre_code'&gt;// Set all of the input elements that have the class error and out_of_range to red&lt;br /&gt;$("#my_form :input").filter('.error, .out_of_range').css('color', 'red');&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style='width:520px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Traversing/filter#fn'&gt;filter(fn)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Removes elements from a group that do not match the supplied function, useful if you want to remove elements based on a complex function&lt;/p&gt;&lt;pre class='pre_code'&gt;// Set all of the input elements that have the class error and out_of_range to red&lt;br /&gt;$("#my_form :input").filter(function(index) {&lt;br /&gt; if ((index &gt; 6) || ($(this).attr("type") == "hidden)) {&lt;br /&gt;  return true;&lt;br /&gt; }&lt;br /&gt;}).css('color', 'red');&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style='width:520px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Traversing/is#expr'&gt;is(expr)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Used to check if one of the matched elements matches the expression&lt;/p&gt;&lt;pre class='pre_code'&gt;// Checks to see if any of the password elements has the error class&lt;br /&gt;&lt;br /&gt;if ($("#my_form :password").is('.error')) {&lt;br /&gt; alert('A password field is still in error');&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style='width:520px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Traversing/map#callback'&gt;map(callback)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Takes a set of elements and maps each one onto the callback&lt;/p&gt;&lt;pre class='pre_code'&gt;// This is a very useful function but takes some understanding, rather than looking at the function below I suggest you &lt;a href='http://stackoverflow.com/questions/708105/jquery-map-practical-uses-for-the-function'&gt;check out this page&lt;/a&gt; for practical uses of this function.&lt;br /&gt;&lt;br /&gt;// Map all of the options from #myselect to the $(this).val() function, get the actual DOM elements and join them with a comma&lt;br /&gt;alert($("#myselect option").map(function() {return $(this).val();}).get().join(', '));&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style='width:520px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Traversing/not#expr'&gt;not(expr)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Removes elements that do not match the expression from the set&lt;/p&gt;&lt;pre class='pre_code'&gt;// Get all of the input elements and remove those that are not inputs and then apply a grey background&lt;br /&gt;$("#my_form :input").not(":password").css('background', 'grey');&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style='width:520px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Traversing/slice#startend'&gt;slice(start, end)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Selects a subset of the elements based on start and end index&lt;/p&gt;&lt;pre class='pre_code'&gt;// Hide all of the radio elements with name foods except the first and last element&lt;br /&gt;$("radio[name='foods']").slice(1, ($("radio[name='blah']").size() - 1)).hide();&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;Finding&lt;/h3&gt;&lt;br /&gt;&lt;div style='width:520px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Traversing/add#expr'&gt;add(expr)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Adds a set of elements to an existing group&lt;/p&gt;&lt;pre class='pre_code'&gt;// Set all of the select elements to red border then set all of the select and text elements to color blue&lt;br /&gt;// This could be useful if you wanted to show which elements had been validated as well as those that are in error&lt;br /&gt;$(":select").css('border', '1px solid red').add(":text").css('color', 'blue');&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style='width:520px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Traversing/children#expr'&gt;children(expr)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Selects all the children of an element and optionaly filters them according to the expression&lt;/p&gt;&lt;pre class='pre_code'&gt;// Retrieve all of the select children elements of my form that have the class validated&lt;br /&gt;$("#my_form :select").children(".validated");&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style='width:520px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Traversing/closest#expr'&gt;closest(expr)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Closest works by first looking at the current element to see if it matches the specified expression, if so it just returns the element itself. If it doesn't match then it will continue to traverse up the document, parent by parent, until an element is found that matches the specified expression. If no matching element is found then none will be returned.&lt;/p&gt;&lt;pre class='pre_code'&gt;// If a button is clicked it checks to see if it has the disabled class, if not it traverses up the document to find the closest element with the disabled class and then adds the matched class&lt;br /&gt;$("button").click(function(e) {&lt;br /&gt;  $(e.target).closest(".disabled").addClass("matched");&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style='width:520px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Traversing/find#expr'&gt;find(expr)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Searches for decendant elements that match the given expression&lt;/p&gt;&lt;pre class='pre_code'&gt;// Apply a yellow background to all p elements that are descendants of the .login_entry fieldset&lt;br /&gt;&lt;br /&gt;$(":fieldset .login_entry").find("p").css('background', 'yellow');&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style='width:520px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Traversing/next#expr'&gt;next(expr) / nextAll(expr)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Find the next (the siblings after) sibling matching expr or find all the sibling after this element matching expr&lt;/p&gt;&lt;pre class='pre_code'&gt;// Set the text element directly after a disabled button to read 'this button is disabled'&lt;br /&gt;$("button[disabled]").next().text("this button is disabled");&lt;br /&gt;&lt;br /&gt;// Hide all p siblings after a disabled button&lt;br /&gt;$("button[disabled]").nextAll("p").hide();&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style='width:520px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Traversing/prev#expr'&gt;prev(expr) / prevAll(expr)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Find the previous (the siblings before) sibling matching expr or find all the siblings before this element matching expr&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style='width:520px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Traversing/siblings#expr'&gt;siblings(expr)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Find all the siblings of this element matching expr&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style='width:520px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Traversing/parent#expr'&gt;parent(expr) / parents(expr)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Find the parent of this element (can be called on a group and filtered by expression) / Find all the parents of this element (the unique ancestors)&lt;br /&gt;&lt;/p&gt;&lt;pre class='pre_code'&gt;// If a parent contains a disabled button then hide it&lt;br /&gt;$("button[disabled]").parent().hide();&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;Chaining&lt;/h3&gt;&lt;br /&gt;&lt;div style='width:520px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Traversing/andSelf'&gt;andSelf()&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Find the parent of this element (can be called on a group and filtered by expression) / Find all the parents of this element (the unique ancestors)&lt;br /&gt;&lt;/p&gt;&lt;pre class='pre_code'&gt;// Find all fieldsets that contain radio elements and place a border around the radio elements and around the fieldset&lt;br /&gt;$("fieldset").find(":radio").andSelf().css('border', '1px solid green');&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;If you found this post useful, here are &lt;a href='http://www.myphpetc.com/2009/10/using-jquery-with-forms-part-1.html'&gt;part 1&lt;/a&gt;, &lt;a href='http://www.myphpetc.com/2009/11/using-jquery-with-forms-part-2-core.html'&gt;part 2&lt;/a&gt;, &lt;a href='http://www.myphpetc.com/2009/11/using-jquery-with-forms-part-3_01.html'&gt;part 3&lt;/a&gt; and &lt;a href='http://www.myphpetc.com/2009/12/using-jquery-with-forms-part-4.html'&gt;part 4&lt;/a&gt; of this series.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-6345169612292842547?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/6345169612292842547/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=6345169612292842547' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/6345169612292842547'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/6345169612292842547'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/12/using-jquery-with-forms-part-5.html' title='Using jQuery with forms - part 5 (Traversing)'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-4358488729700358238</id><published>2009-12-07T18:47:00.005+11:00</published><updated>2009-12-07T18:54:30.400+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='articles'/><title type='text'>Grid based approach to improve your designs</title><content type='html'>This article looks at using the grid based design approach to improve your design efforts. Using a grid will provide clarity, structure and balance to your designs. There now exists a range of easy to use tools that can be turned on and off at will to guide you in the process of designing with a grid.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;The idea of using a grid based system has been around for some while now, Smashing Magazine did one of their usual &lt;a href='http://www.smashingmagazine.com/2007/04/14/designing-with-grid-based-approach/'&gt;mega-link articles&lt;/a&gt; over two years ago now. But there are still a good reasons to have another look at the grid based approach. If you are like me and you are more on the development side and most of your design ideas suck most of the time it is a process of continual improvement. We spend most of our time concentrating on how things work and not on how they should look. The problem is that design, clarity and presentation all matter to the user experience. So, you should care.&lt;br /&gt;&lt;br /&gt;If you are like me and work for a small team, don't have the luxury of a design team or it's just not feasible to have a mock-up for each page you work on, you will be making design decisions and trade-offs all the time. The use of a grid is a simple tool that will improve your design work. Remember it's just a guide, so you can shuffle things around to your liking. But you will find that the use of a guide as a beginning tool-block to lay out your design is a clever and practical way to improve the end result.&lt;br /&gt;&lt;br /&gt;There are tools out there available to make designing with a grid very easy. These are simple links that can be dragged on to your toolbar and will apply the grid over the top of your page. They allow you to customise the grid and tweak your designs as you work on them. Firebug + grid = good idea!&lt;br /&gt;&lt;br /&gt;&lt;a href='http://960.gs/'&gt;960.gs&lt;/a&gt; has a jQuery based grid system which sits on a tab at the side of your page and has many options for displaying vertical and horizontal bars. It is my preferred choice as it looks great and the option to hide it without closing is helpful. As well it contains most of the options you need without being too cluttered.&lt;br /&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/grid_grid3.jpg' style='border:1px solid #CCC' /&gt;&lt;br /&gt;&lt;br /&gt;The next is Allan Jardine's &lt;a href='http://www.sprymedia.co.uk/article/Grid'&gt;Grid javascript bookmarklet&lt;/a&gt;. Grid is highly customisable and has a full feature set. It allows you to set alignment, gutters and margins.&lt;br /&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/grid_grid2.jpg' style='border:1px solid #CCC' /&gt;&lt;br /&gt;&lt;br /&gt;The last one is the simple, easy to use &lt;a href='http://www.badlydrawntoy.com/2009/04/23/grid960-a-grid-overlay-bookmarklet-for-960gs/'&gt;grid960 grid overlay bookmarklet&lt;/a&gt;. This has a 12 and 16 column option and an option to set the opacity. This is a good starting point if you only want to use the grid as a rough guide or you want to do some quick tweaking and don't want to worry about setting too many options.&lt;br /&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/grid_grid.jpg' style='border:1px solid #CCC' /&gt;&lt;br /&gt;&lt;br /&gt;If you want to read up more on the topic and how you can use the grid system to improve your designs I suggest you check out the &lt;a href='http://960.gs/'&gt;960 grid system site&lt;/a&gt;. The site has a good deal of showcase sites and links to other quality tutorials and resources.&lt;br /&gt;&lt;br /&gt;The grid overlay is an easy way to make big gains in your overall site design and using these unobtrusive tools makes it easier for you to apply the grid approach to your next design.&lt;br /&gt;&lt;br /&gt;If you have a grid designed site that you would like to share or if you have something to share on the best way to use the grid based approach let us know in the comments section below.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-4358488729700358238?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/4358488729700358238/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=4358488729700358238' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/4358488729700358238'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/4358488729700358238'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/12/grid-based-approach-to-improve-your.html' title='Grid based approach to improve your designs'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-6561358241388039517</id><published>2009-12-06T22:22:00.003+11:00</published><updated>2009-12-06T22:32:11.926+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tutorials'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><category scheme='http://www.blogger.com/atom/ns#' term='youtube'/><title type='text'>Building a Youtube playlist queue with php and jQuery</title><content type='html'>This post looks at how you can use php and jQuery to build a Youtube playlist queue, be the envy of your friends at your next party and allow your friends to search and drag items to a Youtube playlist.&lt;br /&gt;&lt;br /&gt;As a Youtube playlist refreshes each time the page refreshes there is no need to call a page refresh each you add items, once the current video has finished playing the screen refreshes and updates the playlist.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/youtube.jpg' style='border:1px solid #CCC;'/&gt;&lt;br /&gt;&lt;br /&gt;In order to get a working version of my application you will need to do the following steps:&lt;br /&gt;1. &lt;a href='http://framework.zend.com/download/gdata'&gt;Download Zend Gdata package&lt;/a&gt;&lt;br /&gt;2. &lt;a href='http://sites.google.com/site/myphpetc/Home/jyt.zip'&gt;Download my application code&lt;/a&gt;&lt;br /&gt;3. &lt;a href='http://code.google.com/apis/youtube/dashboard/gwt/index.html'&gt;Get a Google developer key&lt;/a&gt;&lt;br /&gt;4. Extract the Zend Gdata package&lt;br /&gt;5. Extract my application inside the root folder containing the Zend Gdata package, which should look like this:&lt;br /&gt;/ZendGdata-1.9.6/jyt&lt;br /&gt;6. Open /ZendGdata-1.9.6/jyt/operations.php and enter your developer key on line :56 where it says $_SESSION['developerKey'] = '-set your developer key here -';&lt;br /&gt;&lt;br /&gt;To begin with this post should be looked at as an introduction to the world of possibilities available with Gdata and php. The demo application provided is very limited, but presents a glimpse at something that could be a great application given a months development work. It should also give you a taste for how easy it is to use Gdata to build applications based on Google authenticated users.&lt;br /&gt;&lt;br /&gt;In order to build good quality applications with Google you really need to do a bit of reading, it's not something that you can understand in a day. Google's APIs are large and you will need to read them if you want to take things further.&lt;br /&gt;&lt;br /&gt;My demo application uses AuthSub which is the basic method for giving an application permission for using your Google data. You can read more about AuthSub &lt;a href='http://code.google.com/apis/youtube/2.0/developers_guide_php.html#AuthSub_for_Web_Applications'&gt;here&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;But the main part of the application is ZendGdata. As Zend so gracefully put it: "These packages (ZendGdata) contain everything you need to access Google's Data APIs from your PHP 5 application.". When thinking about Zend and writing small applications you may be tempted to think why bother; it was something that held me back before from looking at integrating Google application data previously. Why would you want to use Zend framework when I just want to list my damn youtube videos? Well it turns out you don't need an entire framework, you just need the ZendGdata package that can be downloaded from &lt;a href='http://framework.zend.com/download/gdata'&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;ZendGdata works simply like any other third party API or library. It's not too large or overbearing (the library folder currently comes in at around 2MB), so don't be scared of it. But it does contain a whole bunch of useful functions for authenticating and accessing Google data.&lt;br /&gt;&lt;br /&gt;The package also contains the documentation and also some sample applications that you can begin playing with, how cool is that.&lt;br /&gt;&lt;br /&gt;My application is based on the Youtube application provided with the package. To begin with it generates a link to ask the user to authenticate, if you are signed in to youtube this will ask you to 'allow' or 'deny' the application access to your data.&lt;br /&gt;&lt;br /&gt;Once authentication has taken place the application will then go and retrieve and display your first playlist (it is possible for it to display any available playlist, I have just kept things simple). You are then displayed a search box to enter terms and submit.&lt;br /&gt;&lt;br /&gt;Once you have searched and found a video you like, simply drag the video on to the target, it will be removed from the search list. Your playlist will then update and the added video will be at the bottom.&lt;br /&gt;&lt;br /&gt;Why did I want to build this application? Many years ago I went to a party, it was at a time when Napster was just starting to become popular, I was amazed at the limitless possibilities of what was essentially an infinite jukebox. People could go over to the computer at the party, select the tunes they wanted and they would be queued and played. Allowing anyone to come and choose the tunes they wanted to hear. CD switching was a pain in those days as you had to wait for one song to finish and for the crowed around the stereo to disperse.&lt;br /&gt;&lt;br /&gt;So there you have it. I hope this inspires you to Google application building greatness.&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-6561358241388039517?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/6561358241388039517/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=6561358241388039517' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/6561358241388039517'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/6561358241388039517'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/12/building-youtube-playlist-queue-with.html' title='Building a Youtube playlist queue with php and jQuery'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-789553531725266329</id><published>2009-12-04T22:42:00.004+11:00</published><updated>2009-12-04T22:50:20.213+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tutorials'/><category scheme='http://www.blogger.com/atom/ns#' term='flot'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='analytics'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>Display Google analytics with php, jQuery and flot</title><content type='html'>This tutorial looks at how you can display your &lt;a href='www.google.com/analytics/'&gt;Google Analytics&lt;/a&gt; results using &lt;a href='http://code.google.com/p/flot/'&gt;flot&lt;/a&gt;, the jQuery graphing library.&lt;br /&gt;&lt;br /&gt;Flot will allow us to plot our results on a good looking graph without the need for flash; you can even enable and disable different sites if you are tracking multiple sites.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;Unfortunately due to hosting restrictions I don't have a demo for this tutorial, but you can download the code from &lt;a href='http://sites.google.com/site/myphpetc/Home/analytics.zip'&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/sites.jpg' style='border:1px solid #CCC;' /&gt;&lt;br /&gt;&lt;br /&gt;We will also be using the php analytics API class written by Chris Hope available from &lt;a href='http://www.electrictoolbox.com'&gt;http://www.electrictoolbox.com&lt;/a&gt;. This class will allow us to easily retrieve our analytics data and will allow you to customise your results (including start date etc.)&lt;br /&gt;&lt;br /&gt;We begin with a simple placeholder in our HTML, we then call our php script analytics.php using jQuery's &lt;a href='http://docs.jquery.com/Ajax/jQuery.getJSON'&gt;getJSON method&lt;/a&gt;. The analytics.php script first checks to see if we have a cached version of the results (the retrieval from Google is considerably slow) and then serves the cached results. If there are no cached results it retrieves the data from Google's servers and then builds an array of data for each site. This array is then converted to JSON using php's &lt;a href='http://php.net/manual/en/function.json-encode.php'&gt;json_encode&lt;/a&gt; and returned to our javascript file. Our javascript file builds an array suitable for Flot and then calls Flot's plot method.&lt;br /&gt;&lt;br /&gt;Let's have a look at some of our code, firstly the HTML:&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;&amp;lt;h1&amp;gt;&lt;br /&gt;My sites&amp;lt;/h1&amp;gt;&lt;br /&gt;&amp;lt;div id="placeholder" style="width:600px;height:300px;"&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;p id="choices" style='display:none;'&amp;gt;&lt;br /&gt;Show:&amp;lt;/p&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This is simply our title and place holder for our graph and site toggler.&lt;br /&gt;&lt;br /&gt;Our javascript file is made up of three functions:&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;$("document").ready(function() {&lt;br /&gt;   var url = "analytics.php";&lt;br /&gt;   &lt;br /&gt;   $.getJSON(url, {id:  Math.random()}, function(datasets) {&lt;br /&gt;      if (datasets) {&lt;br /&gt;         // hard-code color indices to prevent them from shifting as&lt;br /&gt;         // countries are turned on/off&lt;br /&gt;         var i = 0;&lt;br /&gt;         $.each(datasets, function(key, val) {&lt;br /&gt;            val.color = i;&lt;br /&gt;            ++i;&lt;br /&gt;         });&lt;br /&gt;         &lt;br /&gt;         // insert checkboxes &lt;br /&gt;         var choiceContainer = $("#choices");&lt;br /&gt;         $.each(datasets, function(key, val) {&lt;br /&gt;            choiceContainer.append('&lt;br /&gt;&amp;lt;input type="checkbox" name="' + key +&lt;br /&gt;                              '" checked="checked" id="id' + key + '"&amp;gt;' +&lt;br /&gt;                              '&amp;lt;label for="id' + key + '"&amp;gt;'&lt;br /&gt;                              + val.label + '&amp;lt;/label&amp;gt;');&lt;br /&gt;         });&lt;br /&gt;         choiceContainer.find("input").click(updateGraph);&lt;br /&gt;         &lt;br /&gt;         plotAccordingToChoices(datasets);&lt;br /&gt;         &lt;br /&gt;         $("#choices").show();&lt;br /&gt;      }&lt;br /&gt;      &lt;br /&gt;   });&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We begin with our document ready function. This starts by calling our analytics.php file using the getJSON function and retrieves our datasets. We loop over our datasets and assign them a colour. Next we create our checkboxes to turn sites on or off and assign the updateGraph click function to these checkboxes. Finally we call our plotAccordingToChoices function and show our choices checkboxes.&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;function plotAccordingToChoices(datasets) {&lt;br /&gt;   var data = [];&lt;br /&gt;   &lt;br /&gt;   var choiceContainer = $("#choices");&lt;br /&gt;&lt;br /&gt;   choiceContainer.find("input:checked").each(function () {&lt;br /&gt;      var key = $(this).attr("name");&lt;br /&gt;      if (key &amp;&amp; datasets[key]) {&lt;br /&gt;         data.push(datasets[key]);&lt;br /&gt;      }&lt;br /&gt;   });&lt;br /&gt;&lt;br /&gt;   var options = {&lt;br /&gt;            xaxis: {&lt;br /&gt;                mode: "time"&lt;br /&gt;            }&lt;br /&gt;        };&lt;br /&gt;   &lt;br /&gt;   if (data.length &gt; 0) {&lt;br /&gt;      var plotarea = $("#placeholder");&lt;br /&gt;      plotarea.css("height", "250px");&lt;br /&gt;      plotarea.css("width", "500px");&lt;br /&gt;      $.plot( plotarea , data, options );&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Our plotAccordingToChoices function takes in our datasets and then compares the data to the checked options to see if any are disabled otherwise they are added to the data array. Our data array is then simply passed through to Flot to plot.&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;function updateGraph() {&lt;br /&gt;   var url = "analytics.php";&lt;br /&gt;&lt;br /&gt;   $.getJSON(url, {id:  Math.random()}, function(datasets) {&lt;br /&gt;      if (datasets) {&lt;br /&gt;         var i = 0;&lt;br /&gt;         $.each(datasets, function(key, val) {&lt;br /&gt;            val.color = i;&lt;br /&gt;            ++i;&lt;br /&gt;         });      &lt;br /&gt;      &lt;br /&gt;         plotAccordingToChoices(datasets);&lt;br /&gt;      }&lt;br /&gt;   });&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Our updateGraph function simply retrieves our data again and then calls plotAccordingToChoices. You could store this information somewhere in a global or in the DOM, &lt;a href='http://www.youtube.com/watch?v=pY8jaGs7xJ0'&gt;if that's what you're in to&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Now let's look at the php side of things.&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;require_once('analytics_api.php');&lt;br /&gt;&lt;br /&gt;$login = '-enter login here-';&lt;br /&gt;$password = '-enter password here-';&lt;br /&gt;&lt;br /&gt;$modified = @filemtime("cache.txt");&lt;br /&gt;&lt;br /&gt;$modified = date("d-m-Y", $modified);&lt;br /&gt;$current = date("d-m-Y");&lt;br /&gt;&lt;br /&gt;if ($modified &amp;&amp; ($current == $modified)) {&lt;br /&gt;   $cache = @file_get_contents("cache.txt");&lt;br /&gt;} else {&lt;br /&gt;   $cache = null;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if (!$cache) {&lt;br /&gt;   $api = new analytics_api();&lt;br /&gt;   if($api-&gt;login($login, $password)) {&lt;br /&gt;      $api-&gt;load_accounts();&lt;br /&gt;      $accounts = $api-&gt;accounts;&lt;br /&gt;&lt;br /&gt;      $return = array();&lt;br /&gt;      &lt;br /&gt;      foreach ($accounts as $accountname =&gt; $account) {&lt;br /&gt;         $data = $api-&gt;data($account['tableId'], 'ga:week', 'ga:visits', 'ga:week', '2009-07-05', '', '52');&lt;br /&gt;         $return[$accountname]['label'] = $accountname;&lt;br /&gt;         &lt;br /&gt;         foreach ($data as $week_number =&gt; $week) { &lt;br /&gt;            $return[$accountname]['data'][] = array( (strtotime("2009W".$week_number) * 1000) , $week['ga:visits'] + rand(0, 400) );&lt;br /&gt;         }&lt;br /&gt;      }&lt;br /&gt;      &lt;br /&gt;      $encoded = json_encode($return);&lt;br /&gt;      &lt;br /&gt;      echo $encoded;&lt;br /&gt;      file_put_contents("cache.txt", $encoded);&lt;br /&gt;   }&lt;br /&gt;} else {&lt;br /&gt;   echo $cache;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We begin by checking our cached file and then checking the date modified to see if the cache file is from today. If the cache file exists and it is from today we simply return the contents of that file.&lt;br /&gt;&lt;br /&gt;Otherwise, we log in to our analytics account using the $api-&gt;login($login, $password) method. We loop over each of our accounts and retrieve the data from that account:&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;$data = $api-&gt;data($account['tableId'], 'ga:week', 'ga:visits', 'ga:week', '2009-07-05', '', '52');&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You see here when we call the data method you can specify a whole bunch of different options, I will leave these to you to investigate. We are simply going to retrieve all weekly visit data starting from 2009-07-05 up to a maximum of 52 weeks if available.&lt;br /&gt;&lt;br /&gt;We loop over this data and store it in the return array per account name. Then once all the data has been looped over we simply JSON encode and return.&lt;br /&gt;&lt;br /&gt;Nice and easy.&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-789553531725266329?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/789553531725266329/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=789553531725266329' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/789553531725266329'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/789553531725266329'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/12/display-google-analytics-with-php.html' title='Display Google analytics with php, jQuery and flot'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-2627682255517968405</id><published>2009-12-03T22:50:00.002+11:00</published><updated>2009-12-03T22:51:10.550+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tutorials'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery-UI'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>jQuery UI sortable drag multiple to target</title><content type='html'>This tutorial looks at building a &lt;a href='http://jqueryui.com/demos/sortable/'&gt;jQuery sortable UI widget&lt;/a&gt; that allows for sorting and for dragging multiple items on to a droppable target.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;This is my first attempt (and possibly last) at building this so I haven't had a chance to check this off with all options available, I only built it for a single purpose.&lt;br /&gt;&lt;br /&gt;The demo can be viewed &lt;a href='http://comp345.awardspace.com/sortable/index.html'&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And you can download the code from &lt;a href='http://sites.google.com/site/myphpetc/Home/sortable.zip'&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A brief rundown on how it works: control-click to select/deselect items. When the first item is dragged the other items are cloned and the original element hidden. If the main item being dragged hits the droppable target then the element and all its siblings are removed:&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;$("document").ready(function() {&lt;br /&gt;  $("#sortable1").multisortable({});&lt;br /&gt;  $("#sortable1").disableSelection();&lt;br /&gt;  $("#target").droppable({&lt;br /&gt;   accept: "#sortable1 li",&lt;br /&gt;   drop: function(event, ui) { &lt;br /&gt;    var elements = $(ui.draggable).siblings(".ui-multisort-grouped").andSelf();&lt;br /&gt;    &lt;br /&gt;    $(elements).remove();&lt;br /&gt;   }&lt;br /&gt;  });&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The element being dragged and its siblings are stored in the elements variable so you can essentially do what you like with them (read attributes etc.) at this point.&lt;br /&gt;&lt;br /&gt;Hope this helps some people.&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-2627682255517968405?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/2627682255517968405/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=2627682255517968405' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/2627682255517968405'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/2627682255517968405'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/12/jquery-ui-sortable-drag-multiple-to.html' title='jQuery UI sortable drag multiple to target'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-503827449018584531</id><published>2009-12-02T19:31:00.007+11:00</published><updated>2009-12-03T20:32:07.455+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tutorials'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>Using jQuery with forms - part 4 (Attributes)</title><content type='html'>This is the fourth in a series of tutorials on using jQuery to manipulate forms. In this series I will be looking at parts of the jQuery API reference in detail. In this tutorial I will be looking at forms and jQuery &lt;a href='http://docs.jquery.com/Attributes'&gt;Attributes&lt;/a&gt;.&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;&lt;h3&gt;Attr&lt;/h3&gt;&lt;br /&gt;&lt;div style='width:520px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Attributes/attr#name'&gt;attr(name)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Retrieves the value of an attribute&lt;/p&gt;&lt;span style='font-family:courier;'&gt;&lt;br /&gt;&lt;pre&gt;// Retrieve the location that the form is submitting to&lt;br /&gt;$("#my_form").attr("action"); &lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style='width:520px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Attributes/attr#keyvalue'&gt;attr(key, value)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Sets the value of an attribute&lt;/p&gt;&lt;span style='font-family:courier;'&gt;&lt;br /&gt;&lt;pre&gt;// Set the location that the form is submitting to, this may be &lt;br /&gt;useful when you want to set the action according to some input&lt;br /&gt;$("#my_form").attr("action", "processing.php"); &lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style='width:520px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Attributes/removeAttr#name'&gt;removeAttr(name)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Removes an attribute from an element&lt;/p&gt;&lt;span style='font-family:courier;'&gt;&lt;br /&gt;&lt;pre&gt;// Remove all inline styling from fields with the password class&lt;br /&gt;$(".password").removeAttr("style"); &lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;HTML&lt;/h3&gt;&lt;br /&gt;&lt;div style='width:520px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Attributes/html'&gt;html()&lt;/a&gt; / &lt;a href='http://docs.jquery.com/Attributes/html#val'&gt;html(val)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Retrieves / sets the innerHTML of the matched element&lt;/p&gt;&lt;span style='font-family:courier;'&gt;&lt;br /&gt;&lt;pre&gt;// Retrieve the html() contents of the fieldset with ID &lt;br /&gt;#fieldset_login and then set the html to the &lt;br /&gt;contents of updatedHTML&lt;br /&gt;var updatedHTML = ... some markup ...&lt;br /&gt;var login_html = $("#fieldset_login").html(updatedHTML);&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;Text&lt;/h3&gt;&lt;br /&gt;&lt;div style='width:520px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Attributes/text'&gt;text()&lt;/a&gt; / &lt;a href='http://docs.jquery.com/Attributes/text#val'&gt;text(val)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Retrieves / sets the text contents of the matched element&lt;/p&gt;&lt;span style='font-family:courier;'&gt;&lt;br /&gt;&lt;pre&gt;// Retrieve the contents of the first label&lt;br /&gt;var label_text = $("label:first").text();&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;Getting and setting the values of different form elements&lt;/h3&gt;&lt;br /&gt;&lt;div style='width:520px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;span style='font-family:courier;'&gt;&lt;br /&gt;&lt;pre&gt;// Retrieve and set the contents of text input&lt;br /&gt;$("#my_text_input").val();&lt;br /&gt;$("#my_text_input").val(new_value);&lt;br /&gt;&lt;br /&gt;// Retrieve and set the contents of label&lt;br /&gt;$("#my_label").text();&lt;br /&gt;$("#my_label").text(new_value);&lt;br /&gt;&lt;br /&gt;// Retrieve and set the contents of textarea&lt;br /&gt;$("#my_textarea").val();&lt;br /&gt;$("#my_textarea").val(new_value);&lt;br /&gt;&lt;br /&gt;// Retrieve and set the value of select&lt;br /&gt;$("#my_select").val()&lt;br /&gt;$("#my_select").val(2) // Set select according to value&lt;br /&gt;&lt;br /&gt;// Retrieve and set the text of select&lt;br /&gt;$("#my_select :selected").text() // Text value of selected option&lt;br /&gt;// Changes the text of selected option&lt;br /&gt;$("#my_select :selected").text("some text") &lt;br /&gt;&lt;br /&gt;// Retrieve and set the text label of a button&lt;br /&gt;$("#my_button").text();&lt;br /&gt;$("#my_button").text("some text");&lt;br /&gt;&lt;br /&gt;// Retrieve the button type attribute&lt;br /&gt;$("#my_button").attr("type"); &lt;br /&gt;&lt;br /&gt;// Retrieve the value of the checked radio element&lt;br /&gt;$("#my_form [name='radio_group']:checked").val();&lt;br /&gt;&lt;br /&gt;// Check if a particular checkbox has been checked&lt;br /&gt;$("#my_form [name='checkbox_group[]']").eq(1).is(":checked")&lt;br /&gt;&lt;br /&gt;// Retrieve all the checked checkboxes in a serialized string&lt;br /&gt;$("#my_form [name='checkbox_group[]']:checked").serialize() &lt;br /&gt;&lt;br /&gt;// Retrieve and set the contents of password input&lt;br /&gt;$("#my_text_input").val();&lt;br /&gt;$("#my_text_input").val(new_value);&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;If you found this post useful, here are &lt;a href='http://www.myphpetc.com/2009/10/using-jquery-with-forms-part-1.html'&gt;part 1&lt;/a&gt;, &lt;a href='http://www.myphpetc.com/2009/11/using-jquery-with-forms-part-2-core.html'&gt;part 2&lt;/a&gt;, and &lt;a href='http://www.myphpetc.com/2009/11/using-jquery-with-forms-part-3_01.html'&gt;part 3&lt;/a&gt; of this series.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-503827449018584531?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/503827449018584531/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=503827449018584531' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/503827449018584531'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/503827449018584531'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/12/using-jquery-with-forms-part-4.html' title='Using jQuery with forms - part 4 (Attributes)'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-6141480137838292859</id><published>2009-12-02T19:29:00.001+11:00</published><updated>2009-12-02T19:30:18.129+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sites'/><category scheme='http://www.blogger.com/atom/ns#' term='plug-ins'/><category scheme='http://www.blogger.com/atom/ns#' term='articles'/><title type='text'>5 sites and 5 jQuery plug-ins - tools for daily use</title><content type='html'>This post looks at 5 sites that I use daily and 5 jQuery plug-ins that I use regularly. The aim of this post is to provide you with some useful tools that you can keep in your toolbox and hopefully they will also be of regular use to you. Both the sites and the plug-ins are practical, reliable and most importantly they do what they are supposed to do.&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;The sites that I have chosen are sites that I personally use frequently. I think it's important to know a bunch of good sites, it saves trying to remember too much: memorise the basics and keep the rest within arms reach. I visit the &lt;a href='http://au.php.net/manual/en/'&gt;php API&lt;/a&gt; and the &lt;a href='http://docs.jquery.com/Core'&gt;jQuery API&lt;/a&gt; several times daily, I remember the basics, but I wouldn't want to try memorising the entire php API. I've tried to choose sites that are more on the practical side, these are more tool like and less reference like. I may only use them once or twice a day for a minute or two, but they are good at what they do.&lt;br /&gt;&lt;br /&gt;The first site is &lt;a href='http://www.colorpicker.com/'&gt;ColorPicker&lt;/a&gt;. No need to install any software, no adds, no clutter, it is a simple color picker and it's handy.&lt;br /&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/fav_colorpicker.jpg' style='border:1px solid #CCC;'/&gt;&lt;br /&gt;&lt;br /&gt;The next site is a &lt;a href='http://en.wikipedia.org/wiki/Lorem_ipsum'&gt;Lorem Ipsum&lt;/a&gt; generator. I'm surprised at how often I use this. The site is &lt;a href='http://lorem2.com/'&gt;Lorem 2&lt;/a&gt;. Lorem 2 has Lorem Ipsum text in many different formats, short/long paragraphs and short/long list items.&lt;br /&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/fav_lorem.jpg' style='border:1px solid #CCC;'/&gt;&lt;br /&gt;&lt;br /&gt;I'm sure most of you know about &lt;a href='www.stackoverflow.com'&gt;Stack Overflow&lt;/a&gt; and &lt;a href='http://www.w3schools.com/'&gt;w3schools&lt;/a&gt;. I use these two for different reasons; I use w3schools whenever I forget the basics, it's presentation is clean and I can reference what I need to know quick and easy, it's for those times when I forget something simple and stupid like how to name radio buttons. I use Stack Overflow when I assume there should exist a practical solution to something I haven't worked out yet. It's a good way to compare your solution to your peers and a good place to get advice and feedback.&lt;br /&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/fav_w3scho.jpg' style='border:1px solid #CCC;'/&gt;&lt;br /&gt;&lt;br /&gt;The jivebay &lt;a href='http://jivebay.com/2007/05/30/handling-checkboxes-radio-buttons-and-select-options-in-jquery/'&gt;Handling Checkboxes, Radio Buttons and Select Options in jQuery&lt;/a&gt; post was the inspiration for my &lt;a href='http://www.myphpetc.com/2009/03/jquery-select-element-cheat-sheet.html'&gt;select element cheat sheet&lt;/a&gt; and I still find myself referencing this post every now and then. The questions and answers in the comments section are just as good as the post itself and the answers are well written.&lt;br /&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/fav_jive.jpg' style='border:1px solid #CCC;'/&gt;&lt;br /&gt;&lt;br /&gt;The last site is the dummy data generator &lt;a href='http://www.generatedata.com/#generator'&gt;Generate Data&lt;/a&gt;. This site will generate large amounts of dummy data in different formats (HTML, Excel, XML, CSV, SQL) and has a large variety of data types. You can also specify the number of rows and row names.&lt;br /&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/fav_dummy.jpg' style='border:1px solid #CCC;'/&gt;&lt;br /&gt;&lt;br /&gt;The 5 plugins that I have chosen are also simple and practical. Simple in that they are east to use and do not try and overcomplicate.&lt;br /&gt;&lt;br /&gt;The main site I work on is an internal CRM, so we have a lot of tabled information. The jQuery &lt;a href='http://tablesorter.com/docs/'&gt;tablesorter&lt;/a&gt; plugin is awesome; it allows for custom parsing for sort order and with &lt;a href='http://myphpetc.blogspot.com/2009/01/in-this-tutorial-i-go-over-some-cool.html'&gt;a bit of work&lt;/a&gt; it is very easy to have inline editing. You can also sort on multiple rows.&lt;br /&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/fav_tablesorter.jpg' style='border:1px solid #CCC;'/&gt;&lt;br /&gt;&lt;br /&gt;The jQuery &lt;a href='http://plugins.jquery.com/project/Cookie'&gt;cookies plugin&lt;/a&gt; works across all browsers and is so easy to set up. You can have a look at &lt;a href='http://www.electrictoolbox.com/jquery-cookies/'&gt;this post&lt;/a&gt; if you want to read over some of it's features rather than reading the code itself. It has very easy set, and get functions and is lightweight.&lt;br /&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/fav_cookies.jpg' style='border:1px solid #CCC;'/&gt;&lt;br /&gt;&lt;br /&gt;There are currently many jQuery autogrow plugins, but my favourite is &lt;a href='http://onehackoranother.com/projects/jquery/jquery-grab-bag/autogrow-textarea.html'&gt;this one&lt;/a&gt;. It is small enough that you could just cut and paste the function out and stick it in your own utility script if needed. It also works well across all browsers without hiccups.&lt;br /&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/fav_autogrow.jpg' style='border:1px solid #CCC;'/&gt;&lt;br /&gt;&lt;br /&gt;The same could be said for watermark plugins, there are many out there, but the one that I like to use (which has been in beta since 2007) is &lt;a href='http://digitalbush.com/projects/watermark-input-plugin/'&gt;this one&lt;/a&gt; by Josh Bush. It also has built in hideAll, showAll functions which are useful when pulling values for submission via ajax.&lt;br /&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/fav_watermark.jpg' style='border:1px solid #CCC;'/&gt;&lt;br /&gt;&lt;br /&gt;The last one and maybe the most useful is the jQuery &lt;a href='http://jquery.malsup.com/form/'&gt;form plugin&lt;/a&gt;. For any ajax heavy application with many forms this plugin has many useful methods for serializing, resetting and submitting forms. It even has a method for submitting files via AJAX.&lt;br /&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/fav_form.jpg' style='border:1px solid #CCC;'/&gt;&lt;br /&gt;&lt;br /&gt;It is always good to have many sites and tools that you can rely upon, once you find something good make sure to bookmark it for later use and then share it around. What are some of your favourite plug-ins that you use daily? What are some sites that you can't live without?&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-6141480137838292859?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/6141480137838292859/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=6141480137838292859' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/6141480137838292859'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/6141480137838292859'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/12/5-sites-and-5-jquery-plug-ins-tools-for.html' title='5 sites and 5 jQuery plug-ins - tools for daily use'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-5949477982866315942</id><published>2009-12-01T21:50:00.004+11:00</published><updated>2009-12-01T21:54:21.248+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='free'/><category scheme='http://www.blogger.com/atom/ns#' term='wallpaper'/><category scheme='http://www.blogger.com/atom/ns#' term='calendar'/><category scheme='http://www.blogger.com/atom/ns#' term='articles'/><title type='text'>Collection of December 2009 Wallpapers</title><content type='html'>I've scoured the net and tried to find some of the best December 2009 wallpapers to kick of the festive Season. I was surprised that there were so few, being Christmas and all. Here is what I came up with.&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;Click on any of the images below to go to the artists page and download the full sized image.&lt;br /&gt;&lt;br /&gt;&lt;a href='http://nbeczkai.deviantart.com/art/december-145056667'&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/dec01.jpg' style='border:1px solid #ccc;'/&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href='http://el-kiks.deviantart.com/art/Crack-and-Bonky-Dec09-wllppr-144983893'&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/dec02.jpg' style='border:1px solid #ccc;'/&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href='http://polluxos.deviantart.com/art/December-2009-wallpaper-v2-145185942'&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/dec03.jpg' style='border:1px solid #ccc;'/&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href='http://fizzy-logic.deviantart.com/art/December-2009-144732707'&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/dec04.jpg' style='border:1px solid #ccc;'/&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href='http://dsnynj4.deviantart.com/art/December-2009-143309788'&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/dec05.jpg' style='border:1px solid #ccc;'/&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href='http://www.flickr.com/photos/ianlivesey/4064385193/sizes/o/'&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/dec06.jpg' style='border:1px solid #ccc;'/&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href='http://www.flickr.com/photos/lesmou/3229194966/'&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/dec07.jpg' style='border:1px solid #ccc;'/&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href='http://fullfx.antzfx.com/2008/12/24/design-calendar-2009/'&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/dec08.jpg' style='border:1px solid #ccc;'/&gt;&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-5949477982866315942?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/5949477982866315942/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=5949477982866315942' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/5949477982866315942'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/5949477982866315942'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/12/collection-of-december-2009-wallpapers.html' title='Collection of December 2009 Wallpapers'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-8979276979721033227</id><published>2009-12-01T19:18:00.003+11:00</published><updated>2009-12-01T19:23:36.262+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tutorials'/><category scheme='http://www.blogger.com/atom/ns#' term='sortable'/><category scheme='http://www.blogger.com/atom/ns#' term='widget'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery-UI'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>jQuery php voting widget</title><content type='html'>This tutorial looks at how to build a jQuery UI themeable voting widget using a jQuery sortable and a bit of php to store the current number of votes. The actual widget itself is quite light-weight and the only markup we need is a single unordered list. The jQuery is also minimal and most of the work is done in php to work out the what the current tally is and to store this information.&lt;br /&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/heston.jpg' style='border:1px solid #CCC;' /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;You can view the working demo this tutorial &lt;a href='http://comp345.awardspace.com/vote/index.html'&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;You can download the code for this tutorial &lt;a href='http://sites.google.com/site/myphpetc/Home/vote.zip'&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;In my implementation I have chosen to store the current number of votes as a single serialized string in a flate file, but this could easily be done in a database.&lt;br /&gt;&lt;br /&gt;To begin with I will show you the unordered list, my list is going to contain Charlton Heston movies:&lt;br /&gt;&lt;pre class='pre_code'&gt;&amp;lt;li class=&amp;quot;non-sortable&amp;quot; style=&amp;quot;height:2.2em;&amp;quot;&amp;gt;Rank your favourite Charlton Heston movies by dragging options&amp;lt;/li&amp;gt;&lt;br /&gt;&amp;lt;li class=&amp;quot;ui-state-default movie-rank&amp;quot; id=&amp;quot;movie-1&amp;quot;&amp;gt;&amp;lt;span class=&amp;#039;counter&amp;#039;&amp;gt;#1&amp;lt;/span&amp;gt;The Ten Commandments&amp;lt;/li&amp;gt;&lt;br /&gt;&amp;lt;li class=&amp;quot;ui-state-default movie-rank&amp;quot; id=&amp;quot;movie-2&amp;quot;&amp;gt;&amp;lt;span class=&amp;#039;counter&amp;#039;&amp;gt;#2&amp;lt;/span&amp;gt;Ben-Hur&amp;lt;/li&amp;gt;&lt;br /&gt;&amp;lt;li class=&amp;quot;ui-state-default movie-rank&amp;quot; id=&amp;quot;movie-3&amp;quot;&amp;gt;&amp;lt;span class=&amp;#039;counter&amp;#039;&amp;gt;#3&amp;lt;/span&amp;gt;Planet of the Apes&amp;lt;/li&amp;gt;&lt;br /&gt;&amp;lt;li class=&amp;quot;ui-state-default movie-rank&amp;quot; id=&amp;quot;movie-4&amp;quot;&amp;gt;&amp;lt;span class=&amp;#039;counter&amp;#039;&amp;gt;#4&amp;lt;/span&amp;gt;The Omega Man&amp;lt;/li&amp;gt;&lt;br /&gt;&amp;lt;li class=&amp;quot;ui-state-default movie-rank&amp;quot; id=&amp;quot;movie-5&amp;quot;&amp;gt;&amp;lt;span class=&amp;#039;counter&amp;#039;&amp;gt;#5&amp;lt;/span&amp;gt;Soylent Green&amp;lt;/li&amp;gt;&lt;br /&gt;&amp;lt;li class=&amp;quot;ui-state-default movie-rank&amp;quot; id=&amp;quot;movie-6&amp;quot;&amp;gt;&amp;lt;span class=&amp;#039;counter&amp;#039;&amp;gt;#6&amp;lt;/span&amp;gt;The Three Musketeers&amp;lt;/li&amp;gt;&lt;br /&gt;&amp;lt;li class=&amp;quot;ui-state-default movie-rank&amp;quot; id=&amp;quot;movie-7&amp;quot;&amp;gt;&amp;lt;span class=&amp;#039;counter&amp;#039;&amp;gt;#7&amp;lt;/span&amp;gt;Antony and Cleopatra&amp;lt;/li&amp;gt;&lt;br /&gt;&amp;lt;li class=&amp;quot;ui-state-default movie-rank&amp;quot; id=&amp;quot;movie-8&amp;quot;&amp;gt;&amp;lt;span class=&amp;#039;counter&amp;#039;&amp;gt;#8&amp;lt;/span&amp;gt;Beneath the Planet of the Apes &amp;lt;/li&amp;gt;&lt;br /&gt;&amp;lt;li class=&amp;quot;ui-state-default movie-rank&amp;quot; id=&amp;quot;movie-9&amp;quot;&amp;gt;&amp;lt;span class=&amp;#039;counter&amp;#039;&amp;gt;#9&amp;lt;/span&amp;gt;El Cid&amp;lt;/li&amp;gt;&lt;br /&gt;&amp;lt;li class=&amp;quot;ui-state-default movie-rank&amp;quot; id=&amp;quot;movie-10&amp;quot;&amp;gt;&amp;lt;span class=&amp;#039;counter&amp;#039;&amp;gt;#10&amp;lt;/span&amp;gt;Julius Caeser&amp;lt;/li&amp;gt;&lt;br /&gt;&amp;lt;li class=&amp;quot;non-sortable&amp;quot;&amp;gt;&amp;lt;button class=&amp;quot;ui-button ui-state-default ui-corner-all&amp;quot; type=&amp;quot;button&amp;quot; name=&amp;quot;submit&amp;quot; style=&amp;quot;float:right;&amp;quot;&amp;gt;Submit&amp;lt;/button&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;If you look at the li classes above you will see there are two main types, the non-sortable and movie-rank. The jQuery sortable plugin allows us to specify which items should be sortable using the 'items' option and which items will not be part of the sorting process (that is, they stay put). We want our widget title and the submit button to stay put so lets look at the jQuery initialisation:&lt;br /&gt;&lt;pre class='pre_code'&gt;$("document").ready(function() {&lt;br /&gt; $("#sortable").sortable({&lt;br /&gt;  placeholder: 'ui-state-highlight',&lt;br /&gt;  items: '.movie-rank',&lt;br /&gt;  cancel: '.non-sortable'&lt;br /&gt; });&lt;br /&gt; &lt;br /&gt; $("#sortable").disableSelection();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The three options from our sortable initialisation are placeholder, items and cancel. Place holder simply provides an indicator for where the item will be dropped, in my example this is the blue bar that appears as the item being dragged hovers over each list item. The items and cancel work as previously mentioned, basically 'items' are sortable and 'cancel' stays put. The final call to disableSelection is an undocumented jQuery UI method that prevents text selection happening on a list element so that grabbing an item to be dragged is easier and the text selection doesn't get the focus first.&lt;br /&gt;&lt;br /&gt;Next I decided to add an update function whenever the sort order is changed. This updates the ranking of each item, so if you move #3 to the #7 position all of the numbers update to show your preferred voting order. Let's look at the code:&lt;br /&gt;&lt;pre class='pre_code'&gt;$('#sortable').bind('sortupdate', function(event, ui) {&lt;br /&gt; $(".counter").each(function() {&lt;br /&gt;  $(this).empty();&lt;br /&gt;  var index = $(".counter").index(this) + 1;&lt;br /&gt;  $(this).text("#" + index);&lt;br /&gt; });&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The sortupdate function is a special function specific to the jQuery UI sortable plugin. You can see all of the options and functions &lt;a href='http://jqueryui.com/demos/sortable/'&gt;here&lt;/a&gt;. This is called when the sort order is updated. I simply remove all of the rankings and then update each of the elements according to their actual position amongst thier peers. This is done using the jQuery &lt;a href='http://docs.jquery.com/Core/index#subject'&gt;index function&lt;/a&gt;, which takes in a group of elements and finds the index of the element amongst that group (0 based).&lt;br /&gt;&lt;br /&gt;The last piece of jQuery code is our submit function:&lt;br /&gt;&lt;pre class='pre_code'&gt;$("#sortable [name='submit']").click(function() {&lt;br /&gt; var rankings = $('#sortable').sortable('serialize');&lt;br /&gt; &lt;br /&gt; $.get("vote.php?" + rankings, {}, function(data) {&lt;br /&gt;  $("#sortable").empty().html(data);&lt;br /&gt; });&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Our sortable has another great funcion, serialize which looks at the IDs of our li elements and passes them in order as follows: arrayname-id. So I have mine set up as movie-1, movie-2 etc. so these will be returned as movie[]=1,movie[]=4,movie=[]=7... according to how we have sorted them. When this gets rebuilt in php we will have an array that is ordered in the same way as our sorted list with a reference to the index of our movie.&lt;br /&gt;&lt;br /&gt;We then make an AJAX call using jQuery's $.get function which sends in our voting submission and waits to get the results back from our php script. Once the results are returned we simply clear out our sortable and insert the results returned from the script.&lt;br /&gt;&lt;br /&gt;We start off our php script vote.php with retrieving the values passed in and setting up an array that has a key corresponding to the movie and the voting points allocated to that movie:&lt;br /&gt;&lt;pre class='pre_code'&gt;$movie_rankings = $_GET['movie'];&lt;br /&gt;&lt;br /&gt;if ($movie_rankings &amp;&amp; is_array($movie_rankings) &amp;&amp; (sizeof($movie_rankings) == 10)) {&lt;br /&gt; $movie_points = array();&lt;br /&gt; &lt;br /&gt; foreach ($movie_rankings as $rank =&gt; $index) {&lt;br /&gt;  if (!is_numeric($rank) || !is_numeric($index) || ($rank &gt; 9) || ($index &gt; 10)) exit; // Prevent hacking&lt;br /&gt;  $movie_points[(int)$index] = (10 - (int)$rank);&lt;br /&gt; } &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You will see I have added a few small security checks in there to avoid someone from screwing this up completely. We begin with getting the value of movie from our $_GET variable. We then check that this wasn't empty, that it is an array and that it has exactly the right number of elements, in our case 10.&lt;br /&gt;&lt;br /&gt;Next we create the $movie_points array to hold our votes for each movie. We loop over the rankings passed in and while we are doing this we need to check that someone hasn't just passed in garbage. We check that the $rank and $index are both numbers and that they are both less than 10, another security check. We then set the points for each movie index inside the $movie_points array, casting each value to int in case some tricky person decided to use float values.&lt;br /&gt;&lt;pre class='pre_code'&gt;$current_rankings = @file_get_contents("rankings.txt");&lt;br /&gt;&lt;br /&gt;if ($current_rankings) {&lt;br /&gt; $current_rankings = unserialize($current_rankings);&lt;br /&gt; &lt;br /&gt; foreach ($current_rankings as $index =&gt; $score) {&lt;br /&gt;  $movie_points[$index] += $score; &lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;$ser_points = serialize($movie_points);&lt;br /&gt;file_put_contents("rankings.txt", $ser_points); &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Following from that we retrieve the current rankings form our rankings.txt flat file. If the file existed we unserialize those values and loop over each value and add it to the point values just pased in by updating the $movie_points array. We then serialize the $movie_points array and store it in our flat file for later reference.&lt;br /&gt;&lt;br /&gt;Now that we have our current standings and all our points tallied we want to build our output. Our output will contain a colourful graphical representation in the form of a bar chart, which will contain the percentages and the names of each of the movies:&lt;br /&gt;&lt;pre class='pre_code'&gt;arsort($movie_points);&lt;br /&gt;  &lt;br /&gt;$movies = array();&lt;br /&gt;$movies[1] = &amp;quot;The Ten Commandments&amp;quot;;&lt;br /&gt;$movies[2] = &amp;quot;Ben-Hur&amp;quot;;&lt;br /&gt;$movies[3] = &amp;quot;Planet of the Apes&amp;quot;;&lt;br /&gt;$movies[4] = &amp;quot;The Omega Man&amp;quot;;&lt;br /&gt;$movies[5] = &amp;quot;Soylent Green&amp;quot;;&lt;br /&gt;$movies[6] = &amp;quot;The Three Musketeers&amp;quot;;&lt;br /&gt;$movies[7] = &amp;quot;Antony and Cleopatra&amp;quot;;&lt;br /&gt;$movies[8] = &amp;quot;Beneath the Planet of the Apes&amp;quot;;&lt;br /&gt;$movies[9] = &amp;quot;El Cid&amp;quot;;&lt;br /&gt;$movies[10] = &amp;quot;Julius Caeser&amp;quot;;&lt;br /&gt;&lt;br /&gt;$colours = array();&lt;br /&gt;$colours[1] = &amp;quot;#E52E2E&amp;quot;;&lt;br /&gt;$colours[2] = &amp;quot;#E58F2E&amp;quot;;&lt;br /&gt;$colours[3] = &amp;quot;#E5DF2E&amp;quot;;&lt;br /&gt;$colours[4] = &amp;quot;#8FE52E&amp;quot;;&lt;br /&gt;$colours[5] = &amp;quot;#2EE56C&amp;quot;;&lt;br /&gt;$colours[6] = &amp;quot;#2EE5D2&amp;quot;;&lt;br /&gt;$colours[7] = &amp;quot;#2E49E5&amp;quot;;&lt;br /&gt;$colours[8] = &amp;quot;#942EE5&amp;quot;;&lt;br /&gt;$colours[9] = &amp;quot;#C02EE5&amp;quot;;&lt;br /&gt;$colours[10] = &amp;quot;#DE2EE5&amp;quot;;&lt;br /&gt;&lt;br /&gt;$total_points = array_sum($movie_points);&lt;br /&gt;&lt;br /&gt;$html = &amp;#039;&amp;#039;;&lt;br /&gt;&lt;br /&gt;$counter = 1;&lt;br /&gt;foreach ($movie_points as $key =&amp;gt; $points) {&lt;br /&gt; $percent = round(($points / $total_points * 100), 0);&lt;br /&gt; $html .= &amp;quot;&amp;lt;li class=&amp;#039;ui-state-default movie-rank non-sortable&amp;#039; id=&amp;#039;movie-{$key}&amp;#039;&amp;gt;&amp;lt;div style=&amp;#039;background:{$colours[$counter]};height:25px;width:{$percent}%;padding:5px;margin-top:-6px;margin-left:-6px;&amp;#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div style=&amp;#039;position:absolute;left:0px;top:0px;&amp;#039;&amp;gt;&amp;lt;span class=&amp;#039;counter&amp;#039;&amp;gt;{$percent}%&amp;lt;/span&amp;gt;{$movies[$key]}&amp;lt;/li&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt; $counter ++;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;echo $html;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We begin by sorting our $movie_points from highest to lowest. Then we set up two arrays, one with the index to name mapping of our movies and the next with the colour level for our bar chart. We us php's built in array_sum to count up the total number of points already awarded, this will be used to work out percentages.&lt;br /&gt;&lt;br /&gt;Next we loop over (from highest to lowest) each of our movies; we calculate the percentage points and then build the list item displaying our movie name, points and the coloured bar.&lt;br /&gt;&lt;br /&gt;This is then echod out and returned to the jQuery scipt which will clear out our voting system and display the colourful results.&lt;br /&gt;&lt;br /&gt;That's the lot.&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-8979276979721033227?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/8979276979721033227/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=8979276979721033227' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/8979276979721033227'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/8979276979721033227'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/12/jquery-php-voting-widget.html' title='jQuery php voting widget'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-1254528121236653029</id><published>2009-11-29T22:07:00.006+11:00</published><updated>2011-01-28T09:25:21.423+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tutorials'/><category scheme='http://www.blogger.com/atom/ns#' term='plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery-UI'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>jQuery UI multiple draggable plugin</title><content type='html'>The jQuery multiple draggable plugin is an extension to the &lt;a href='http://jqueryui.com/demos/draggable/'&gt;jQuery UI Draggable plugin&lt;/a&gt;. This plugin extends the current functionality to allow for elements to be grouped and dragged as a group. The aim of the plugin is to include all of the current functionality listed in the &lt;a href='http://jqueryui.com/demos/draggable/#options'&gt;options&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;To group and ungroup elements simply control click, the ui-multidraggable extension is applied for styling purposes and also to alert the plugin as to which elements are grouped.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;You can view the following demos:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://comp345.awardspace.com/multidraggable/base.html'&gt;base functionality&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href='http://comp345.awardspace.com/multidraggable/containment.html'&gt;containment functionality&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href='http://comp345.awardspace.com/multidraggable/handle_cancel.html'&gt;handle and cancel functionality&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href='http://comp345.awardspace.com/multidraggable/revert.html'&gt;revert functionality&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;You can also download the plugin and the demos from &lt;a href='http://sites.google.com/site/myphpetc/Home/multidraggable.zip'&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;An update has now been provided for this plugin thanks to Caili Crane @ Pulse Energy allowing the plugin to be used with jQueryUI 1.8.8 and jQuery 1.4.4 and can be downloaded &lt;a href='https://sites.google.com/site/myphpetc/Home/multidraggable-for-jquery-ui-1.8.8.zip'&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;As this is an extension of the base functionality it is also released under a dual GPL and MIT license. You can view copies of these licenses in the package when you download the source from the link above.&lt;br /&gt;&lt;br /&gt;Following is a list of all the options from the draggable element and how they work with the multidraggable plugin:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='http://jqueryui.com/demos/draggable/#option-addClasses'&gt;addClasses&lt;/a&gt; works and is set on an individual level&lt;/li&gt;&lt;li&gt;&lt;a href='http://jqueryui.com/demos/draggable/#option-appendTo'&gt;appendTo&lt;/a&gt; works and is set on an individual level&lt;/li&gt;&lt;li&gt;&lt;a href='http://jqueryui.com/demos/draggable/#option-axis'&gt;axis&lt;/a&gt; works and is set on an individual level&lt;/li&gt;&lt;li&gt;&lt;a href='http://jqueryui.com/demos/draggable/#option-cancel'&gt;cancel&lt;/a&gt; works and is set on an individual level&lt;/li&gt;&lt;li&gt;&lt;a href='http://jqueryui.com/demos/draggable/#option-containment'&gt;containment&lt;/a&gt; works and is set on an individual level&lt;/li&gt;&lt;li&gt;&lt;a href='http://jqueryui.com/demos/draggable/#option-cursor'&gt;cursor&lt;/a&gt; works and is set on an individual level&lt;/li&gt;&lt;li&gt;&lt;a href='http://jqueryui.com/demos/draggable/#option-cursorAt'&gt;cursorAt&lt;/a&gt; works and is set on an individual level&lt;/li&gt;&lt;li&gt;&lt;a href='http://jqueryui.com/demos/draggable/#option-delay'&gt;delay&lt;/a&gt; works and is set on an individual level&lt;/li&gt;&lt;li&gt;&lt;a href='http://jqueryui.com/demos/draggable/#option-distance'&gt;distance&lt;/a&gt; works and is set on an individual level&lt;/li&gt;&lt;li&gt;&lt;a href='http://jqueryui.com/demos/draggable/#option-grid'&gt;grid&lt;/a&gt; works and is set on an individual level&lt;/li&gt;&lt;li&gt;&lt;a href='http://jqueryui.com/demos/draggable/#option-handle'&gt;handle&lt;/a&gt; works and is set on an individual level&lt;/li&gt;&lt;li&gt;&lt;a href='http://jqueryui.com/demos/draggable/#option-helper'&gt;helper&lt;/a&gt; works and is set on an individual level&lt;/li&gt;&lt;li&gt;&lt;a href='http://jqueryui.com/demos/draggable/#option-iFrameFix'&gt;iFrameFix&lt;/a&gt; works and is set on an individual level&lt;/li&gt;&lt;li&gt;&lt;a href='http://jqueryui.com/demos/draggable/#option-opacity'&gt;opacity&lt;/a&gt; works and is set on an individual level&lt;/li&gt;&lt;li&gt;&lt;a href='http://jqueryui.com/demos/draggable/#option-refreshPositions'&gt;refreshPositions&lt;/a&gt; works and is set on an individual level&lt;/li&gt;&lt;li&gt;&lt;a href='http://jqueryui.com/demos/draggable/#option-revert'&gt;revert&lt;/a&gt; works and is set on an individual level&lt;/li&gt;&lt;li&gt;&lt;a href='http://jqueryui.com/demos/draggable/#option-revertDuration'&gt;revertDuration&lt;/a&gt; works and is set on an individual level. Note: this currently throws an error if two elements have different revertDurations and you attempt to drag before both have reverted to their original position.&lt;/li&gt;&lt;li&gt;&lt;a href='http://jqueryui.com/demos/draggable/#option-scope'&gt;scope&lt;/a&gt; works and is set on an individual level&lt;/li&gt;&lt;li&gt;&lt;a href='http://jqueryui.com/demos/draggable/#option-scroll'&gt;scroll&lt;/a&gt; works and if any in the group have scroll set to true then enclosing element will scroll&lt;/li&gt;&lt;li&gt;&lt;a href='http://jqueryui.com/demos/draggable/#option-scrollSensitivity'&gt;scrollSensitivity&lt;/a&gt; works and is set on an individual level&lt;/li&gt;&lt;li&gt;&lt;a href='http://jqueryui.com/demos/draggable/#option-scrollSpeed'&gt;scrollSpeed&lt;/a&gt; works and is set on an individual level, but once all elements are outside the original container the speed of the fastest grouped element is used&lt;/li&gt;&lt;li&gt;&lt;a href='http://jqueryui.com/demos/draggable/#option-snap'&gt;snap&lt;/a&gt; works and is set on an individual level&lt;/li&gt;&lt;li&gt;&lt;a href='http://jqueryui.com/demos/draggable/#option-snapMode'&gt;snapMode&lt;/a&gt; works and is set on an individual level&lt;/li&gt;&lt;li&gt;&lt;a href='http://jqueryui.com/demos/draggable/#option-snapTolerance'&gt;snapTolerance&lt;/a&gt; works and is set on an individual level&lt;/li&gt;&lt;li&gt;&lt;a href='http://jqueryui.com/demos/draggable/#option-stack'&gt;stack&lt;/a&gt; works, whichever element from the group is the one being dragged will have the highest zIndex&lt;/li&gt;&lt;li&gt;&lt;a href='http://jqueryui.com/demos/draggable/#option-zIndex'&gt;zIndex&lt;/a&gt; works and is set on an individual level&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;The only functionality I am aware of that currently does not work is the &lt;a href='http://jqueryui.com/demos/draggable/#option-connectToSortable'&gt;connectToSortable&lt;/a&gt; which I am working on resolving for the next release.&lt;br /&gt;&lt;br /&gt;As you can see from the working options above, these settings are set on an individual but are likely to work more cohesively if they have the same values and options set. This was purposely done to allow for flexibility and usability (you may want certain items to have different opacity etc.).&lt;br /&gt;&lt;br /&gt;I have very pleased to be able to release this plugin and hope it is useful. My first &lt;a href='http://www.myphpetc.com/2009/01/jquery-multiple-draggable-elements.html'&gt;attempt&lt;/a&gt; at doing this nearly a year ago was miles away from where it is now and I am grateful to &lt;a href='http://bililite.com/blog/understanding-jquery-ui-widgets-a-tutorial/'&gt;this post&lt;/a&gt; for teaching me how to do this the correct way.&lt;br /&gt;&lt;br /&gt;Please let me know if you have any constructive feedback and if you are using this plugin anywhere.&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-1254528121236653029?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/1254528121236653029/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=1254528121236653029' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/1254528121236653029'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/1254528121236653029'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/11/jquery-ui-multiple-draggable-plugin.html' title='jQuery UI multiple draggable plugin'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-6117786145955655326</id><published>2009-11-26T18:06:00.005+11:00</published><updated>2009-11-26T18:09:15.781+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='opinion'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='microsoft'/><category scheme='http://www.blogger.com/atom/ns#' term='articles'/><title type='text'>How can Chrome OS win market share?</title><content type='html'>Who really rules the net? I know with most popular culture that it's somewhere between 8 and 18 year olds with an ever increaing dispensible income; they decide our music stars, our fashion and the growing movie takings. They brought us the Spice Girls, then Brittany, Miley and now New Moon. God bless their socks, they have brought us some real shit, but I'm not going to turn this into a rant about how teenage girls should really be listening to &lt;a href='http://www.youtube.com/watch?v=RUmmsMeHAaE'&gt;Radiohead&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;God knows they've tried to influence the net; Facebook, lolcatz and Perez. But real IT companies are not considered with the steady stream of cultural detrits that is floating around the web. What they are more concerned about is how you are viewing it. You see, the folks at Redmond are sitting on one giant nest-egg that has been around for years that according to statcounter around 90% of us worldwide are continuing to use. &lt;br /&gt;&lt;br /&gt;So who decides which OS is king? Is it just a matter of cool? I doubt it, I'm not sure where Windows sits on the &lt;a href='http://mrtrivia.net/wp-content/uploads/2009/08/Coolmeter.jpg'&gt;cool-o-meter&lt;/a&gt; and I don't think that operating systems as a whole are the kind of cool that the kids are interested in. They are kind of the opposite to the big guys, they are more interested in what they are looking and not what they are using. I would argue that the driving influence for any computer technology are those of us who actually care.&lt;br /&gt;&lt;br /&gt;Why is my Mother now using Firefox when 6 months ago she was stuck on IE6? Because someone who cared bothered to go and install an alternative. A couple of years back I may not have bothered, but what has made this shift in the environment that now so many people are moving away from Explorer and installing Chrome or Firefox or something else. We have! The people who care. The stuff floating around the net may belong to our cultural heroes, but what you are using belongs to us. The developers, the tech writers, the support team and the salesmen, not the &lt;a href='http://www.youtube.com/watch?v=o4MwTvtyrUQ'&gt;guy on the street&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;If it were just a matter choice maybe the Mac guys or the Linux guys would have had a better share, but recently there has been a real movement to change and you can see it in the last twelve months of browser statistics. It has been mobilised through blogging and demonstrated by the number of installs on friends and parents machines. So why is this so important to the OS market?&lt;br /&gt;&lt;br /&gt;If you have ever tried, you will know how hard it is to convince someone to switch their browser, but once they have switched it is just as hard to switch them back. So, although at most major stores across the world your shiny new PC will come pre-installed with the latest version of Explorer, these same friends and parents will come back and ask you to reinstall their new favourite browser.&lt;br /&gt;&lt;br /&gt;I just finished reading Robert Scoble's latest post titled "Why Google Chrome OS has already won":&lt;br /&gt;&lt;quote style='font-size:14px;font-weight:bold;font-style:italic;'&gt;&lt;br /&gt;"Google is in a war over developers with Microsoft. Google wants developers to build for the open web. Microsoft wants developers to build for Silverlight. Those messages are VERY clear coming out of both camps now."&lt;br /&gt;&lt;/quote&gt;&lt;br /&gt;&lt;br /&gt;I would argue that Google is not in a war over developers for the sake of building an open web, but for the reasons I have already mentioned. Google's war is not won at the storefront, but at the same place that Firefox won its battle. They want the tech guys to get off their backsides and install their new operating system on as many Friends / Mum and Dad machines as possible. Yes they are battling over developers, not to write code for a specific purpose, although they are trying to win the developers with their code, but they want the developers to be inspired to change.&lt;br /&gt;&lt;br /&gt;In the end the cool kids will still use whatever is put in front of them, they can't tell the difference between Greenday and My Chemical Romance. The only way to change what the average Joe is using is if we can be bothered enough to go out and do it ourselves and now that Google knows that, hopefully they can deliver an OS good enough for us to get out there and do it.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-6117786145955655326?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/6117786145955655326/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=6117786145955655326' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/6117786145955655326'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/6117786145955655326'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/11/how-can-chrome-os-win-market-share.html' title='How can Chrome OS win market share?'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-1231426396386091151</id><published>2009-11-25T22:12:00.008+11:00</published><updated>2009-11-26T08:34:07.230+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='flickr'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorials'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>jQuery flickr widget</title><content type='html'>&lt;style type="text/css"&gt;#flickr_widget { border:1px solid #777; background:#337E9B; width:162px; padding:10px;}#images { border:1px solid #444; background:#EEE; text-align:center; display:block;}#images a { display:block; margin:0px auto; padding:2px;}a img { border:0px;}#flick_widget_heading { color:white; font-family:tahoma, helvetica, serif; font-size:11px; padding:0px; margin:0px; margin-bottom:5px; font-weight:bold; text-decoration:none; display:block;}#images * { padding:0px; margin:0px;}/** * HoverScroll Style Sheet * * @author RasCarlito &lt;carl.ogren@gmail.com&gt; * @version 0.3.0 * @revision 8 *//* Main container */div.hoverscroll { position:relative;}/* List container */div.hoverscroll div.listcontainer { overflow:hidden;}/* Actual list containing items */div.hoverscroll ul.list { list-style:none; margin:0; padding:0;}/* Items contained in the list */div.hoverscroll ul.list li.item { display:block; padding:0;}div.hoverscroll.horizontal ul.list li.item { float:left;}/* Arrows */div.hoverscroll div.arrow { position:absolute; float:none; background-color:#ccc; background-position:center; background-repeat:no-repeat; opacity:0.8; filter:alpha(opacity=80);}div.hoverscroll div.arrow.left,div.hoverscroll div.arrow.right { top:0px; width:40px; height:100%;}div.hoverscroll div.arrow.left { left:0px; background-image:url('http://comp345.awardspace.com/flickr/gfx/arrow-left-small.png');}div.hoverscroll div.arrow.right { right:0px; background-image:url('http://comp345.awardspace.com/flickr/gfx/arrow-right-small.png');}div.hoverscroll div.arrow.top,div.hoverscroll div.arrow.bottom { left:0px; width:100%; height:40px;}div.hoverscroll div.arrow.top { top:0px; background-image:url('http://sites.google.com/site/myphpetc/Home/arrow-up-small.png'); }div.hoverscroll div.arrow.bottom { bottom:0px; background-image:url('http://sites.google.com/site/myphpetc/Home/arrow-down-small.png');}&lt;/style&gt;&lt;script type="text/javascript" src="http://www.google.com/jsapi"&gt;&lt;/script&gt;&lt;script type="text/javascript"&gt; google.load("jquery", "1.3.2");&lt;/script&gt;&lt;script type="text/javascript" src="http://comp345.awardspace.com/flickr/js/hoverscroll.js"&gt;&lt;/script&gt;&lt;script type="text/javascript" src="http://comp345.awardspace.com/flickr/js/flickr.js"&gt;&lt;/script&gt;&lt;br /&gt;This tutorial shows you how to build a jQuery widget for your flickr photos or for your favourite flickr group.&lt;br /&gt;&lt;br /&gt;Here is a look at the widget we will be building:&lt;br /&gt;&lt;div id='flickr_widget'&gt;&lt;a id='flick_widget_heading' href='http://www.flickr.com/groups/sydneyaustralia/'&gt;Flickr Sydney, Australia Pool&lt;/a&gt;&lt;br /&gt;&lt;ul id='images'&gt;&lt;/ul&gt;&lt;/div&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;You can download the code for this widget &lt;a href='http://sites.google.com/site/myphpetc/Home/flickr.zip'&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;To build the widget we need to grab the &lt;a href='http://rascarlito.free.fr/hoverscroll/'&gt;jQuery hoverscroll plugin&lt;/a&gt; which allows us to do the nice scrolling action.&lt;br /&gt;&lt;br /&gt;The rest is just a simple call to flickr's JSON API to retrieve the feed and &lt;a href='http://thejudens.com/eric/2009/07/jquery-image-resize/'&gt;another function&lt;/a&gt; to scale the images to size.&lt;br /&gt;&lt;br /&gt;If you want to read about importing your flickr feed with jQuery and JSON I suggest you read this &lt;a href='http://www.viget.com/inspire/pulling-your-flickr-feed-with-jquery/'&gt;helpful post&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;To begin with we simply grab our feed via JSON:&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;$(&amp;quot;document&amp;quot;).ready(function() {&lt;br /&gt;     $.getJSON(&amp;quot;http://api.flickr.com/services/feeds/groups_pool.gne?id=32142572@N00&amp;amp;lang=en-us&amp;amp;format=json&amp;amp;jsoncallback=?&amp;quot;, function(data){&lt;br /&gt;          $.each(data.items, function(i,item){&lt;br /&gt;          $(&amp;quot;&amp;lt;img/&amp;gt;&amp;quot;).attr(&amp;quot;src&amp;quot;, item.media.m).appendTo(&amp;quot;#images&amp;quot;)&lt;br /&gt;               .wrap(&amp;quot;&lt;br /&gt;&amp;lt;li&amp;gt;&amp;lt;a href=&amp;#039;&amp;quot; + item.link + &amp;quot;&amp;#039;&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;&amp;quot;);&lt;br /&gt;          });&lt;br /&gt;          &lt;br /&gt;          $(&amp;#039;#images&amp;#039;).hoverscroll({&lt;br /&gt;               vertical: true,&lt;br /&gt;               width: 166,&lt;br /&gt;               height: 400&lt;br /&gt;          });&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The main part of the call is the &lt;a href='http://docs.jquery.com/Ajax/jQuery.getJSON'&gt;jQuery getJSON call&lt;/a&gt;, this calls the &lt;a href='http://www.flickr.com/services/api/response.json.html'&gt;flickr API&lt;/a&gt; with the group ID of the group you want to display. You can easily get this URL and ID as it is almost identical to the RSS feed of the group. This feed is displayed at the bottom of the page, so it's a matter of clicking on the feed, grabbing the URL and changing the format over to JSON as above.&lt;br /&gt;&lt;br /&gt;To view the different kinds of feed that flickr offers follow this link &lt;a href='http://www.flickr.com/services/feeds/'&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The jQuery hoverscroll plugin is then called to build our lovely scrolling widget. You can view more detail about how the plugin works &lt;a href='http://rascarlito.free.fr/hoverscroll/'&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The next part of the script just loops over the images and scales them accordingly.&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;$('#images img').each(function() {&lt;br /&gt;               var maxWidth = 160; // Max width for the image&lt;br /&gt;               var maxHeight = 160;    // Max height for the image&lt;br /&gt;               var ratio = 0;  // Used for aspect ratio&lt;br /&gt;               var width = $(this).width();    // Current image width&lt;br /&gt;               var height = $(this).height();  // Current image height&lt;br /&gt;      &lt;br /&gt;               // Check if the current width is larger than the max&lt;br /&gt;               if(width &gt; maxWidth){&lt;br /&gt;                    ratio = maxWidth / width;   // get ratio for scaling image&lt;br /&gt;                    $(this).css("width", maxWidth); // Set new width&lt;br /&gt;                    $(this).css("height", height * ratio);  // Scale height based on ratio&lt;br /&gt;                    height = height * ratio;    // Reset height to match scaled image&lt;br /&gt;                    width = width * ratio;    // Reset width to match scaled image&lt;br /&gt;               }&lt;br /&gt;      &lt;br /&gt;               // Check if current height is larger than max&lt;br /&gt;               if(height &gt; maxHeight){&lt;br /&gt;                    ratio = maxHeight / height; // get ratio for scaling image&lt;br /&gt;                    $(this).css("height", maxHeight);   // Set new height&lt;br /&gt;                    $(this).css("width", width * ratio);    // Scale width based on ratio&lt;br /&gt;                    width = width * ratio;    // Reset width to match scaled image&lt;br /&gt;               }&lt;br /&gt;          }); &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I won't go into detail as to how the above works, it is just some math to scale the image to the provide constraint. Here I have set maxWidth and maxHeight to 160px.&lt;br /&gt;&lt;br /&gt;The rest is just a bit of HTML and css.&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-1231426396386091151?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/1231426396386091151/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=1231426396386091151' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/1231426396386091151'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/1231426396386091151'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/11/jquery-flickr-widget.html' title='jQuery flickr widget'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-972243373936057488</id><published>2009-11-25T19:53:00.002+11:00</published><updated>2009-11-25T19:56:12.854+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='articles'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>Best jQuery games from across the net</title><content type='html'>Today I'm going to look at some of the best jQuery games on the net. As javascript speeds get faster and the great things you can now do with jQuery make it possible to produce some good quality games. Although speed and sizes are a bit of a restriction to the type of game that can be produced (no 3D shooters yet) these are great games none the less and some are quite addictive.&lt;br /&gt;&lt;br /&gt;I hope to show you a range of what is available. Although there are quite a few jQuery games out there, I chose these for their playability and completeness. You can tell these guys put in a decent effort to make a quality product.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;I'd like to start with the &lt;a href='http://blog.benogle.com/2009/04/20/jquery-pong/'&gt;jQuery pong clone&lt;/a&gt;. Why play against your friends when you can play against your browser! This game has a whole bunch of options that you can set yourself if you decide to download it for yourself including ball speed, score to play to and paddle sizes. Click on the image to follow the link.&lt;br /&gt;&lt;br /&gt;&lt;a href='http://blog.benogle.com/2009/04/20/jquery-pong/'&gt;&lt;img style='border:1px solid #CCC' src='http://sites.google.com/site/myphpetc/Home/jgames_pong.jpg' /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The next game is extremely addictive, but based on a simple idea. In &lt;a href='http://demo.marcofolio.net/jcharacterfall/'&gt;jCharacterfall&lt;/a&gt;, water drips from the ceiling and you stop them from hitting the ground by pressing the matching letter. As the game goes on the drops fall faster and faster. Hours of fun!&lt;br /&gt;&lt;br /&gt;&lt;a href='http://demo.marcofolio.net/jcharacterfall/'&gt;&lt;img style='border:1px solid #CCC' src='http://sites.google.com/site/myphpetc/Home/jgames_fall.jpg' /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Next up is a &lt;a href='http://www.anti.ro/games/sudoku/'&gt;sudoku&lt;/a&gt; game. This is a nice clean implementation and is a real challenge to get your name up in the highscores (not like all the other hacked high-score lists!). Only thing I think is missing is the ability to pencil in smaller guesses.&lt;br /&gt;&lt;br /&gt;&lt;a href='http://www.anti.ro/games/sudoku/'&gt;&lt;img style='border:1px solid #CCC' src='http://sites.google.com/site/myphpetc/Home/jgames_sudoko.jpg' /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Sticking with the retro theme is an old fashioned &lt;a href='http://jquery-snakey.googlecode.com/svn/trunk/index.html'&gt;snake clone&lt;/a&gt;. You know the score, snake goes round, eats stuff, crashes into walls.&lt;br /&gt;&lt;br /&gt;&lt;a href='http://jquery-snakey.googlecode.com/svn/trunk/index.html'&gt;&lt;img style='border:1px solid #CCC' src='http://sites.google.com/site/myphpetc/Home/jgames_snake.jpg' /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The next one is really special and a lot of effort has gone in to building it. Jon Raasch has built a clone of the old NES game &lt;a href='http://jonraasch.com/blog/jquery-video-game-remake-tc-surf-designs'&gt;T&amp;C Surf Designs&lt;/a&gt;. It looks and handles like the classic Nintendo game and the sprites look great.&lt;br /&gt;&lt;br /&gt;&lt;a href='http://jonraasch.com/blog/jquery-video-game-remake-tc-surf-designs'&gt;&lt;img style='border:1px solid #CCC' src='http://sites.google.com/site/myphpetc/Home/jgames_tandc.jpg' /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you have any more suggestions for great jQuery games leave a comment.&lt;br /&gt;&lt;br /&gt;Have fun and enjoy!&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-972243373936057488?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/972243373936057488/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=972243373936057488' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/972243373936057488'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/972243373936057488'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/11/best-jquery-games-from-across-net.html' title='Best jQuery games from across the net'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-3816866954843438567</id><published>2009-11-24T20:38:00.007+11:00</published><updated>2009-11-24T20:57:14.983+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tutorials'/><category scheme='http://www.blogger.com/atom/ns#' term='weather'/><category scheme='http://www.blogger.com/atom/ns#' term='widget'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>jQuery weather widget</title><content type='html'>&lt;style type='text/css'&gt;#weather_widget * { margin:0px; padding:0px; font-family:arial; font-size:14px; line-height:1.2em;}#weather_widget { border:1px solid #444; background:#EEE; width:275px; padding:15px; overflow:auto;}#weather_img { float:left; padding-right:20px;}#weather_country { font-weight:bold;}#weather_city { font-size:10px;}#weather_temp { margin-top:5px;}#weather_cond { margin-top:5px; font-style:italic;}#weather_conditions { float:left;}&lt;/style&gt;&lt;script type="text/javascript" src="http://www.google.com/jsapi"&gt;&lt;/script&gt;&lt;script type="text/javascript"&gt; google.load("jquery", "1.3.2");&lt;/script&gt;&lt;script type="text/javascript" src="http://comp345.awardspace.com/weather/js/jquery.cookie.js"&gt;&lt;/script&gt;&lt;script type="text/javascript" src="http://comp345.awardspace.com/weather/js/weather.js"&gt;&lt;/script&gt;&lt;br /&gt;In this tutorial we are going to build a jQuery weather widget. This widget is pure javascript and requires no back-end/server so you can place it on your blog or anywhere you like.&lt;br /&gt;&lt;br /&gt;Please note: Information in this widget should not be taken as accurate under any circumstance and should not be used to make any decisions in any circumstance. It is purely a toy. We make no claim to its accuracy for any purpose.&lt;br /&gt;&lt;br /&gt;&lt;div id='weather_widget'&gt;&lt;/div&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;You can get the code for this tutorial &lt;a href='http://sites.google.com/site/myphpetc/Home/weather.zip'&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The widget makes two main calls using JSON to retrieve the users geolocation and then to retrieve the local weather for that location. It also uses the &lt;a href='http://plugins.jquery.com/project/cookie'&gt;jQuery cookie plugin&lt;/a&gt; to remember the details so that it doesn't need to make these calls each time the page reloads.&lt;br /&gt;&lt;br /&gt;The two JSON calls are to the &lt;a href='http://www.geoplugin.com/'&gt;geoPlugin&lt;/a&gt; site and then to the &lt;a href='http://www.geonames.org/export/JSON-webservices.html#weatherJSON'&gt;geonames&lt;/a&gt; weather webservice using the retrieved longitude and latitude coordinates. Please check the terms and conditions from their site if you want to use this widget on your own site. It also uses Googles weather images.&lt;br /&gt;&lt;br /&gt;Let's look at the first part of the javascript code. We begin with the jQuery document ready function:&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;$("document").ready(function() {&lt;br /&gt;     if ($.cookie('loc_longitude') &amp;&amp; $.cookie('loc_latitude')) {&lt;br /&gt;          getWeather();&lt;br /&gt;     } else {&lt;br /&gt;          $.getJSON("http://www.geoplugin.net/json.gp?callback=?", function(data) {&lt;br /&gt;                eval(data);&lt;br /&gt;          });&lt;br /&gt;     }&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;It begins by checking if the geocordinates for this user have been set for this user. If not it calls the geoplugin site to retrieve geolocation details.&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;function geoPlugin(data) {&lt;br /&gt;     $.cookie('loc_latitude', data.geoplugin_latitude, {expires: 7}); &lt;br /&gt;     $.cookie('loc_longitude', data.geoplugin_longitude, {expires: 7});&lt;br /&gt;     $.cookie('loc_country', data.geoplugin_countryName, {expires: 7});&lt;br /&gt;     $.cookie('loc_region', data.geoplugin_region, {expires: 7});&lt;br /&gt;     $.cookie('loc_city', data.geoplugin_city, {expires: 7});&lt;br /&gt;     $.cookie('loc_country_code', data.geoplugin_countryCode, {expires: 7});&lt;br /&gt;     getWeather();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The eval function above calls the geoPlugin function and sets the geolocation details in the cookie, this will be used in the getWeather function which you will notice is called above if the location details are already set.&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;function getWeather() {&lt;br /&gt;     var latitude = $.cookie('loc_latitude');&lt;br /&gt;     var longitude = $.cookie('loc_longitude');&lt;br /&gt;&lt;br /&gt;     var loc_conditions = $.cookie('loc_conditions');&lt;br /&gt;     var loc_conditions_img = $.cookie('loc_conditions_img');&lt;br /&gt;     var loc_temp = $.cookie('loc_temp');&lt;br /&gt;     var loc_humidity = $.cookie('loc_humidity');&lt;br /&gt;&lt;br /&gt;     if (loc_conditions &amp;&amp; loc_conditions_img) {&lt;br /&gt;          setConditions(loc_conditions, loc_conditions_img, loc_temp, loc_humidity);&lt;br /&gt;     } else {&lt;br /&gt;          var url = "http://ws.geonames.org/findNearByWeatherJSON?lat=" + latitude + "&amp;lng=" + longitude + "&amp;callback=?";&lt;br /&gt;          $.getJSON(url, function(data) {&lt;br /&gt;               var clouds = data.weatherObservation.clouds;&lt;br /&gt;               var weather = data.weatherObservation.weatherCondition;&lt;br /&gt;               var temp = data.weatherObservation.temperature;&lt;br /&gt;               var humidity = data.weatherObservation.humidity;&lt;br /&gt;   &lt;br /&gt;               var conditions_img = getConditions(clouds, weather);&lt;br /&gt;   &lt;br /&gt;               var conditions = '';&lt;br /&gt;               if (weather == 'n/a') {&lt;br /&gt;                    if (clouds == 'n/a') {&lt;br /&gt;                         conditions = 'fine';&lt;br /&gt;                    } else {&lt;br /&gt;                         conditions = clouds;&lt;br /&gt;                    }&lt;br /&gt;               } else {&lt;br /&gt;                    conditions = weather;&lt;br /&gt;               }&lt;br /&gt;   &lt;br /&gt;                    $.cookie('loc_conditions', conditions); &lt;br /&gt;                    $.cookie('loc_conditions_img', conditions_img); &lt;br /&gt;                    $.cookie('loc_temp', temp); &lt;br /&gt;                    $.cookie('loc_humidity', humidity); &lt;br /&gt;                    setConditions(conditions, conditions_img, temp, humidity);&lt;br /&gt;          });&lt;br /&gt;     }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The getWeather function starts by retrieving all of the geolocation details from the cookie. It then checks the cookie to see if the temperature details have been set in the cookie, if they have it simply goes ahead and displays all the information in the widget by calling the setConditions function.&lt;br /&gt;&lt;br /&gt;If the temperature details haven't been set in the cookie it then calls the JSON weather service using the latitude and longitude details from the first JSON call. It then calls the getConditions function to retrieve the correct image corresponding to the current weather condition.&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;function getConditions(clouds, weather) {&lt;br /&gt;     if (weather == 'n/a') {&lt;br /&gt;          switch (clouds) {&lt;br /&gt;               case 'n/a':&lt;br /&gt;                    return 'sunny.gif';&lt;br /&gt;               case 'clear sky':&lt;br /&gt;                    return 'sunny.gif';&lt;br /&gt;               case 'few clouds':&lt;br /&gt;                    return 'partly_cloudy.gif';&lt;br /&gt;               case 'scattered clouds':&lt;br /&gt;                    return 'partly_cloudy.gif';&lt;br /&gt;               case 'broken clouds':&lt;br /&gt;                    return 'partly_cloudy.gif';&lt;br /&gt;               default:&lt;br /&gt;                    return 'cloudy.gif';&lt;br /&gt;          }&lt;br /&gt;     } else {&lt;br /&gt;          weather = weather.replace('light ', '').replace('heavy ', '').replace(' in vicinity', '');&lt;br /&gt;          switch(weather) {&lt;br /&gt;               case 'drizzle':&lt;br /&gt;                    return 'rain.gif';&lt;br /&gt;               case 'rain':&lt;br /&gt;                    return 'rain.gif';&lt;br /&gt;               case 'snow':&lt;br /&gt;                    return 'snow.gif';&lt;br /&gt;               case 'snow grains':&lt;br /&gt;                    return 'sleet.gif';&lt;br /&gt;               case 'ice crystals':&lt;br /&gt;                    return 'icy.gif';&lt;br /&gt;               case 'ice pellets':&lt;br /&gt;                    return 'icy.gif';&lt;br /&gt;               case 'hail':&lt;br /&gt;                    return 'sleet.gif';&lt;br /&gt;               case 'small hail':&lt;br /&gt;                    return 'sleet.gif';&lt;br /&gt;               case 'snow pellets':&lt;br /&gt;                    return 'sleet.gif';&lt;br /&gt;               case 'unknown precipitation':&lt;br /&gt;                    return 'rain.gif';&lt;br /&gt;               case 'mist':&lt;br /&gt;                    return 'mist.gif';&lt;br /&gt;               case 'fog':&lt;br /&gt;                    return 'fog.gif';&lt;br /&gt;               case 'smoke':&lt;br /&gt;                    return 'smoke.gif';&lt;br /&gt;               case 'volcanic ash':&lt;br /&gt;                    return 'smoke.gif';&lt;br /&gt;               case 'sand':&lt;br /&gt;                    return 'dust.gif';&lt;br /&gt;               case 'haze':&lt;br /&gt;                    return 'haze.gif';&lt;br /&gt;               case 'spray':&lt;br /&gt;                    return 'rain.gif';&lt;br /&gt;               case 'widespread dust':&lt;br /&gt;                    return 'dust.gif';&lt;br /&gt;               case 'squall':&lt;br /&gt;                    return 'flurries.gif';&lt;br /&gt;               case 'sandstorm':&lt;br /&gt;                    return 'dust.gif';&lt;br /&gt;               case 'duststorm':&lt;br /&gt;                    return 'dust.gif';&lt;br /&gt;               case 'well developed dust':&lt;br /&gt;                    return 'dust.gif';&lt;br /&gt;               case 'sand whirls':&lt;br /&gt;                    return 'dust.gif';&lt;br /&gt;               case 'funnel cloud':&lt;br /&gt;                    return 'flurries.gif';&lt;br /&gt;               case 'tornado':&lt;br /&gt;                    return 'storm.gif';&lt;br /&gt;               case 'waterspout':&lt;br /&gt;                    return 'storm.gif';&lt;br /&gt;               case 'showers':&lt;br /&gt;                    return 'storm.gif';&lt;br /&gt;               case 'thunderstorm':&lt;br /&gt;                    return 'thunderstorm.gif';&lt;br /&gt;               default:&lt;br /&gt;                    if (weather.indexOf("rain")) {&lt;br /&gt;                         return 'rain.gif';&lt;br /&gt;                    } else if (weather.indexOf("snow")) {&lt;br /&gt;                         return 'snow.gif';&lt;br /&gt;                    } else if (weather.indexOf("thunder")) {&lt;br /&gt;                         return 'thunderstorm.gif';&lt;br /&gt;                    } else if (weather.indexOf("dust")) {&lt;br /&gt;                         return 'dust.gif';&lt;br /&gt;                    } else {&lt;br /&gt;                         return 'sunny.gif';&lt;br /&gt;                    }&lt;br /&gt;          }&lt;br /&gt;     }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;getConditions is simply a couple of large switch statements to retrieve the correct image. Once this is returned the image and the conditions details are set in the cookie. The last step is calling the setConditions function to display the details in the widget.&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;function setConditions(conditions, conditions_img, temp, humidity) {&lt;br /&gt;     var country = $.cookie('loc_country');&lt;br /&gt;     var region = $.cookie('loc_region');&lt;br /&gt;     var city = $.cookie('loc_city');&lt;br /&gt;     var loc_country_code = $.cookie('loc_country_code');&lt;br /&gt;     if (loc_country_code == 'US') {&lt;br /&gt;          temp = parseInt(temp) + 32;&lt;br /&gt;          temp_type = "F";&lt;br /&gt;     } else {&lt;br /&gt;          temp_type = "C";&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     $("#weather_widget").append("&lt;img id='weather_img' src='http://www.google.com/images/weather/" + conditions_img + "' /&gt;");&lt;br /&gt;     $("#weather_widget").append("&lt;div id='weather_conditions'&gt;&lt;p id='weather_country'&gt;" + country + "&lt;/p&gt;&lt;p id='weather_city'&gt;" + city + ", " + region + "&lt;/p&gt;&lt;p id='weather_temp'&gt;Temp: " + temp + "&amp;deg; " + temp_type + "&lt;/p&gt;&lt;p id='weather_hum'&gt;Humidity: " + humidity + "%&lt;/p&gt;&lt;p id='weather_cond'&gt;" + conditions.substr(0, 1).toUpperCase() + conditions.substr(1) + "&lt;/p&gt;&lt;/div&gt;");&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The rest is just a little bit of css and html.&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-3816866954843438567?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/3816866954843438567/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=3816866954843438567' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/3816866954843438567'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/3816866954843438567'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/11/jquery-weather-widget.html' title='jQuery weather widget'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-4107467432525685767</id><published>2009-11-23T21:50:00.002+11:00</published><updated>2009-11-24T20:40:14.044+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='art'/><category scheme='http://www.blogger.com/atom/ns#' term='christmas'/><category scheme='http://www.blogger.com/atom/ns#' term='articles'/><title type='text'>Christmas digital art from deviantART</title><content type='html'>Hope everyone is starting to get into the festive spirit. Today I've had a good look through &lt;a href='http://www.deviantart.com'&gt;deviantART&lt;/a&gt; and selected some of my favourite designs. I hope you like them and they help to brighten your holidays.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;The first one I picked is fractal art, there are a whole bunch of really good fractal art Christmas images so if you like this kind of thing make sure you browse the &lt;a href='http://browse.deviantart.com/digitalart/fractals/#order=9&amp;q=christmas'&gt;category&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a href='http://sophquest.deviantart.com/art/Christmas-Floral-105397737'&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/Christmas_Floral_by_Sophquest.png.jpg' /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The second picture I chose looks like a movie poster and subtle Christmas reference is just the icing on the cake to an already fantastic image.&lt;br /&gt;&lt;br /&gt;&lt;a href='http://alyn.deviantart.com/art/The-Night-Before-Christmas-13335366'&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/The_Night_Before_Christmas_by_alyn.jpg' /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I really like this next picture, you have to look at it a few times to decide how you feel about it.&lt;br /&gt;&lt;br /&gt;&lt;a href='http://thenass.deviantart.com/art/Merry-christmas-45316920'&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/Merry_christmas_by_TheNass.jpg' /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This next one is a great Christmas card design, it's a shame that there isn't a larger version available. Some lucky people will be getting this card.&lt;br /&gt;&lt;br /&gt;&lt;a href='http://ianibal.deviantart.com/art/Santatan-144502113'&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/Santatan_by_ianibal.jpg' /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here is another great fractal. It looks like Christmas flowers growing out of mould; kind of strange, but Christmas like.&lt;br /&gt;&lt;br /&gt;&lt;a href='http://ianibal.deviantart.com/art/Santatan-144502113'&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/Christmas_Flowers_by_nightmares06.jpg' /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This next image was actually the first one I chose and it really stood out amongst the others. Something stark and beautiful. It uses great Christmas imagery in a different context.&lt;br /&gt;&lt;br /&gt;&lt;a href='http://yagak.deviantart.com/art/Christmas-ghost-43535512'&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/Christmas_ghost_by_YagaK.jpg' /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The last one is some art done over the top of an existing photo. A job well done that really captures the moment.&lt;br /&gt;&lt;br /&gt;&lt;a href='http://noahz.deviantart.com/art/Christmas-Wallpaper-71827054'&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/Christmas_Wallpaper_by_noahz.jpg' /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I hope wherever you end up and whatever you believe this Christmas that you have a fantastic time with friends and family.&lt;br /&gt;&lt;br /&gt;Take care and enjoy!&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-4107467432525685767?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/4107467432525685767/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=4107467432525685767' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/4107467432525685767'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/4107467432525685767'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/11/christmas-digital-art-from-deviantart.html' title='Christmas digital art from deviantART'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-7400013380250883532</id><published>2009-11-23T19:41:00.001+11:00</published><updated>2009-11-23T19:42:18.393+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IE'/><category scheme='http://www.blogger.com/atom/ns#' term='standards'/><category scheme='http://www.blogger.com/atom/ns#' term='explorer'/><category scheme='http://www.blogger.com/atom/ns#' term='articles'/><title type='text'>What is most important in a browser? Microsoft discuss IE9</title><content type='html'>Dean Hachamovitch, General Manager, Internet Explorer &lt;a href='http://blogs.msdn.com/ie/archive/2009/11/18/an-early-look-at-ie9-for-developers.aspx'&gt;recently blogged&lt;/a&gt; on the future release of Explorer, IE9. Titled 'An Early Look At IE9 for Developers', the post covers the direction that Microsoft are aiming to take with the next release of Explorer. If you want a good idea of the reaction to this post I suggest you check out the &lt;a href='http://blogs.msdn.com/ie/commentrss.aspx?PostID=9924056'&gt;posts comments&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;A picture says a thousand words, so here are some pictures (and quotes) taken out of context and hopefully they will say something:&lt;br /&gt;&lt;br /&gt;&lt;h3 style='color:#348591;font-weight:normal;font-size:22px;font-style:italic;'&gt;One common test of script performance is from Apple's Webkit team, the SunSpider test&lt;/h3&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/sunspider.jpg' /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3 style='color:#348591;font-weight:normal;font-size:22px;font-style:italic;'&gt;Our goal is to deliver better performance across the board for real-world sites, not just benchmarks.&lt;/h3&gt;&lt;br /&gt;&lt;h3 style='color:#348591;font-weight:normal;font-size:22px;font-style:italic;'&gt;With IE8, we delivered a highly-interoperable implementation of CSS 2.1&lt;/h3&gt;&lt;br /&gt;&lt;h3 style='color:#348591;font-weight:normal;font-size:22px;font-style:italic;'&gt;Some standards tests - like Acid3 - have become widely used as shorthand for standards compliance, even with some shortcomings. As we improve support in IE for technologies that site developers use, the score will continue to go up.&lt;/h3&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/acid.jpg' /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3 style='color:#348591;font-weight:normal;font-size:22px;font-style:italic;'&gt;A more meaningful (from the point of view of web developers) example of standards support involves rounded corners.&lt;/h3&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/stackoverflow.jpg'&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/w3schools.jpg'&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3 style='color:#348591;font-weight:normal;font-size:22px;font-style:italic;'&gt;Another example of standards support that matters to web developers is CSS3 selectors.&lt;/h3&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/IE9_selectors.jpg'&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3 style='color:#348591;font-weight:normal;font-size:22px;font-style:italic;'&gt;Ultimately, we want to work with the community and W3C and other members of the working groups to define true validation test suites, like the one that we're all working on together for CSS 2.1, for the standards that matter to developers.&lt;/h3&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/FF_selectors.jpg'&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-7400013380250883532?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/7400013380250883532/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=7400013380250883532' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/7400013380250883532'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/7400013380250883532'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/11/what-is-most-important-in-browser.html' title='What is most important in a browser? Microsoft discuss IE9'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-3388063496299723533</id><published>2009-11-19T20:42:00.002+11:00</published><updated>2009-11-26T21:43:25.146+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CDN'/><category scheme='http://www.blogger.com/atom/ns#' term='AJAX'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorials'/><category scheme='http://www.blogger.com/atom/ns#' term='API'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='articles'/><title type='text'>Google AJAX libraries CDN</title><content type='html'>Are you using the &lt;a href='http://code.google.com/apis/ajaxlibs/'&gt;Google AJAX libraries CDN&lt;/a&gt; for your applications? Google offers the simplest and fastest way to deliver the latest version of your favourite AJAX libraries over the net.&lt;br /&gt;&lt;br /&gt;With a few lines of code you can grab your preferred libraries without having to download or host them yourself. You can even specify a specific version.&lt;br /&gt;&lt;br /&gt;Libraries include:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a alt="jQuery.com" href="http://code.google.com/apis/ajaxlibs/documentation/index.html#jquery"&gt;jQuery&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a alt="ui.jQuery.com" href="http://code.google.com/apis/ajaxlibs/documentation/index.html#jqueryUI"&gt;jQuery UI&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a alt="Prototype" href="http://code.google.com/apis/ajaxlibs/documentation/index.html#prototype"&gt;Prototype&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a alt="script.aculo.us" href="http://code.google.com/apis/ajaxlibs/documentation/index.html#script_aculo_us"&gt;script.aculo.us&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a alt="MooTools" href="http://code.google.com/apis/ajaxlibs/documentation/index.html#mootools"&gt;MooTools&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a alt="Dojo" href="http://code.google.com/apis/ajaxlibs/documentation/index.html#dojo"&gt;Dojo&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.google.com/apis/ajaxlibs/documentation/index.html#swfobject"&gt;SWFObject&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.google.com/apis/ajaxlibs/documentation/index.html#yui"&gt;Yahoo! User Interface Library (YUI)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.google.com/apis/ajaxlibs/documentation/index.html#ext-core"&gt;Ext Core&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.google.com/apis/ajaxlibs/documentation/index.html#chrome-frame"&gt;Chrome Frame&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;I now regularly use this method to include jQuery and the jQuery UI and the speed is definitely comparable to hosting it yourself.&lt;br /&gt;&lt;br /&gt;Here's an example of including jQuery 1.3.2:&lt;br /&gt;&lt;pre class="pre_code"&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;http://www.google.com/jsapi&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt; google.load(&amp;quot;jquery&amp;quot;, &amp;quot;1.3.2&amp;quot;);&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;It also parses as valid HTML.&lt;br /&gt;&lt;br /&gt;No need to worry about downloading another copy of jQuery just include the lines above to get the version you need.&lt;br /&gt;&lt;br /&gt;John Resig also mentioned in the &lt;a href='http://blog.jquery.com/2009/11/13/announcing-the-official-jquery-podcast/'&gt;first jQuery podcast&lt;/a&gt; that eventually core plug-ins and add-ons will also be available across the CDN so look forward to seeing that in the near future also.&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-3388063496299723533?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/3388063496299723533/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=3388063496299723533' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/3388063496299723533'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/3388063496299723533'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/11/google-ajax-libraries-cdn.html' title='Google AJAX libraries CDN'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-7459984716131075376</id><published>2009-11-18T20:39:00.017+11:00</published><updated>2009-11-26T21:43:59.252+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tutorials'/><category scheme='http://www.blogger.com/atom/ns#' term='Twitter'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>jQuery Twitter streaming widget in 30 lines</title><content type='html'>&lt;style type="text/css"&gt;a img { border:0px;}#twitter_stream { font-family:tahoma; background:#97D9F5; border:1px solid #21BCFF; width:210px; padding:20px; position:relative;}#stream_term { font-size:18px; margin-bottom:10px; color:#00B2FF; font-weight:bold; font-family:tahoma;}#twitter_results { width:200px; background:#F9FFFF; border:1px solid #7EE8FF; padding:5px; height:300px; overflow:auto;}.tweet_result { font-size:11px; line-height:16px; margin-bottom:10px; color:#444;}.tweet_result a { color:#2CC0C6;}.tweet_user { margin-right:5px;}&lt;/style&gt;&lt;script type="text/javascript" src="http://www.google.com/jsapi"&gt;&lt;/script&gt;&lt;script type="text/javascript"&gt; google.load("jquery", "1.3.2");&lt;/script&gt;&lt;script type="text/javascript"&gt;$("document").ready(function() { setInterval(load_tweets, 20000);load_tweets();});function load_tweets() { var last_ID = $(".tweet_result:first").attr("ID"); if (last_ID) {  last_ID = last_ID.replace("tweet", "");  var url = "http://search.twitter.com/search.json?q=jQuery&amp;since_id=" + last_ID + "&amp;callback=?"; } else {  var url = "http://search.twitter.com/search.json?q=jQuery&amp;rpp=5&amp;callback=?";  } $.getJSON(url, function(json) {   var results = '';  $(json.results).each(function() {   if (this.id == undefined) return;   results += "&lt;p class='tweet_result' id='tweet" + this.id + "'&gt;&lt;a href='http://twitter.com/" + this.from_user + "' class='tweet_user'&gt;&lt;img width='16' height='16' alt='" + this.from_user + " on Twitter' src='" + this.profile_image_url + "' /&gt;&lt;/a&gt;" + linkify(this.text) + "&lt;/p&gt;";  });   $("#twitter_results").prepend(results); }); $(".tweet_result:gt(20)").remove();}function linkify(text) {    // modified from TwitterGitter by David Walsh (davidwalsh.name)    // courtesy of Jeremy Parrish (rrish.org)    return text.replace(/(https?:\/\/[\w\-:;?&amp;=+.%#\/]+)/gi, '&lt;a href="$1"&gt;$1&lt;/a&gt;')               .replace(/(^|\W)@(\w+)/g, '$1&lt;a href="http://twitter.com/$2"&gt;@$2&lt;/a&gt;')               .replace(/(^|\W)#(\w+)/g, '$1#&lt;a href="http://search.twitter.com/search?q=%23$2"&gt;$2&lt;/a&gt;');}&lt;/script&gt;&lt;br /&gt;Today we are going to build a widget for streaming Twitter search results using jQuery. This widget only requires 30 lines of javascript and the rest is CSS and a small bit of HTML.&lt;br /&gt;&lt;br /&gt;The widget takes in a search term, in the example we are searching for the term "jQuery". It then updates every 20 seconds (you can change the frequency). Each time it updates it places the latest results at the top and if the number of results exceeds 20 it removes the excess results from the bottom.&lt;br /&gt;&lt;br /&gt;&lt;div id='twitter_stream'&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/twitter.png' style='position:absolute;right:5px;top:-2px;' /&gt;&lt;p id="stream_term"&gt;Search jQuery&lt;/p&gt;&lt;div id='twitter_results'&gt;&lt;/div&gt;&lt;/div&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;You can download the code for the above widget from &lt;a href='http://sites.google.com/site/myphpetc/Home/tstream.zip'&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Let's begin by looking at the HTML:&lt;br /&gt;&lt;pre class="pre_code"&gt;&amp;lt;div id=&amp;#039;twitter_stream&amp;#039;&amp;gt;&lt;br /&gt;     &amp;lt;img src=&amp;#039;./images/twitter.png&amp;#039; style=&amp;#039;position:absolute;right:5px;top:-2px;&amp;#039; /&amp;gt;&lt;br /&gt;     &amp;lt;p id=&amp;quot;stream_term&amp;quot;&amp;gt;Search jQuery&amp;lt;/p&amp;gt;&lt;br /&gt;     &amp;lt;div id=&amp;#039;twitter_results&amp;#039;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This is very simple and consists of the widget div, the Twitter bird icon, the heading and then the results pane.&lt;br /&gt;&lt;br /&gt;The javascript is essentially one main function, load_tweets():&lt;br /&gt;&lt;pre class="pre_code"&gt;function load_tweets() {&lt;br /&gt;     var last_ID = $(&amp;quot;.tweet_result:first&amp;quot;).attr(&amp;quot;ID&amp;quot;);&lt;br /&gt;     &lt;br /&gt;     if (last_ID) {&lt;br /&gt;          last_ID = last_ID.replace(&amp;quot;tweet&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;          var url = &amp;quot;http://search.twitter.com/search.json?q=jQuery&amp;amp;since_id=&amp;quot; + last_ID + &amp;quot;&amp;amp;callback=?&amp;quot;;&lt;br /&gt;     } else {&lt;br /&gt;          var url = &amp;quot;http://search.twitter.com/search.json?q=jQuery&amp;amp;rpp=5&amp;amp;callback=?&amp;quot;; &lt;br /&gt;     }&lt;br /&gt;     &lt;br /&gt;     $.getJSON(url, function(json) { &lt;br /&gt;          var results = &amp;#039;&amp;#039;;&lt;br /&gt;          $(json.results).each(function() {&lt;br /&gt;               if (this.id == undefined) return;&lt;br /&gt;               results += &amp;quot;&amp;lt;p class=&amp;#039;tweet_result&amp;#039; id=&amp;#039;tweet&amp;quot; + this.id + &amp;quot;&amp;#039;&amp;gt;&amp;lt;a href=&amp;#039;http://twitter.com/&amp;quot; + this.from_user + &amp;quot;&amp;#039; class=&amp;#039;tweet_user&amp;#039;&amp;gt;&amp;lt;img width=&amp;#039;16&amp;#039; height=&amp;#039;16&amp;#039; alt=&amp;#039;&amp;quot; + this.from_user + &amp;quot; on Twitter&amp;#039; src=&amp;#039;&amp;quot; + this.profile_image_url + &amp;quot;&amp;#039; /&amp;gt;&amp;lt;/a&amp;gt;&amp;quot; + linkify(this.text) + &amp;quot;&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;          });&lt;br /&gt;          if (last_ID) {&lt;br /&gt;               $(&amp;quot;#twitter_results&amp;quot;).prepend(results);&lt;br /&gt;          } else {&lt;br /&gt;               $(&amp;quot;#twitter_results&amp;quot;).append(results);&lt;br /&gt;          }&lt;br /&gt;     });&lt;br /&gt;&lt;br /&gt;     $(&amp;quot;.tweet_result:gt(20)&amp;quot;).remove();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;load_tweets() checks to see if there are already any tweets loaded by retrieving the ID of the first tweet (this will be the ID of the most recent tweet form the results). &lt;br /&gt;&lt;br /&gt;If there were already tweets then it sets the URL to retrieve all the results since that ID by passing in the &amp;since_id= variable.&lt;br /&gt;&lt;br /&gt;If there wasn't any tweets loaded then it just grabs the 5 most recent results.&lt;br /&gt;&lt;br /&gt;The results are then loaded in via JSON using the jQuery &lt;a href='http://docs.jquery.com/Ajax/jQuery.getJSON#urldatacallback'&gt;$.getJSON&lt;/a&gt; call. It loops over the results and adds them to the results string and then prepends the results string to the #twitter_results div.&lt;br /&gt;&lt;br /&gt;The next bit of magic is the &lt;a href='http://davidwalsh.name/linkify-twitter-feed'&gt;linkify&lt;/a&gt; function. This function builds us some nice links depending on the type of link provided:&lt;br /&gt;&lt;br /&gt;&lt;pre class="pre_code"&gt;function linkify(text) {&lt;br /&gt;    // modified from TwitterGitter by David Walsh (davidwalsh.name)&lt;br /&gt;    // courtesy of Jeremy Parrish (rrish.org)&lt;br /&gt;    return text.replace(/(https?://[w-:;?&amp;amp;=+.%#/]+)/gi, &amp;#039;&amp;lt;a href=&amp;quot;$1&amp;quot;&amp;gt;$1&amp;lt;/a&amp;gt;&amp;#039;)&lt;br /&gt;               .replace(/(^|W)@(w+)/g, &amp;#039;$1&amp;lt;a href=&amp;quot;http://twitter.com/$2&amp;quot;&amp;gt;@$2&amp;lt;/a&amp;gt;&amp;#039;)&lt;br /&gt;               .replace(/(^|W)#(w+)/g, &amp;#039;$1#&amp;lt;a href=&amp;quot;http://search.twitter.com/search?q=%23$2&amp;quot;&amp;gt;$2&amp;lt;/a&amp;gt;&amp;#039;);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The rest is just a little bit of CSS styling and the final touch is in the document ready function to get our results to stream we use the &lt;a href='http://www.w3schools.com/jsref/met_win_setinterval.asp'&gt;setInterval&lt;/a&gt; function:&lt;br /&gt;&lt;pre class='pre_code'&gt;$(&amp;quot;document&amp;quot;).ready(function() {&lt;br /&gt;     load_tweets();&lt;br /&gt;     setInterval(load_tweets, 20000);&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Hope you like it!&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-7459984716131075376?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/7459984716131075376/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=7459984716131075376' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/7459984716131075376'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/7459984716131075376'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/11/jquery-twitter-streaming-widget-in-30.html' title='jQuery Twitter streaming widget in 30 lines'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-4359367959723088406</id><published>2009-11-17T18:45:00.002+11:00</published><updated>2009-11-26T21:44:14.197+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='context'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorials'/><category scheme='http://www.blogger.com/atom/ns#' term='menu'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>jQuery multi-tiered drop-up menu</title><content type='html'>This post provides a working example of the drop-up version of the jQuery &lt;a href='http://plugins.jquery.com/project/superfish'&gt;Superfish drop-down menu&lt;/a&gt; plugin. A cross browser multi-tiered menu plugin that has many great features; it looks great and works great and was designed by fellow Aussie Joel Birch.&lt;br /&gt;&lt;br /&gt;Drop-up functionality works similar to drop-down functionality except that it works from the bottom up and menu options are placed at the bottom of the screen or element rather than at the top of the page or element.&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/superup.jpg?attredirects=0' /&gt;&lt;br /&gt;&lt;br /&gt;You can view an example of the drop-up functionality &lt;a href='http://comp345.awardspace.com/superfish/superfish.html'&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;You can download the working code &lt;a href='http://sites.google.com/site/myphpetc/Home/super.zip'&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;You can visit the original &lt;a href='http://users.tpg.com.au/j_birch/plugins/superfish/#getting-started'&gt;Superfish site&lt;/a&gt;. Where you can view working examples and documentation of the original and also download the original code.&lt;br /&gt;&lt;br /&gt;Superfish easily takes an multi-tiered unordered list and using CSS and jQuery generates a nice looking menu that can easily be styled to your liking.&lt;br /&gt;&lt;br /&gt;The solution was &lt;a href='http://groups.google.com/group/jquery-en/msg/0e7421555ce09d23?pli=1'&gt;discovered&lt;/a&gt; when I was looking for similar functionality for myself. I haven't found a similar solution yet that looks as good and works across all the major browsers.&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-4359367959723088406?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/4359367959723088406/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=4359367959723088406' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/4359367959723088406'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/4359367959723088406'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/11/jquery-multi-tiered-drop-up-menu.html' title='jQuery multi-tiered drop-up menu'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-4704184655256039842</id><published>2009-11-16T20:48:00.005+11:00</published><updated>2009-11-26T21:44:34.439+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='stylesheet'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorials'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>jQuery CSS stylesheet switcher</title><content type='html'>This tutorial shows you how to create a CSS style sheet switcher using jQuery for your site. This style sheet switcher has conventient forward and back links for you to cycle through available sheets and incorporates the cookie plugin so that user preferences can be retained for later visits.&lt;br /&gt;&lt;br /&gt;The switcher widget is built by looking at each stylesheet that has the .switch class and uses the link tag's CSS color value to decide the color of the swatch in the widget. Clicking on a particular swatch will disable other stylesheets with the .switch class and activate the selected style sheet allowing a user to choose their style preference. Users can also use the left and right arrows which will either cycle forwards or backwards through available stylesheets.&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;To view a demonstration of this in action go &lt;a href="http://comp345.awardspace.com/sheetswitch/index.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;To download the files for this tutorial click &lt;a href="http://sites.google.com/site/myphpetc/Home/styleswitch.zip"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/switch_screen.jpg' style='border:1px solid #777;'/&gt;&lt;br /&gt;&lt;br /&gt;To begin with we have our html file, it is made up of 3 main parts:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Our stylesheets each with a color style, and with the class switch (all other stylesheets will be ignored)&lt;/li&gt;&lt;li&gt;Our sheetswitch div that will hold the color swatches for users to select their stylesheet&lt;/li&gt;&lt;li&gt;The rest of the html body to be styled&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;To begin with our stylesheets for us to switch between will look like the following:&lt;br /&gt;&lt;pre class='pre_code'&gt;&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; class=&amp;quot;switch&amp;quot; style=&amp;quot;color:#23B2D2;&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;./css/styles_blue.css&amp;quot; /&amp;gt;&lt;br /&gt;&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; class=&amp;quot;switch&amp;quot; style=&amp;quot;color:#8BE487;&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;./css/styles_green.css&amp;quot; /&amp;gt;&lt;br /&gt;&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; class=&amp;quot;switch&amp;quot; style=&amp;quot;color:#F24633;&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;./css/styles_red.css&amp;quot; /&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Notice they all have the .switch class and a color style attribute. Our jQuery code will loop over these stylesheets when the page loads. It will get the color style from each link element and use it to build the color swatches that appear in the sheetswitch div.&lt;br /&gt;&lt;br /&gt;The sheetswitch div is made up of color swatches; colored squares that users can click on to change the stylesheet. It also has a left and right arrow for users to loop forwards or backwards through available stylesheets. The style for the sheetswich div sits in its own stylesheet styles.css, because this stylesheet does not have the .switch class it will be ignored by the javascript during switching.&lt;br /&gt;&lt;br /&gt;Let's look at the javascript:&lt;br /&gt;&lt;br /&gt;To begin with we loop over the .switch stylesheets and build up the colors array as follows:&lt;br /&gt;&lt;pre class='pre_code'&gt;var colors = new Array;&lt;br /&gt;&lt;br /&gt;// Disable all .switch stylesheets and build array of colours&lt;br /&gt;$(".switch[rel='stylesheet']").each(function() {&lt;br /&gt;    $(this).attr("disabled", "true");&lt;br /&gt;    colors.push($(this).css("color"));&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We then loop over the colors array to build the swatches and append them to the #sheetswitch. This is followed by the right looping arrow:&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;$(colors).each(function(index, el) {&lt;br /&gt;     $("#sheetswitch").append("&lt;a class='swatch' style='background-color:" + el + &lt;br /&gt;     ";'&gt;&lt;/a&gt;");&lt;br /&gt;});&lt;br /&gt;&lt;br /&gt;$("#sheetswitch").append("&lt;a href='#' class='sheetswitch_next'&gt;&lt;img src='./images&lt;br /&gt;/1rightarrow.png' /&gt;&lt;/a&gt;");&lt;br /&gt;&lt;/pre&gt;Next comes the click function for each of the swatches. The swatches are added in the same order as the sheets themselves so we can use the index of the selected element to set the active stylesheet. Once we get the index we disable all stylesheets, enable the selected index and then we store the value in our cookie:&lt;br /&gt;&lt;pre class='pre_code'&gt;$(".swatch").click(function() {&lt;br /&gt;   $(".swatch").removeClass("swatch_hi");&lt;br /&gt;   $(this).addClass("swatch_hi");&lt;br /&gt;   var index = $(".swatch").index(this);&lt;br /&gt;   $(".switch[rel='stylesheet']").attr("disabled", "true");&lt;br /&gt;   $(".switch[rel='stylesheet']").eq(index).attr("disabled", "");&lt;br /&gt;   $.cookie('mysite_sheetswitch_idx', index, {expires: 7});&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Our next and previous links that correspond to the forward and back arrows are a little more complex. They find the index of the currently selected sheet. They also get the number of sheets using the size() function. Then either add or deduct 1 fom the index to select either the previous or next stylesheet. The length of sheets is used to determine whether we need to loop (either to the last or first element depending on which way we are going):&lt;br /&gt;&lt;pre class='pre_code'&gt;var selected = $(".switch[rel='stylesheet']").filter(function () { return &lt;br /&gt;$(this).attr("disabled") == false; });&lt;br /&gt;var current_idx = $(".switch[rel='stylesheet']").index($(selected));&lt;br /&gt;var length = $(".switch[rel='stylesheet']").size();&lt;br /&gt;&lt;br /&gt;if (current_idx &gt;= 0) {&lt;br /&gt; var next = current_idx + 1;&lt;br /&gt; if (next &gt; (length - 1)) next = 0;&lt;br /&gt; &lt;br /&gt; $(".switch[rel='stylesheet']").attr("disabled", "true");&lt;br /&gt; $(".switch[rel='stylesheet']").eq(next).attr("disabled", "");&lt;br /&gt; &lt;br /&gt; $(".swatch").removeClass("swatch_hi");&lt;br /&gt; $(".swatch").eq(next).addClass("swatch_hi");&lt;br /&gt; &lt;br /&gt; $.cookie('mysite_sheetswitch_idx', next, {expires: 7});&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The last step is for when the page loads, we check to see if a cookie is already set. If so we take the index value and set the stylesheet accordingly.&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;if ($.cookie('mysite_sheetswitch_idx')) {&lt;br /&gt;   var idx = $.cookie('mysite_sheetswitch_idx');&lt;br /&gt;   $(".switch[rel='stylesheet']").eq(idx).attr("disabled", "");&lt;br /&gt;   $(".swatch").eq(idx).addClass("swatch_hi");&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Currently no stylesheet is set by default, this could be implemented easily by yourself. It would also be quite easy to add a random, or disable all links.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-4704184655256039842?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/4704184655256039842/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=4704184655256039842' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/4704184655256039842'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/4704184655256039842'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/11/jquery-css-stylesheet-switcher.html' title='jQuery CSS stylesheet switcher'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-6720801829560124635</id><published>2009-11-14T22:05:00.006+11:00</published><updated>2009-11-26T21:45:02.132+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='opinion'/><category scheme='http://www.blogger.com/atom/ns#' term='news'/><category scheme='http://www.blogger.com/atom/ns#' term='chrome'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='google docs'/><category scheme='http://www.blogger.com/atom/ns#' term='articles'/><title type='text'>Would enterprise adopt Google Docs?</title><content type='html'>Google have announced in a &lt;a href="http://www.zdnetasia.com/news/software/0,39044164,62059318,00.htm?tag=mncol;txt"&gt;recent interview&lt;/a&gt; with ZDNet Asia that within a years time that Google Docs should have enough functionality that most enterprises could "get rid of [Microsoft] Office if they chose to".&lt;br /&gt;&lt;br /&gt;As I am currently working for a large company this is a bold statement to be making. From this side of the fence there are few things that would need to be considered before a switch like that could be made:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Is the feature set comparable?&lt;/li&gt;&lt;li&gt;Is the security comparable?&lt;/li&gt;&lt;li&gt;Is the application compatible with my equipment?&lt;/li&gt;&lt;/ul&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;Is the feature set comparable? In the article it goes on to mention that MS Office is "an overkill tool for most people" and that "Microsoft's offering will become a specialized offering for office workers who need its additional functions". I would argue from this respect, if Google are still offering a cut-down version of Word that Word will still continue to stay on top in the enterprise. I also don't see the difference between what Google are referring to as "most enterprises" and "office workers"?&lt;br /&gt;&lt;br /&gt;Is the security comparable? Most large enterprises have highly secured documents that need to be edited on a daily basis; why would an enterprise support two applications internally? Big business requires that highly sensitive files are encrypted before being sent over the internet. I'm not sure what Google offers on this front, but from business perspective the trust is not there.&lt;br /&gt;&lt;br /&gt;Is the application compatible with my equipment? For a business to adopt Google Docs they would need to be sure that Docs was compatible with their other applications (printers, faxing software, cut and paste to other applications) etc. This may be the smallest hurdle but is something to be considered.&lt;br /&gt;&lt;br /&gt;Looking at it form here, for a multinational to start using Google Docs they would decide this on a company wide basis. That means the decision to use Google Docs is a decision to support Google Docs worldwide on every machine in every country. I would suggest that for any large company the first three points would need to be satisfied before the cost/benefit could be looked at.&lt;br /&gt;&lt;br /&gt;Besides enterprise edition, for people like my parents and for my own personal use, I look forward to a new improved Google Docs with excitement. My parents collect a lot of garbage on their machine and it would be great to use a cut-down operating system in combination with Google Docs. As it stands, it's hard to argue for them to move away from Office as &lt;a href='http://www.cracked.com/blog/the-5-lamest-forwarded-emails-and-why-your-mom-loves-them/'&gt;the things that my Mum gets emailed&lt;/a&gt; are usually buried in powerpoint slides, excel sheets and word docs. You don't know how much fun it is when your mother calls every time there is a file with an extension that she can't open.&lt;br /&gt;&lt;br /&gt;&lt;a href='http://www.techcrunch.com'&gt;Tech Crunch&lt;/a&gt; today also &lt;a href='http://www.techcrunch.com/2009/11/13/google-chrome-os-to-launch-within-a-week/'&gt;speculated&lt;/a&gt; through a "reliable source" that the Google Chrome OS will be launched within a week. Not sure what to expect from this one as it has been previously suggested that the initial support will be targeted towards netbooks.&lt;br /&gt;&lt;br /&gt;Disclaimer: Views expressed here about Google Docs are my personal opinion and have nothing to do with my employer.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-6720801829560124635?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/6720801829560124635/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=6720801829560124635' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/6720801829560124635'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/6720801829560124635'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/11/big-announcements-for-google-docs-and.html' title='Would enterprise adopt Google Docs?'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-2246783564583306242</id><published>2009-11-13T17:25:00.005+11:00</published><updated>2009-11-26T21:46:08.917+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='news'/><category scheme='http://www.blogger.com/atom/ns#' term='1.4'/><category scheme='http://www.blogger.com/atom/ns#' term='podcast'/><category scheme='http://www.blogger.com/atom/ns#' term='articles'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>New jQuery podcasts</title><content type='html'>It's always nice to get surprises and yesterday I got three in the form of three jQuery podcasts. I wasn't even aware that they were coming and yesterday by sheer luck I came across one after the other. The three podcasts I'm referring to are &lt;a href='http://paulirish.com/2009/introducing-yayquery-a-jquery-podcast/'&gt;yayQuery&lt;/a&gt;, the &lt;a href='http://twitter.com/jquerypodcast'&gt;official jQuery podcast&lt;/a&gt; and &lt;a href='http://jqueryfordesigners.com/'&gt;Remy Sharp's jQuery&lt;/a&gt; (click on the iTunes podcast link) podcasts.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;I haven't had a chance to listen to Remy Sharp's podcasts yet, but the two that I did hear were a special treat. Remy's has several podcasts already up his sleeve, but the other two only just started this week and are well worth the listen.&lt;br /&gt;&lt;br /&gt;&lt;a href='http://paulirish.com/2009/introducing-yayquery-a-jquery-podcast/'&gt;yayQuery&lt;/a&gt; is an informal discussion with four top class jQuery developers who chat about some of their own ideas and what they see going on around using jQuery. These guys spend a lot of time in the IRC channel and are quite in touch with those people who use jQuery the most. The end of the podcast has a nice surprise, well worth watching.&lt;br /&gt;&lt;br /&gt;&lt;img style='border:1px solid #CCC;' src='http://sites.google.com/site/myphpetc/Home/yay.jpg' alt='Picture of the yayQuery podcast'/&gt;&lt;br /&gt;&lt;label&gt;Picture of the yayQuery podcast&lt;/label&gt;&lt;br /&gt;&lt;br /&gt;The &lt;a href='http://twitter.com/jquerypodcast'&gt;official jQuery podcast&lt;/a&gt; will have a regular guest each week, this week was John Resig who talked further about jQuery in mobile phones, the jQuery project and more about the upcoming 1.4 release. At the end of the show the guys went over some of their favourite jQuery plug-ins and add-ons that were released in the past couple of weeks, so work hard and maybe you can get a mention.&lt;br /&gt;&lt;br /&gt;Next week (18th of Nov) they will have &lt;a href='http://rdworth.org/blog/'&gt;Richard D Worth&lt;/a&gt; from the jQuery UI development team. If you have a chance you can catch the live stream from &lt;a href='http://www.ustream.tv/channel/the-official-jquery-podcast-live'&gt;here&lt;/a&gt;. Alternatively you will need to wait till U.S. Friday morning when they put the edited cast on line. You can subscrive via feedburner &lt;a href='http://feeds.feedburner.com/jQueryPodcast'&gt;here&lt;/a&gt; or search on iTunes to subscribe via iTunes.&lt;br /&gt;&lt;br /&gt;If you can get the chance it may be preferable to listen live to the jQuery podcast as you can also participate in the online chat. USTREAM allows you to chat and use twitter while listening to the cast, its a good chance to ask a question. At the end of this weeks show John went over some of the questions asked in the chatroom at the end of the podcast so it's worthwhile sticking around.&lt;br /&gt;&lt;br /&gt;The best part of both podcasts was getting an insight into some of the parts of jQuery that I haven't used in detail and hearing from the pros some best practices. yayQuery and the official podcast are different enough to be worthwhile to have and listen to both, so take time to check them out and you might prefer one over the other or both. &lt;br /&gt;&lt;br /&gt;Enjoy!&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-2246783564583306242?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/2246783564583306242/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=2246783564583306242' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/2246783564583306242'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/2246783564583306242'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/11/new-jquery-podcasts.html' title='New jQuery podcasts'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-8523735511723516593</id><published>2009-11-13T13:21:00.001+11:00</published><updated>2009-11-13T13:38:32.154+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='submit'/><category scheme='http://www.blogger.com/atom/ns#' term='AJAX'/><category scheme='http://www.blogger.com/atom/ns#' term='form'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>jQuery - Submitting a form with an AJAX call to determine return value</title><content type='html'>A quick tip for submitting a form that has an AJAX call and submitting the form from inside the AJAX success function.&lt;br /&gt;&lt;br /&gt;The issue happens when a function is bound to the submit event on a form and you want to validate details of the form via an AJAX call. This will look something like the following:&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;&lt;pre&gt;$("#my_form").submit(function() {&lt;br /&gt;&lt;br /&gt; var some_data = ....whatever...&lt;br /&gt;&lt;br /&gt; var url = 'call_to_some_script_for_validation';&lt;br /&gt; &lt;br /&gt; $.get(url, {data: somedata}, function(response) {&lt;br /&gt;  if (response == 'success') {&lt;br /&gt;   return true;&lt;br /&gt;  } else {&lt;br /&gt;   // Display error msg, whatever...&lt;br /&gt;   return false;&lt;br /&gt;  }&lt;br /&gt; });&lt;br /&gt;&lt;br /&gt; return ???&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The issue here is in the line return ???. What should you place here? If we place return true here 99% of the time it is not going to wait for your ajax call to complete so it will always return true. If we place false here how are we going to get the AJAX function to return true.&lt;br /&gt;&lt;br /&gt;To start with we want our AJAX function to determine whether or not the submit was a success. Because the stuff outside the AJAX call is going to be processed faster you should include anything that could cause the function to return false outside of the AJAX call to appear first and have the AJAX function have the final say. To do this you should have our function return false and let the AJAX function decide whether or not to reverse this, see below:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;$("#my_form").submit(function() {&lt;br /&gt;&lt;br /&gt; var some_data = ....whatever...&lt;br /&gt; &lt;br /&gt; // Any other processing that may cause us to return false early&lt;br /&gt;&lt;br /&gt; var url = 'call_to_some_script_for_validation';&lt;br /&gt; &lt;br /&gt; $.get(url, {data: somedata}, function(response) {&lt;br /&gt;  if (response == 'success') {&lt;br /&gt;   return true;&lt;br /&gt;  } else {&lt;br /&gt;   // Display error msg, whatever...&lt;br /&gt;   return false;&lt;br /&gt;  }&lt;br /&gt; });&lt;br /&gt;&lt;br /&gt; return false;&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now this is not the finished product. The issue with the return true inside the AJAX function is that it only returns true to the AJAX function itself and will not trigger the submit of the form. Your first thought may be to call $("#my_form").submit(); but this will only trigger the submit function action and end in an infinite loop. So how to fix this?&lt;br /&gt;&lt;br /&gt;The easiest way to get around this issue once we have success is to unbind the submit function from your form before submitting, as follows:&lt;br /&gt;&lt;pre&gt;$("#my_form").unbind("submit");&lt;br /&gt; $("#my_form").submit();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So in the end you should have something that looks like this:&lt;br /&gt;&lt;pre&gt;$("#my_form").submit(function() {&lt;br /&gt;&lt;br /&gt; var some_data = ....whatever...&lt;br /&gt; &lt;br /&gt; // Any other processing that may cause us to return false early&lt;br /&gt;&lt;br /&gt; var url = 'call_to_some_script_for_validation';&lt;br /&gt; &lt;br /&gt; $.get(url, {data: somedata}, function(response) {&lt;br /&gt;  if (response == 'success') {&lt;br /&gt;   $("#my_form").unbind("submit");&lt;br /&gt;   $("#my_form").submit();  &lt;br /&gt;   return true;&lt;br /&gt;  } else {&lt;br /&gt;   // Display error msg, whatever...&lt;br /&gt;   return false;&lt;br /&gt;  }&lt;br /&gt; });&lt;br /&gt;&lt;br /&gt; return false;&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-8523735511723516593?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/8523735511723516593/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=8523735511723516593' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/8523735511723516593'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/8523735511723516593'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/11/jquery-submitting-form-with-ajax-call.html' title='jQuery - Submitting a form with an AJAX call to determine return value'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-6282224587616977597</id><published>2009-11-12T19:14:00.002+11:00</published><updated>2009-11-12T20:22:41.965+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='data'/><category scheme='http://www.blogger.com/atom/ns#' term='art'/><category scheme='http://www.blogger.com/atom/ns#' term='information'/><category scheme='http://www.blogger.com/atom/ns#' term='table'/><title type='text'>Examples of beautiful information</title><content type='html'>This post looks at several creative ways of presenting information. Each example, while presenting a large amount of information, combines together to make a work of art. Although it may not seem practical to combine these forms of presentation in your own pages and applications it is a good idea to think of information as more than just a collection of data.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;As a software developer you may not spend much time thinking about the presentation of information. Much of the focus of making a site look beautiful is spent on the overall look and feel of a site, whereas a large portion of the information presented on sites and in applications is stuck in tables. Again, if you are a software developer, you may see a large number of forms and database result sets every day and we present most of this information in a flat grid.&lt;br /&gt;&lt;br /&gt;The main point that can be taken from these examples is that data can be presented in a way that provides further meaning. The white space, the grouping of related information, the relative size and coloring all take on different meanings and enhance the raw data. By sticking data into a grid you remove a large portion of its context aside from the table headings and we are stuck of coming up with ways of how to highlight a particular row, minimising the context and the meaning down to its smallest possible level.&lt;br /&gt;&lt;br /&gt;The speed at which a user can interpret information on a page is important, especially for applications used in daily work life. The longer your staff are spending unnecessary time on page the more money it is costing your business. Tools are a simple primitive thing and if your work application is overly complicated it is not functioning as a tool.&lt;br /&gt;&lt;br /&gt;If you develop a site, think about the role the data plays in usability. Or, if you are selling something on a site, if you place your pricing in a grid what does this say about the different values on offer? Are all values the same even though one costs $20 per month and the other $240?&lt;br /&gt;&lt;br /&gt;Take some time to look at the examples of well presented information and think about why they work and how they provide extra meaning to the data they are representing. Rather than taking away an idea of how you could present your data in a practical way, think about what techniques have been used to enhance the information provided; white space, the grouping of related information, the relative size and coloring etc.&lt;br /&gt;&lt;br /&gt;The first example &lt;a href='http://www.gapminder.org/'&gt;Gapminder&lt;/a&gt; presents comparative statistical information for countries around the world. You can view &lt;a href='http://bit.ly/jHIhF'&gt;oil production vs. consumption&lt;/a&gt; or &lt;a href='http://bit.ly/3O7y8C'&gt;life expectancy vs. income per person&lt;/a&gt;. These statistics can be compared per person and per country.&lt;br /&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/world.jpg' /&gt;&lt;br /&gt;&lt;br /&gt;The next example is a collection of similar sites. &lt;a href='http://www.visualcomplexity.com/vc/'&gt;visual complexity&lt;/a&gt; provides a range of sites displaying complex visual information. It provides a gallery of information artworks. One of my favourites is the results of the &lt;a href='http://blob.creanode.com/blob/eu2009/'&gt;2009 eurovision song contest&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/euro.jpg' /&gt;&lt;br /&gt;&lt;br /&gt;The last site is the &lt;a href='http://processing.org/exhibition/'&gt;Processing exhibition site&lt;/a&gt;. &lt;a href='http://en.wikipedia.org/wiki/Processing_%28programming_language%29'&gt;Processing&lt;/a&gt; is a programming language designed specifically for visual display. &lt;a href='http://ejohn.org/'&gt;John Resig&lt;/a&gt; of &lt;a href='jquery.com'&gt;jQuery&lt;/a&gt; fame also wrote a &lt;a href='http://processingjs.org/'&gt;port of Processing&lt;/a&gt; to javascript. The exhibition page showcases many fine examples of displaying visual information using Processing. My favourite being the &lt;a href='http://everyware.kr/portfolio/contents/09_oasis/'&gt;Oasis&lt;/a&gt; project, a display of spatially aware living creatures that swim around under a display of black sand waiting to be discovered in this art piece.&lt;br /&gt;&lt;br /&gt;&lt;object width="400" height="225"&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=1631013&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1" /&gt;&lt;embed src="http://vimeo.com/moogaloop.swf?clip_id=1631013&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="225"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;p&gt;&lt;a href="http://vimeo.com/1631013"&gt;OASIS&lt;/a&gt; from &lt;a href="http://vimeo.com/user384268"&gt;yunsil heo&lt;/a&gt; on &lt;a href="http://vimeo.com"&gt;Vimeo&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;Consider next time before placing your information in a box, can you enhance the information with a variety of methods. Should your users search the grid for their one row or be guided by a display of well presented enhanced information.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-6282224587616977597?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/6282224587616977597/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=6282224587616977597' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/6282224587616977597'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/6282224587616977597'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/11/examples-of-beautiful-information.html' title='Examples of beautiful information'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-2635514076462163054</id><published>2009-11-11T17:21:00.000+11:00</published><updated>2009-11-11T17:21:22.015+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='conference'/><category scheme='http://www.blogger.com/atom/ns#' term='1.4'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>jQuery 2009 Conference Slides - jQuery 1.4 release</title><content type='html'>This post covers two presentations that &lt;a href='http://ejohn.org/'&gt;John Resig&lt;/a&gt; made at the 2009 jQuery Conference that was held in September. These presentations provide a great insight into the current state of jQuery and what we can expect in the upcoming 1.3.3/1.4 release.&lt;br /&gt;&lt;br /&gt;Below I have embedded the two slideshows from the talks John gave. I'm still not certain if there is going to be a 1.3.3 and a 1.4 release. Ealier this year it looked like we were going to get a 1.3.3 release, but it &lt;a href='http://ejohn.org/blog/talks-at-the-2009-jquery-conference/'&gt;has been mentioned&lt;/a&gt; that 1.3.3 is likely to be called 1.4 and there will be no 1.3.3 release. Quote: "We're much closer to shipping 1.3.3 now (which is likely to become 1.4, with all the new features that're being added)".&lt;br /&gt;&lt;br /&gt;There are rumours that 1.4 will ship in January, but we'll have to wait and see. I recommend you look at &lt;a href='http://www.myphpetc.com/2009/10/preview-of-whats-new-in-jquery-14.html'&gt;my other post&lt;/a&gt; which goes in detail over some of the features that we are likely to see in 1.4. Of note is the dramatic increase in speed with the new Sizzle selector engine and an expected three time faster increase in speed. Also moving towards support for jQuery in mobile applications.&lt;br /&gt;&lt;br /&gt;The first talk covers recent changes to jQuery and the upcoming release.&lt;br /&gt;&lt;br /&gt;&lt;div style="width:425px;text-align:left" id="__ss_2006206"&gt;&lt;object style="margin:0px" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=jquery-internals-09-090916091927-phpapp02&amp;stripped_title=recent-changes-to-jquerys-internals" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=jquery-internals-09-090916091927-phpapp02&amp;stripped_title=recent-changes-to-jquerys-internals" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The second talk covers the state of jQuery and more of what is happening around the software (Google groups alternative, growth, moving to Git) etc. It is well worth the read to find out about the effort behind jQuery and the direction of the jQuery project.&lt;br /&gt;&lt;br /&gt;&lt;div style="width:425px;text-align:left" id="__ss_2006198"&gt;&lt;object style="margin:0px" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=state-of-jquery-09-090916091836-phpapp02&amp;stripped_title=state-of-jquery-09" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=state-of-jquery-09-090916091836-phpapp02&amp;stripped_title=state-of-jquery-09" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;&lt;br /&gt;For those of you who can't wait, you can get a copy of jQuery 1.4pre from the &lt;a href='http://code.jquery.com/jquery-nightly.js'&gt;jQuery nightly build&lt;/a&gt;. As this hasn't been officially released/documented yet, I'm not sure what is already implenting, working or stable so you will need to have a look around for yourself.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-2635514076462163054?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/2635514076462163054/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=2635514076462163054' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/2635514076462163054'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/2635514076462163054'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/11/jquery-2009-conference-slides-jquery-14.html' title='jQuery 2009 Conference Slides - jQuery 1.4 release'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-2464351057921489630</id><published>2009-11-10T17:52:00.002+11:00</published><updated>2009-11-10T17:53:49.094+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='image'/><category scheme='http://www.blogger.com/atom/ns#' term='selectable'/><category scheme='http://www.blogger.com/atom/ns#' term='font'/><category scheme='http://www.blogger.com/atom/ns#' term='replacement'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>Selectable font image replacement</title><content type='html'>This tutorial provides a technique on how to implement cross-browser selectable font image replacement.&lt;br /&gt;&lt;br /&gt;You can download the files for this example &lt;a href='http://sites.google.com/site/myphpetc/Home/fir.zip'&gt;here&lt;/a&gt;. Note: the files do not contain the fonts. You can follow the links at the bottom of this post to obtain free fonts. You can view a demo of the functionality &lt;a href='http://comp345.awardspace.com/fir/test.html'&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;After so many years of being stuck with a small number of web fonts it's a shame that there isn't a standards compliant solution to the problem. What do we want? An accessible (as in users don't need to have anything installed and turn everything off and the page is still readable), fast, usable (text should be selectable, single, double and triple click should work as expected as well as copy/paste) and minimal (easy set up, limited number of DOM elements) solution to the font issue.&lt;br /&gt;&lt;br /&gt;Designers want to use any font available, developers want to be able to implement it without doing extensive hacks and tricks and users want to enjoy the beauty while having the styled text function as standard text.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;Currently there are several ways to go about trying to achieve the above, but I would argue that none of them meets the criteria above. They either rely on flash, don't work across all browsers, the text isn't selectable in most solutions or they require a hell of a load of mark up. The main issue is the lack of a standard that is already implemented across all of the major browsers. We want a solution that will work in 90 plus percent of all of the browsers currently in use.&lt;br /&gt;&lt;br /&gt;This solution requires a limited amount of mark up, works in all of the current major browsers (IE6/7/8, Chrome, Firefox, Safari 4 Mac and Safari 4 Windows), works in text browsers (tested in WebbIE3) and can be used with any TTF and OTF fonts. This works in an unobtrusive way to allow users to select and copy text and single, double and triple click functionality works in all browsers.&lt;br /&gt;&lt;br /&gt;My solution is really a collection of parts of other peoples solutions glued together with jQuery. I would like to take credit for it and give it a fancy name, but I think the solution has been around for a while in parts, but not put together in a clever way. At the end of this tutorial I will give links to some of the sources who deserve credit for their work.&lt;br /&gt;&lt;br /&gt;The answer is in three parts: php and GD is used to render the custom font, a little bit of CSS hackiness is used to provide the text selection and jQuery is the glue which holds it all together by determining the text and font to be displayed and doing a little bit of browser checking to see if opacity is supported to get IE to work.&lt;br /&gt;&lt;br /&gt;So how is it done? We start with an element, say a h2 and add a pair of span tags inside with some text as follows. Each of these pairs of elements will have a special class for later styling; I have called mine font_substitue and inner.&lt;br /&gt;&lt;br /&gt;&amp;lt;h2 class=&amp;#039;font_substitute&amp;#039;&amp;gt;&lt;br /&gt;&amp;lt;span class=&amp;#039;inner&amp;#039;&amp;gt;This is my fancy text&amp;lt;/span&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;&lt;br /&gt;Furthermore you can provide a second class to the h2 to determine which font to display, e.g. Anidka&lt;br /&gt;&lt;br /&gt;&amp;lt;h2 class=&amp;#039;andika font_substitute&amp;#039;&amp;gt;&lt;br /&gt;&amp;lt;span class=&amp;#039;inner&amp;#039;&amp;gt;This is my fancy text&amp;lt;/span&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;&lt;br /&gt;Using jQuery we loop over each of the $("h2 .andika") classes and then retrieve the text from the span. Using the combination of the selector and the text we use jQuery to insert a background image on the h2 element by setting the src of the image to point to our php script. The php script serves a png image with our rendered font. CSS is used to hide our text and provide a solution to the selection problem. This is done using filters in IE and ::selection rules for Opera, Firefox and Chrome. The last bit and the most tricky is getting the line-height, font size, wrapping and word-spacing to line up. This can take some playing around but a seasoned CSS expert shouldn't have too much difficulty in getting it done.&lt;br /&gt;&lt;br /&gt;I'm not going to go in to great deal on how the php font rendering is done, this solution has been around for several years now and the full article on how to do this can be read &lt;a href='http://www.alistapart.com/articles/dynatext/'&gt;here&lt;/a&gt;. My php script also allows custom &lt;a href='http://en.wikipedia.org/wiki/Tracking_%28typography%29'&gt;tracking&lt;/a&gt; (like kerning), word wrapping and custom line height. Also be warned that GD appears to render the images slightly differently (spacing, line height etc.) depending on which version you are using so you will need to do a bit of tweeking. I also took &lt;a href='http://www.xanthir.com/pir/'&gt;TJ Atkins&lt;/a&gt; great color matching function.&lt;br /&gt;&lt;br /&gt;This solution provides us with an accessible, fast, usable and minimal solution that works in all current browsers without the need for the user to install anything extra, designers can have their fonts and developers only need to add a minimal amount of code to get it working.&lt;br /&gt;&lt;br /&gt;Sources:&lt;br /&gt;Stewart Rosenbergers - &lt;a href='http://www.alistapart.com/articles/dynatext/'&gt;Dynamic Text Replacement&lt;/a&gt;&lt;br /&gt;TJ Atkins - &lt;a href='http://www.xanthir.com/pir/'&gt;php Image Replacement&lt;/a&gt;&lt;br /&gt;ultraniblet at gmail dot com - &lt;a href='http://php.net/manual/en/function.imagettftext.php'&gt;tracking&lt;/a&gt;&lt;br /&gt;One of many sources for free (as in please read the license first) fonts - &lt;a href='http://www.fontsquirrel.com/fonts/list/mostdownloaded'&gt;sources for fonts&lt;/a&gt;&lt;br /&gt;jQuery - &lt;a href='http://jquery.com/'&gt;jQuery&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Fonts for example:&lt;br /&gt;&lt;a href='http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&amp;item_id=andika&amp;highlight=andika'&gt;Andika&lt;/a&gt;&lt;br /&gt;&lt;a href='http://www.fontsquirrel.com/fonts/Marketing-Script'&gt;Marketing Script&lt;/a&gt;&lt;br /&gt;&lt;a href='http://www.fontsquirrel.com/fonts/saxMono'&gt;Sax Mono&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-2464351057921489630?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/2464351057921489630/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=2464351057921489630' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/2464351057921489630'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/2464351057921489630'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/11/selectable-font-image-replacement.html' title='Selectable font image replacement'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-8899126845849631414</id><published>2009-11-01T19:46:00.002+11:00</published><updated>2009-12-03T20:40:15.641+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='forms'/><category scheme='http://www.blogger.com/atom/ns#' term='form'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>Using jQuery with forms - part 3 (Selectors)</title><content type='html'>This is the third in a series of tutorials on using jQuery to manipulate forms. In this series I will be looking at parts of the jQuery API reference in detail. In this tutorial I will be looking at forms and jQuery &lt;a href='http://docs.jquery.com/Selectors'&gt;Selectors&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;&lt;h3&gt;Basics&lt;/h3&gt;&lt;br /&gt;&lt;div style='width:520px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Core/each#callback'&gt;element&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Matches all elements with the given tag name&lt;/p&gt;&lt;span style='font-family:courier;'&gt;&lt;br /&gt;&lt;pre&gt;// Can be used to select the following elements&lt;br /&gt; &lt;br /&gt;$("select")&lt;br /&gt;$("label")&lt;br /&gt;$("input")&lt;br /&gt;$("form")&lt;br /&gt;$("textarea")&lt;br /&gt;$("fieldset")&lt;br /&gt;$("legend")&lt;br /&gt;$("select")&lt;br /&gt;$("optgroup")&lt;br /&gt;$("option")&lt;br /&gt;$("button")&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;Basic Filters&lt;/h3&gt;&lt;br /&gt;&lt;div style='width:520px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Selectors/first'&gt;:first&lt;/a&gt; / &lt;a href='http://docs.jquery.com/Selectors/last'&gt;:last&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Matches the first or last of group of elements&lt;/p&gt;&lt;span style='font-family:courier;'&gt;&lt;br /&gt;&lt;pre&gt;// Selects the first button element in my form&lt;br /&gt;$("#my_form :button:first"); &lt;br /&gt;&lt;br /&gt;// Selects the last password element in my form&lt;br /&gt;$("#my_form :password:last"); &lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style='width:520px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Selectors/not#selector'&gt;:not(selector)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Filters out elements from a previous group that match the given selector&lt;/p&gt;&lt;span style='font-family:courier;'&gt;&lt;br /&gt;&lt;pre&gt;// Selects all of the input fields &lt;br /&gt;// that are not hidden&lt;br /&gt;$(":input:not([type='hidden'])")&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style='width:520px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Selectors/even'&gt;:even&lt;/a&gt; / &lt;a href='http://docs.jquery.com/Selectors/odd'&gt;:odd&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Matches all elements with an even or odd index&lt;/p&gt;&lt;span style='font-family:courier;'&gt;&lt;br /&gt;&lt;pre&gt;// Hide all the buttons with an even index&lt;br /&gt;$("#my_form :button:even").hide(); &lt;br /&gt;&lt;br /&gt;// Apply the odd class to all text input elements &lt;br /&gt;// with an odd index&lt;br /&gt;$("#my_form :text:odd").addClass("odd"); &lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style='width:520px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Selectors/eq#index'&gt;:eq(index)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Select a single element by its index&lt;/p&gt;&lt;span style='font-family:courier;'&gt;&lt;br /&gt;&lt;pre&gt;// Selects the third radio element with the name browser in &lt;br /&gt;// the form (count starts from 0) and set it to checked&lt;br /&gt;$("#my_form :radio[name='rad']:eq(2)").attr('checked', 'checked');&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style='width:520px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Selectors/lt#index'&gt;:lt(index)&lt;/a&gt; / &lt;a href='http://docs.jquery.com/Selectors/gt#index'&gt;:gt(index)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Selects all elements with an index that is either less than or greater than the one specified&lt;/p&gt;&lt;span style='font-family:courier;'&gt;&lt;br /&gt;&lt;pre&gt;// Remove all radio elements with name browser &lt;br /&gt;// that have an index less than 2&lt;br /&gt;$("#my_form :radio[name='browser']:lt(2)").remove();&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;Content Filters&lt;/h3&gt;&lt;br /&gt;&lt;div style='width:520px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Selectors/contains#text'&gt;:contains(text)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Selects all elements that contain the specified text&lt;/p&gt;&lt;span style='font-family:courier;'&gt;&lt;br /&gt;&lt;pre&gt;// Select all labels that have the word detail&lt;br /&gt;$("#my_form label:contains('detail')");&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style='width:520px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Selectors/has#selector'&gt;:has(selector)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Selects parents that contain the select area&lt;/p&gt;&lt;span style='font-family:courier;'&gt;&lt;br /&gt;&lt;pre&gt;// Matches all fieldsets that contain &lt;br /&gt;// at least one radio element&lt;br /&gt;$("fieldset:has(':radio')")&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;Forms&lt;/h3&gt;&lt;br /&gt;&lt;div style='width:520px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;The following special selectors are available for forms&lt;/p&gt;&lt;span style='font-family:courier;'&gt;&lt;br /&gt;&lt;pre&gt;// Matches all input, textarea, select and button elements.&lt;br /&gt;&lt;a href='http://docs.jquery.com/Selectors/input'&gt;$(":input");&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;// Matches all input elements of type text.&lt;br /&gt;&lt;a href='http://docs.jquery.com/Selectors/input'&gt;$(":text");&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;// Matches all input elements of type password.&lt;br /&gt;&lt;a href='http://docs.jquery.com/Selectors/input'&gt;$(":password");&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;// Matches all input elements of type radio.&lt;br /&gt;&lt;a href='http://docs.jquery.com/Selectors/input'&gt;$(":radio");&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;// Matches all input elements of type checkbox.&lt;br /&gt;&lt;a href='http://docs.jquery.com/Selectors/input'&gt;$(":checkbox");&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;// Matches all input elements of type submit.&lt;br /&gt;&lt;a href='http://docs.jquery.com/Selectors/input'&gt;$(":submit");&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;// Matches all input elements of type image.&lt;br /&gt;&lt;a href='http://docs.jquery.com/Selectors/input'&gt;$(":image");&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;// Matches all input elements of type reset.&lt;br /&gt;&lt;a href='http://docs.jquery.com/Selectors/input'&gt;$(":reset");&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;// Matches all button elements and input elements of type button.&lt;br /&gt;&lt;a href='http://docs.jquery.com/Selectors/input'&gt;$(":button");&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;// Matches all input elements of type file.&lt;br /&gt;&lt;a href='http://docs.jquery.com/Selectors/input'&gt;$(":file");&lt;/a&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;Form Filters&lt;/h3&gt;&lt;br /&gt;&lt;div style='width:520px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Selectors/enabled'&gt;:enabled&lt;/a&gt; / &lt;a href='http://docs.jquery.com/Selectors/disabled'&gt;:disabled&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Selects elements that either have or do not have the disabled attribute set&lt;/p&gt;&lt;span style='font-family:courier;'&gt;&lt;br /&gt;&lt;pre&gt;// Select all the textareas that are disabled and enable them&lt;br /&gt;$("textarea:disabled").enable();&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style='width:520px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Selectors/enabled'&gt;:checked&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Matches elements that are checked (typically checkboxes, radio)&lt;/p&gt;&lt;span style='font-family:courier;'&gt;&lt;br /&gt;&lt;pre&gt;// Select the value of the checked radio element with name browser&lt;br /&gt;$(":radio[name='browser']:checked").val();&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style='width:520px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Selectors/enabled'&gt;:selected&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Matches option that is selected (typically select element options)&lt;/p&gt;&lt;span style='font-family:courier;'&gt;&lt;br /&gt;&lt;pre&gt;// Get the text value of the select element named cheese&lt;br /&gt;$("select[name='cheese'] :selected").text();&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;If you found this post useful, here are &lt;a href='http://www.myphpetc.com/2009/10/using-jquery-with-forms-part-1.html'&gt;part 1&lt;/a&gt;, &lt;a href='http://www.myphpetc.com/2009/11/using-jquery-with-forms-part-2-core.html'&gt;part 2&lt;/a&gt;, and &lt;a href='http://www.myphpetc.com/2009/12/using-jquery-with-forms-part-4.html'&gt;part 4&lt;/a&gt; of this series.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-8899126845849631414?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/8899126845849631414/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=8899126845849631414' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/8899126845849631414'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/8899126845849631414'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/11/using-jquery-with-forms-part-3_01.html' title='Using jQuery with forms - part 3 (Selectors)'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-6744228906230794196</id><published>2009-11-01T19:45:00.002+11:00</published><updated>2009-12-03T20:40:42.141+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='forms'/><category scheme='http://www.blogger.com/atom/ns#' term='form'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>Using jQuery with forms - part 2 (Core)</title><content type='html'>This is the second in a series of tutorials on using jQuery to manipulate forms. In this series I will be looking at parts of the jQuery API reference in detail. In this tutorial I will be looking at forms and jQuery &lt;a href='http://docs.jquery.com/Core'&gt;Core functionality&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;&lt;h3&gt;jQuery Object Accessors&lt;/h3&gt;&lt;br /&gt;&lt;div style='width:500px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Core/each#callback'&gt;each(callback)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Applying a function to each of the elements in the form&lt;/p&gt;&lt;span style='font-family:courier;'&gt;&lt;br /&gt;&lt;pre&gt;// Loop over each of the text elements in the form #my_form&lt;br /&gt; and set their background color to red if they are empty&lt;br /&gt; &lt;br /&gt;$("#my_form :text").each(function() {&lt;br /&gt; if (!$(this).val()) {&lt;br /&gt;  $(this).css('background-color', 'red');&lt;br /&gt; }&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style='width:500px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Core/size'&gt;size()&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Returns the number of matching elements&lt;/p&gt;&lt;span style='font-family:courier;'&gt;&lt;br /&gt;&lt;pre&gt;// Alerts the number of password elements in the form&lt;br /&gt; &lt;br /&gt;alert($("#my_form :password").size());&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style='width:500px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Core/eq#position'&gt;eq(position)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Returns the element at the specified position&lt;/p&gt;&lt;span style='font-family:courier;'&gt;&lt;br /&gt;&lt;pre&gt;// Returns the third radio element with the name browser in &lt;br /&gt;the form (count starts from 0)&lt;br /&gt; &lt;br /&gt;$("#my_form :radio[name='browser']").eq(2);&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style='width:500px;background:#EEE;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;p&gt;&lt;a href='http://docs.jquery.com/Core/index#subject'&gt;index(subject)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Returns the index of a matched element if found (starting from 0) otherwise -1&lt;/p&gt;&lt;span style='font-family:courier;'&gt;&lt;br /&gt;&lt;pre&gt;// Alerts the index of each radio element amongst its siblings&lt;br /&gt;&lt;br /&gt;$("#my_form :radio").click(function() {&lt;br /&gt; alert($(this).parent().children(":radio").index(this));&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;If you found this post useful, here are &lt;a href='http://www.myphpetc.com/2009/10/using-jquery-with-forms-part-1.html'&gt;part 1&lt;/a&gt;, &lt;a href='http://www.myphpetc.com/2009/11/using-jquery-with-forms-part-3_01.html'&gt;part 3&lt;/a&gt;, and &lt;a href='http://www.myphpetc.com/2009/12/using-jquery-with-forms-part-4.html'&gt;part 4&lt;/a&gt; of this series.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-6744228906230794196?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/6744228906230794196/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=6744228906230794196' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/6744228906230794196'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/6744228906230794196'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/11/using-jquery-with-forms-part-2-core.html' title='Using jQuery with forms - part 2 (Core)'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-1061278359098651548</id><published>2009-10-28T17:40:00.002+11:00</published><updated>2009-10-28T17:47:41.387+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='commercial'/><category scheme='http://www.blogger.com/atom/ns#' term='icons'/><category scheme='http://www.blogger.com/atom/ns#' term='free'/><category scheme='http://www.blogger.com/atom/ns#' term='iconset'/><title type='text'>Free large icon sets for commercial and personal use</title><content type='html'>Thank God for the open source community and those people who are willing to give up their time to produce top quality goods for us all to share. In this post I have a whole bunch of top quality free (as in read the license before you use them) icon sets for your personal and commercial sites.&lt;br /&gt;&lt;br /&gt;Why is important to have a post that provides icons for commercial use? Besides being handy to have your own pool of quality icons that you can use on any site, many developers start out working on small commercial projects and it's hard to come across a range of good quality icons. Sets such as &lt;a href='http://www.famfamfam.com/lab/icons/silk/'&gt;FAMFAMFAM&lt;/a&gt; pop up all over the web and it was the first free icon set I ever worked with and it's still used in many projects today.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;I don't want to provide you with links to sites with hundreds of sets where you have to wade through to find anything decent and I don't want to provide you with "80 free icon sets for commercial and personal use" where most of the sets only have 5 icons or only two out of eighty sets can be used in commrecial projects. Folks, this is the good stuff; five sets of icons with no less than 100 icons in each.&lt;br /&gt;&lt;br /&gt;In order to share the love, I have provided a link to the actual site where the icons reside not just a direct download link. These people have taken there time to design some top quality icons for us all to use so take the time to have a look around while you are there.&lt;br /&gt;&lt;br /&gt;Note: licenses change, please read (and obey) the license of each set at the time of download &lt;br /&gt;&lt;br /&gt;&lt;div style='width:500px;background:#F0F8FF;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;h3&gt;FAMFAMFAM Silk Icons &lt;span style='color:#4F9C19'&gt;700+ icons&lt;/span&gt;&lt;/h3&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/famfam.jpg' style='border:1px solid #CCC;'/&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;A collection of over 700 16x16 icons in .png format.&lt;br /&gt;This collection is great for CMS and dashboard sites or anywhere requiring several smaller sized controls.&lt;/p&gt;&lt;p&gt;Download and license information &lt;a href='http://www.famfamfam.com/lab/icons/silk/'&gt;here&lt;/a&gt;&lt;/p&gt;&lt;p&gt;License: &lt;a href='http://creativecommons.org/licenses/by/3.0/'&gt;Creative Commons Attribution&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;div style='width:500px;background:#F0F8FF;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;h3&gt;Min Tran's Bright! iconset &lt;span style='color:#4F9C19'&gt;148 icons&lt;/span&gt;&lt;/h3&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/bright.jpg' style='border:1px solid #CCC;'/&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Bright has a various assortment of large icons that are useful for any web site.&lt;br /&gt;Contains a number of music related and control icons.&lt;/p&gt;&lt;p&gt;Download and license information &lt;a href='http://www.iconeden.com/icon/bright-free-stock-iconset.html'&gt;here&lt;/a&gt;&lt;/p&gt;&lt;p&gt;License: &lt;a href='http://www.iconeden.com/icon/free/get/bright-free-stock-iconset'&gt;Custom - permits personal and commercial&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;div style='width:500px;background:#F0F8FF;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;h3&gt;wefunction.com Function Icon Set &lt;span style='color:#4F9C19'&gt;128 icons&lt;/span&gt;&lt;/h3&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/function.jpg' style='border:1px solid #CCC;'/&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The Function icon set is set of glossy icons that features bright colours and high detail.&lt;br /&gt;Included in the set are a large number of social networking icons including twitter, RSS and digg.&lt;br /&gt;Also noteworthy is the inclusion of credit card and paypal icons.&lt;/p&gt;&lt;p&gt;Download and license information &lt;a href='http://wefunction.com/2008/07/function-free-icon-set/'&gt;here&lt;/a&gt;&lt;/p&gt;&lt;p&gt;License: &lt;a href='http://wefunction.com/2008/07/function-free-icon-set/'&gt;From the author: "basically my licence is 'do what you want with em' as long as you don’t re-distribute them without linking to this page"&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;div style='width:500px;background:#F0F8FF;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;h3&gt;WooFunction Icon Set &lt;span style='color:#4F9C19'&gt;178 icons&lt;/span&gt;&lt;/h3&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/woofunc.jpg' style='border:1px solid #CCC;'/&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The WooFunction Icon Set includes 178 amazing web-related icons in a sophisticated and glossy design style. All 178 icons are available as 32×32 pixel PNG files.&lt;br /&gt;These icons are quite useful if you are wanting to design an e-commerce site or any site that has a lot of add-remove-update functionality.&lt;/p&gt;&lt;p&gt;Download and license information &lt;a href='http://www.woothemes.com/2009/09/woofunction-178-amazing-web-design-icons/'&gt;here&lt;/a&gt;&lt;/p&gt;&lt;p&gt;License: &lt;a href='http://www.gnu.org/licenses/gpl.html'&gt;GNU GPL (doesn't mention which version)&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;div style='width:500px;background:#F0F8FF;border:1px solid #CCC;padding-left:10px;padding-right:10px;margin-bottom:20px;'&gt;&lt;h3&gt;Everaldo.com Crystal Project &lt;span style='color:#4F9C19'&gt;1300 icons in different sizes&lt;/span&gt;&lt;/h3&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/crystal.jpg' style='border:1px solid #CCC;'/&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;This is one of my favourite icon sets. The quality is awesome.&lt;br /&gt;Considering the large number of icons here, there are a million uses.&lt;/p&gt;&lt;p&gt;Download and license information &lt;a href='http://www.everaldo.com/crystal/?action=preview'&gt;here&lt;/a&gt;&lt;/p&gt;&lt;p&gt;License: &lt;a href='http://www.everaldo.com/crystal/?action=license'&gt;GNU LGPL&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-1061278359098651548?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/1061278359098651548/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=1061278359098651548' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/1061278359098651548'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/1061278359098651548'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/10/free-large-icon-sets-for-commercial-and.html' title='Free large icon sets for commercial and personal use'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-1444073380381349257</id><published>2009-10-27T17:39:00.003+11:00</published><updated>2009-12-03T20:42:03.723+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='forms'/><category scheme='http://www.blogger.com/atom/ns#' term='form'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>Using jQuery with forms - part 1</title><content type='html'>Every day when writing code I come across a form of some type. Forms are the main way we capture user data outside of page/click tracking. How forms are displayed and handled are vital to the quality of information you receive from the user and also the overall usability of a site.&lt;br /&gt;&lt;br /&gt;jQuery has a wealth of plug-ins that can help us deal with some of the major obstacles when handling forms; submit via Ajax, clearing/resetting a form, validation etc. jQuery can also help us to access and manipulate form elements with ease to provide a greater level of usability and improve interaction across a site. In this tutorial I will go over some of the basics of using jQuery with form elements.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;To begin with I always like to add an ID to the form element itself. You can access a form using its name or some other selector but for readability I prefer to use an ID and use attribute selectors for other parts of the form e.g.&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;&amp;lt;form id=&amp;quot;example_form&amp;quot; name=&amp;quot;example_form&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;/form&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You could access this form either via its ID or via its name e.g.&lt;br /&gt;&lt;br /&gt;$("#example_form")&lt;br /&gt;&lt;br /&gt;or&lt;br /&gt;&lt;br /&gt;$("[name='example_form']")&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Once you add on another field with an attribute it becomes obvious why using the ID selector is more readable:&lt;br /&gt;&lt;br /&gt;$("#example_form [name='address']")&lt;br /&gt;&lt;br /&gt;or&lt;br /&gt;&lt;br /&gt;$("[name='example_form'] [name='address']")&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Then we know that anything that comes below our id selector is a child of form element. And we can even retrieve all of those elements using the &lt;a href='http://docs.jquery.com/Traversing/children#expr'&gt;children()&lt;/a&gt; function as follows:&lt;br /&gt;&lt;br /&gt;$("#example_form").children();&lt;br /&gt;&lt;br /&gt;You can also retrieve any of the forms attributes name, ID, method etc. using the attribute function &lt;a href='http://docs.jquery.com/Attributes/attr#name'&gt;attr()&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;$("#example_form").attr("name");&lt;br /&gt;$("#example_form").attr("ID");&lt;br /&gt;$("#example_form").attr("method");&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You can set/change these values using the same function by passing in a value as a second argument:&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;$("#example_form").attr("name", "form_new_name");&lt;br /&gt;$("#example_form").attr("ID", "form_new_ID");&lt;br /&gt;$("#example_form").attr("method", "post");&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Or remove an attribute altogether:&lt;br /&gt;&lt;br /&gt;$("#example_form").removeAttr("name");&lt;br /&gt;&lt;br /&gt;To access any of our child elements we simply specify our forms ID selector, followed by a space and then the child selector:&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;$("#example_form select") // Retrieve all the select child elements&lt;br /&gt;&lt;br /&gt;$("#example_form .label") // Retrieve all the child elements with the class label&lt;br /&gt;&lt;br /&gt;$("#example_form :input") // Retrieve all the child elements that are inputs (input, textarea, select and button elements)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;To perform an action on an element(s) we simply specify the selector as above and then the function:&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;$("#example_form select").remove() // Remove all the select elements from our form&lt;br /&gt;&lt;br /&gt;$("#example_form select").hide() // Hide all the select elements on our form&lt;br /&gt;&lt;br /&gt;$("#example_form select").show() // Show all the select elements on our form&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;To set or retrieve a value will vary on the type of element i.e. radio, select, text input&lt;br /&gt;&lt;br /&gt;&lt;pre class='pre_code'&gt;$("#example_form [name='text_input']").val() // Gets the value of a text input&lt;br /&gt;$("#example_form [name='text_input']").val('new value') // Sets the value of a text input&lt;br /&gt;$("#example_form [name='text_input']").val('')// Clears the value of a text input&lt;br /&gt;&lt;br /&gt;$("#example_form [name='select_input']").val() // Get the option value of the selected element&lt;br /&gt;$("#example_form [name='select_input']").val("1") // Sets the value of the select according to the option value&lt;br /&gt;$("#example_form [name='select_input'] :selected").text() // Get the text of the selected element&lt;br /&gt;&lt;br /&gt;$("#example_form [name='radio_input']").val() // Get the text of the checked radio&lt;br /&gt;$("#example_form [name='radio_input'][value='some_value']").attr("checked", "checked") // Set a radio button to checked according to its value attribute&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I will be releasing a series of tutorials over the coming days (weeks?) that will cover in detail form manipulation. In the mean time check out the &lt;a href='http://docs.jquery.com/Main_Page'&gt;jQuery API&lt;/a&gt; for further functionality.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If you found this post useful, here are &lt;a href='http://www.myphpetc.com/2009/11/using-jquery-with-forms-part-2-core.html'&gt;part 2&lt;/a&gt;, &lt;a href='http://www.myphpetc.com/2009/11/using-jquery-with-forms-part-3_01.html'&gt;part 3&lt;/a&gt; and &lt;a href='http://www.myphpetc.com/2009/12/using-jquery-with-forms-part-4.html'&gt;part 4&lt;/a&gt; of this series.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-1444073380381349257?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/1444073380381349257/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=1444073380381349257' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/1444073380381349257'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/1444073380381349257'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/10/using-jquery-with-forms-part-1.html' title='Using jQuery with forms - part 1'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-466871198680384002</id><published>2009-10-21T17:48:00.010+11:00</published><updated>2010-01-13T18:52:21.264+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>Preview of what's new in jQuery 1.4</title><content type='html'>&lt;div style='border:1px solid blue;'&gt;&lt;h4&gt;Update!&lt;/h4&gt;This post was written before jQuery 1.4 was released and is now out of date. If you would like to see a run down of what &lt;b&gt;is&lt;/b&gt; in the jQuery 1.4 release, look at &lt;a href='http://www.myphpetc.com/2010/01/whats-in-jquery-14-release.html'&gt;my latest post here&lt;/a&gt;&lt;br /&gt;Thanks,&lt;br /&gt;Tim.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;jQuery and other javascript libraries have significantly changed the way that sites are written. In particular, with visual elements and selectors it has opened up a whole new world of speed and accessabilty for developers. With an easy to use API, long gone are the days of writing lengthy javascript code; we can now build fast, attractive and responsive elements with a few lines of code. With all of this it is with great excitement that we look forward to the next major release of jQuery, jQuery 1.4. And why wouldn't you be? The team behind jQuery guarantees that this next release will be better, faster and contain even more useful functionality.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;It is awesome to think that as jQuery pushes the boundaries that they uncover the need for newer functionality. So as jQuery grows we discover even more ways to improve the way we code and approach site design.&lt;br /&gt;&lt;br /&gt;So when can we expect the jQuery 1.4 release to arrive? John &lt;a href="http://blog.jquery.com/2009/08/14/fall-2009-jquery-talks/#comment-466063"&gt;recently mentioned&lt;/a&gt; on the &lt;a href="http://blog.jquery.com/"&gt;jQuery blog&lt;/a&gt; that we could be seeing 1.4 arrive as soon as January 2010. In his own words: "we'll probably release 1.4 on jQuery’s 4th birthday in January."&lt;br /&gt;&lt;br /&gt;In this post I am going to provide a sneak peak of some of the features listed on the &lt;a href="http://docs.jquery.com/JQuery_1.4_Roadmap"&gt;jQuery 1.4 Roadmap&lt;/a&gt;. These are the features that may make it in to the 1.4 release of jQuery. As you can see, some of these have been knocked off in earlier releases so this is a give or take list, but will give us a good idea on what the jQuery team are looking to deliver.&lt;br /&gt;&lt;br /&gt;As the 1.4 roadmap is not a detailed document I will do my best to spell out what these features are likely to include. As the roadmap is not a definitive document this is speculative, but gives a good insight into what we might see in a few months time.&lt;br /&gt;&lt;h4&gt;Lazy loader / require&lt;/h4&gt;The example given at the beginning of the roadmap indicates the possiblity to require certain js/css files to load before the document ready function with the use of a function call similar to jQuery.require("foo.js");. It is currently possible to load CSS and javascript files on-the-fly easily using something like &lt;a href="http://getfirebug.com/"&gt;firebug&lt;/a&gt; and also destroy css files. I suspect this feature will include both options; being able to have certain .js and .css files completed loading before the $("document").ready function is called and also the ability to include .js and .css files on-the-fly with an easy to use API. Also have a look at &lt;a href="http://code.google.com/p/ajaxsoft/wiki/xLazyLoader"&gt;this link&lt;/a&gt; for similar existing functionality.&lt;br /&gt;&lt;h4&gt;contains&lt;/h4&gt;&lt;a href="http://dev.jquery.com/ticket/4101"&gt;$.contains&lt;/a&gt; which may end up being $.has is used to determine if an element is inside another one e.g. jQuery("div").contains(DOMElement). This functionality already exists in this form $(".container").contains(event.target) would return the same elements as $(".container:has(" + event.target + ")").&lt;br /&gt;&lt;h4&gt;radio class&lt;/h4&gt;The idea is that &lt;a href="http://dev.jquery.com/ticket/4630"&gt;radioClass&lt;/a&gt; method (inspired by Ext Core) adds a class to one element and removes it from its siblings. The idea would be something similar to this $(foo).radioClass('on'); would be equivelant of $(foo).addClass('on').siblings().removeClass('on');&lt;br /&gt;&lt;h4&gt;copy entire object&lt;/h4&gt;Would provide a method to clone an element as well as the associatied data objects (see &lt;a href="http://dev.jquery.com/ticket/4284"&gt;bug filed here&lt;/a&gt;. Currently the clone method allows you to clone the element as well as its event handlers, but not the associated data objects. We may end up seeing a single method to deep copy and element including all events, data etc.&lt;br /&gt;&lt;h4&gt;set offset&lt;/h4&gt;&lt;a href="http://plugins.jquery.com/files/offset.js.txt"&gt;Code sample already provided&lt;/a&gt; so we can see what is likely to be included. A method to set or get the specific left and top position of the matched elements, relative the the browser window by calling setXY&lt;br /&gt;&lt;h4&gt;mouse wheel&lt;/h4&gt;I have come across many places asking why this hasn't been included in jQuery yet. This an event listener for the mouse wheel and would trigger an event when the mouse wheel is rolled. Don't expect anything magic out of this like tracking velocity as this is usually just a 1 or a 0 in most browsers. Here is &lt;a href="http://adomas.org/javascript-mouse-wheel/"&gt;a good rundown&lt;/a&gt;&lt;br /&gt;&lt;h4&gt;new live events&lt;/h4&gt;1.4 should see four new $.live event handlers with the implementation of .live("change"), .live("submit"), .live("blur") and .live("focus") added to the &lt;a href="http://docs.jquery.com/Events/live"&gt;existing events&lt;/a&gt; already available.&lt;br /&gt;&lt;h4&gt;improved param serialization&lt;/h4&gt;Ability to serialize paramaters within an object. You begin with something like this $.param({page: {name: 'Foo', author: 'Bar'}) and end up with something like page[name]=Foo&amp;amp;page[author]=Bar. Have a look at &lt;a href="http://dev.jquery.com/ticket/4201"&gt;this request&lt;/a&gt; for more detail.&lt;br /&gt;&lt;h4&gt;Synchronized animations&lt;/h4&gt;The &lt;a href="http://ejohn.org/files/sync/"&gt;demonstration here&lt;/a&gt; speaks for itself. A way to have animations happening synchronously. Good idea to view source on that page a have a look through the code. John has definitely been working hard with animations and javascript, have a look at his &lt;a href="http://processingjs.org/"&gt;processing.js&lt;/a&gt; project if you would like a good idea of what's possible.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-466871198680384002?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/466871198680384002/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=466871198680384002' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/466871198680384002'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/466871198680384002'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/10/preview-of-whats-new-in-jquery-14.html' title='Preview of what&apos;s new in jQuery 1.4'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-5355107642981278712</id><published>2009-10-20T13:30:00.007+11:00</published><updated>2009-10-21T19:37:17.181+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tagging'/><category scheme='http://www.blogger.com/atom/ns#' term='version control'/><category scheme='http://www.blogger.com/atom/ns#' term='subversion'/><category scheme='http://www.blogger.com/atom/ns#' term='repository'/><category scheme='http://www.blogger.com/atom/ns#' term='branching'/><title type='text'>Good practice Branching and Tagging with version control</title><content type='html'>In this tutorial I will go over my preferred method for branching, tagging and comitting. I will steer away from calling this best practice as there are other ways to do this, but I will go so far as to say this is a clean method that works and ensures you can easily keep control of your different working versions, easily reintegrate changes from different paths and restore previous versions for testing / fixing. Which should be your aim for tagging and branching.&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;If you like to discuss, there are several reasonable discussion going on at Stack Overflow. If you are interested &lt;a href='http://stackoverflow.com/questions/464417/how-to-use-svn-branch-tag-trunk'&gt;here&lt;/a&gt;, &lt;a href='http://stackoverflow.com/questions/35646/do-you-continue-development-in-a-branch-or-in-the-trunk'&gt;here&lt;/a&gt; and &lt;a href='http://stackoverflow.com/questions/465658/cvs-svn-best-practices-for-branching-and-tagging'&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;If you are using subversion to manage your version control and you haven't done so yet, take the time to read &lt;a href='http://svnbook.red-bean.com/'&gt;the book&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Let's start by going over some common definitions that I'll be using throught the tutorial:&lt;br /&gt;&lt;br /&gt;Trunk - this is where your main version of your application will be held; any maintstream development will take place on the trunk version of your application&lt;br /&gt;&lt;br /&gt;Branch - a branch is a work-in-progress version of your application and will be for fixing a particular release or for developing new features which may or may not be reintegrated into the trunk at a later stage&lt;br /&gt;&lt;br /&gt;Tag - start by thinking that a tag is a version that will never be altered again; it is like a piece of boxed software that has already hit the shelves, if you want to make changes, you will need to call it something else, if it was 7.0.1 you will might call the work in progress the 7.0.2 version&lt;br /&gt;&lt;br /&gt;Commit - saving a version of your changes to the repository&lt;br /&gt;&lt;br /&gt;Merge / merging - taking the changes from one version of your application and moving it to another version&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I will begin with our trunk. If you have been using a version control system, but haven't been branching or tagging you will have a good idea of how the trunk works. For any simple system the whole repository is used as the trunk and will look like this:&lt;br /&gt;&lt;br /&gt;* Repository is created.&lt;br /&gt;* Files are committed in and out of repository by individuals and are worked on&lt;br /&gt;* Changes are then committed back to the repository&lt;br /&gt;* Any new development that may cause issues is not committed until it has been tested then it is committed to the repository&lt;br /&gt;* A release is made simply by checking out a version of the repository at a point in time when the team is happy that it is stable&lt;br /&gt;* Any further tweeks made before a full release are made to the repository and the version for release is just updated&lt;br /&gt;&lt;br /&gt;This is a pretty standard workflow for many smaller teams and will give you a good idea of what our trunk will look like. As development goes along our trunk continues to grow in a straight line; the repository is rarely reverted and past changes are not reflected on, just modified. The trunk contains all of our changes and just keeps going up and up.&lt;br /&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/trunk.jpg' /&gt;&lt;br /&gt;&lt;br /&gt;This is a perfectly fine way to operate, but let's go over some of the benefits of being able to tag and branch:&lt;br /&gt;* By branching we can multiple versions of the system being worked on that can either be abandoned or reintegrated at any point. The beauty of this is that any changes made don't need to be held back from being committed and won't infect the trunk with untested / unstable code. Think of smaller part of your team having to work on a new feature that will take over 3 months; having them not commit for that time will mean they will need to work outside of the repository and will be difficult to integrate changes.&lt;br /&gt;* By branching we can easily reintegrate individual commits to the branch back in to the trunk as they are tested&lt;br /&gt;* By tagging we know exactly what is in a release that has been passed on to a customer or is on your production server currently. No more guessing as to which commits went in to production last month.&lt;br /&gt;* By tagging we can easily retrieve a tagged version from the repository for testing purposes&lt;br /&gt;* By tagging you can retrieve the tagged version, make changes just to that tag and then create a new tag. Think of this, your production 7.5.1 version has an issue that you only just found and your team has already made 100+ commits to the trunk in that time. Rather than making the changes on the live version, you just grab the 7.5.1 tagged version, make your changes to it, create a 7.5.1.1 tagged version and move the new version to production. There will no longer be any chance of new changes being moved to production without testing.&lt;br /&gt;&lt;br /&gt;Be aware that by using branching and tagging, each branch or tag is like a mini-repository, you can check-out and commit to you branches and tags as well as your trunk.&lt;br /&gt;&lt;br /&gt;We'll now look at branching. Branches are work-in-progess versions of your application. There are a few different reasons that you may want to branch;&lt;br /&gt;1. You want to start developing some new functionality that may or may not be integrated into the trunk at a later stage.&lt;br /&gt;2. You are getting ready for a release, but you may still have some final non-major changes to be made.&lt;br /&gt;3. You want to start working on a version based on a previous tag because you have discovered an issue with that tag, but the trunk has already progressed past that tag.&lt;br /&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/branches.jpg' /&gt;&lt;br /&gt;&lt;br /&gt;With each of the scenarios above there is a particular workflow. The generic workflow is as follows: &lt;br /&gt;* Create a branch by copying a particular revision of your application; either by copying a tagged version or by taking the latest version of your repository. &lt;br /&gt;* Make changes to your branch and commit until you are finished.&lt;br /&gt;* Tag your branch for any future operations and then remove your branch so that nobody else continues to perform work on it&lt;br /&gt;* Reintegrate the changes to your branch back in to your trunk if necessary&lt;br /&gt;&lt;br /&gt;Now let's have a look at home we can apply our workflow to each of our branching scenarios above:&lt;br /&gt;1.&lt;br /&gt; * Create a branch by copying the trunk&lt;br /&gt; * Develop the new functionality&lt;br /&gt; * Tag the version with new functionality&lt;br /&gt; * Add the new functionality to the trunk if necessary by merging changes from the tagged version to the trunk&lt;br /&gt;2.&lt;br /&gt; * Create a branch by copying the trunk&lt;br /&gt; * Test the branch as though it were the release version&lt;br /&gt; * If there are any changes make these to the branch and merge back to the trunk as necessary&lt;br /&gt; * When there are no further changes to be made create a tagged version and then remove the branch&lt;br /&gt; * Move the tagged version to production server&lt;br /&gt;3.&lt;br /&gt; * Create a branch based upon the tag with a bug in it&lt;br /&gt; * Make the fix on the branch and merge the change into the trunk if necessary&lt;br /&gt; * Create a tagged version of the branch and remove the branch&lt;br /&gt; * Move the tagged version in to production (if necessary)&lt;br /&gt; &lt;br /&gt;You should now be able to see the benefit of branching and tagging. Your production version is protected from accidental changes and your working trunk version is developed independantly and alongside any major changes.&lt;br /&gt;&lt;br /&gt;Your version control software should have features to allow for branching and tagging and to easily merge changes. I prefer to use &lt;a href='http://subversion.tigris.org/'&gt;subversion&lt;/a&gt; with &lt;a href='http://tortoisesvn.tigris.org/'&gt;TortoiseSVN client&lt;/a&gt; as the above operations are done with a few clicks.&lt;br /&gt;&lt;br /&gt;The best way to structure your folders for branching and tagging should be similar to the follow to alow you to easily view your versions:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;/branches&lt;br /&gt; /4.1.7&lt;br /&gt; /4.2.1.1&lt;br /&gt;/tags&lt;br /&gt; /4.1.6&lt;br /&gt; /4.2.1&lt;br /&gt; /4.2.2&lt;br /&gt;/trunk&lt;br /&gt; ..trunk files&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;I also recommend you use a visual repository browser so that you can easily view changes and commit mesasges to each of your versions. We are using &lt;a href='http://websvn.tigris.org/'&gt;websvn&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-5355107642981278712?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/5355107642981278712/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=5355107642981278712' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/5355107642981278712'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/5355107642981278712'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/10/good-practice-branching-and-tagging.html' title='Good practice Branching and Tagging with version control'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-9187751411128775592</id><published>2009-10-15T20:34:00.006+11:00</published><updated>2009-10-21T19:37:33.142+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='firefox'/><category scheme='http://www.blogger.com/atom/ns#' term='usability'/><category scheme='http://www.blogger.com/atom/ns#' term='links'/><title type='text'>How and why not to remove dotted links form Firefox</title><content type='html'>&lt;p&gt;This tutorial looks at fixing the issue with the dotted area around links in Firefox.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;If you do a search on google for 'dotted links firefox', almost all of the pages will have a title such as 'Remove dotted links from Firefox', 'Destroy annoying dotted links on Firefox' or 'How the hell do I get rid of dotted border around links in Firefox!!!'.&lt;/p&gt;&lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/dotted.jpg' /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span id="summary-area"&gt;&lt;br /&gt;&lt;p&gt;The sad thing is that these dotted links, although giving some designers a headache are actually there for a good reason and... shouldn't be removed!&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The good reason for having these dots here is so that others who have issues with mobility e.g. they can't use a mouse, need to be able to see which element on a page has focus so that they can press their enter button at the appropriate time.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Like everything else in the world, the internet should be for everyone to share, so we should be doing our best as developer designer to ensure that our websites are accessible. (More visitors the better right?)&lt;/p&gt;&lt;br /&gt;&lt;p&gt;After this tutorial I will be placing a couple of links about acessibility that will hopefully give you some further background into accessability issues and the internet.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Before I go in to the issue, just some background. Many people run in to this problem when trying to use the combination of the text-indent css rule along with a background image, popularised by Mike Rundle in &lt;a href='http://phark.typepad.com/phark/2003/08/accessible_imag.html'&gt;this post&lt;/a&gt;. Which in itself is a good practice, it is helpful for screen readers (read the post for more info).&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ok, on to the problem. Have a look at the code below and you will see an &amp;lt;a&amp;gt; tag that with a link inside that has the text indented so it no longer appears on the screen.&lt;/p&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;div style=&amp;#039;float:right;&amp;#039;&amp;gt;&lt;br /&gt; &amp;lt;a href=&amp;#039;#&amp;#039; style=&amp;#039;text-indent:-10000px;display:block;width:40px;height:40px;background:red;&amp;#039;&amp;gt;&lt;br /&gt;  Hello&lt;br /&gt; &amp;lt;/a&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;p&gt;Here it is below. If you are using Firefox and you click on the red box you will notice the dotted line stretches accross the page.&lt;/p&gt;&lt;br /&gt;&lt;div style='float:right;'&gt;&lt;br /&gt; &lt;a href='#' style='text-indent:-10000px;display:block;width:40px;height:40px;background:red;' onclick='return false;'&gt;Hello&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style='clear:both;'&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Now look at the example below and notice how the dotted line raps nicely around the red box.&lt;/p&gt;&lt;br /&gt;&lt;div style='clear:both;float:right;'&gt;&lt;br /&gt; &lt;a href='#' style='text-indent:-10000px;display:block;width:40px;height:40px;background:red;overflow:hidden;' onclick='return false;'&gt;Hello&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style='clear:both;'&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;This is fixed simply by using the css rule overflow:hidden. Once this simple rule is in place the dotted indicator wraps nicely around the &amp;lt;a&amp;gt; tag. Considering coders much better than ourselves spend their time build browsers like Firefox with the best intentions in mind (that include industry best standards and practices); take time to consider why things may not appear correctly in your browser before wanting to chop them out.&lt;/p&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;div style=&amp;#039;float:right;&amp;#039;&amp;gt;&lt;br /&gt; &amp;lt;a href=&amp;#039;#&amp;#039; style=&amp;#039;text-indent:-10000px;display:block;width:40px;height:40px;background:red;overflow:hidden;&amp;#039;&amp;gt;&lt;br /&gt;  Hello&lt;br /&gt; &amp;lt;/a&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Here are some links that you may find helpful.&lt;br /&gt;&lt;ul&gt;&lt;br /&gt; &lt;li&gt;A great post about removing the dotted line, but adding your own styles &lt;a href="http://css-tricks.com/removing-the-dotted-outline/"&gt;here&lt;/a&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;A List Apart article about user with accessibility issue &lt;a href="http://www.alistapart.com/articles/wiwa/"&gt;read it here&lt;/a&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;W3 Consortium's &lt;a href="http://jquery.com/"&gt;international policies&lt;/a&gt; for accessibility laws&lt;/li&gt;&lt;br /&gt; &lt;li&gt;W3 Consortium's Web &lt;a href="http://www.w3.org/WAI/"&gt;Web Accessibility Initative (WAI)&lt;/a&gt; home page&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4356457360167243215-9187751411128775592?l=www.myphpetc.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.myphpetc.com/feeds/9187751411128775592/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4356457360167243215&amp;postID=9187751411128775592' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/9187751411128775592'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4356457360167243215/posts/default/9187751411128775592'/><link rel='alternate' type='text/html' href='http://www.myphpetc.com/2009/10/how-and-why-not-to-remove-dotted-links.html' title='How and why not to remove dotted links form Firefox'/><author><name>.</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4356457360167243215.post-7734041448494617717</id><published>2009-10-15T13:52:00.005+11:00</published><updated>2009-10-27T18:10:32.318+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='AJAX'/><category scheme='http://www.blogger.com/atom/ns#' term='pagination'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>Easy pagination with jQuery and Ajax</title><content type='html'>In this tutorial I would like to go over an easy way to display your database data with jQuery using Ajax and pagination.&lt;br /&gt;&lt;br /&gt;If you would like a brief introduction to using Ajax with jQuery you can have a look at &lt;a href='http://myphpetc.blogspot.com/2009/10/beginners-jquery-ajax-tutorial.html'&gt;this tutorial&lt;/a&gt;. jQuery makes it very easy to send Ajax requests.&lt;br /&gt;&lt;br /&gt;You can view the demo of this tutorial &lt;a href='http://comp345.awardspace.com/pagination/index.html'&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You can download the files for this tutorial &lt;a href='http://sites.google.com/site/myphpetc/Home/pagination.zip?attredirects=0&amp;d=1'&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Pagination is the process of chunking up your data into fixed sizes so that you only view one fixed size chunk at a time and can navigate easily backwards and forwards through other chunks. You can see this process on sites like &lt;a href='http://digg.com/all/popular/24hours'&gt;digg&lt;/a&gt; and &lt;a href='www.ebay.com'&gt;ebay&lt;/a&gt;. Usually the navigation links show the first page, the last page, a next and previous link and a small range of page numbers. The pagination links in this tutorial will look something like this: &lt;br /&gt;&lt;img src='http://sites.google.com/site/myphpetc/Home/pagelinks.jpg' /&gt;&lt;br /&gt;&lt;br /&gt;Pagination allows your users to digest information in small, easily digestible pieces and with a familiar interface for navigating backwards and forwards through that information.&lt;br /&gt;&lt;br /&gt;Using Ajax we can provide a way to navigate through larger amounts of information loading one page at a time. This should reduce the load on the server and minimise page reloading times. The use of Ajax should be weighed up as it is not appropriate for all sites.&lt;br /&gt;&lt;br /&gt;Lets start by thinking what our page will look like. We will have our information (displayed one page at a time) and another section to display which page we are currently on and navigation to other pages. I will name the two secions #content and #paginator. The main aim is to update the #content information each time someone clicks on a #paginator page link. So we start with three main functions:&lt;br /&gt;&lt;br /&gt;&lt;code class="brush: php;"&gt;&lt;br /&gt;function initialize() {&lt;br /&gt;// Display first page&lt;br /&gt;&lt;br /&gt;// Display initial status of page links with the first page selected&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function displayPage(current_page) {&lt;br /&gt;// Retrieve data from table equivelant to page size (for this example 10 rows) based on which page we are currently on (current_page) and return formatted rows&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function displayLinks(current_page) {&lt;br /&gt;// Create page links with first and last links based upon which page we are currently on (current_page)&lt;br /&gt;&lt;br /&gt;// Attach event listeners to our page links&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Now lets think about where each of these functions should reside; Since we want our program to retrieve the data on the fly and we are going to use Ajax we will have our displayPage functionality sitting in the backend (whatever your preffered language, I will be using php). We will place our initialize function in javascript so that it can load the pages and I have decided since the page links are essentially the same element and require little processing I will have javascript render the page links also. We will still need to have another function in the javascript to make the Ajax request to the php file whenever a page link is clicked. So lets have another look at our functions.&lt;br /&gt;&lt;br /&gt;&lt;code class="brush: php;"&gt;&lt;br /&gt;/*** Javascript - page.js ***/&lt;br /&gt;&lt;br /&gt;function initialize() {&lt;br /&gt;// Load first page into #content&lt;br /&gt;&lt;br /&gt;// Call displayLinks(1)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function displayLinks(current_page) {&lt;br /&gt;// Create / refresh page links with first and last links based upon which page we are currently on (current_page)&lt;br /&gt;&lt;br /&gt;// Attach event listeners to our page links which will call updatePage function when clicked&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function updatePage(clicked_element) {&lt;br /&gt;// Get the current_page based upon the text of the selected element&lt;br /&gt;&lt;br /&gt;// Call php displayPage(current_page) function via Ajax to get data and load this into #content section&lt;br /&gt;&lt;br /&gt;// Update links on the page by calling displayLinks(current_page)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;/*** php - loaddata.php***/&lt;br /&gt;&lt;br /&gt;function displayPage(current_page) {&lt;br /&gt;// Get the names from the database by calling $data = getNames(current_page)&lt;br /&gt;&lt;br /&gt;// Format raw data by calling $formatted_data = formatData($data)&lt;br /&gt;&lt;br /&gt;// Return $formatted_data&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function getNames(current_page) {&lt;br /&gt;// Retrieve data from table equivelant to page size (for this example 10 rows) based on which page we are currently on using SQL&lt;br /&gt;&lt;br /&gt;// Return rows&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function formatData(data) {&lt;br /&gt;// We are simply going to attach &amp;lt;p&amp;gt; tags to the columns 'firstname lastname' for each row then return this as a single string&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;We now have most of our pseudocode written out and we should be able to start coding from here. With a little bit of css the finished product will be a simple, good looking and easy to use Ajax program that will show us pages of names, 10 at a time.&lt;br /&gt;&lt;br /&gt;The glue that is going to hold our application together is &lt;a href='http://jquery.com/'&gt;jQuery&lt;/a&gt;. If you are unfamiliar with jQuery I suggest you begin by having a look at this tutorial &lt;a href='http://oneupcode.com/?p=3'&gt;Getting started with jQuery&lt;/a&gt;. jQuery will supply many of the methods we need for getting the joby done in an easy straight forward way.&lt;br /&gt;&lt;br /&gt;There is on last function we are missing. In order to display a link to the last page we will need to retrieve the page count from the database. As this needs to be used each time displayLinks is called we will retrieve this from the database once and store it in a hidden input element on the page.&lt;br /&gt;&lt;br /&gt;It's probably best if we start with php file so that you can know what we the data will look like when it is retrieved by our Ajax calls.&lt;br /&gt;&lt;br /&gt;&lt;code class="brush: php;"&gt;&lt;br /&gt;/*** php - loaddata.php***/&lt;br /&gt;&lt;br /&gt;&amp;lt;?php&lt;br /&gt;if (isset($_REQUEST['action'])) {&lt;br /&gt;$action = $_REQUEST['action'];&lt;br /&gt;&lt;br /&gt;switch ($action) { // We will determine which function to call based on an action paramater passed in through the url&lt;br /&gt;case 'get_rows':&lt;br /&gt;displayPage();&lt;br /&gt;break;&lt;br /&gt;case 'row_count':&lt;br /&gt;getRowCount(); // Return the number of rows in the database&lt;br /&gt;break;&lt;br /&gt;default;&lt;br /&gt;break;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;exit;&lt;br /&gt;} else {&lt;br /&gt;return false;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Returns the number of rows from the table we are querying&lt;br /&gt;function getRowCount() {&lt;br /&gt;$db = array(&lt;br /&gt;// Database connection details&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;$link = mysql_connect($db['host'], $db['login'], $db['password']);&lt;br /&gt;&lt;br /&gt;mysql_select_db($db['database']);&lt;br /&gt;&lt;br /&gt;$strSQL = "SELECT COUNT(*) FROM names";&lt;br /&gt;$result = mysql_query($strSQL);&lt;br /&gt;$count = mysql_fetch_row($result);&lt;br /&gt;&lt;br /&gt;echo $count[0];&lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;// Retrieves raw data from the database then formats it and then returns the formatted rows as a string&lt;br /&gt;function displayPage() {&lt;br /&gt;$start_row = isset($_REQUEST['start'])?$_REQUEST['start']:0;&lt;br /&gt;$start_row = 10 * (int)$start_row;&lt;br /&gt;&lt;br /&gt;$employees = getNames($start_row);&lt;br /&gt;&lt;br /&gt;$formatted_names = "&amp;lt;div id='formatted_eployees'&amp;gt;" . formatData($employees) . "&amp;lt;/div&amp;gt;";&lt;br /&gt;&lt;br /&gt;echo $formatted_names;&lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;// Retrieves rows from the names table&lt;br /&gt;function getNames($start_row = 0) {&lt;br /&gt;$db = array(&lt;br /&gt;// Database connection details&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;$link = mysql_connect($db['host'], $db['login'], $db['password']);&lt;br /&gt;&lt;br /&gt;mysql_select_db($db['database']);&lt;br /&gt;&lt;br /&gt;$strSQL = "SELECT * FROM names ORDER BY id ASC LIMIT {$start_row}, 10"; // Returns 10 rows based on 
