<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ajgraham.com &#187; Web Development</title>
	<atom:link href="http://www.ajgraham.com/category/web-development/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ajgraham.com</link>
	<description>web design, development and consultation in Prague</description>
	<lastBuildDate>Tue, 01 Nov 2011 22:16:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
		<item>
		<title>Getting an RSS feed from Facebook</title>
		<link>http://www.ajgraham.com/2011/01/data-feed-facebook-rss-jso/</link>
		<comments>http://www.ajgraham.com/2011/01/data-feed-facebook-rss-jso/#comments</comments>
		<pubDate>Mon, 24 Jan 2011 02:13:10 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[RSS]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://www.ajgraham.com/?p=530</guid>
		<description><![CDATA[From my experience Facebook tends to provoke strong reactions, both positive or negative. As a developer who works with Facebook often in one way or another I&#8217;ve had lots of frustrating moments mainly due to poor/incorrect documentation. I spent a while trying to find the best way to export a [...]]]></description>
			<content:encoded><![CDATA[<p>From my experience Facebook tends to provoke strong reactions, both positive or negative. As a developer who works with Facebook often in one way or another I&#8217;ve had lots of frustrating moments mainly due to poor/incorrect documentation.</p>
<p>I spent a while trying to find the best way to export a public Facebook pages posts in the form of an RSS feed. Facebook don&#8217;t provide an easy way to do this (only on Notifications, e.g. <a href="http://www.facebook.com/notifications.php">facebook.com/notifications.php</a>), although it can be done with a workaround in 2 different ways.</p>
<h3>Via Twitter</h3>
<p>You can connect a Facebook page to Twitter and any new posts will automatically be sent to a Twitter account you specify (you can do this through <a href="http://www.facebook.com/twitter/">facebook.com/twitter/</a>). With this carried out, you can then access the RSS feed of the Twitter account. This works but confines you to the 140 characters limit and will include a link back to the original Facebook post within the tweet.</p>
<h3>The long way round</h3>
<p>Another way would be to make a system to automatically create an RSS feed from the Facebook pages JSON feed (example: https://graph.facebook.com/<em>pagename or id</em>/feed). This has the benefit of displaying your Facebook posts in full. The downside is of course the extra work and complication involved.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ajgraham.com/2011/01/data-feed-facebook-rss-jso/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Social Media: Overview of Facebook, Twitter and LinkedIn</title>
		<link>http://www.ajgraham.com/2010/11/social-media-efficient-marketing-with-facebook-twitter/</link>
		<comments>http://www.ajgraham.com/2010/11/social-media-efficient-marketing-with-facebook-twitter/#comments</comments>
		<pubDate>Tue, 09 Nov 2010 22:30:59 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[linked in]]></category>
		<category><![CDATA[linkedin]]></category>
		<category><![CDATA[marketing]]></category>
		<category><![CDATA[media]]></category>
		<category><![CDATA[social]]></category>
		<category><![CDATA[twitter]]></category>
		<category><![CDATA[web2.0]]></category>

		<guid isPermaLink="false">http://www.ajgraham.com/?p=420</guid>
		<description><![CDATA[Over the past few years I&#8217;ve watched the way the Internet has gradually changed. The leap from old school websites where all the content and features were served up 100% themselves is so far gone that I can barely remember it existing. Almost every website has some form of external [...]]]></description>
			<content:encoded><![CDATA[<p>Over the past few years I&#8217;ve watched the way the Internet has gradually changed. The leap from old school websites where all the content and features were served up 100% themselves is so far gone that I can barely remember it existing. Almost every website has some form of external input or aggregation, whether to provide additional niche features or website content that can make the difference between websites/companies being successful or not.</p>
<p>The challenge is to make the correct decisions when adding social media features, it&#8217;s all too easy to add 20 &#8216;sharing&#8217; buttons to a page when trying to cover all the bases and end up creating an awful user experience. The key is to know which social media services demographics best match the demographics and the type of info being shared by a company or organisation. Basically trying to find a best fit, if one exists.</p>
<h3>Facebook</h3>
<p>Facebook over the past 2 years has grown to become a huge social platform. They have 500 million registered members, and 200+ million of those use it through mobile devices and both stats are growing steadily (see <a href="http://www.facebook.com/press/info.php?statistics">www.facebook.com/press/info.php?statistics</a>). A wide variety of age groups use Facebook, although it is heavily slanted towards teenagers and &#8217;20-somethings&#8217;, this is changing gradually though as Facebook becomes synonymous with using the Internet.</p>
<p>Age Range: All (13 y/o&#8217;s and over).<br />
Location: Generally US, Europe and South America have very high use, although it is quickly spreading in Asia, Middle East and beyond.</p>
<p>Marketing with Facebook can be carried out via 2 main methods:<br />
<strong>Fan Pages</strong> allow standard Facebook users to &#8216;Like&#8217; them, which means that anything published to the Fan Page will be seen by everyone who has &#8216;Liked&#8217; it. This creates a valuable communication stream which is best used with weekly/bi-weekly updates to ensure regular contact, although it&#8217;s important to make sure you don&#8217;t spam the user as you&#8217;ll likely dilute the usefulness of the tool and/or lose them as a &#8216;fan&#8217;. There is also a spin-off of this whereby users can allowed to &#8216;Share&#8217; or &#8216;Like&#8217; specific webpages, which is used to good effect on news items, video or other similar individual pieces of content. A good example of this is the ability to share a video on YouTube to your Facebook account.</p>
<p><strong>Facebook Ads</strong> allow an advertiser to focus ads to Facebook users via specific demographics such as age, location and interests. Due to Facebook users supplying this information via their profiles this helps to make advertising as pin-point as is possible on the internet at the moment, which is much more accurate than almost all over alternatives.</p>
<h3>Twitter</h3>
<p>Twitter is similar in some respects to Facebook, but has some key differences. Twitter is designed for much more verbose communication with a 140 character limit, and an emphasis on time sensitivity. Twitter has ~150 million registered users, although its churn rate (the number of users that sign up and don&#8217;t use their account again) is widely regarded as being far higher than Facebook. <a href="http://techcrunch.com/2010/09/02/twitter-stats/">Twitter stats</a>.</p>
<p>Age Range: All (13 y/o&#8217;s and over).<br />
Location: Significant usage almost everywhere.</p>
<p>Marketing is generally best done via encouraging retweeting (which is the equivalent of repeating a specific piece of information, thus adding kudos). This is often described as something &#8216;going viral&#8217; on the internet. Twitter is used to publicise pretty much anything, although it&#8217;s best used as bait (due to the limited number of characters) to link to breaking news or similar situations.</p>
<h3>LinkedIn</h3>
<p>LinkedIn is primarily used for professional contacts to build a network of people they know via employment both past and present. There are 80 million users, although 40 million are based in the US which weaken its appeal outside of the US. <a href="http://press.linkedin.com/">LinkedIn stats</a>.</p>
<p>Age Range: All (18 y/o&#8217;s and over).<br />
Location: Significant usage US mostly, but still common in Europe.</p>
<p>Marketing can be carried out similarily to Facebook, by allowing people to share content to LinkedIn this content would then be visible to all of their contacts. Marketing aimed towards LinkedIn (due to the nature of LinkedIn) is best done for any information that is work related, thus is more niche than what you would share on Facebook.</p>
<h3>Conclusions</h3>
<p>Each service is significantly different, in some cases all 3 may be useful to visitors if a website has a wide range of content but is unlikely. Try not to clog a website with 100 ways to share content when only 2 are really popular as you&#8217;ll sacrifice a lot of page space and confuse some users, not to mention increase page loading times.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ajgraham.com/2010/11/social-media-efficient-marketing-with-facebook-twitter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WordPress Posts Pagination</title>
		<link>http://www.ajgraham.com/2010/08/wordpress-posts-pagination-with/</link>
		<comments>http://www.ajgraham.com/2010/08/wordpress-posts-pagination-with/#comments</comments>
		<pubDate>Thu, 05 Aug 2010 19:42:44 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[global]]></category>
		<category><![CDATA[paginated]]></category>
		<category><![CDATA[paging]]></category>
		<category><![CDATA[post]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.ajgraham.com/?p=460</guid>
		<description><![CDATA[I recently had to find a way of forcing WordPress to display a post that had been paginated using the nextpage quicktag, to display different content on different dynamically generated pages. After some help from StackOverflow.com I found out that within The Loop you can access 2 particular variables that [...]]]></description>
			<content:encoded><![CDATA[<p>I recently had to find a way of forcing WordPress to display a post that had been paginated using the nextpage quicktag, to display different content on different dynamically generated pages. After some help from StackOverflow.com I found out that within <a href="http://codex.wordpress.org/The_Loop">The Loop</a> you can access 2 particular variables that WordPress uses: <em>$page</em> and <em>$numpages</em>. </p>
<p>Without having to be a genius <em>$page</em> is the current page number and <em>$numpages</em> is the total number of pages that a post has been converted into by WordPress.</p>
<p>Example: To have something appear only on the first page of a paginated post use:</p>
<pre><code>if($page == 1 || $numpages == 1) {
	//will only appear on first page
}</code></pre>
<p>Example: To have something appear only on the last page of a paginated post use:</p>
<pre><code>if($page == $numpages) {
	//will only appear on last page
}</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://www.ajgraham.com/2010/08/wordpress-posts-pagination-with/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Retrieve Facebook page status with no authenticating or permissions issues</title>
		<link>http://www.ajgraham.com/2010/07/get-facebook-page-stream-simple-easy/</link>
		<comments>http://www.ajgraham.com/2010/07/get-facebook-page-stream-simple-easy/#comments</comments>
		<pubDate>Fri, 02 Jul 2010 21:42:11 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[auth]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[feed]]></category>
		<category><![CDATA[get]]></category>
		<category><![CDATA[key]]></category>
		<category><![CDATA[read]]></category>
		<category><![CDATA[retrieve]]></category>
		<category><![CDATA[RSS]]></category>
		<category><![CDATA[scraping]]></category>
		<category><![CDATA[session]]></category>
		<category><![CDATA[status]]></category>
		<category><![CDATA[stream]]></category>

		<guid isPermaLink="false">http://www.ajgraham.com/?p=451</guid>
		<description><![CDATA[If you&#8217;re just looking to read the &#8216;Stream&#8217; or &#8216;Statuses&#8217; of a Facebook fan page (not a normal Profile page) it can be done very easily. Due to all Fan Pages being public (their are 2 settings: published or unpublished), as long as the Fan page is published then you [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re just looking to read the &#8216;Stream&#8217; or &#8216;Statuses&#8217; of a Facebook fan page (<em>not</em> a normal Profile page) it can be done very easily. Due to all Fan Pages being public (their are 2 settings: published or unpublished), as long as the Fan page is published then you can retrieve any data from it, no authentication, no API, no messing around.</p>
<p>Step 1 &#8211; Find the page feed for the Fan Page<br />
The basic URL format of a Facebook fan page feed is:</p>
<pre><code>https://graph.facebook.com/ID of Page/feed</code></pre>
<p>If you can&#8217;t find your unique Page ID <a target="_blank" rel="nofollow" href="http://help.wildfireapp.com/faqs/tutorials/how-to-find-out-your-facebook-fan-page-public-profile-id">read this guide</a>.<br />
<a target="_blank" rel="nofollow" href="https://graph.facebook.com/ID of Page/feed">Test it by opening the link in another browser window</a>. If you get a whole load of data in square and curly brackets (it&#8217;s JSON) that contains posts from your fan page then you&#8217;re set for Step 2.</p>
<p>*Please note that this URL gets every post from your Wall/Stream limited to about the 50 most recent from what I&#8217;ve seen. This includes everything that other people have posted as well in the form of their posts or comments, etc.</p>
<p>Step 2 &#8211; Extract the last status from the feed URL data</p>
<p>Here comes the basic PHP code, you need to put in the Page ID for the
<pre><code>$pageID</code></pre>
<p> variable:</p>
<pre><code>$pageID = "ID of Page"
$url = "https://graph.facebook.com/". $pageID ."/feed";
$json = file_get_contents($url);
$jsonData = json_decode($json);

foreach($jsonData->data as $val) {
	if($val->from->id == $pageID) { //find the first matching post/status by a fan page admin
		$message = $val->message;
		echo $message;
		break; //stop looping on most recent status posted by page admin
	}
}</code></pre>
<h3>Things to consider</h3>
<p>Extracting the data from Facebook directly using a server-side approach should not be used for production as it&#8217;s really inefficient as it adds a noticeable pause to page loading times and will break if Facebook is slow in responding. I provided a basic demo to show how easy it can be done, but you should expand on this by storing the data extracted in a database or file on your server via CRON jobs. Another alternative would be to do it client-side with JavaScript, it depends on the frequency the Fan page data you want is expected to change and what you&#8217;re doing with it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ajgraham.com/2010/07/get-facebook-page-stream-simple-easy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JQuery: Open external links in new window</title>
		<link>http://www.ajgraham.com/2010/05/jquery-open-external-links-in-new-window/</link>
		<comments>http://www.ajgraham.com/2010/05/jquery-open-external-links-in-new-window/#comments</comments>
		<pubDate>Mon, 24 May 2010 18:00:29 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[JQuery]]></category>
		<category><![CDATA[rel="external"]]></category>

		<guid isPermaLink="false">http://www.ajgraham.com/?p=396</guid>
		<description><![CDATA[Finally got round to writing a small bit of code to automatically force anchor links to open in new windows if they are for different domains: $(document).ready(function() { var myDomain = ["www.ajgraham.com", "testing.ajgraham.com", "lifestream.ajgraham.com"]; //do NOT include the http:// pls! $("a[href^='http://']").each(function() { var slicedHref = $(this).attr('href').slice(7); var slashPosition = slicedHref.indexOf("/"); [...]]]></description>
			<content:encoded><![CDATA[<p>Finally got round to writing a small bit of code to automatically force anchor links to open in new windows if they are for different domains:</p>
<pre><code>$(document).ready(function() {
	var myDomain = ["www.ajgraham.com", "testing.ajgraham.com", "lifestream.ajgraham.com"]; //do NOT include the http:// pls!
	$("a[href^='http://']").each(function() {
		var slicedHref = $(this).attr('href').slice(7);
		var slashPosition = slicedHref.indexOf("/");
		if (slashPosition != -1) {
			slicedHref = slicedHref.slice(0,(slashPosition));
		}
		var matchCounter = 0;
		for (i=0;i&lt;myDomain.length;i++) {
			if (slicedHref.indexOf(myDomain[i]) == -1) {
				matchCounter++;
			}
		}
		if (matchCounter == myDomain.length) {
			$(this).attr("target","_blank").attr("rel","external").append("&lt;img class='new-window-link' alt='new window' src='http://www.ajgraham.com/wp-content/themes/ajgrahampro/images/external.png' style='padding-left:2px' /&gt;");
		}
	});
});</code></pre>
<p><a target="_blank" href="http://www.ajgraham.com/codestore/linksinnewwindow/anchorlinkstest.html">See Demo</a></p>
<p><a href="http://www.ajgraham.com/codestore/linksinnewwindow/newWindowLinks.zip">Download basic example</a></p>
<p>Just remember to change
<pre><code>var myDomain = ["www.ajgraham.com", "testing.ajgraham.com", "lifestream.ajgraham.com"];</code></pre>
<p> to your internal domain(s). You can use as many as you like, just don&#8217;t include the http:// bit.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ajgraham.com/2010/05/jquery-open-external-links-in-new-window/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simple but powerful JQuery Form Validation</title>
		<link>http://www.ajgraham.com/2010/05/simple-but-powerful-jquery-form-validation/</link>
		<comments>http://www.ajgraham.com/2010/05/simple-but-powerful-jquery-form-validation/#comments</comments>
		<pubDate>Thu, 20 May 2010 01:29:46 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Field]]></category>
		<category><![CDATA[Form]]></category>
		<category><![CDATA[Input]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[JQuery]]></category>
		<category><![CDATA[Validator]]></category>

		<guid isPermaLink="false">http://www.ajgraham.com/?p=363</guid>
		<description><![CDATA[I wrote a relatively simple and intuitive form validation script for a client, which they kindly allowed me to release into the open-source community. Contents The Objective The Basics Including The JavaScript Explaining The Code Core Functions Expanded Functions Options HTML Examples Download License To-Do&#8217;s Change-log The Objective The aim [...]]]></description>
			<content:encoded><![CDATA[<p>I wrote a relatively simple and intuitive form validation script for a client, which they kindly allowed me to release into the open-source community.</p>
<h2>Contents</h2>
<p><a href="#objective">The Objective</a><br />
<a href="#basics">The Basics</a><br />
<a href="#include-the-javascript">Including The JavaScript</a><br />
<a href="#explain-code">Explaining The Code</a><br />
<a href="#core-functions">Core Functions</a><br />
<a href="#expanded-functions">Expanded Functions</a><br />
<a href="#options">Options</a><br />
<a href="#html">HTML</a><br />
<a href="#examples">Examples</a><br />
<a href="#download">Download</a><br />
<a href="#license">License</a><br />
<a href="#to-dos">To-Do&#8217;s</a><br />
<a href="#change-log">Change-log</a></p>
<h2 id="objective">The Objective</h2>
<p>The aim was to develop a simple JavaScript form validator plugin to be:</p>
<ul>
<li>JQuery based</li>
<li>Fast and efficient</li>
<li>Automated (via CSS Classes)</li>
<li>Adjustable (via option settings)</li>
<li>Easily expandable</li>
</ul>
<h2 id="basics">The Basics</h2>
<p>From a simplistic overview, the plugin loops around any form with a submit button and validates input elements based on its CSS classes.<br />
The standard CSS classes it works on are:<br />
<strong>required</strong> &#8211; if an input is marked as &#8216;required&#8217; it simply makes sure the field is not empty.<br />
<strong>email</strong> &#8211; it does a simple regex check to ensure the format is correct.<br />
<strong>digit</strong> &#8211; it checks whether the field only contains numbers 0 to 9.<br />
<strong>alpha</strong> &#8211; checks if the field contains characters a to z and A to Z.</p>
<h2 id="include-the-javascript">Including the JavaScript</h2>
<p>First include JQuery, supports 1.3.2 &#8211; 1.4.2:</p>
<pre><code>&lt;script type=&quot;text/javascript&quot; src=&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js&quot;&gt;&lt;/script&gt;</code></pre>
<p>Then include our <a href="#download">script</a>:</p>
<pre><code>&lt;script type=&quot;text/javascript&quot; src=&quot;options.validate-form.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;validate-form.js&quot;&gt;&lt;/script&gt;</code></pre>
<h2 id="explain-code">Explaining the Code</h2>
<p>Attaching the code automatically to all Forms is carried out by:</p>
<pre><code>$().ready(function() {
	//attach plugin to all forms with a submit button (except for ignored forms)
	$('form:not('+ formsToIgnore() +')').submit(function() {
		var formId = $(this).attr('id');
		var matchingElements = $('form#'+ formId +' input[type=text], form#'+ formId +' textarea, form#'+ formId +' input[type=checkbox]');
		if (!matchingElements == &quot;&quot;) {
			var formError = validateForm(formId, matchingElements);
			if (formError == true) {
				return false
			} else {
				return true;
			}
		}
	});
});</code></pre>
<p>If you need eager validation (it annoys me, but some people seem to love it #shake-head), set the options variable <em>eagerValidation=true</em> (see script options or examples), or if you don&#8217;t need it, remove it.</p>
<pre><code>//check whether to eagerly validate each field
	if (eagerValidation == true) {
		$('form input[type=text], form textarea, form input[type=checkbox]').focusout(function() {
			var fieldId = $(this).attr('id');
			var formId = $('#'+fieldId).parents('form').attr('id');
			if (validateField(formId, fieldId) == false) {
				removeFieldError(formId, fieldId);
			}
			removeFormError(formId);
			addFormError(formId);
		});
	}</code></pre>
<h2 id="core-functions">Core Functions</h2>
<pre><code>function validateField(formId, fieldId) {
	if (fieldId) {
		removeFieldError(formId, fieldId);

		var element = buildElement(formId, fieldId);
		var fieldValue = jQuery.trim(jQuery(element).val());
		var fieldLength = fieldValue.length;
		var fieldErrorMessage = &quot;&quot;;

		if ($(element).hasClass('text')) {
			if ($(element).hasClass('alpha') &#038;&#038; fieldLength &gt; 0) { // from string start to end, only contains '-' &quot;whitespace&quot; or 'aA'-'zZ'
				if (validateAlpha(fieldValue) == false) {
					fieldErrorMessage = alphaFieldError;
				}
			} else if ($(element).hasClass('digit') &#038;&#038; fieldLength &gt; 0) {
				if (validateDigit(fieldValue) == false) {
					fieldErrorMessage = digitFieldError;
				}
			} else if ($(element).hasClass('email') &#038;&#038; fieldLength &gt; 0) {
				if (validateEmail(fieldValue) == false) {
					fieldErrorMessage = emailFieldError;
				}
			} else if ($(element).hasClass('required') &#038;&#038; fieldLength == 0) {
				fieldErrorMessage = requiredTextError;
			}
		} else if ($(element).is('.textarea.required') &#038;&#038; fieldLength == 0) {
			fieldErrorMessage = requiredTextareaError;
		} else if ($(element).is('.checkbox.required') &#038;&#038; !$(element).is(':checked')) {
			fieldErrorMessage = requiredCheckboxError;
		}

		if (!fieldErrorMessage) {
			return false;
		} else {
			if (customErrorSelectors.length &gt; 0) {
				for (i=0;i&lt;customErrorSelectors.length;i++) { //check for overrides
					if (customErrorSelectors[i] == element) {
						fieldErrorMessage = customErrorMessages[i];
					}
				}
			}
			addFieldError(formId, fieldId, fieldErrorMessage);
			return true;
		}
	}
}

function validateForm(formId, matchingElements) {
	removeAllErrors(formId);

	matchingElements.each(function(index) {
		var elementId = $(this).attr('id');
		var fieldErrorStatus = validateField(formId, elementId);
	});

	if (countFormErrors(formId) &gt; 0) {
		if (focusFirstError == true) {
			focusOnFirstError(formId);
		}
		if (errorSummary == true) {
			addFormError(formId);
		}
		return true;
	} else {
		if (errorSummary == true) {
			removeFormError(formId);
		}
		return false;
	}
}</code></pre>
<h2 id="expanded-functions">Expanded Functions</h2>
<pre><code>function buildElement(formId, fieldId) {
	var element = &quot;form#&quot;+formId+&quot; #&quot;+fieldId;
	return element;
}

function focusOnFirstError(formId) {
	$('form#'+formId+' input.'+inputErrorClass+':first').focus();
}

function formsToIgnore() { //check for forms to ignore
	var formIgnoreItems = &quot;&quot;;
	for (i=0;i&lt;ignoreForms.length;i++) {
		if (i&gt;0) {
			formIgnoreItems += &quot;, &quot;;
		}
		formIgnoreItems += ignoreForms[i];
	}
	return formIgnoreItems;
}

function countFormErrors(formId) {
	var errorCounter = $('form#'+formId+' '+inputWrapper+'.'+inputWrapperErrorClass).size();
	return errorCounter;
}

function addFormError(formId) {
	var formSelector = 'form#'+formId;
	var errorMessageSelector = formSelector+' p.error-summary';
	var errorCounter = countFormErrors(formId);
	if (errorCounter &gt; 0) {
		if ($(errorMessageSelector).length) {
			$(errorMessageSelector).html(errorCounter + ' field(s) are invalid.');
		} else {
			$(formSelector).prepend('&lt;p class=\&quot;error-summary\&quot;&gt;' + errorCounter + ' field(s) are invalid.&lt;/p&gt;');
		}
	}
}

function removeAllErrors(formId) {
	removeFormError(formId);
	removeAllFieldErrors(formId);
}

function removeFormError(formId) {
	$('form#'+formId+' p.error-summary').remove();
}

function removeAllFieldErrors(formId) {
	var formSelector = 'form#'+formId;
	$(formSelector+' '+inputWrapper).removeClass(inputWrapperErrorClass);
	$(formSelector+' input[type=text], '+formSelector+' textarea, '+formSelector+' input[type=checkbox]').removeClass(inputErrorClass);
	$(formSelector+' '+inputWrapper+' p.error-message').remove();
}

function addFieldError(formId, fieldId, fieldErrorMessage) {
	var element = buildElement(formId, fieldId);
	$(element).addClass(inputErrorClass)
			  .parents(inputWrapper).addClass(inputWrapperErrorClass)
									.append('&lt;p class=\&quot;error-message\&quot;&gt;&gt;' + fieldErrorMessage + '&lt;/p&gt;');
}

function removeFieldError(formId, fieldId) {
	var element = buildElement(formId, fieldId);
	$(element).removeClass(inputErrorClass)
			  .parents(inputWrapper).removeClass(inputWrapperErrorClass);
	$(element).parents(inputWrapper).children('p.error-message').remove();
}

function validateAlpha(alpha) {
	var regex = /^[-\sa-zA-Z]+$/
	return regex.test(alpha);
}

function validateDigit(digit) {
	var regex = /^[0-9]+$/
	return regex.test(digit);
}

function validateEmail(email) {
	var regex = /^(([^&lt;&gt;()[\]\\.,;:\s@\&quot;]+(\.[^&lt;&gt;()[\]\\.,;:\s@\&quot;]+)*)|(\&quot;.+\&quot;))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
	return regex.test(email);
}</code></pre>
<h2 id="options">Options</h2>
<pre><code>//Validator options
var eagerValidation = false; //true/false   if set to true, form will eagerly validate each field. False will validate only ever on form submission
var errorSummary = true; //true/false    if set to true will show error summary at the top of the form
var focusFirstError = true; //true/false    if set to true will refocus user input to first error field on form submission
var inputErrorClass = &quot;error&quot;;    //set the class name that will be appended to the form input/textarea when an error is detected
var inputWrapper = &quot;p&quot;;    //set the element type that is used to wrap the form input/textarea in your forms
var inputWrapperErrorClass = &quot;err&quot;;    //set the class name that will be appended to the wrapper of the input/textarea when an error is detected

//Error Messages
var requiredTextError = &quot;cannot be empty&quot;; //Textbox error
var requiredTextareaError = &quot;cannot be empty&quot;; //Textarea error
var requiredCheckboxError = &quot;needs to be ticked&quot;; //Checkbox error
var alphaFieldError = &quot;characters only, no numbers&quot;; //Alpha Textbox error
var digitFieldError = &quot;numbers only, no characters&quot;; //Numeric Textbox error
var emailFieldError = &quot;valid email address only&quot;; //email Textbox error

var ignoreForms = ['#search-form']; //add any forms you need want the form to ignore, e.g search forms, etc. This can be ignored as long as none of the form inputs have 'required' or other validation classes attached

var customErrorSelectors = ['form#testform #el_0','form#testform #el_2']; //include form Id and element Id!
var customErrorMessages = ['this is an error message override, as specified in the config options','this is another error message override']; //Relates directly to customErrorSelectors</code></pre>
<h2 id="html">HTML</h2>
<p>The script assumes an element wrapper is used, and must be included in the options under inputWrapper, the default is &lt;p&gt;. See the examples included for the structure of HTML compatible.</p>
<h2 id="examples">Examples</h2>
<p><a target="_blank" href="http://www.ajgraham.com/codestore/jqueryformvalidator/formvalidation-basic.html">Simple Example</a><br />
<a target="_blank" href="http://www.ajgraham.com/codestore/jqueryformvalidator/formvalidation-complex.html">More Complex Example</a></p>
<h2 id="download">Download</h2>
<p>Options script &#8211; <strong>required for validation script to work</strong></p>
<p><a href="http://www.ajgraham.com/codestore/jqueryformvalidator/jquery.form-validator.zip">Download everything in 1 zipped package</a></p>
<h2 id="license">License</h2>
<p>Released under <a href="http://www.ajgraham.com/codestore/jqueryformvalidator/MIT-LICENSE.txt">MIT License</a>.</p>
<h2 id="to-dos">To Do&#8217;s</h2>
<ul>
<li>Improve the efficiency of the code execution.</li>
<li>Add min-length class options for fields.</li>
</ul>
<h2 id="change-log">Change-log</h2>
<p>2010/05/20: v0.2 released</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ajgraham.com/2010/05/simple-but-powerful-jquery-form-validation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tracking Email Signature click throughs</title>
		<link>http://www.ajgraham.com/2010/05/tracking-analytics-by-email-campaign/</link>
		<comments>http://www.ajgraham.com/2010/05/tracking-analytics-by-email-campaign/#comments</comments>
		<pubDate>Thu, 13 May 2010 21:23:51 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[campaign]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[google analytics]]></category>
		<category><![CDATA[monitoring]]></category>
		<category><![CDATA[tracking]]></category>

		<guid isPermaLink="false">http://www.ajgraham.com/?p=352</guid>
		<description><![CDATA[Update 08/2011: GMail has since added the ability to use HTML within signatures in the online version which simplifies much of what I originally wrote. A while ago I thought about how best to create a more modern and useful email signature. At the same time I was doing some [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Update 08/2011</strong>: GMail has since added the ability to use HTML within signatures in the online version which simplifies much of what I originally wrote.</p>
<p>A while ago I thought about how best to create a more modern and useful email signature. At the same time I was doing some work with Google Analytics and thought it might be useful to track how many people click on my website link in my signature. I decided to use the following bit of code which would track it:</p>
<pre><code>&lt;a style="color:#353535" title="www.ajgraham.com/" href="http://www.ajgraham.com/?utm_source=Signature&#038;utm_medium=Email&#038;utm_term=Gmail&#038;utm_campaign=Email%2BSignature"&gt;
www.ajgraham.com/
&lt;/a&gt;</code></pre>
<p>The inline colour is used so the line isn&#8217;t the nasty default blue, change the #colour to anything you like.<br />
Change the title attribute to whatever you like, or omit it.</p>
<p>The only problem with using the above is that using it natively within GMail or an online web based email will not process it, and the only way to use it would be to use the full (nasty) URL like:
<pre><code>http://www.ajgraham.com/?utm_source=Signature&#038;utm_medium=Email&#038;utm_term=Gmail&#038;utm_campaign=Email%2BSignature</code></pre>
<p>There&#8217;s a workaround though, but it forces you to use a mail client like Thunderbird or Outlook and use it as part of a signature, which is a bit of a hassle simply to track email signature clicks. Unfortunately, until GMail allows full HTML in its online signatures then this is the only automated way of doing this.</p>
<p>It is interesting how many people click on it though, and the level of potential granularity if you wanted to take it even further to track different sets of email correspondents.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ajgraham.com/2010/05/tracking-analytics-by-email-campaign/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Website redevelopment</title>
		<link>http://www.ajgraham.com/2010/04/website-redevelopment/</link>
		<comments>http://www.ajgraham.com/2010/04/website-redevelopment/#comments</comments>
		<pubDate>Thu, 01 Apr 2010 15:40:06 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[redesign]]></category>
		<category><![CDATA[site]]></category>

		<guid isPermaLink="false">http://www.ajgraham.com/?p=270</guid>
		<description><![CDATA[I moved to Prague about a month ago, despite a lack of blog posts, I have been both a live and working (although not doing any bank manager pleasing work in the sense of making any money). Just managed to finish my own website redesign which I&#8217;d spent a while [...]]]></description>
			<content:encoded><![CDATA[<p>I moved to Prague about a month ago, despite a lack of blog posts, I have been both a live and working (although not doing any bank manager pleasing work in the sense of making any money). Just managed to finish my own website redesign which I&#8217;d spent a while on as I was really working hard on creating something both a little different to the usual corporate uber serious looking websites while not wanting it to be too over the top as to scare people. I hope I&#8217;ve found a pleasant middle ground using some semi transparency affects using transparent .png&#8217;s, although I would have used the new RGBA CSS3 rules had Internet Explorer supported them <img src='http://www.ajgraham.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </p>
<p>I also decided to create it using WordPress as having completed 1 WordPress website recently, and working on another one at the moment, I&#8217;ve learnt an alot about it and grown rather fond of it.</p>
<p>I&#8217;ve also been developing my own JQuery plugin, which I&#8217;m going to release under a GPL license in the next few days. I&#8217;ll post more details soon&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ajgraham.com/2010/04/website-redevelopment/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SEO analysis for dummies: links</title>
		<link>http://www.ajgraham.com/2010/01/seo-analysis-for-dummies-links/</link>
		<comments>http://www.ajgraham.com/2010/01/seo-analysis-for-dummies-links/#comments</comments>
		<pubDate>Sat, 09 Jan 2010 11:13:42 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[analysis]]></category>
		<category><![CDATA[basics]]></category>
		<category><![CDATA[dummies]]></category>
		<category><![CDATA[SEO]]></category>
		<category><![CDATA[statistic]]></category>
		<category><![CDATA[website]]></category>

		<guid isPermaLink="false">http://www.ajgraham.com/?p=207</guid>
		<description><![CDATA[What follows are the basic few steps I start with when analysing a site: 1/ Checking backlinks (also known as incoming links, inbound links, inlinks, and inward links &#8211; basically they&#8217;re pages that link to your website/page) Use a Google Advanced Search: for example http://www.google.co.uk/search?as_lq=google.com&#038;btnG=Search The basic idea here is [...]]]></description>
			<content:encoded><![CDATA[<p>What follows are the basic few steps I start with when analysing a site:</p>
<p>1/ Checking backlinks (also known as incoming links, inbound links, inlinks, and inward links &#8211; basically they&#8217;re pages that link to your website/page)</p>
<p>Use a <a href="http://www.google.co.uk/advanced_search">Google Advanced Search</a>: for example <a href="http://www.google.co.uk/search?as_lq=google.com&#038;btnG=Search">http://www.google.co.uk/search?as_lq=google.com&#038;btnG=Search</a></p>
<p>The basic idea here is to see what websites link to your website. Google (and other Search Engines) use both the number of links and the weight of the website linking to you. I.e the more popular the site that links to you, the more &#8216;weight&#8217; it adds to your website, the more &#8216;weight&#8217; your website has the higher up the search ranking your site will be. There are even more complicated factors involved in this algorithm but it&#8217;s probably too in depth for this brief guide.</p>
<p>2/ Assuming you have some websites/pages that link to your website it&#8217;s a good idea to analyse them for quality. Ideally you want links from reputable websites with a good amount of visitors, this ensures that  some of there kudos &#8216;rubs&#8217; off on you when they link to you.</p>
<p>I&#8217;ll continue this subject in another post as I want to cover keyword usage, link formatting and optimising websites&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ajgraham.com/2010/01/seo-analysis-for-dummies-links/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Classifying your website and content</title>
		<link>http://www.ajgraham.com/2009/10/classifying-your-website-and-content/</link>
		<comments>http://www.ajgraham.com/2009/10/classifying-your-website-and-content/#comments</comments>
		<pubDate>Sun, 25 Oct 2009 00:13:18 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[categorise]]></category>
		<category><![CDATA[classify]]></category>
		<category><![CDATA[filter content]]></category>
		<category><![CDATA[FOSI]]></category>
		<category><![CDATA[ICRA]]></category>
		<category><![CDATA[label]]></category>
		<category><![CDATA[self regulation]]></category>

		<guid isPermaLink="false">http://www.ajgraham.com/?p=189</guid>
		<description><![CDATA[When creating a website for any company or organisation its important to adhere to as many generally accepted web standards as possible. Due to the huge amount of content on the Internet, and the range of it too, the market in Internet filtering software continues to grow. There&#8217;s no legal [...]]]></description>
			<content:encoded><![CDATA[<p>When creating a website for any company or organisation its important to adhere to as many generally accepted web standards as possible. Due to the huge amount of content on the Internet, and the range of it too, the market in Internet filtering software continues to grow. There&#8217;s no legal obligation to categorise a websites content, but from an ethical point of view you should do if your content is not suitable for children.</p>
<p>You may also want to categorise your content simply to ensure it isn&#8217;t wrongly categorised by filtering software.</p>
<p>I use a method devised by <abbr title="Family Online Safety Institute">FOSI</abbr> who are a non-profit organisation who have been devising Internet categorisation techniques since 1994.</p>
<p><a href="http://www.icra.org/webmasters/">Find out more about FOSI.</a></p>
<p><a href="http://www.icra.org/support/howtolabel/">How to label your website or content.</a></p>
<p><a href="http://www.icra.org/label/generator/">Start labelling your website or content.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ajgraham.com/2009/10/classifying-your-website-and-content/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

