<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
<channel><generator>http://textpattern.com/?v=4.0.8</generator>
<title>beardscratchers.com - Journal - Web</title>
<link>http://beardscratchers.com/</link>

<description>A music-focused web experiment and creative-arts journal from London, England</description>
<pubDate>Thu, 16 Jul 2009 08:55:18 GMT</pubDate>

<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/beardscratcherscom-journal-web" type="application/rss+xml" /><item><title>Best API Update. Ever.</title>
<content:encoded>
<![CDATA[<p class="first">One thing I <strong>love</strong> about all the <span class="caps">API</span>s and web-services out there&#8212;especially those from commercial entities&#8212;is that they&#8217;re driven, designed and built <em>by</em> developers <em>for</em> developers. </p>

	<p>They bypass all the detritus in &#8216;economic leveraging&#8217;, &#8216;strategic incubation&#8217;, &#8216;synergistic e-business&#8217; and the rest of the bullshit and produce something simply for the challenge and love of experimentation. Last week <a href="http://flickr.com">flickr</a> exemplified this beautifully, and really renewed my faith in the development and web community at-large having a good sense of humour. Yet at the same time pushing forward at what&#8217;s possible with data and technology. I present:</p>

	<p><img src="http://beardscratchers.com/images/125.jpg" width="500" height="341" alt="" class="nobg ic" /></p>

	<p class="c"><a href="http://code.flickr.com/blog/2009/03/03/panda-tuesday-the-history-of-the-panda-new-apis-explore-and-you/">The Rainbow Vomiting Panda of Awesomeness</a></p>

	<p>If the image wasn&#8217;t enough to warrant the highest of praise&#8212;I foresee pandas as the new meme to beat unicorns&#8212; flickr have just launched a couple of very curious and <em>fun</em> <span class="caps">API</span> calls that may have limited usefulness but really exalt what today&#8217;s Web should be about. </p>

	<p>We&#8217;re no longer a passive Web of static, inaccessible content. Today&#8217;s Web is a huge, living, breathing pool of data and it&#8217;s all about seeing what we can do with it!</p>

	<p><strong>Long may the renaissance continue!</strong></p>]]>
</content:encoded>
<link>http://beardscratchers.com/journal/greatest-api-update-ever</link>
<pubDate>Mon, 09 Mar 2009 23:58:57 GMT</pubDate>
<dc:creator>Nick</dc:creator>
<guid isPermaLink="false">tag:beardscratchers.com,2009-03-09:4357bcf9c70b1807791cd39e76b16baa/a9820d8d3f1ae8731cf823e196e0cebc</guid>
</item>
<item><title>How to inline Opensocial Message Bundles for improved performance</title>
<content:encoded>
<![CDATA[<p class="first">In my work at <a href="http://www.huddle.net">team collaboration</a> startup, Huddle.net, we&#8217;ve encountered a number of issues with externally referenced <a href="http://wiki.opensocial.org/index.php?title=Localizing_OpenSocial_applications">message bundles</a> in our Opensocial application, Huddle Workspaces.</p>

	<p><img src="http://beardscratchers.com/images/122.png" width="288" height="70" alt="" class="nobg ir" /> Due to the size and scale of of the application&#8212;it&#8217;s quite big and complex in comparison to many Opensocial apps&#8212;our message bundle <span class="caps">XML</span> files contain a lot of content and, as a consequence, consume quite a lot of a bandwidth over the wire. </p>

	<p>Why is this a problem? Well, it shouldn&#8217;t be, but many Opensocial containers opt not to cache message bundles, and instead request them on every application invocation. The result is that network dropouts, latency or server-load can mean your message bundles occasionally fail to reach the consumer server and entirely prevent your app from loading. End-users shouldn&#8217;t ever have to suffer as a result of server-to-server communication.</p>

	<p>So, in lieu of consistent caching across Opensocial containers, this issue can be sidestepped by <em>inlining</em> the message bundle content inside your application gadget specification. This is a new feature introduced in Opensocial 0.8.1, and so you should ensure the container you&#8217;re working with is operating on a 0.8.1 codebase.</p>

	<h2>How to Inline a Message Bundle</h2>

	<p>It&#8217;s actually <em>very</em> simple, but it&#8217;s also something that isn&#8217;t officially documented anywhere. Opensocial development often involves shooting in the dark&#8230; but fortunately it&#8217;s well enough spec&#8217;ed that a little bit of guesswork goes a long way.</p>

	<p>Message bundles are always referenced from the <code>&lt;ModulePrefs /&gt;</code> block in a gadget spec, and look something like this:</p>

 <div class="code-sample"><table summary="This table lists the contents of the file moduleprefs-external"><colgroup><col class="line-no" /><col class="line" /></colgroup>
<thead><tr><th>#</th><th>Code</th></tr></thead>
<tbody><tr class="odd"><td>0001</td><td class="tab0">&lt;ModulePrefs title=&quot;beardscratchers.com&quot; author_email=&quot;nick@example.com&quot;&gt;</td></tr>
<tr><td>0002</td><td class="tab1">&lt;Require feature=&quot;tabs&quot; /&gt;</td></tr>
<tr class="odd"><td>0003</td><td class="tab1">&lt;Require feature=&quot;views&quot; /&gt;</td></tr>
<tr><td>0004</td><td class="tab1">&lt;Require feature=&quot;setprefs&quot;/&gt;</td></tr>
<tr class="odd"><td>0005</td><td class="tab1">&lt;Require feature=&quot;dynamic-height&quot;/&gt;</td></tr>
<tr><td>0006</td><td class="tab1">&lt;Require feature=&quot;settitle&quot;/&gt;</td></tr>
<tr class="odd"><td>0007</td><td class="tab1">&lt;Require feature=&quot;opensocial-0.8.1&quot;/&gt;</td></tr>
<tr><td>0008</td><td class="tab1">&lt;Locale messages=&quot;http://beardscratchers.com/lang/ALL_ALL.xml&quot;/&gt;</td></tr>
<tr class="odd"><td>0009</td><td class="tab1">&lt;Locale lang=&quot;fr&quot; country=&quot;fr&quot; messages=&quot;http://beardscratchers.com/lang/fr_ALL.xml&quot;/&gt;</td></tr>
<tr><td>0010</td><td class="tab1">&lt;Locale lang=&quot;es&quot; messages=&quot;http://beardscratchers.com/lang/es_ALL.xml&quot;/&gt;</td></tr>
<tr class="odd"><td>0011</td><td class="tab0">&lt;/ModulePrefs&gt;</td></tr>
<tr><td>0012</td><td class="tab0">&#160;</td></tr>
</tbody></table>
</div>

	<p>By simply removing the <code>messages</code> attribute from each <code>&lt;Locale /&gt;</code> element, and placing the relevant message bundle content (excluding the xml prolog), message bundles are no longer referenced externally and load along with your gadget spec:</p>

 <div class="code-sample"><table summary="This table lists the contents of the file moduleprefs-inline"><colgroup><col class="line-no" /><col class="line" /></colgroup>
<thead><tr><th>#</th><th>Code</th></tr></thead>
<tbody><tr class="odd"><td>0001</td><td class="tab0">&lt;ModulePrefs title=&quot;beardscratchers.com&quot; author_email=&quot;nick@example.com&quot;&gt;</td></tr>
<tr><td>0002</td><td class="tab1">&lt;Require feature=&quot;tabs&quot; /&gt;</td></tr>
<tr class="odd"><td>0003</td><td class="tab1">&lt;Require feature=&quot;views&quot; /&gt;</td></tr>
<tr><td>0004</td><td class="tab1">&lt;Require feature=&quot;setprefs&quot;/&gt;</td></tr>
<tr class="odd"><td>0005</td><td class="tab1">&lt;Require feature=&quot;dynamic-height&quot;/&gt;</td></tr>
<tr><td>0006</td><td class="tab1">&lt;Require feature=&quot;settitle&quot;/&gt;</td></tr>
<tr class="odd"><td>0007</td><td class="tab1">&lt;Require feature=&quot;opensocial-0.8.1&quot;/&gt;</td></tr>
<tr><td>0008</td><td class="tab1">&lt;Locale&gt;</td></tr>
<tr class="odd"><td>0009</td><td class="tab2">&lt;messagebundle&gt;</td></tr>
<tr><td>0010</td><td class="tab3">&lt;msg name=&quot;hello&quot;&gt;</td></tr>
<tr class="odd"><td>0011</td><td class="tab4">Hello!</td></tr>
<tr><td>0012</td><td class="tab3">&lt;/msg&gt;</td></tr>
<tr class="odd"><td>0013</td><td class="tab2">&lt;/messagebundle&gt;</td></tr>
<tr><td>0014</td><td class="tab1">&lt;/Locale&gt;</td></tr>
<tr class="odd"><td>0015</td><td class="tab1">&lt;Locale lang=&quot;fr&quot; country=&quot;fr&quot;&gt;</td></tr>
<tr><td>0016</td><td class="tab2">&lt;messagebundle&gt;</td></tr>
<tr class="odd"><td>0017</td><td class="tab3">&lt;msg name=&quot;hello&quot;&gt;</td></tr>
<tr><td>0018</td><td class="tab4">Bonjour!</td></tr>
<tr class="odd"><td>0019</td><td class="tab3">&lt;/msg&gt;</td></tr>
<tr><td>0020</td><td class="tab2">&lt;/messagebundle&gt;</td></tr>
<tr class="odd"><td>0021</td><td class="tab1">&lt;Locale lang=&quot;es&quot;&gt;</td></tr>
<tr><td>0022</td><td class="tab2">&lt;messagebundle&gt;</td></tr>
<tr class="odd"><td>0023</td><td class="tab3">&lt;msg name=&quot;hello&quot;&gt;</td></tr>
<tr><td>0024</td><td class="tab4">Hola!</td></tr>
<tr class="odd"><td>0025</td><td class="tab3">&lt;/msg&gt;</td></tr>
<tr><td>0026</td><td class="tab2">&lt;/messagebundle&gt;</td></tr>
<tr class="odd"><td>0027</td><td class="tab1">&lt;/Locale&gt;</td></tr>
<tr><td>0028</td><td class="tab0">&lt;/ModulePrefs&gt;</td></tr>
<tr class="odd"><td>0029</td><td class="tab0">&#160;</td></tr>
</tbody></table>
</div>

	<p>We&#8217;ve found that it&#8217;s much more common for gadget specs to be cached hard. Thus the additional weight of inlining your message bundle content inside your gadget <span class="caps">XML</span> is negated, and the application should&#8212;container-dependant&#8212;get some improvements to stability and performance.</p>

	<p>There is one caveat. Inlining content introduces maintenance and development issues, especially if you&#8217;re running several gadget specs for different enviroments i.e. development, QA and live. In respect of this, I&#8217;d recommend keeping all your message bundles in external files and instead adding something into your deployment process that will perform the inlining as and when it is needed.</p>]]>
</content:encoded>
<link>http://beardscratchers.com/journal/how-to-inline-opensocial-message-bundles-for-improved-performance</link>
<pubDate>Sun, 08 Mar 2009 18:14:19 GMT</pubDate>
<dc:creator>Nick</dc:creator>
<guid isPermaLink="false">tag:beardscratchers.com,2009-03-08:4357bcf9c70b1807791cd39e76b16baa/77b589fb0222185b914044dd3a0f5772</guid>
</item>
<item><title>5 Hot Icon Sets for your Next Web Application Design</title>
<content:encoded>
<![CDATA[<p class="first">In this age of web-development, where static brochure sites are truly old-hat and every client demands interactivity, having a consistent theme for user interaction has become one of the most important steps in realising a successful design. </p>

	<p>One of the first lessons of <acronym title="Human Computer Interaction"><span class="caps">HCI</span></acronym> is the concept of <a href="http://en.wikipedia.org/wiki/Interface_metaphors">interface metaphors</a> &#8211; singular design elements that quickly infer an action or result of the user based on familiarity and association. The Recycle Bin and the Folder being two of the most well-known. </p>

	<p>On the web, icon design contributes to this hugely, and the success of a site&#8217;s design is largely thanks to a consistent icon set. Unfortunately most of us don&#8217;t have the time, patience (or talent!) to create an all-encompassing set of icons for a project, and so we must rely on the excellent work of designers around the World to help us on our way. </p>

	<p>Here are 5 free icon sets, available for commercial use, that I believe fit the bill over the plethora of icon sets available:</p>

	<h2>FamFamFam Silk</h2>

	<p>How could I not start with the ubiquitous Silk set. It&#8217;s a set that is seen absolutely everywhere, for a very good reason. It&#8217;s a huge set of 700 beautifully crafted icons that are free of a strong design-style; able to fit into any design and for any purpose.</p>

	<p class="clear"><img src="http://beardscratchers.com/images/103.png" width="16" height="16" alt="" class="nobg" /> <img src="http://beardscratchers.com/images/104.png" width="16" height="16" alt="" class="nobg" /> <img src="http://beardscratchers.com/images/101.png" width="16" height="16" alt="" class="nobg" /> <img src="http://beardscratchers.com/images/100.png" width="16" height="16" alt="" class="nobg" /> <img src="http://beardscratchers.com/images/102.png" width="16" height="16" alt="" class="nobg" /> <img src="http://beardscratchers.com/images/99.png" width="16" height="16" alt="" class="nobg" /></p>

	<p>&raquo; <a href="http://www.famfamfam.com/lab/icons/silk/">Download FamFamFam Silk</a></p>

	<h2>FamFamFam Mint</h2>

	<p>I&#8217;m particularly fond of this small set of minty-hued icons (apparently inspired by Shaun Inman&#8217;s <a href="http://haveamint.com">Mint</a>). While they might not find their place in every design, their minimalism and space-saving dimensions deserves giving them a look.</p>

	<p class="clear"><img src="http://beardscratchers.com/images/98.png" width="11" height="11" alt="" class="nobg" /> <img src="http://beardscratchers.com/images/97.png" width="11" height="11" alt="" class="nobg" /> <img src="http://beardscratchers.com/images/95.png" width="11" height="11" alt="" class="nobg" /> <img src="http://beardscratchers.com/images/96.png" width="11" height="11" alt="" class="nobg" /></p>

	<p>&raquo; <a href="http://www.famfamfam.com/lab/icons/mint/">Download FamFamFam Mint</a></p>

	<h2>Sweetie</h2>

	<p>Compact, but useful icon set with a glossy and colourful style. Comes with 4 icons sizes, from 8&#215;8 up to 24&#215;24, for a number of the included icons.</p>

	<p class="clear"><img src="http://beardscratchers.com/images/105.png" width="16" height="16" alt="" class="nobg" /> <img src="http://beardscratchers.com/images/106.png" width="16" height="16" alt="" class="nobg" /> <img src="http://beardscratchers.com/images/107.png" width="16" height="16" alt="" class="nobg" /> <img src="http://beardscratchers.com/images/108.png" width="16" height="16" alt="" class="nobg" /> <img src="http://beardscratchers.com/images/109.png" width="16" height="16" alt="" class="nobg" /></p>

	<p>&raquo; <a href="http://sweetie.sublink.ca/">Download Sweetie</a></p>

	<h2>n-design Mini Pixel-Icons</h2>

	<p>A smart and well-featured set of 320 14&#215;14 icons; particularly good for e-commerce sites, as a good number of credit-card, shopping-cart and basket icons are included. Comes bundled with multiple shades to fit into and brighten up a plain app design.</p>

	<p class="clear"><img src="http://beardscratchers.com/images/116.gif" width="14" height="14" alt="" class="nobg" /> <img src="http://beardscratchers.com/images/117.gif" width="14" height="14" alt="" class="nobg" /> <img src="http://beardscratchers.com/images/118.gif" width="16" height="16" alt="" class="nobg" /> <img src="http://beardscratchers.com/images/119.gif" width="14" height="14" alt="" class="nobg" /> <img src="http://beardscratchers.com/images/120.gif" width="14" height="14" alt="" class="nobg" /> <img src="http://beardscratchers.com/images/121.gif" width="14" height="14" alt="" class="nobg" /></p>

	<p>&raquo; <a href="http://www.ndesign-studio.com/resources/mini-pixel-icons/">Download n-design Mini Pixel-Icons</a></p>

	<h2>Pinvoke Fugue</h2>

	<p>A huge, stylish icon set that I&#8217;ve not seen as widespread in the wild as Silk. Certainly one of the best large icon sets available on the Web.</p>

	<p class="clear"><img src="http://beardscratchers.com/images/110.png" width="16" height="16" alt="" class="nobg" /> <img src="http://beardscratchers.com/images/111.png" width="16" height="16" alt="" class="nobg" /> <img src="http://beardscratchers.com/images/112.png" width="16" height="16" alt="" class="nobg" /> <img src="http://beardscratchers.com/images/113.png" width="16" height="16" alt="" class="nobg" /> <img src="http://beardscratchers.com/images/114.png" width="16" height="16" alt="" class="nobg" /> <img src="http://beardscratchers.com/images/115.png" width="16" height="16" alt="" class="nobg" /></p>

	<p>&raquo; <a href="http://www.pinvoke.com/">Download Pinvoke Fugue</a></p>

	<h2>Closing Note</h2>

	<p>Most icon sets come prepared with transparent backgrounds, using <span class="caps">PNG</span> alpha-transparency. This type of transparency is unsupported in IE6 and produces undesirable results.</p>

	<p>The simplest solution to this problem, is to create alternative versions for IE6 in <span class="caps">PNG</span>-8 format (which supports 1-bit transparency). A little bit of pixel-pushing will be needed to make them look perfect, but I&#8217;ve never had any problems using this workaround. The Pinvoke and Sweetie sets already come bundled with alternative IE6-friendly versions.</p>]]>
</content:encoded>
<link>http://beardscratchers.com/journal/5-icon-sets-for-your-next-web-app</link>
<pubDate>Tue, 30 Dec 2008 10:59:24 GMT</pubDate>
<dc:creator>Nick</dc:creator>
<guid isPermaLink="false">tag:beardscratchers.com,2008-12-14:4357bcf9c70b1807791cd39e76b16baa/ebaacfc3ec0af065dc4fe7aaace17207</guid>
</item>
<item><title>Compendium Videos now Triple Filtered for your Pleasure</title>
<content:encoded>
<![CDATA[<p class="first">Since introducing <span class="caps">MTV</span> networks into the Compendium, I happened across <a href="http://developer.yahoo.com/music/">Yahoo&#8217;s excellent Music <span class="caps">API</span></a>, which offers up the Yahoo music video catalogue as part of the service. Good news, these are now  available through the Compendium. This brings the total number of officially released music videos to over 60,000.</p>

	<p><img src="http://beardscratchers.com/images/92.gif" width="150" height="65" alt="" class="nobg ir" />Well, almost&#8230; In combining the two content networks, I&#8217;ve had to be quite careful about what appears where, to whom and how. As I mentioned in a previous post about <span class="caps">MTV</span> Networks, video content comes from the most restricted datafeeds used on the Compendium, particularly regarding geographical location. Dependant on your location, and licensing, some videos may not be available.</p>

	<p>When videos are loaded in an artist profile on the Compendium, an <span class="caps">AJAX</span> request invokes two simultaneous server-side requests to go off and retrieve videos from Y!Music and <span class="caps">MTVN</span>&#8212;this is cached. Once these are successfully retrieved, they are combined and then passed off for pre-filtering.</p>

	<p>Filtering the video feeds involves three steps:</p>

	<ol>
		<li>Remove duplicate videos, based on the song title</li>
		<li>Remove videos that are not specifically by the artist or under the artist&#8217;s name, but may have been returned as part of the webservice search query</li>
		<li>Remove videos that are restricted either by geographical location or are not available for external embedding.</li>
	</ol>

	<p>Geographical filtering is done with the help of the <a href="http://pear.php.net/package/Net_GeoIP/">Net_GeoIP</a> Pear package. This is OO version of the regular Pear GeoIP package that queries the flat Maxmind GeoIP databases. This returns geolocation information based on IP. It is still in beta, but appears completely stable. It can be installed from the command-line using:</p>

<pre><code>$ pear config-set preferred_state beta
$ pear install Net_GeoIP
$ pear config-set preferred_state stable
</code></pre>

	<p>Conveniently it uses a Singleton pattern to stop the flat database files being initialised multiple times within a script. However it is still by far the slowest data lookup in the Compendium. I wrapped my own lookup methods into another Singleton, and used <code>$_SESSION</code> values to store country and city lookups. This prevent multiple database lookups happening, unless they change, since geolocation is used not only in Video feeds but also Events data lookups. Further improvements can be made by pushing the flat database files into memory or into a <span class="caps">DBMS</span> like MySQL.</p>

	<p>With this geolocation data at hand, <span class="caps">MTVN</span> videos are filtered based on attributes in the returned dataset. Y!Music works slightly differently, in that each geographical location has it&#8217;s own base <span class="caps">API</span> address, returning videos only available in that region. So Y!Music is filtered at the source, rather than at the point of retrieval.</p>

	<p>Once this filtering takes place, the resulting array is checked to see if it still contains any valid videos. If there are no videos available, an empty response is returned to the page. This return value causes the Compendium javascript to invoke another <span class="caps">AJAX</span> call to retrieve fallback content from Youtube. Youtube nearly always returns results from its catalogue of x million videos; but these still need a little bit of filtering and nudging to produce accurate results.</p>

	<p>All these lookups are cached, and the <span class="caps">AJAX</span> lookups are bypassed when valid caches exist, meaning that videos are injected directly into the page when it renders.</p>

	<p>If you&#8217;re in the US, UK, much or Europe and a few other places, you should see official music videos appearing for selected artists. If not, you&#8217;ll get Youtube results appearing.</p>

	<p>Some examples:</p>

	<ul>
		<li><a href="http://beardscratchers.com/compendium/britney-spears#av">Britney Spears Videos</a></li>
		<li><a href="http://beardscratchers.com/compendium/led-zeppelin#av">Led Zeppelin Videos</a></li>
		<li><a href="http://beardscratchers.com/compendium/my-brightest-diamond#av">My Brightest Diamond Videos</a></li>
	</ul>

	<p>The last, however, is US only. So to end this post on a high-note, here&#8217;s the excellent video by Raf Toro of  <em>My Brightest Diamond</em> &#8211; <strong>Inside a Boy</strong>. In hi-def, courtesy of <a href="http://www.vimeo.com/1697530">Vimeo</a> (coming soon to the Compendium&#8230; perhaps):</p>

 <object width="667" height="500"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=1697530&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=1&amp;color=ffffff&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=1697530&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=1&amp;color=ffffff&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="667" height="500"></embed></object><p><a href="http://vimeo.com/1697530">Inside  A Boy</a> from <a href="http://vimeo.com/rafatoro">Rafa Toro</a> on <a href="http://vimeo.com">Vimeo</a>.</p>

	<p>If you find any bugs with the video feeds, please let me know.</p>]]>
</content:encoded>
<link>http://beardscratchers.com/journal/compendium-videos-now-triple-filtered</link>
<pubDate>Sun, 30 Nov 2008 20:41:08 GMT</pubDate>
<dc:creator>Nick</dc:creator>
<guid isPermaLink="false">tag:beardscratchers.com,2008-11-30:4357bcf9c70b1807791cd39e76b16baa/ed5d8fd45908f2958165f21a9a3acf1f</guid>
</item>
<item><title>Fixing the Enter Keypress Event in ASP.NET with jQuery</title>
<content:encoded>
<![CDATA[<p class="first">One of the most frustrating things about working with .NET from a front-end developer&#8217;s viewpoint is the Single Form Model. Enclosing an entire website or web-application in one single <code>&lt;form&gt;</code> element poses a number of accessibility and usability problems surrounding form input and usage. One of these is ensuring the correct default actions are assigned to sets of input fields when the enter key is used.</p>

	<p><img src="http://beardscratchers.com/images/88.gif" width="291" height="90" alt="" class="nobg ir" />Traditionally, the default action for a <code>&lt;form&gt;</code> is to fire the <em>first submit button</em> found within the current <code>&lt;form&gt;</code> element. Every form has one default action. </p>

	<p>Striking the enter key within a text input field should submit the current set of&#8212;logically grouped&#8212;fields; <strong>this is the expected behaviour</strong>.  For pages with multiple forms and actions, this is easily separated by having multiple <code>&lt;form&gt;</code> elements, each with their own submit buttons and actions. Each form operates independently, has its own default action, and doesn&#8217;t interfere with other forms.</p>

	<p>In the Single Form Model, the presence of just one <code>&lt;form&gt;</code> element, means that different default actions cannot be easily separated. Every input field on the page is automatically tied to just <em>one</em> default action &#8211; the first submit button on the page. </p>

	<p>Take a blog site as an example &#8211; like this very page! It has a search form at the top, with associated submit button, a comment form further down the page and perhaps another form for signing up to a newsletter. Implemented with the Single Form Model, only the search form will produce the correct behaviour as it introduces the first submit button on the page. All subsequent fields will be tied to this same button as their  default action &#8211; submitting a comment by pressing enter would cause the search form to submit, as would signing up to a newsletter. Not particularly useful.</p>

	<h2>Can we cure this problem?</h2>

	<p>The answer is yes&#8230; partially. The problem we have concerns UI behaviour. Any solution needs to manipulate and override behaviour, and this is the domain of Javascript. We can&#8217;t manipulate the markup in our favour as we&#8217;re under the control of the Single Form Model (not without a complete switch to .NET <span class="caps">MVC</span> anyway). But there&#8217;s a conflict here&#8212;javascript is not a fully accessible technology. There are many environments where users do not have Javascript available.</p>

	<p>However, in this case, using Javascript is an acceptable answer&#8212;this <em>is</em> progressive enhancement of sorts. We&#8217;re not adding a dependency on Javascript, merely enhancing the usability of the form inputs for those users with it enabled. Javascript-disabled users will still be able to use the form, except they will experience the &#8216;broken&#8217; behaviour. Form accessibility in .NET is pretty horrendous anyway, so anything we can do to make improvements is better than nothing at all.</p>

	<h2>Doesn&#8217;t .NET provide a solution already?</h2>

	<p>Yes, it does in version 2.0 and above. This is the <a href="http://www.w3schools.com/aspnet/prop_webcontrol_panel_defaultbutton.asp">defaultbutton attribute</a>, which can be used in <code>&lt;asp:panel /&gt;</code> and <code>&lt;form&gt;</code>.  Fine, so why not use this? There&#8217;s no real reason not to, <em>if you&#8217;re starting from scratch</em> and don&#8217;t mind crufty .aspx pages.  </p>

	<p>But this wasn&#8217;t suitable for me. In an existing codebase, this requires a lot of extra change, and the addition of specific panels to group related sets of form fields is <em>completely</em> unnecessary. An <span class="caps">HTML</span> element already exists for that: <code>&lt;fieldset&gt;</code>. Yes, the mighty fieldset-who would have thought?! In any sanely coded page, fieldsets group fields, and so we already have part of the solution without needing to make any changes. </p>

	<p><div class="code-sample"><table summary="This table lists the contents of the file keylistener-markup"><colgroup><col class="line-no" /><col class="line" /></colgroup>
<thead><tr><th>#</th><th>Code</th></tr></thead>
<tbody><tr class="odd"><td>0001</td><td class="tab0">&lt;fieldset&gt;</td></tr>
<tr><td>0002</td><td class="tab1">&lt;legend&gt;Search&lt;/legend&gt;</td></tr>
<tr class="odd"><td>0003</td><td class="tab1">&lt;input type=&quot;text&quot; id=&quot;query&quot; name=&quot;query&quot; value=&quot;&quot; /&gt;</td></tr>
<tr><td>0004</td><td class="tab1">&lt;button type=&quot;submit&quot; name=&quot;search&quot; id=&quot;search&quot;&gt;Search&lt;/button&gt;</td></tr>
<tr class="odd"><td>0005</td><td class="tab0">&lt;/fieldset&gt;</td></tr>
</tbody></table>
<p><a href="http://beardscratchers.com/file_download/20/keylistener-markup.txt">get this code</a></p>
</div></p>

	<p>The other reason for rolling our own solution is that <code>defaultbutton</code> doesn&#8217;t offer the flexibility of applying the default action to any type of button&#8212;be it a <code>&lt;input type=&quot;submit /&gt;</code>, a <code>&lt;button /&gt;</code>, an <code>&lt;a href=&quot;javascript:...&quot;&gt;</code> anchor and so on. Nor provide any custom event handling when default actions are fired.</p>

	<h2>A Proposed Solution</h2>

	<h3>1. Connect fieldsets with their default buttons using minimal markup</h3>

	<p>Although fields are grouped, we still need to provide some relationship between a button and a fieldset. We should provide enough flexibility that our default button could be anywhere on the page, not necessarily within the <code>&lt;fieldset&gt;</code>.</p>

	<p>A clean and unobtrusive way to provide the relationship is via a common attribute, the classname. We could use the id attribute, but this should be avoided &#8211; you have to accept that when you&#8217;re working with .NET, it owns every ID attribute.</p>

	<p>Using the classname, we create a unique identifier for the fieldset. If we then add the same identifier to the default button for that fieldset, a useful relationship between the two is created. For this to work best, all identifiers should begin with the same string so that we may write a generic function to pick them out of the markup and identifiers for each button to fieldset relationship must be unique. Here I&#8217;ve used &#8220;<em>submit-&#8230;</em>&#8220;:</p>

	<p><div class="code-sample"><table summary="This table lists the contents of the file keylistener-markup-connected"><colgroup><col class="line-no" /><col class="line" /></colgroup>
<thead><tr><th>#</th><th>Code</th></tr></thead>
<tbody><tr class="odd hi1"><td>0001</td><td class="tab0">&lt;fieldset class=&quot;submit-search&quot;&gt;</td></tr>
<tr><td>0002</td><td class="tab1">&lt;legend&gt;Search&lt;/legend&gt;</td></tr>
<tr class="odd"><td>0003</td><td class="tab1">&lt;input type=&quot;text&quot; id=&quot;query&quot; name=&quot;query&quot; value=&quot;&quot; /&gt;</td></tr>
<tr class="hi1"><td>0004</td><td class="tab1">&lt;button type=&quot;submit&quot; name=&quot;search&quot; id=&quot;search&quot; class=&quot;submit-search&quot;&gt;Search&lt;/button&gt;</td></tr>
<tr class="odd"><td>0005</td><td class="tab0">&lt;/fieldset&gt;</td></tr>
<tr><td>0006</td><td class="tab0">&#160;</td></tr>
<tr class="odd"><td>0007</td><td class="tab0">...</td></tr>
<tr><td>0008</td><td class="tab0">&#160;</td></tr>
<tr class="odd hi1"><td>0009</td><td class="tab0">&lt;fieldset class=&quot;submit-comment&quot;&gt;</td></tr>
<tr><td>0010</td><td class="tab1">&lt;legend&gt;Add a comment&lt;/legend&gt;</td></tr>
<tr class="odd"><td>0011</td><td class="tab1">&lt;input type=&quot;text&quot; id=&quot;name&quot; name=&quot;name&quot; value=&quot;&quot; /&gt;</td></tr>
<tr><td>0012</td><td class="tab0">    &lt;textarea name=&quot;comment&quot; id=&quot;comment&quot;&gt;&lt;/textarea&gt;</td></tr>
<tr class="odd hi1"><td>0013</td><td class="tab1">&lt;input type=&quot;submit&quot; name=&quot;search&quot; id=&quot;search&quot; class=&quot;submit-comment&quot; value=&quot;Submit Comment&quot; /&gt;</td></tr>
<tr><td>0014</td><td class="tab0">&lt;/fieldset&gt;</td></tr>
</tbody></table>
<p><a href="http://beardscratchers.com/file_download/21/keylistener-markup-connected.txt">get this code</a></p>
</div></p>

	<p>Now we have connected buttons and fieldsets, we need to handle events on the page fired when the enter key is hit.</p>

	<h3>2. Handle enter key events with Javascript/jQuery</h3>

	<p>There are a couple of ways we can do this:</p>

	<ol>
		<li>Be proactive. Scan the entire <span class="caps">DOM</span> on page load, find any fieldsets with a &#8220;submit-&#8230;&#8221; class and bind an onkeypress event to every input inside to connect it with the right  button.</li>
		<li>Be passive. Use event delegation and <em>listen</em> for keypress events on the page and decide whether we <em>need</em> to handle a default action event for it.</li>
	</ol>

	<p>Option 1 is quick to implement, but very inefficient. On <em>every</em> page load, we must scan the entire <span class="caps">DOM</span> for <code>&lt;fieldset&gt;</code>s, and then do all the work of binding events to the input elements, even to elements that may never be used. This is computationally expensive and will be a real drag on page startup times.</p>

	<p>With option 2, we need only find <strong>one element</strong> in the <span class="caps">DOM</span>, bind <strong>one event</strong> to it and then <strong>wait</strong> for the enter key to be pressed:</p>

	<ol>
		<li>Using a fast ID selector, <code>$(&#39;#content&#39;)</code>, we find one containing element for the whole page. It could be <code>&lt;body&gt;</code>, but in this code I&#8217;ve gone for an imaginary <code>&lt;div id=&quot;content&quot;&gt;&lt;/div&gt;</code> element that might always surround our site&#8217;s content. This element will handle the keypresses for all fields on the page.</li>
		<li>To this element we bind an <code>onkeypress</code> event listener function to listen out for any keypress that happen within it&#8212; <code>$(&#39;#content&#39;).bind(&#39;keypress&#39;, function(e) {});</code>.</li>
		<li>We start the function by checking for two attributes of the keypress event. These are both contained within the event object that is passed into the function&#8212; <code>e</code>:
	<ol>
		<li>The key that was pressed</li>
		<li>The target <span class="caps">HTML</span> element that the keypress has bubbled up from.</li>
	</ol></li>
		<li>For valid keypresses&#8212; an enter keypress from an input target&#8212; we find the input element&#8217;s parent fieldset, and extract the classname begining with &#8220;submit-&#8221;. We use the <span class="caps">CSS</span> attribute selector and find any value that begins with (^=) the submit string&#8212; <code>(&#39;class^=&quot;submit-&quot;&#39;)</code>.</li>
		<li>We can now find the button in the page that corresponds to the identifier, and trigger a click event on it. We need to handle different types of buttons, submits and anchors slightly differently.</li>
	</ol>

	<p><div class="code-sample"><table summary="This table lists the contents of the file keylistener"><colgroup><col class="line-no" /><col class="line" /></colgroup>
<thead><tr><th>#</th><th>Code</th></tr></thead>
<tbody><tr class="odd"><td>0001</td><td class="tab0">KeyListener = {</td></tr>
<tr><td>0002</td><td class="tab0">&#160;</td></tr>
<tr class="odd"><td>0003</td><td class="tab1">init : function() {</td></tr>
<tr><td>0004</td><td class="tab2">$('#content').bind('keypress', function(e) {</td></tr>
<tr class="odd"><td>0005</td><td class="tab3">var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0;</td></tr>
<tr><td>0006</td><td class="tab3">var target = e.target.tagName.toLowerCase();</td></tr>
<tr class="odd"><td>0007</td><td class="tab3">if (key === 13 &amp;&amp; target === 'input') {</td></tr>
<tr><td>0008</td><td class="tab4">e.preventDefault();</td></tr>
<tr class="odd"><td>0009</td><td class="tab0">&#160;</td></tr>
<tr><td>0010</td><td class="tab4">var parentFieldset = $(e.target).parents('fieldset');</td></tr>
<tr class="odd"><td>0011</td><td class="tab4">parentFieldset = parentFieldset.filter('class^=&quot;submit-&quot;').eq(0);</td></tr>
<tr><td>0012</td><td class="tab0">&#160;</td></tr>
<tr class="odd"><td>0013</td><td class="tab4">if (parentFieldset.length &gt; 0) {</td></tr>
<tr><td>0014</td><td class="tab5">var classnames = parentFieldset.attr('class').split(' ');</td></tr>
<tr class="odd"><td>0015</td><td class="tab0">&#160;</td></tr>
<tr><td>0016</td><td class="tab5">for (var i = 0; i &lt; classnames.length; i++) {</td></tr>
<tr class="odd"><td>0017</td><td class="tab6">if (classnames[i].substring(0, 7) == 'submit-') {</td></tr>
<tr><td>0018</td><td class="tab7">var button = $('a.' + classnames[i] + ', button.' + classnames[i], $(this)).eq(0);</td></tr>
<tr class="odd"><td>0019</td><td class="tab7">if (button.length &gt; 0) {</td></tr>
<tr><td>0020</td><td class="tab8">if (typeof(button.get(0).onclick) == 'function') {</td></tr>
<tr class="odd"><td>0021</td><td class="tab9">button.trigger('click');</td></tr>
<tr><td>0022</td><td class="tab8">} else if (button.attr('href')) {</td></tr>
<tr class="odd"><td>0023</td><td class="tab9">window.location = button.attr('href');</td></tr>
<tr><td>0024</td><td class="tab8">} else {</td></tr>
<tr class="odd"><td>0025</td><td class="tab9">button.trigger('click');</td></tr>
<tr><td>0026</td><td class="tab8">}</td></tr>
<tr class="odd"><td>0027</td><td class="tab7">}</td></tr>
<tr><td>0028</td><td class="tab7">break;</td></tr>
<tr class="odd"><td>0029</td><td class="tab6">}</td></tr>
<tr><td>0030</td><td class="tab5">}</td></tr>
<tr class="odd"><td>0031</td><td class="tab4">}</td></tr>
<tr><td>0032</td><td class="tab3">}</td></tr>
<tr class="odd"><td>0033</td><td class="tab2">});</td></tr>
<tr><td>0034</td><td class="tab1">}</td></tr>
<tr class="odd"><td>0035</td><td class="tab0">};</td></tr>
<tr><td>0036</td><td class="tab0">&#160;</td></tr>
<tr class="odd"><td>0037</td><td class="tab0">$(document).ready(function() {</td></tr>
<tr><td>0038</td><td class="tab1">KeyListener.init()</td></tr>
<tr class="odd"><td>0039</td><td class="tab0">});</td></tr>
<tr><td>0040</td><td class="tab0">&#160;</td></tr>
</tbody></table>
<p><a href="http://beardscratchers.com/file_download/19/keylistener.txt">get this code</a></p>
</div></p>

	<p>If no button is found, we leave the function silently. We could re-trigger the default action, but this is what we&#8217;re trying to fix. I think it&#8217;s better the enter key stops working completely, rather than producing unexpected or potentially dangerous results if the wrong action is triggered.</p>]]>
</content:encoded>
<link>http://beardscratchers.com/journal/fixing-the-enter-keypress-event-in-aspnet-with-jquery</link>
<pubDate>Sun, 30 Nov 2008 18:38:23 GMT</pubDate>
<dc:creator>Nick</dc:creator>
<guid isPermaLink="false">tag:beardscratchers.com,2008-11-11:4357bcf9c70b1807791cd39e76b16baa/340985627edc8cbf7513ad6de20e4955</guid>
</item>
<item><title>Linkedin launch new Opensocial platform, featuring Huddle.net</title>
<content:encoded>
<![CDATA[<p class="first">In case you missed <a href="http://blog.linkedin.com/blog/2008/10/announcing-appl.html">the news</a>, one of the largest business networking sites <a href="http://linkedin.com">Linkedin</a> have just launched their new platform for <a href="http://code.google.com/apis/opensocial/">Opensocial applications</a>.</p>

	<p>In this initial phase of the platform rollout, Linkedin sensibly took the decision not to open the floodgates to developers and launch with just eight selected partners who could provide application features that are relevant and provide value for the core Linkedin userbase. Business deals aren&#8217;t made by virtual high-fiving the <span class="caps">CEO</span> of a multinational, and dream jobs aren&#8217;t won by poking your prospective employer&#8212;well at least not without the risk of legal action.</p>

	<p><a href="http://www.huddle.net"><img src="http://beardscratchers.com/images/85.png" width="201" height="79" alt="" class="nobg ir" /></a> But enough about Linkedin&#8217;s launch from me; there&#8217;s lots in the <a href="http://blogsearch.google.com/blogsearch?hl=en&amp;ie=UTF-8&amp;as_drrb=q&amp;as_qdr=m&amp;q=linkedin+applications">blogosphere and the tech press out there</a>. I want to focus on the <em>most important</em> and <em>exciting</em> aspect of this launch. That being the existence of online collaboration startup <a href="http://huddle.net">Huddle.net</a> as one of the eight partners to be featured in the launch. They are the <em>only</em> UK-based partner&#8212;in fact the only one outside the US&#8212;and a company that I hold in very high regard&#8230; it is the company that I work for. It&#8217;s a very exciting time to see Huddle sitting up there against big heavyweights Google, Wordpress and Amazon. And, from the development team&#8217;s viewpoint, a somewhat frightening prospect too&#8230; scalability in code and hardware is a whole new ballgame.</p>

	<p>So, without further ado, I present to you the result of a fair amount of blood, sweat and tears [not forgetting the coffee, cigarettes, beer and pizza] amongst my colleagues&#8212;it&#8217;s been an incredibly intense couple of months&#8212; the <strong><a href="http://bit.ly/huddle">Huddle Workspaces application</a> </strong> on Linkedin. </p>

 <a href="http://bit.ly/huddle"><img src="http://beardscratchers.com/images/84.jpg" width="464" height="273" alt="" class="nobg ir" /></a>

	<blockquote class="full">
		<p class="full">&#8220;Huddle Workspaces offers private online workspaces for secure team collaboration, document sharing and discussions within the LinkedIn network. Users receive 1Gb of free storage and can collaborate with unlimited connection.&#8221;</p>
	</blockquote>

	<p>I&#8217;m unashamedly biased, but I do highly recommend you to go and <a href="http://bit.ly/huddle">get it installed</a> and simply have a play. There&#8217;s a lot more going on in the app than anything else on Linkedin&#8217;s platform at the moment. It&#8217;s a shame that it&#8217;s the only properly interactive and genuinely collaborative tool available. All the others seem, at first glance, to suffer from that rather ugly social network trait of passive &#8220;look at me! look at me!&#8221; signposting and ignore the point of networking in the first place &#8211; to actively connect, engage and collaborate with likeminded people. So, in case you didn&#8217;t catch that&#8230; <a href="http://bit.ly/huddle">install Huddle Workspaces on Linkedin here</a>.</p>

	<p>Ok. I&#8217;ll stop with the shameless pimping. I do have sleep to catch up on. In future entries I want to write about the more interesting stuff of actually working with the <a href="http://code.google.com/apis/opensocial/docs/index.html">Opensocial <span class="caps">API</span></a>. It&#8217;s currently a technology lacking general blog chatter. There are lots of questions out there, but usually with few answers; it was peculiar to discover Myspace as a technical resource. And the documentation is currently too dry/technical and lacking in &#8216;human&#8217; explanation to be a sufficient one-stop Opensocial resource. If in fact there is something out there I missed, please let me know in the comments.</p>]]>
</content:encoded>
<link>http://beardscratchers.com/journal/linkedin-launch-new-opensocial-platform-with-huddlenet</link>
<pubDate>Fri, 31 Oct 2008 01:17:02 GMT</pubDate>
<dc:creator>Nick</dc:creator>
<guid isPermaLink="false">tag:beardscratchers.com,2008-10-30:4357bcf9c70b1807791cd39e76b16baa/c02a1911cf8ca81d0b6d6e5df066804b</guid>
</item>
<item><title>Bootstrapping with Javascript</title>
<content:encoded>
<![CDATA[<p class="first">Who said you shouldn&#8217;t run before you can walk? In the race to rice up web UIs with all manner of <a href="http://en.wikipedia.org/wiki/Document_Object_Model"><span class="caps">DOM</span></a> manipulation magic, we are forced to be patient. Until the <span class="caps">DOM</span> is fully loaded and ready in the browser, we can&#8217;t walk it, creating an idle loading period in which we can&#8217;t, or don&#8217;t, run any javascript. Or can we?</p>

	<p>Yes, most certainly we can. In this tiny whisper of time, we&#8217;ve got a great opportunity to exploit an inactive javascript engine before the serious work starts at <a href="http://docs.jquery.com/Events/ready"><span class="caps">DOM</span></a> <a href="http://mootools.net/docs/Utilities/DomReady">Ready</a>. This period of time occurs before <span class="caps">CSS</span> styling, layout and rendering (the &#8216;painting&#8217; of the UI after the previous steps). The typical model for page load in a browser is <em>Parse/Load <span class="caps">DOM</span> -&gt; Styling -&gt; Layout -&gt; Rendering</em>, with javascript being allowed to execute at each step. </p>

	<p>Of course, executing javascript before the <span class="caps">DOM</span> Ready &#8216;event&#8217; is certainly not a new technique, but a pertinent reminder in these days where <span class="caps">DOM</span> manipulation is the hot topic that we don&#8217;t <em>need</em> the entire <span class="caps">DOM</span> loaded for javascript to be of use, just a little bit before the first code can be introduced in the <code>&lt;head /&gt;</code>:</p>

 <div class="code-sample"><table summary="This table lists the contents of the file predomready"><colgroup><col class="line-no" /><col class="line" /></colgroup>
<thead><tr><th>#</th><th>Code</th></tr></thead>
<tbody><tr class="odd"><td>0001</td><td class="tab0">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01//EN&quot; &quot;http://www.w3.org/TR/html4/strict.dtd&quot;&gt;</td></tr>
<tr><td>0002</td><td class="tab0">&lt;html lang=&quot;en&quot;&gt;</td></tr>
<tr class="odd"><td>0003</td><td class="tab0">    &lt;head&gt;</td></tr>
<tr><td>0004</td><td class="tab0">        &lt;title&gt;Running...&lt;/title&gt;</td></tr>
<tr class="odd hi3"><td>0005</td><td class="tab0">        &lt;script type=&quot;text/javascript&quot; src=&quot;/js/canhas.js&quot;&gt;&lt;/script&gt;</td></tr>
<tr><td>0006</td><td class="tab0">    &lt;/head&gt;</td></tr>
<tr class="odd"><td>0007</td><td class="tab0">    &lt;body dir=&quot;ltr&quot;&gt;</td></tr>
</tbody></table>
</div>

	<p>At this point, code in <code>&lt;script&gt;</code> can access and manipulate a few elements, two important ones being the <a href="http://developer.mozilla.org/En/DOM/Window">Window Object</a> and the root of the Document Object&#8212;whence the <span class="caps">DOM</span> descends&#8212; otherwise known as <code>documentElement</code>, or everyone&#8217;s favourite <span class="caps">HTML</span> element, <code>&lt;html /&gt;</code>. On this, the very cusp of page load, we can actually do some useful startup initialisation aka <a href="http://en.wikipedia.org/wiki/Bootstrapping_%28computing%29">bootstrapping</a>.</p>

	<p>Bear in mind that browsers these days reach <span class="caps">DOM</span> Ready <em>very</em> quickly, and so no matter how fiendishly inventive the code you might write to run here is, it must be compact and efficient to be downloaded and run in a manner of milliseconds. Just native javascript here, nothing fancy from your favourite framework. Expensive calculations and weighty scripts can end up having negative impact on page load times. For a start, <code>&lt;script /&gt;</code> elements block parallel downloads &#8211; that is to say that they prevent the browser from starting to download any other page assets&#8212;like images and css&#8212;until the referenced script has been downloaded, parsed and executed.</p>

	<p>So, with this in mind, what are some simple and useful pieces of code to run?</p>

	<h2>Utilising the Window Object &#8211; frame busting!</h2>

	<p>The traditional javascript &#8220;frame buster&#8221; technique is designed to prevent sites from being enclosed in an <code>&lt;iframe /&gt;</code>. For most, it&#8217;s a defensive measure against website hijacking and other similar nastiness. It&#8217;s a simple trick that requires only a reference to the parent window object.</p>

 <div class="code-sample"><table summary="This table lists the contents of the file framebust"><colgroup><col class="line-no" /><col class="line" /></colgroup>
<thead><tr><th>#</th><th>Code</th></tr></thead>
<tbody><tr class="odd"><td>0001</td><td class="tab0">if (window.self !== window.top) {</td></tr>
<tr><td>0002</td><td class="tab0">    window.top.location = window.self.location.href;</td></tr>
<tr class="odd"><td>0003</td><td class="tab0">}</td></tr>
</tbody></table>
<p><a href="http://beardscratchers.com/file_download/15/framebust.txt">get this code</a></p>
</div>

	<p>By making a strict comparsion&#8212;using the <code>!==</code> operator&#8212;of <code>window.self</code> (<cite><em>a reference to the window object itself</em></cite>) against <code>window.top</code> (<cite><em>a reference to the topmost window in the window hierarchy</em></cite>) we can ascertain whether the window of the <em>calling page</em> is the one it is supposed to belong to.</p>

	<p>In a non-iframed page, <code>top</code> is identical to <code>self</code>. The <cite>topmost window in the window hierarchy</cite> is the calling page&#8217;s window and not a reference to another window outside an iframe.</p>

	<p>In iframed pages, the condition evaluates to true, and so the parent window location is set to the calling page&#8217;s location causing the entire page to redirect directly to the calling page.</p>

	<p>Simple, quick and handy&#8230; though not always useful.  In the real world, we sometimes need to use iframes.</p>

	<h2>Utilising <code>documentElement</code> &#8211; enhancing accessibility</h2>

	<p>Accessibility&#8217;s not just about making your page work in a screen reader. It&#8217;s about providing a usable site for as many different types of users, in as many different environments as possible. In this code snippet, we can enhance accessibility for two types of users &#8211; javascript-enabled users and those with javascript disabled. And we can do this with <span class="caps">CSS</span>.</p>

	<p>Having access to <code>documentElement</code>, or <code>&lt;html /&gt;</code>, means we can manipulate it; notably its attributes. With a few lines of code we can modify the document&#8217;s <code>&lt;html /&gt;</code> element to enforce a global <span class="caps">CSS</span> class on the document&#8230; perhaps something like &#8220;canhasjs&#8221;:</p>

 <div class="code-sample"><table summary="This table lists the contents of the file canhas-js"><colgroup><col class="line-no" /><col class="line" /></colgroup>
<thead><tr><th>#</th><th>Code</th></tr></thead>
<tbody><tr class="odd"><td>0001</td><td class="tab0">var root = document.documentElement;</td></tr>
<tr><td>0002</td><td class="tab0">if (root.className.match(/\bcanhasjs\b/) === null) {</td></tr>
<tr class="odd"><td>0003</td><td class="tab0">  root.className = (!root.className) ? 'canhasjs' : root.className + ' canhasjs';</td></tr>
<tr><td>0004</td><td class="tab0">}</td></tr>
</tbody></table>
<p><a href="http://beardscratchers.com/file_download/16/canhas-js.txt">get this code</a></p>
</div>

	<p>In this code, we first check whether the class name &#8220;canhasjs&#8221; already exists using  a regular expression match(). If it doesn&#8217;t, we attach it. The class name is attached under two conditions using a ternary operator for brevity &#8211; if <code>&lt;html /&gt;</code> already has a class name, we append it with a preceding space character, otherwise we just set an entirely new class name.</p>

	<p>And voila, the page is loaded javascript aware. With this selector available it is simple to use <span class="caps">CSS</span> styling conditionally &#8211; enabling certain styling for javascript aware browsers, and different styling for javascript-disabled browsers.</p>

	<h2>Bringing the Two Together &#8211; accessibility and flexibility</h2>

	<p>In the first code snippet, a simple conditional informs us whether the page is iframed, while the second informs us about the availability of javascript. With a simple change, we can combine the two bits of information to initialise a page that can render in multiple states &#8211; be it iframed and javascript disabled, javascript-enabled and not iframed and so on.</p>

 <div class="code-sample"><table summary="This table lists the contents of the file canhas-jsframe"><colgroup><col class="line-no" /><col class="line" /></colgroup>
<thead><tr><th>#</th><th>Code</th></tr></thead>
<tbody><tr class="odd"><td>0001</td><td class="tab0">var root = document.documentElement;</td></tr>
<tr><td>0002</td><td class="tab0">if (root.className.match(/\bcanhasjs\b/) === null) {</td></tr>
<tr class="odd"><td>0003</td><td class="tab0">  root.className = (!root.className) ? 'canhasjs' : root.className + ' canhasjs';</td></tr>
<tr><td>0004</td><td class="tab0">}</td></tr>
<tr class="odd"><td>0005</td><td class="tab0">&#160;</td></tr>
<tr><td>0006</td><td class="tab0">if (self !== top &amp;&amp; root.className.match(/\bcanhasiframe\b/) === null) {</td></tr>
<tr class="odd"><td>0007</td><td class="tab0">  root.className = (!root.className) ? 'canhasiframe' : root.className + ' canhasiframe';</td></tr>
<tr><td>0008</td><td class="tab0">}</td></tr>
</tbody></table>
<p><a href="http://beardscratchers.com/file_download/17/canhas-jsframe.txt">get this code</a></p>
</div>

	<p>Produces:</p>

 <div class="code-sample"><table summary="This table lists the contents of the file jsframed"><colgroup><col class="line-no" /><col class="line" /></colgroup>
<thead><tr><th>#</th><th>Code</th></tr></thead>
<tbody><tr class="odd"><td>0001</td><td class="tab0">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01//EN&quot; &quot;http://www.w3.org/TR/html4/strict.dtd&quot;&gt;</td></tr>
<tr class="hi3"><td>0002</td><td class="tab0">&lt;html lang=&quot;en&quot; class=&quot;canhasjs canhasiframe&quot;&gt;</td></tr>
<tr class="odd"><td>0003</td><td class="tab0">    &lt;head&gt;</td></tr>
<tr><td>0004</td><td class="tab0">        &lt;title&gt;I'm in an iframe and has JS... and a flavour&lt;/title&gt;</td></tr>
<tr class="odd"><td>0005</td><td class="tab0">        &lt;script type=&quot;text/javascript&quot; src=&quot;/js/canhas.js&quot;&gt;&lt;/script&gt;</td></tr>
<tr><td>0006</td><td class="tab0">    &lt;/head&gt;</td></tr>
<tr class="odd"><td>0007</td><td class="tab0">    &lt;body dir=&quot;ltr&quot;&gt;</td></tr>
</tbody></table>
<p><a href="http://beardscratchers.com/file_download/18/jsframed.txt">get this code</a></p>
</div>

	<p><code>&lt;iframe /&gt;</code> and Javascript aware <span class="caps">CSS</span> selector goodness!</p>

	<p>This is a very simple, and somewhat naive, example of bootstrapping. But it provides the basic principle to build upon. A smart idea would be to perform some kind of javascript dependency handling and injection: instead of loading all your JS up front, the bootstrap code could figure out which javascript files need to be included in the page&#8212;using class names or similar attributes&#8212; and load them on demand. Or detecting window width and loading an appropriate stylesheet that would manipulate layout for smaller or larger window sizes. Lots of potential.</p>]]>
</content:encoded>
<link>http://beardscratchers.com/journal/bootstrapping-with-javascript</link>
<pubDate>Tue, 07 Oct 2008 00:56:58 GMT</pubDate>
<dc:creator>Nick</dc:creator>
<guid isPermaLink="false">tag:beardscratchers.com,2008-10-06:4357bcf9c70b1807791cd39e76b16baa/82190ff9a6c9036dcb959edb31cd7b2e</guid>
</item>
<item><title>Upcoming performance data now live on the Compendium</title>
<content:encoded>
<![CDATA[<p class="first">Just launched on the <a href="http://beardscratchers.com/compendium">Compendium</a> is an early preview of events data for all the artists available. It can be accessed from any artist entry by clicking the &#8216;upcoming events&#8217; link at the top of the page (just underneath the artist name).</p>

	<p>It&#8217;s <em>very much</em> an initial dip in the water &#8211; it&#8217;s unstyled and unformatted, and frankly pretty damn rough and ready. But it&#8217;s working, and that&#8217;s the exciting thing. At this stage, the Compendium is automagically determining your current location with a pinch of magic powder, and attempts to provide details of any relevant upcoming events for the selected artist. Events data comes courtesy of <a href="http://eventful.com">eventful.com</a>.</p>

	<p>This geolocation method does need to be tuned, and will be modified to offer a choice of location in case it doesn&#8217;t accurately choose a location for you in the first instance. Along with lots more usability improvements for &#8216;events&#8217;, this is the first of a series of planned updates to the Compendium over the coming month or so.</p>

	<h2>And now, a few Compendium statistics:</h2>

	<ul>
		<li>Total number of Artists known : <strong>55,358</strong></li>
		<li>Total number of Releases known : <strong>62,963</strong></li>
		<li>Volume of cover artwork stored: <strong>1.2GB</strong></li>
		<li>Volume of raw Compendium data stored: <strong>2.5GB</strong></li>
		<li>Total number of web-services consumed: <strong>9</strong></li>
		<li>Average number of web-service calls made per page: <strong>11</strong></li>
		<li>Average level of awesomeness of artist viewed: <strong>high</strong></li>
		<li>Typical data retrieval speed: <strong>Ninja-speed</strong></li>
		<li>Volume of coffee consumed: <strong>Dangerous</strong></li>
		<li>Hours of sleep lost: <strong>Not that much, actually&#8230;</strong></li>
	</ul>]]>
</content:encoded>
<link>http://beardscratchers.com/journal/events-live-on-the-compendium</link>
<pubDate>Tue, 30 Sep 2008 00:22:53 GMT</pubDate>
<dc:creator>Nick</dc:creator>
<guid isPermaLink="false">tag:beardscratchers.com,2008-09-30:4357bcf9c70b1807791cd39e76b16baa/9d6cf583c6318eb85deb1acaac2f7ef3</guid>
</item>
<item><title>Compressing CSS and Javascript with Y!UI Compressor [2]</title>
<content:encoded>
<![CDATA[<p class="first">With websites and web applications becoming increasingly complex, having thousands of lines of Javascript and <span class="caps">CSS</span> split over many files, it is important to ensure your <span class="caps">CSS</span> and JS files are being sent to users in the most efficient manner.</p>

	<p>There are a number of steps involved in providing assets to clients efficiently. This entry covers one of them: combining and compressing. The primary aim is to reduce the number of (<span class="caps">HTTP</span>) requests made to the webserver while serving assets and to reduce the bandwidth consumed in delivering them. <img src="http://beardscratchers.com/images/82.png" width="220" height="210" alt="" class="ir nobg" /> In the simplest form, we do this by combining all our <span class="caps">CSS</span> and all our Javascript into single files, compress the text by removing redundant whitespace and comments and/or running code optimisation routines, and finally send them gzipped. The latter takes place, if supported by the end-user, to further compress the files when they&#8217;re sent over the wire from the webserver to the end-user.</p>

	<p>We could do all this from the very start of developing a new project, but this introduces great pain into the development process. It&#8217;s nigh on impossible  to debug combined code compressed to a single line of text, and a massive headache to manage and work with in multi-developer situations under revision control. So, in this case, compression and combining&#8212;&#8220;combressing&#8221; perhaps!&#8212;should always take place just before code is put into a production environment, leaving development with fully commented, uncompressed code. Thus &#8216;combressing&#8217; (I&#8217;m going to patent it) should be scripted so that it&#8217;s a simple one-click process to  push these special live-only assets to live servers.</p>

	<ol>
		<li>Combine files to a single file</li>
		<li>Compress files using our method of choice</li>
		<li>Configure our webserver to send the files gzipped</li>
		<li>Modify the codebase to make development easier</li>
	</ol>

	<h2>Combining</h2>

	<p>The first step, combining, is a simple process.  On Linux boxen, we use the <code>cat</code> command and on Windows we can use the <code>copy</code> command. Both are roughly equivalent commands. Note that the process is identical for both <span class="caps">CSS</span> and JS, bar the file extension.</p>

	<h3>Combining on Linux (.sh)</h3>

	<p>We con_cat_enate all files together at once and push the output to one file &#8216;tmp.js&#8217;.</p>

 <div class="code-sample"><table summary="This table lists the contents of the file nix-combine"><colgroup><col class="line-no" /><col class="line" /></colgroup>
<thead><tr><th>#</th><th>Code</th></tr></thead>
<tbody><tr class="odd"><td>0001</td><td class="tab0"> JSDIR=&quot;./www/js&quot;</td></tr>
<tr><td>0002</td><td class="tab0">&#160;</td></tr>
<tr class="odd"><td>0003</td><td class="tab0"> echo &quot;1. Combining Javascript&quot;</td></tr>
<tr><td>0004</td><td class="tab0">&#160;</td></tr>
<tr class="odd"><td>0005</td><td class="tab0"> # Combine all the javascript to a single temporary file</td></tr>
<tr><td>0006</td><td class="tab0"> cat $JSDIR/mootools-1.2-core.js \</td></tr>
<tr class="odd"><td>0007</td><td class="tab0"> $JSDIR/mootools-1.2-more.js \</td></tr>
<tr><td>0008</td><td class="tab0"> $JSDIR/functions.js \</td></tr>
<tr class="odd"><td>0009</td><td class="tab0"> $JSDIR/common.js &gt; $JSDIR/tmp.js</td></tr>
</tbody></table>
<p><a href="http://beardscratchers.com/file_download/8/nix-combine.txt">get this code</a></p>
</div>

	<h3>Combining on Windows (.bat)</h3>

	<p>We <code>copy</code> each file on to the previous and push the result to one file &#8216;tmp.js&#8217;. Note that each line must copy the previous tmp.js to the next file, and then save to tmp.js again. As ever, Windows makes life overtly verbose for the developer.</p>

 <div class="code-sample"><table summary="This table lists the contents of the file win-combine"><colgroup><col class="line-no" /><col class="line" /></colgroup>
<thead><tr><th>#</th><th>Code</th></tr></thead>
<tbody><tr class="odd"><td>0001</td><td class="tab0">set folder=..\www\js</td></tr>
<tr><td>0002</td><td class="tab0">copy/b %folder%\mootools-1.2-core.js %folder%\tmp.js</td></tr>
<tr class="odd"><td>0003</td><td class="tab0">copy/b %folder%\tmp.js + %folder%\functions.js %folder%\tmp.js</td></tr>
<tr><td>0004</td><td class="tab0">copy/b %folder%\tmp.js + %folder%\common.js %folder%\tmp.js</td></tr>
</tbody></table>
<p><a href="http://beardscratchers.com/file_download/9/win-combine.txt">get this code</a></p>
</div>

	<h2>Compressing</h2>

	<p>I choose to use the <a href="http://developer.yahoo.com/yui/compressor/">Y!UI compressor</a> as it tends to produce the best overall compression results in combination with gzipping, while being a lot less brutal in actual code optimisation routines (for javascript) and being able to compress <span class="caps">CSS</span> too. Other options for javascript exist, such as <a href="http://dean.edwards.name/packer/">/packer/</a> and <a href="http://www.crockford.com/javascript/jsmin.html"><span class="caps">JSM</span>in</a>. Your mileage may vary!</p>

	<p>The following commands are from a Linux script, but are identical for Windows except directory slashes should be \.</p>

	<p>Compressing JS: </p>

 <div class="code-sample"><table summary="This table lists the contents of the file yuicompress-js"><colgroup><col class="line-no" /><col class="line" /></colgroup>
<thead><tr><th>#</th><th>Code</th></tr></thead>
<tbody><tr class="odd"><td>0001</td><td class="tab0"># Compress the combined javascript</td></tr>
<tr><td>0002</td><td class="tab0">java -jar ./assets/yuicompressor/yuicompressor.jar --type js -o $JSDIR/combined.js $JSDIR/tmp.js</td></tr>
</tbody></table>
<p><a href="http://beardscratchers.com/file_download/11/yuicompress-js.txt">get this code</a></p>
</div>

	<p>Compressing <span class="caps">CSS</span> requires just a change to the <code>type</code> flag: </p>

 <div class="code-sample"><table summary="This table lists the contents of the file yuicompress-css"><colgroup><col class="line-no" /><col class="line" /></colgroup>
<thead><tr><th>#</th><th>Code</th></tr></thead>
<tbody><tr class="odd"><td>0001</td><td class="tab0"># Compress the combined CSS</td></tr>
<tr><td>0002</td><td class="tab0">java -jar ./assets/yuicompressor/yuicompressor.jar --type css -o $CSSDIR/combined.css $CSSDIR/tmp.css</td></tr>
</tbody></table>
<p><a href="http://beardscratchers.com/file_download/10/yuicompress-css.txt">get this code</a></p>
</div>

	<p>At this point there should be two files, a <code>combined.css</code> and a <code>combined.js</code>, You should note a <em>marked difference</em> in file size between the uncompressed files and the finished version.</p>

	<h2>Reducing Bandwidth Consumption with <a href="http://en.wikipedia.org/wiki/Gzip">gzip</a></h2>

	<p>This part isn&#8217;t essential, but it helps a great deal and gzip-encoding is supported by most modern web clients. Even after combining and compressing, you can see anything from 40%-60% reduction in bandwidth consumption per file! For example, employed on beardscratchers.com, 22KB of javascript drops down to a tiny 6KB!</p>

	<p>Naturally this comes with a little bit of processing overhead as it&#8217;s performed on-the-fly, so beware of using it on <em>everything</em>. It&#8217;s somewhat of a topic all of its own, so I&#8217;d like to point you towards my <a href="http://delicious.com/beardscratchers/gzip+compression">del.icio.us gzip+compression page</a>, which will be updated with the most useful resources I find on the subject. Currently the best reading is at:</p>

	<ul>
		<li><a href="http://www.julienlecomte.net/blog/2007/08/13/">Gzip Your Minified JavaScript Files</a></li>
		<li><a href="http://www.fiftyfoureleven.com/weblog/web-development/css/the-definitive-css-gzip-method">The Definitive Post on Gzipping your <span class="caps">CSS</span></a></li>
	</ul>

	<h2>Easing the Pain of Development</h2>

	<p>How can we make this easier to deal with? Is there one fire-and-forget method for this? The answer is no. In my experience, the best practice is twofold:</p>

	<ul>
		<li>Script the combining and compressing, and make it part of your deployment process. On personal projects I use a simple bash script and run it while my <span class="caps">FTP</span> client fires up. While professionally it&#8217;s employed into the build processes, and checked for errors (yui compressor returns parser errors).</li>
		<li>Modify your web site/app code so that it conditionally loads the <span class="caps">CSS</span> based on the hostname or some other flag indicated by the environment/configs.</li>
	</ul>

	<p>By example, I&#8217;ve modified my Textpattern templates here to conditionally load <span class="caps">CSS</span> based on the hostname aided by the <a href="http://www.zenscope.com/blog/51/aam_if_host">aam_if_host</a> plugin. </p>

 <div class="code-sample"><table summary="This table lists the contents of the file if-host-beardscratchers"><colgroup><col class="line-no" /><col class="line" /></colgroup>
<thead><tr><th>#</th><th>Code</th></tr></thead>
<tbody><tr class="odd"><td>0001</td><td class="tab0">&lt;txp:aam_if_host name=&quot;beardscratchers,bl&quot;&gt;</td></tr>
<tr><td>0002</td><td class="tab0">  &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; media=&quot;screen,projection&quot; href=&quot;/css/master.css&quot; /&gt;</td></tr>
<tr class="odd"><td>0003</td><td class="tab0">&lt;txp:else /&gt;</td></tr>
<tr><td>0004</td><td class="tab0">  &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; media=&quot;screen,projection&quot; href=&quot;/css/combined.css&quot; /&gt;</td></tr>
<tr class="odd"><td>0005</td><td class="tab0">&lt;/txp:aam_if_host&gt;</td></tr>
</tbody></table>
<p><a href="http://beardscratchers.com/file_download/13/if-host-beardscratchers.txt">get this code</a></p>
</div>

	<p>My master.css contains a list of @import statements, importing all the separated <span class="caps">CSS</span> files during development.</p>

	<p>This is only a brief overview; it can get quite complex when you&#8217;re dealing with conditional comments for <span class="caps">CSS</span>, loading <span class="caps">CSS</span> for individual browsers (these shouldn&#8217;t be combined), or wish to implement lazy/on-demand loading of Javascript. But hopefully it&#8217;s a good starting-point for improving the efficiency of serving <span class="caps">CSS</span> and Javascript on the web.</p>]]>
</content:encoded>
<link>http://beardscratchers.com/journal/compressing-css-and-javascript-with-yui-compressor</link>
<pubDate>Sun, 31 Aug 2008 05:20:48 GMT</pubDate>
<dc:creator>Nick</dc:creator>
<guid isPermaLink="false">tag:beardscratchers.com,2008-08-31:4357bcf9c70b1807791cd39e76b16baa/dd81967e030069a954b488242c1ad792</guid>
</item>
<item><title>jQuery, it's all about context! (part 2) [2]</title>
<content:encoded>
<![CDATA[<p class="first">In the previous part of this entry, I went over the concept of <code>context</code> in jQuery and <span class="caps">DOM</span> manipulation, and why I think we should care about it. In this second part, I&#8217;d like to describe one way in I like to make use of <code>context</code> in real-world situations.</p>

	<p>I&#8217;m an advocate of encapsulating Javascript functionality in an object-oriented manner using <a href="http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Guide:Literals#Object_Literals">native Object Literals</a>, following a rule of one object per application feature; one for navigation, another to enhance forms or provide an image gallery and so on. Aside from the benefits of <a href="http://en.wikipedia.org/wiki/Information_hiding">encapsulation</a>, it&#8217;s just a lot less problematic to scale and manage your javascript codebase across files <em>and developers</em> by organising code in this fashion.</p>

	<p>Design patterns for writing javascript objects are in fair abundance in the wider Web. Some are much more strict about exhibiting true object-oriented features than others. One such is the <a href="http://yuiblog.com/blog/2007/06/12/module-pattern/">&#8216;module pattern&#8217; by Douglas Crockford</a>. Personally, I tend to be a bit more lax about it, and simply use literals to reduce the number of objects and variables in the global namespace, while maintaining a quasi-OO structure. If you&#8217;re a <span class="caps">PHP</span> developer, you can think of it like the difference between <span class="caps">OOP</span> in PHP4 and <span class="caps">OOP</span> in PHP5. If you&#8217;re not, don&#8217;t worry.</p>

	<h2>A simple javascript object</h2>

 <div class="code-sample"><table summary="This table lists the contents of the file object-literal"><colgroup><col class="line-no" /><col class="line" /></colgroup>
<thead><tr><th>#</th><th>Code</th></tr></thead>
<tbody><tr class="odd"><td>0001</td><td class="tab0">var myObject = {</td></tr>
<tr><td>0002</td><td class="tab1">myProperty : 42,</td></tr>
<tr class="odd"><td>0003</td><td class="tab1">myOtherProperty : 'Hello World',</td></tr>
<tr><td>0004</td><td class="tab0">&#160;</td></tr>
<tr class="odd"><td>0005</td><td class="tab1">myFunction : function() {</td></tr>
<tr><td>0006</td><td class="tab2">return this.myProperty;</td></tr>
<tr class="odd"><td>0007</td><td class="tab1">},</td></tr>
<tr><td>0008</td><td class="tab0">&#160;</td></tr>
<tr class="odd"><td>0009</td><td class="tab1">myOtherFunction : function() {</td></tr>
<tr><td>0010</td><td class="tab2">return this.myOtherProperty;</td></tr>
<tr class="odd"><td>0011</td><td class="tab1">}</td></tr>
<tr><td>0012</td><td class="tab0">}</td></tr>
</tbody></table>
<p><a href="http://beardscratchers.com/file_download/7/object-literal.txt">get this code</a></p>
</div>

	<p>With this code, we&#8217;ve contained our methods and properties in a single namespace, avoiding potential collisions with other Javascript code running concurrently. </p>

	<h2>Making the object useful</h2>

	<p>If one object is used for each feature we write, then each object should only ever have one <code>context</code>. It is a single static property which we will continually access. In the following example, a new object is created in which our desired <code>context</code> is an element with the incredibly imaginative ID of &#8220;element&#8221;:</p>

 <div class="code-sample"><table summary="This table lists the contents of the file object-context"><colgroup><col class="line-no" /><col class="line" /></colgroup>
<thead><tr><th>#</th><th>Code</th></tr></thead>
<tbody><tr class="odd"><td>0001</td><td class="tab0">var myFeature = {</td></tr>
<tr><td>0002</td><td class="tab1">/*</td></tr>
<tr class="odd"><td>0003</td><td class="tab1"> * Store our reference to the DOM element we're working on (the 'context')</td></tr>
<tr><td>0004</td><td class="tab1"> */</td></tr>
<tr class="odd"><td>0005</td><td class="tab1">_context : false,</td></tr>
<tr><td>0006</td><td class="tab0">&#160;</td></tr>
<tr class="odd"><td>0007</td><td class="tab0">    /*</td></tr>
<tr><td>0008</td><td class="tab1"> * A simple getter function for this object's context</td></tr>
<tr class="odd"><td>0009</td><td class="tab1"> */</td></tr>
<tr><td>0010</td><td class="tab1">getContext : function() {</td></tr>
<tr class="odd"><td>0011</td><td class="tab2">if (this._context === false) {</td></tr>
<tr><td>0012</td><td class="tab3">this._context = $('#element');</td></tr>
<tr class="odd"><td>0013</td><td class="tab2">}</td></tr>
<tr><td>0014</td><td class="tab2">return this._context;</td></tr>
<tr class="odd"><td>0015</td><td class="tab1">}</td></tr>
<tr><td>0016</td><td class="tab0">&#160;</td></tr>
<tr class="odd"><td>0017</td><td class="tab1">highlightItems : function() {</td></tr>
<tr><td>0018</td><td class="tab2">$('.item', this.getContext()).css('background-color', 'red');</td></tr>
<tr class="odd"><td>0019</td><td class="tab1">},</td></tr>
<tr><td>0020</td><td class="tab0">}</td></tr>
<tr class="odd"><td>0021</td><td class="tab0">&#160;</td></tr>
<tr><td>0022</td><td class="tab0">$(document).ready(function() {</td></tr>
<tr class="odd"><td>0023</td><td class="tab1">myFeature.highlightItems();</td></tr>
<tr><td>0024</td><td class="tab0">}</td></tr>
</tbody></table>
<p><a href="http://beardscratchers.com/file_download/6/object-context.txt">get this code</a></p>
</div>

	<p>It has a single property, <code>_context</code>. This contains the <span class="caps">DOM</span> <em>reference</em> returned from a regular jQuery selector call &#8211; $(&#8217;#element&#8217;). We can use this property throughout our feature&#8217;s code, passing it in as selector context or working with it directly.</p>

	<p>However, since we will be using the object context a great deal, it makes sense to try and look for any quick-wins. By using a simple <a href="http://en.wikipedia.org/wiki/Accessor">getter function,</a> getContext() [line 10], we ensure the actual $(&#8217;#element&#8217;) function call happens only once, and every subsequent request for <code>context</code> simply returns the reference we&#8217;ve already stored in <code>_context</code>. This is a nice and simple optimisation;  <code>context</code> shouldn&#8217;t ever change, we don&#8217;t have to rememeber to initialise the property at the start, and potentially save many unecessary getElementById() calls in our code! </p>

	<p>In practice, we use the getter with a call to <code>this.getContext()</code>, as shown in the dummy highlightItems() function [line 18]. The first time it&#8217;s called, we retrieve the <span class="caps">DOM</span> reference. Do bear in mind that <code>this</code> only references the current scope. You&#8217;ll need to watch out for cases where you&#8217;re in a different scope, stopping you from accessing the property in this way &#8211; a subject for another day, perhaps!</p>]]>
</content:encoded>
<link>http://beardscratchers.com/journal/jquery-its-all-about-context-part-2</link>
<pubDate>Wed, 23 Jul 2008 00:12:59 GMT</pubDate>
<dc:creator>Nick</dc:creator>
<guid isPermaLink="false">tag:beardscratchers.com,2008-07-14:4357bcf9c70b1807791cd39e76b16baa/45cb270c35e1b2b21396812049ec54e6</guid>
</item></channel>
</rss>
