<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Stuart's Notes</title>
	<atom:link href="http://srackham.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://srackham.wordpress.com</link>
	<description>Just another WordPress.com weblog</description>
	<lastBuildDate>Tue, 24 Jan 2012 19:09:32 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='srackham.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Stuart's Notes</title>
		<link>http://srackham.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://srackham.wordpress.com/osd.xml" title="Stuart&#039;s Notes" />
	<atom:link rel='hub' href='http://srackham.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Bash completion for cake files</title>
		<link>http://srackham.wordpress.com/2011/11/01/bash-completion-for-cake-files/</link>
		<comments>http://srackham.wordpress.com/2011/11/01/bash-completion-for-cake-files/#comments</comments>
		<pubDate>Tue, 01 Nov 2011 02:37:46 +0000</pubDate>
		<dc:creator>srackham</dc:creator>
				<category><![CDATA[bash]]></category>
		<category><![CDATA[cake]]></category>
		<category><![CDATA[coffeescript]]></category>

		<guid isPermaLink="false">http://srackham.wordpress.com/?p=766</guid>
		<description><![CDATA[Published: 2011-11-01 To implement bash(1) tab completion for Cakefile task names all you need to do is add this completion function and command to your ~/.bashrc file: # Task name completion for cake files. function _cake() { local cur tasks cur="${COMP_WORDS[COMP_CWORD]}" tasks=$(cake &#124; awk '{print $2}') if [ $COMP_CWORD -eq 1 ]; then # Task [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=srackham.wordpress.com&amp;blog=3711161&amp;post=766&amp;subd=srackham&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a name="preamble"></a>
<p><strong>Published</strong>: 2011-11-01</p>
<p>To implement <a href="http://www.gnu.org/software/bash/manual/html_node/Programmable-Completion.html#Programmable-Completion">bash(1) tab completion</a> for <a href="http://jashkenas.github.com/coffee-script/#cake">Cakefile</a> task names all you need to do is add this completion function and command to your <tt>~/.bashrc</tt> file:</p>
<p><span id="more-766"></span><br />
<table border="0" bgcolor="#e8e8e8" width="100%" style="margin:.2em 0;">
<tr>
<td style="padding:.5em;">
<pre style="margin:0;padding:0;"># Task name completion for cake files.
function _cake() {
    local cur tasks
    cur="${COMP_WORDS[COMP_CWORD]}"
    tasks=$(cake | awk '{print $2}')
    if [ $COMP_CWORD -eq 1 ]; then
        # Task name completion for first argument.
        COMPREPLY=( $(compgen -W "$tasks" $cur) )
    else
        # File name completion for other arguments.
        COMPREPLY=( $(compgen -f $cur) )
    fi
}
complete -o default -F _cake cake c</pre>
</td>
</tr>
</table>
<p>Now it you type <tt>cake &lt;Tab&gt;</tt> at the bash command prompt you will get a list of tasks from the current <tt>Cakefile</tt>.  As with all bash completion, if you start typing a name and press Tab then bash will complete the name for you.</p>
<p>To cut down key strokes I&#8217;ve also added a <em>c</em> alias for <em>cake</em> to <tt>~/.bashrc</tt>:</p>
<table border="0" bgcolor="#e8e8e8" width="100%" style="margin:.2em 0;">
<tr>
<td style="padding:.5em;">
<pre style="margin:0;padding:0;">alias c='cake'</pre>
</td>
</tr>
</table>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/srackham.wordpress.com/766/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/srackham.wordpress.com/766/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/srackham.wordpress.com/766/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/srackham.wordpress.com/766/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/srackham.wordpress.com/766/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/srackham.wordpress.com/766/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/srackham.wordpress.com/766/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/srackham.wordpress.com/766/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/srackham.wordpress.com/766/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/srackham.wordpress.com/766/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/srackham.wordpress.com/766/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/srackham.wordpress.com/766/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/srackham.wordpress.com/766/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/srackham.wordpress.com/766/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=srackham.wordpress.com&amp;blog=3711161&amp;post=766&amp;subd=srackham&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://srackham.wordpress.com/2011/11/01/bash-completion-for-cake-files/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e74a88a96ce8caecbc7d265e4763e26c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">srackham</media:title>
		</media:content>
	</item>
		<item>
		<title>Testing CoffeeScript apps with Selenium</title>
		<link>http://srackham.wordpress.com/2011/10/25/testing-coffeescript-apps-with-selenium/</link>
		<comments>http://srackham.wordpress.com/2011/10/25/testing-coffeescript-apps-with-selenium/#comments</comments>
		<pubDate>Tue, 25 Oct 2011 02:53:01 +0000</pubDate>
		<dc:creator>srackham</dc:creator>
				<category><![CDATA[coffeescript]]></category>
		<category><![CDATA[Selenium]]></category>

		<guid isPermaLink="false">http://srackham.wordpress.com/?p=738</guid>
		<description><![CDATA[Published: 2011-10-25 This blog entry describes how to write functional tests for CoffeeScript web apps using Selenium. By way of example I&#8217;ll describe how I added Selenium tests to the Routeless Backbone Contacts tutorial app and automated it&#8217;s execution with a Cakefile. The source is on Github, the tests described in this post are at [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=srackham.wordpress.com&amp;blog=3711161&amp;post=738&amp;subd=srackham&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a name="preamble"></a>
<p><strong>Published</strong>: 2011-10-25</p>
<p>This blog entry describes how to write functional tests for CoffeeScript web apps using <a href="http://seleniumhq.org/">Selenium</a>. By way of example I&#8217;ll describe how I added Selenium tests to the <a href="http://srackham.wordpress.com/2011/10/02/routeless-backbone-contacts-2-0/">Routeless Backbone Contacts</a> tutorial app and automated it&#8217;s execution with a <a href="http://jashkenas.github.com/coffee-script/#cake">Cakefile</a>.</p>
<p><span id="more-738"></span>
<p>The source is <a href="https://github.com/srackham/routeless-backbone-contacts">on Github</a>, the tests described in this post are at the <em>3.0</em> tag.</p>
<p>Unit testing frameworks such as <a href="http://docs.jquery.com/Qunit">QUnit</a> work well for testing libraries, APIs and computational logic but fall short when it comes to testing user interface intensive browser applications, this is where <a href="http://seleniumhq.org/">Selenium</a> comes in.  The Selenium IDE provides an easy way to functionally test an application user interface in a real browser with exactly the same mouse and keyboard input that a user would enter.</p>
<p>At it&#8217;s core &#8220;Selenium automates browsers&#8221; with a macro-like scripting language called <a href="#X2">Selenese</a> and a Firefox IDE for recording and playing Selenese scripts.  Selenium tests the actual user interface so you record your tests after the user interface has been implemented.</p>
<p>The primary purpose of functional user interface tests is to catch future user interface regressions. The likelihood of user interface regressions at each release increases with the size of the application.</p>
<p> <a name="X3"></a><br />
<table bgcolor="#ffffee" width="100%" style="margin:.2em 0;">
<tr>
<td style="padding:.5em;">
<p style="margin-top:0;"><b>Selenese</b></p>
<p>Selenese is the Selenium IDE scripting language, it is surprisingly powerful:</p>
<ul>
<li> Variables can be stored and manipulated. </li>
<li> You can run JavaScript snippets with the <em>runScript</em> and <em>waitForCondition</em> commands. </li>
<li> The Selenese native format is an HTML table but it can also be exported to languages with Selenium binding (<em>Python</em>, <em>Java</em>, <em>C#</em>). </li>
</ul>
</td>
</tr>
</table>
<hr />
<h2><a name="_requisites"></a>Requisites</h2>
<p>To use the Selenium IDE you will need to install:</p>
<ul>
<li> The <a href="http://www.mozilla.org/">Firefox</a> web browser. </li>
<li> The <a href="http://seleniumhq.org/docs/02_selenium_ide.html#installing-the-ide">Selenium IDE</a>. Once installed you open the IDE with the Firefox <em>Tools&#8594;Selenium IDE</em> menu command. </li>
<li> I also installed the <a href="https://addons.mozilla.org/en-US/firefox/addon/highlight-elements-selenium-id/">Highlight Elements</a> IDE plugin. </li>
</ul>
<p>This post is based on Firefox 7.0.1 (Ubuntu) with Selenium IDE 1.3.0.</p>
<hr />
<h2><a name="_creating_a_test"></a>Creating a test</h2>
<p>Creating a Selenese test script is a two step process:</p>
<ol type="1">
<li> <a href="http://seleniumhq.org/docs/02_selenium_ide.html#recording">Record</a> a sequence of user interface interactions (mouse and keyboard inputs). </li>
<li> Add <a href="http://seleniumhq.org/docs/02_selenium_ide.html#adding-verifications-and-asserts-with-the-context-menu">asserts and verifications</a> to the test sequence. This is the step that transforms the browser automation sequence into a test. </li>
</ol>
<p>The Selenium IDE documentation also explains how to <a href="http://seleniumhq.org/docs/02_selenium_ide.html#running-test-cases">run</a>, <a href="http://seleniumhq.org/docs/02_selenium_ide.html#opening-and-saving-a-test-case">save</a> and <a href="http://seleniumhq.org/docs/02_selenium_ide.html#editing">edit</a> tests.</p>
<p><a href="https://github.com/srackham/routeless-backbone-contacts/blob/3.0/test/test.html">Here&#8217;s the test</a> for the tutorial application.</p>
<table style="margin:.2em 0;">
<tr valign="top">
<td style="padding:.5em;">
<p><b><u>Note</u></b></p>
</td>
<td style="border-left:3px solid #e8e8e8;padding:.5em;">To run the tests you will need to open the application in a web server (file based URLs won&#8217;t work). I use the <a href="http://code.google.com/p/mongoose/">Mongoose</a> web server for app testing.</td>
</tr>
</table>
<p> <a name="X2"></a><br />
<table bgcolor="#ffffee" width="100%" style="margin:.2em 0;">
<tr>
<td style="padding:.5em;">
<p style="margin-top:0;"><b>Mongoose web server</b></p>
<p>The <a href="http://code.google.com/p/mongoose/">Mongoose</a> web server is a neat little configurationless cross-platform web server that&#8217;s ideal for testing web apps.</p>
<p>To install Mongoose on Linux:</p>
<ol type="1">
<li> Unpack and make the source distribution:
<pre style="color:gray;padding:.5em;">tar -xzf mongoose-3.0.tgz
cd mongoose
make linux</pre>
</li>
<li> Copy the <em>mongoose</em> executable to somewhere in your <em>PATH</em>. </li>
</ol>
<p>To use:</p>
<ol type="1">
<li> Change to your app directory. </li>
<li> Run mongoose:
<pre style="color:gray;padding:.5em;">mongoose [-i &lt;index-files&gt;]</pre>
</li>
<li> Open your browser at <tt>localhost:8080</tt>, if an index file exists it will be displayed else you&#8217;ll be presented with a file browser interface. </li>
</ol>
</td>
</tr>
</table>
<hr />
<h2><a name="_running_tests_from_the_command_line"></a>Running tests from the command-line</h2>
<p>There&#8217;s no easy way to open the Selenium IDE and get it to execute a test from the command-line (at least I couldn&#8217;t find one), but you can export the tests to Python (or Java or C#) and then run them from the command-line. Apparently a JavaScript driver is in the works but not here yet, so I opted for Python.</p>
<p>I like being able to run Python tests from the command-line but I prefer developing the tests using the IDE. Keeping both in sync can be a challenge but being able to copy commands from the Selenium IDE to the Python source is a real help (set the IDE <em>Options&#8594;Clipboard Format&#8594;Python 2 (WebDriver)</em> option and you will be able to copy-and-paste IDE commands as Python code).</p>
<ol type="1">
<li> In addition to the Selenium IDE you will need to install the Python bindings for Selenium:
<pre style="color:gray;padding:.5em;">sudo pip install selenium</pre>
</li>
<li> Now export the test from the Selenium IDE to a Python test file using the IDE <em>File&#8594;Export Test Case As&#8594;Python 2 (WebDriver)</em> menu command. </li>
</ol>
<p>The exported Python scripts make use of the Python <a href="http://docs.python.org/library/unittest.html">unit testing framework</a>.</p>
<h3><a name="_export_anomalies_and_omissions"></a>Export anomalies and omissions</h3>
<p>The export of Selenese to Python is not perfect, here are some of the manual edits I had to do:</p>
<ul>
<li> Replace:
<pre style="color:gray;padding:.5em;"># ERROR: Caught exception [ERROR: Unsupported command [getConfirmation]]</pre>
<div>
<p>with this:</p>
<pre style="color:gray;padding:.5em;">driver.switch_to_alert().accept()</pre>
<p>See also the <a href="http://code.google.com/p/selenium/wiki/FrequentlyAskedQuestions#Q:_Does_WebDriver_support_Javascript_alerts_and_prompts?">Selenium FAQ</a>.</p>
</p></div>
</li>
<li> Moved the focus from the search box to fire the search box <em>change</em> event (used <em>click</em> command as <em>focus</em> is not supported by Python WebDriver API):
<pre style="color:gray;padding:.5em;">driver.find_element_by_css_selector("input.search").send_keys("sm")
driver.find_element_by_name("name").click()   # Fire search 'change' event.</pre>
<p>See <a href="#X1">Dynamic UI controls</a> below.</p>
</li>
</ul>
<p><a href="https://github.com/srackham/routeless-backbone-contacts/blob/3.0/test/test.py">Here&#8217;s the Python test</a> for the tutorial.</p>
<h3><a name="X1"></a>Dynamic user interface controls</h3>
<p>Incremental search boxes and auto-completing drop-down lists typically emit keystroke events (up/down/press) to dynamically update other elements in response to user keyboard entry. The Selenese <em>type</em> command will not work in this situation.</p>
<ul>
<li> The <em>typeKeys</em> command is designed for these situations but I was unable to get it to work. </li>
<li> Nor did the <em>fireEvent</em> command on <em>keyup</em> work. </li>
</ul>
<p>The only reliable work-around I could find for testing the incremental <em>Search</em> was to add the <em>change</em> event to the search box and use:</p>
<pre style="color:gray;padding:.5em;">driver.find_element_by_css_selector("input.search").send_keys("sm")
driver.find_element_by_name("name").click()</pre>
<p>The <em>click</em> command moves the focus from the search box to trigger a search box DOM <em>change</em> event.</p>
<hr />
<h2><a name="_setup_and_teardown"></a>Setup and Teardown</h2>
<p>At the start of testing you will typically create test fixtures to put the application in a known state. For data oriented apps this means means populating the database with fixed data, the <a href="http://srackham.wordpress.com/2011/10/02/routeless-backbone-contacts-2-0/">Routeless Backbone Contacts</a> application has built-in <em>Clear All</em> and <em>Import Data</em> commands that serve this purpose.</p>
<p>Built-in <em>data fixture</em> commands are not normally part of an application but there&#8217;s no reason not to implement <em>hidden</em> or <em>debug only</em> fixture commands.  Alternatively, if you have moved exclusively to Python scripts for Selenium testing then, you could setup and teardown fixtures in the traditional fashion using Python <a href="http://docs.python.org/library/unittest.html#class-and-module-fixtures">unittest class and module fixtures</a>.</p>
<hr />
<h2><a name="_cakefile_automation"></a>Cakefile automation</h2>
<p>The <a href="http://srackham.wordpress.com/2011/10/02/routeless-backbone-contacts-2-0/">Routeless Backbone Contacts</a> application is written in <a href="http://jashkenas.github.com/coffee-script/">CoffeeScript</a> so it made sense to automate the tests with a <a href="http://jashkenas.github.com/coffee-script/#cake">Cakefile</a>. Because <em>cake</em> runs under <a href="http://nodejs.org/">Node.js</a> you have a <a href="http://search.npmjs.org/">wealth of modules</a> available.</p>
<p>The tutorial <a href="https://github.com/srackham/routeless-backbone-contacts/blob/3.0/Cakefile">Cakefile</a> implements two tasks:</p>
<dl>
<dt> <tt>cake server</tt> </dt>
<dd> Start the <a href="#X2">Mongoose</a> server. </dd>
<dt> <tt>cake test</tt> </dt>
<dd> Run the Python Selenium test. </dd>
</dl>
<p><b>Cakefile</b></p>
<table border="0" bgcolor="#e8e8e8" width="100%" style="margin:.2em 0;">
<tr>
<td style="padding:.5em;">
<pre style="margin:0;padding:0;">{exec,spawn} = require 'child_process'

task 'server', 'Start mongoose server', -&gt;
    console.log 'starting mongoose web server...'
    server = spawn 'mongoose', [],
        customFds: [process.stdin, process.stdout, process.stderr]
    process.exit()

task 'test', 'Run tests', -&gt;
    console.log 'starting mongoose web server...'
    server = spawn 'mongoose'
    console.log 'starting tests...'
    exec 'python test/test.py', (err, stdout, stderr) -&gt;
        throw err if err
        console.log stdout + stderr
        server.kill()   # and exit cake.</pre>
</td>
</tr>
</table>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/srackham.wordpress.com/738/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/srackham.wordpress.com/738/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/srackham.wordpress.com/738/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/srackham.wordpress.com/738/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/srackham.wordpress.com/738/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/srackham.wordpress.com/738/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/srackham.wordpress.com/738/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/srackham.wordpress.com/738/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/srackham.wordpress.com/738/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/srackham.wordpress.com/738/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/srackham.wordpress.com/738/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/srackham.wordpress.com/738/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/srackham.wordpress.com/738/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/srackham.wordpress.com/738/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=srackham.wordpress.com&amp;blog=3711161&amp;post=738&amp;subd=srackham&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://srackham.wordpress.com/2011/10/25/testing-coffeescript-apps-with-selenium/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e74a88a96ce8caecbc7d265e4763e26c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">srackham</media:title>
		</media:content>
	</item>
		<item>
		<title>Compiling CoffeeScript with Vim</title>
		<link>http://srackham.wordpress.com/2011/10/20/compiling-coffeescript-with-vim/</link>
		<comments>http://srackham.wordpress.com/2011/10/20/compiling-coffeescript-with-vim/#comments</comments>
		<pubDate>Thu, 20 Oct 2011 00:06:02 +0000</pubDate>
		<dc:creator>srackham</dc:creator>
				<category><![CDATA[coffeescript]]></category>
		<category><![CDATA[Vim]]></category>

		<guid isPermaLink="false">http://srackham.wordpress.com/?p=735</guid>
		<description><![CDATA[Published: 2011-10-20 You can configure Vim to automatically compile CoffeeScript files when you save them from within Vim, it&#8217;s easy, just add an autocmd to run the CoffeeScript compiler to your ~/.vimrc file: autocmd BufWritePost,FileWritePost *.coffee :silent !coffee -c &#60;afile&#62; I prefer this to the CoffeeScript compiler --watch option because you get to see any [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=srackham.wordpress.com&amp;blog=3711161&amp;post=735&amp;subd=srackham&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a name="preamble"></a>
<p><strong>Published</strong>: 2011-10-20</p>
<p>You can configure Vim to automatically compile <a href="http://jashkenas.github.com/coffee-script/">CoffeeScript</a> files when you save them from within Vim, it&#8217;s easy, just add an <em>autocmd</em> to run the CoffeeScript compiler to your <tt>~/.vimrc</tt> file:</p>
<p><span id="more-735"></span><br />
<table border="0" bgcolor="#e8e8e8" width="100%" style="margin:.2em 0;">
<tr>
<td style="padding:.5em;">
<pre style="margin:0;padding:0;">autocmd BufWritePost,FileWritePost *.coffee :silent !coffee -c &lt;afile&gt;</pre>
</td>
</tr>
</table>
<p>I prefer this to the CoffeeScript compiler <tt>--watch</tt> option because you get to see any compiler errors in the editor when you save the CoffeeScript source file.</p>
<table style="margin:.2em 0;">
<tr valign="top">
<td style="padding:.5em;">
<p><b><u>Tip</u></b></p>
</td>
<td style="border-left:3px solid #e8e8e8;padding:.5em;">Use <em>Ctrl+L</em> to clear any compiler errors and redraw the screen.</td>
</tr>
</table>
<p>This technique works, but what happens if you want to selectively include CoffeeScript compiler options with some files and not others? I came up against this problem writing <a href="http://docs.jquery.com/Qunit">QUnit</a> tests using CoffeeScript which must be compiled without the top-level function wrapper using the <tt>--bare</tt> command-line option.</p>
<p>My solution was to take a cue from Vim&#8217;s <em>mode line</em> feature and write a CoffeeScript compiler wrapper shell script which scans the end of the CoffeeScript source file for a comment line starting with <em># coffee:</em>, it then passes the remainder of the line to the CoffeeScript compiler as command-line options. Here&#8217;s a basic CoffeeScript QUnit test file specifying the <tt>--bare</tt> option in the trailing mode line:</p>
<table border="0" bgcolor="#e8e8e8" width="100%" style="margin:.2em 0;">
<tr>
<td style="padding:.5em;">
<pre style="margin:0;padding:0;">module 'Test'

test 'addition', -&gt;
    equals 1+1, 2, 'one and one is two'

# coffee: --bare</pre>
</td>
</tr>
</table>
<p>And here&#8217;s the <tt>coffee.sh</tt> wrapper script:</p>
<table border="0" bgcolor="#e8e8e8" width="100%" style="margin:.2em 0;">
<tr>
<td style="padding:.5em;">
<pre style="margin:0;padding:0;">#!/bin/sh
#
# 'Mode line' wrapper for CoffeeScript 'coffee' compiler command.
#
# Executes CoffeeScript compiler and includes compiler options from line at the
# end of the CoffeeScript source file starting with '# coffee:' (c.f. Vim mode
# lines).
#

# Last argument is the source file name.
for srcfile; do true; done

# Search the last 5 lines in the source for a mode line and extract the
# trailing coffee command options.
pat='^#\s*coffee:'
opts=`tail -n5 $srcfile | grep "$pat" | sed "/$pat/s/$pat//"`

coffee $opts $@</pre>
</td>
</tr>
</table>
<p>You also need to change <tt>coffee</tt> to <tt>coffee.sh</tt> in your <tt>~/.vimrc</tt> <em>autocmd</em> plus you need to ensure both <tt>coffee</tt> to <tt>coffee.sh</tt> are in your shell search <tt>PATH</tt>:</p>
<table border="0" bgcolor="#e8e8e8" width="100%" style="margin:.2em 0;">
<tr>
<td style="padding:.5em;">
<pre style="margin:0;padding:0;">autocmd BufWritePost,FileWritePost *.coffee :silent !coffee.sh -c &lt;afile&gt;</pre>
</td>
</tr>
</table>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/srackham.wordpress.com/735/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/srackham.wordpress.com/735/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/srackham.wordpress.com/735/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/srackham.wordpress.com/735/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/srackham.wordpress.com/735/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/srackham.wordpress.com/735/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/srackham.wordpress.com/735/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/srackham.wordpress.com/735/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/srackham.wordpress.com/735/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/srackham.wordpress.com/735/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/srackham.wordpress.com/735/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/srackham.wordpress.com/735/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/srackham.wordpress.com/735/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/srackham.wordpress.com/735/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=srackham.wordpress.com&amp;blog=3711161&amp;post=735&amp;subd=srackham&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://srackham.wordpress.com/2011/10/20/compiling-coffeescript-with-vim/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e74a88a96ce8caecbc7d265e4763e26c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">srackham</media:title>
		</media:content>
	</item>
		<item>
		<title>Getters and Setters for Backbone Model attributes</title>
		<link>http://srackham.wordpress.com/2011/10/16/getters-and-setters-for-backbone-model-attributes/</link>
		<comments>http://srackham.wordpress.com/2011/10/16/getters-and-setters-for-backbone-model-attributes/#comments</comments>
		<pubDate>Sun, 16 Oct 2011 07:15:09 +0000</pubDate>
		<dc:creator>srackham</dc:creator>
				<category><![CDATA[Backbone.js]]></category>
		<category><![CDATA[coffeescript]]></category>

		<guid isPermaLink="false">http://srackham.wordpress.com/?p=732</guid>
		<description><![CDATA[Published: 2011-10-16 The Backbone.js Model class provides get and set methods to read and write Model attributes which is not a concise or natural as object property access. But it&#8217;s not difficult to add a class method to generate Model getter/setter properties so that you can do this in CoffeeScript: person.name = 'Joe Bloggs' ph [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=srackham.wordpress.com&amp;blog=3711161&amp;post=732&amp;subd=srackham&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a name="preamble"></a>
<p><strong>Published</strong>: 2011-10-16</p>
<p>The <a href="http://documentcloud.github.com/backbone/">Backbone.js</a> Model class provides <em>get</em> and <em>set</em> methods to read and write Model attributes which is not a concise or natural as object property access. But it&#8217;s not difficult to add a class method to generate Model getter/setter properties so that you can do this in <a href="http://jashkenas.github.com/coffee-script/">CoffeeScript</a>:</p>
<pre style="color:gray;padding:.5em;">person.name = 'Joe Bloggs'
ph = person.phone</pre>
<p>instead of this:</p>
<pre style="color:gray;padding:.5em;">person.set {name: 'Joe Bloggs'}
ph = person.get 'name'</pre>
<p><span id="more-732"></span>
<p>The <a href="http://jashkenas.github.com/coffee-script/">CoffeeScript</a> example below shows how it&#8217;s done using the <a href="http://www.ecma-international.org/publications/standards/Ecma-262.htm">ECMAScript 5</a> <em>Object.defineProperty</em> function to define a Model <em>attribute</em> method. I&#8217;ve added the <em>attribute</em> class method to a <em>BaseModel</em> class which is inherited by application classes. To create a Model attribute property call the <em>attribute</em> method and pass it the name of the property.</p>
<table border="0" bgcolor="#e8e8e8" width="100%" style="margin:.2em 0;">
<tr>
<td style="padding:.5em;">
<pre style="margin:0;padding:0;">Backbone = require 'backbone'

class BaseModel extends Backbone.Model
    # Create model attribute getter/setter property.
    @attribute = (attr) -&gt;
        Object.defineProperty @prototype, attr,
            get: -&gt; @get attr
            set: (value) -&gt;
                attrs = {}
                attrs[attr] = value
                @set attrs

class Contact extends BaseModel
    @attribute 'name'
    @attribute 'phone'

p = new Contact()
p.name = 'Joe Bloggs'
p.phone = '1234'
console.log p.attributes    # { name: 'Joe Bloggs', phone: '1234' }</pre>
</td>
</tr>
</table>
<p>Being able to create custom getter/setter properties is a testament to the little known power of JavaScript.</p>
<p><b>References</b></p>
<ul>
<li> <a href="http://ejohn.org/blog/ecmascript-5-objects-and-properties/">ECMAScript 5 Objects and Properties</a> </li>
<li> <a href="http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/">ECMAScript 5 Strict Mode, JSON, and More</a> </li>
<li> <a href="http://kangax.github.com/es5-compat-table/">ECMAScript 5 compatibility table</a> </li>
</ul>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/srackham.wordpress.com/732/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/srackham.wordpress.com/732/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/srackham.wordpress.com/732/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/srackham.wordpress.com/732/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/srackham.wordpress.com/732/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/srackham.wordpress.com/732/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/srackham.wordpress.com/732/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/srackham.wordpress.com/732/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/srackham.wordpress.com/732/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/srackham.wordpress.com/732/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/srackham.wordpress.com/732/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/srackham.wordpress.com/732/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/srackham.wordpress.com/732/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/srackham.wordpress.com/732/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=srackham.wordpress.com&amp;blog=3711161&amp;post=732&amp;subd=srackham&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://srackham.wordpress.com/2011/10/16/getters-and-setters-for-backbone-model-attributes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e74a88a96ce8caecbc7d265e4763e26c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">srackham</media:title>
		</media:content>
	</item>
		<item>
		<title>Routeless Backbone Contacts 2.0</title>
		<link>http://srackham.wordpress.com/2011/10/02/routeless-backbone-contacts-2-0/</link>
		<comments>http://srackham.wordpress.com/2011/10/02/routeless-backbone-contacts-2-0/#comments</comments>
		<pubDate>Sun, 02 Oct 2011 22:16:05 +0000</pubDate>
		<dc:creator>srackham</dc:creator>
				<category><![CDATA[Backbone.js]]></category>
		<category><![CDATA[coffeescript]]></category>

		<guid isPermaLink="false">http://srackham.wordpress.com/?p=715</guid>
		<description><![CDATA[Published: 2011-10-03 Updated: 2011-10-25 This post describes a revamped version 2.0 of my original Routeless Backbone Contacts application. The material covered here builds on the original post. The basic application functionality and the underlying data remains the same. The new user interface is a single two-pane page with a selectable list of contacts on the [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=srackham.wordpress.com&amp;blog=3711161&amp;post=715&amp;subd=srackham&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a name="preamble"></a>
<p><strong>Published</strong>: 2011-10-03<br /> <strong>Updated</strong>: 2011-10-25</p>
<p>This post describes a revamped version 2.0 of my <a href="http://srackham.wordpress.com/2011/09/22/routeless-backbone-contacts">original Routeless Backbone Contacts application</a>. The material covered here builds on the original post.</p>
<ol type="1">
<li> The basic application functionality and the underlying data remains the same. </li>
<li> The new user interface is a single two-pane page with a selectable list of contacts on the left and contact details on the right. </li>
<li> A <em>Search box</em> has been added to incrementally filter the list of displayed contacts. </li>
<li> The application is 100% event driven&#8201;&#8212;&#8201;there is no direct coupling between the views. <a href="http://documentcloud.github.com/backbone/#Events">Backbone.js events</a> emitted by the underlying contact data collection ensure the views are updated automatically when the state of the underlying data changes. </li>
</ol>
<p><span id="more-715"></span>
<p><em>Routeless Backbone.js Contacts</em> is a totally client-side CRUD tutorial application written using <a href="http://jashkenas.github.com/coffee-script/">CoffeeScript</a>, <a href="http://learnboost.github.com/stylus/">Stylus</a>, <a href="http://documentcloud.github.com/backbone/">Backbone.js</a> and <a href="http://jquery.com/">jQuery</a> which are a perfect match for writing concise, readable well structured web applications.</p>
<ul>
<li> The source is <a href="https://github.com/srackham/routeless-backbone-contacts">on Github</a>:
<ul>
<li> This release described in this post is at the <em>2.0</em> tag. </li>
<li> A subsequent release includes <a href="http://srackham.wordpress.com/2011/10/25/testing-coffeescript-apps-with-selenium/">Selenium tests</a> and is at the <em>3.0.</em> tag. </li>
</ul>
</li>
<li> The contacts data is persisted locally using browser <a href="http://en.wikipedia.org/wiki/Web_Storage">Web&nbsp;Storage</a>. </li>
<li> Templates are written using <a href="http://documentcloud.github.com/underscore/">Underscore.js</a> templates (included with <a href="http://documentcloud.github.com/backbone/">Backbone.js</a>). </li>
<li> Refer to the <a href="http://srackham.wordpress.com/2011/09/22/routeless-backbone-contacts">original Routeless Backbone Contacts 1.0 blog post</a> for more information. </li>
</ul>
<hr />
<h2><a name="_user_interface"></a>User Interface</h2>
<div> <img src="http://srackham.files.wordpress.com/2011/10/contacts2-screenshot.png?w=450" style="border-width:0;" alt="contacts2-screenshot.png"> </div>
<p>The single page user interface combines four <a href="http://documentcloud.github.com/backbone/#View">Backbone.js views</a>. The views subscribe to, and are updated by, <a href="http://documentcloud.github.com/backbone/#Events">events</a> emitted by the contacts collection (<em>add</em>, <em>remove</em>, <em>change</em>, <em>reset</em>, <em>filter</em>, <em>select</em>).</p>
<hr />
<h2><a name="_models_and_collections"></a>Models and Collections</h2>
<h3><a name="_contactmodel"></a>ContactModel</h3>
<p>The same <a href="http://documentcloud.github.com/backbone/#Model">model</a> as version 1.0.</p>
<h3><a name="_contactscollection"></a>ContactsCollection</h3>
<p>The <em>ContactsCollection</em> <a href="http://documentcloud.github.com/backbone/#Collection">collection</a> has been enhanced:</p>
<ol type="1">
<li> The <em>Filter</em> class provides functions to filter the collection by contact name. When the filter criteria changes the collection broadcasts a custom <em>filter</em> event to subscribed views. </li>
<li> The <em>Cursor</em> class provides a cursor object which represents the currently selected model in the contacts collection. The cursor listens for changes to the collection so that it can automatically ensure the cursor points to a valid contact in the filtered collection.  When the cursor changes the contacts collection broadcasts a custom <em>select</em> event to subscribed views. </li>
</ol>
<hr />
<h2><a name="_views"></a>Views</h2>
<h3><a name="_ribbonview"></a>RibbonView</h3>
<div> <img src="http://srackham.files.wordpress.com/2011/10/contacts2-ribbon.png?w=450" style="border-width:0;" alt="contacts2-ribbon.png"> </div>
<h3><a name="_statusview"></a>StatusView</h3>
<div> <img src="http://srackham.files.wordpress.com/2011/10/contacts2-status.png?w=450" style="border-width:0;" alt="contacts2-status.png"> </div>
<h3><a name="_listview"></a>ListView</h3>
<div> <img src="http://srackham.files.wordpress.com/2011/10/contacts2-list.png?w=450" style="border-width:0;" alt="contacts2-list.png"> </div>
<h3><a name="_detailview"></a>DetailView</h3>
<div> <img src="http://srackham.files.wordpress.com/2011/10/contacts2-detail.png?w=450" style="border-width:0;" alt="contacts2-detail.png"> </div>
<hr />
<h2><a name="_browser_compatibility"></a>Browser Compatibility</h2>
<p>The markup generated by this tutorial is HTML5 with CSS3, no attempt has been made to accommodate legacy browsers.</p>
<ul>
<li> Was developed and tested on Google Chrome 14. </li>
<li> Firefox 6 works fine. </li>
<li> Requires IE9+ for correct CSS styling (though the header gradient doesn&#8217;t work in IE9). </li>
<li> Requires iOS5+ for the names <a href="http://davidbcalhoun.com/2011/new-mobile-safari-stuff-in-ios5-position-fixed-overflow-scroll-new-input-type-support-web-workers-ecmascript-5">list to scroll</a>. </li>
</ul>
<hr />
<h2><a name="_backbone_js_tips"></a>Backbone.js Tips</h2>
<ul>
<li> The use of the <em>fat arrow</em> function definition operator in event handlers is significant. In the following example, when <em>render</em> is called <em>this</em> will be bound to the callee&#8217;s <em>this</em> context so the reference to <em>@el</em> will be correct:<br />
<table border="0" bgcolor="#e8e8e8" width="100%" style="margin:.2em 0;">
<tr>
<td style="padding:.5em;">
<pre style="margin:0;padding:0;">  @model.bind 'change', @render
  render: =&gt;
      @el.html @template</pre>
</td>
</tr>
</table>
</li>
<li> Don&#8217;t rely on the execution order of registered events. </li>
<li> The Model <em>change</em> event bubbles up through related collections. </li>
<li> It pays to monitor event handler execution during development. If a section of code triggers the execution of the same handler multiple times this may be symptomatic of a non-optimal design. For example, without the <em>silent</em> option the following code would trigger multiple collection <em>remove</em> events (the collection <em>reset</em> is sufficient to  ensure listener notification):<br />
<table border="0" bgcolor="#e8e8e8" width="100%" style="margin:.2em 0;">
<tr>
<td style="padding:.5em;">
<pre style="margin:0;padding:0;">contact.destroy {silent: true} for contact in @collection.toArray()
@collection.reset()</pre>
</td>
</tr>
</table>
<p>On the other hand, it&#8217;s not unusual for event handlers to execute common code which can also result in execution redundancy (for example, the <em>renderCursor</em> handler is also called by the <em>render</em> handler in the <em>ListView</em>). In cases like this don&#8217;t sweat over eliminating the redundancy unless it impacts performance&#8201;&#8212;&#8201;code clarity is usually preferable to the convoluted and brittle optimisations generated by a &#8220;fix&#8221;.</p>
</li>
<li> When Backbone.js Models and Collections emit built-in events they pass associated event information to the event handler arguments. The <a href="http://documentcloud.github.com/backbone/#FAQ-events">catalog of Backbone.js events</a> documents the event handler arguments. Currently undocumented is fact that <em>options</em> arguments passed to event triggering methods are passed through to the handlers as the trailing argument.  In the following example an object containing a custom option <em>myOption</em> will be the third argument passed to the <em>add</em> event handlers <tt>"add"(model, collection, options)</tt>:<br />
<table border="0" bgcolor="#e8e8e8" width="100%" style="margin:.2em 0;">
<tr>
<td style="padding:.5em;">
<pre style="margin:0;padding:0;">myCollection.add myModel, {myOption: 'foobar'}</pre>
</td>
</tr>
</table>
</li>
<li> Don&#8217;t forget that Backbone.js event handlers are passed arguments (see previous item).  For example, the Backbone.js Collection <em>reset</em> event passes the associated collection to the handler in the first argument which will cause the following code to fail:<br />
<table border="0" bgcolor="#e8e8e8" width="100%" style="margin:.2em 0;">
<tr>
<td style="padding:.5em;">
<pre style="margin:0;padding:0;">@_collection.bind 'reset', @set
set: (model=null) =&gt;
    :</pre>
</td>
</tr>
</table>
<p>If you assumed that the <em>set</em> handler would be called with no arguments you would expect <em>model</em> to be set to <em>null</em>&#8201;&#8212;&#8201;in fact <em>model</em> is assigned <em>@_collection</em>.  The code can be fixed by introducing an anonymous proxy handler that is bound to <em>this</em> and called without any arguments:</p>
<table border="0" bgcolor="#e8e8e8" width="100%" style="margin:.2em 0;">
<tr>
<td style="padding:.5em;">
<pre style="margin:0;padding:0;">@_collection.bind 'reset', =&gt; @set()
set: (model=null) -&gt;
    :</pre>
</td>
</tr>
</table>
</li>
<li> Use the <a href="http://documentcloud.github.com/backbone/#FAQ-events">built-in event</a> argument passing conventions if you have to <a href="http://documentcloud.github.com/backbone/#Events-trigger">trigger</a> a built-in event programmatically. For example:<br />
<table border="0" bgcolor="#e8e8e8" width="100%" style="margin:.2em 0;">
<tr>
<td style="padding:.5em;">
<pre style="margin:0;padding:0;">@collection.trigger 'reset', @collection</pre>
</td>
</tr>
</table>
</li>
</ul>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/srackham.wordpress.com/715/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/srackham.wordpress.com/715/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/srackham.wordpress.com/715/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/srackham.wordpress.com/715/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/srackham.wordpress.com/715/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/srackham.wordpress.com/715/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/srackham.wordpress.com/715/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/srackham.wordpress.com/715/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/srackham.wordpress.com/715/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/srackham.wordpress.com/715/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/srackham.wordpress.com/715/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/srackham.wordpress.com/715/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/srackham.wordpress.com/715/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/srackham.wordpress.com/715/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=srackham.wordpress.com&amp;blog=3711161&amp;post=715&amp;subd=srackham&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://srackham.wordpress.com/2011/10/02/routeless-backbone-contacts-2-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e74a88a96ce8caecbc7d265e4763e26c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">srackham</media:title>
		</media:content>

		<media:content url="http://srackham.files.wordpress.com/2011/10/contacts2-screenshot.png" medium="image">
			<media:title type="html">contacts2-screenshot.png</media:title>
		</media:content>

		<media:content url="http://srackham.files.wordpress.com/2011/10/contacts2-ribbon.png" medium="image">
			<media:title type="html">contacts2-ribbon.png</media:title>
		</media:content>

		<media:content url="http://srackham.files.wordpress.com/2011/10/contacts2-status.png" medium="image">
			<media:title type="html">contacts2-status.png</media:title>
		</media:content>

		<media:content url="http://srackham.files.wordpress.com/2011/10/contacts2-list.png" medium="image">
			<media:title type="html">contacts2-list.png</media:title>
		</media:content>

		<media:content url="http://srackham.files.wordpress.com/2011/10/contacts2-detail.png" medium="image">
			<media:title type="html">contacts2-detail.png</media:title>
		</media:content>
	</item>
		<item>
		<title>Routeless Backbone Contacts</title>
		<link>http://srackham.wordpress.com/2011/09/22/routeless-backbone-contacts/</link>
		<comments>http://srackham.wordpress.com/2011/09/22/routeless-backbone-contacts/#comments</comments>
		<pubDate>Thu, 22 Sep 2011 22:50:31 +0000</pubDate>
		<dc:creator>srackham</dc:creator>
				<category><![CDATA[Backbone.js]]></category>
		<category><![CDATA[coffeescript]]></category>

		<guid isPermaLink="false">http://srackham.wordpress.com/?p=636</guid>
		<description><![CDATA[Published: 2011-09-24 Updated: 2011-10-03 You don&#8217;t need a URL router to write client-side applications. Routeless Backbone.js Contacts is a totally client-side CRUD tutorial application written using CoffeeScript, Stylus, Backbone.js and jQuery which are a perfect match for writing concise, readable well structured web applications. The source is on Github. Note This release described in this [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=srackham.wordpress.com&amp;blog=3711161&amp;post=636&amp;subd=srackham&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a name="preamble"></a>
<p><strong>Published</strong>: 2011-09-24<br /> <strong>Updated</strong>: 2011-10-03</p>
<p>You don&#8217;t need a URL router to write client-side applications.</p>
<p><em>Routeless Backbone.js Contacts</em> is a totally client-side CRUD tutorial application written using <a href="http://jashkenas.github.com/coffee-script/">CoffeeScript</a>, <a href="http://learnboost.github.com/stylus/">Stylus</a>, <a href="http://documentcloud.github.com/backbone/">Backbone.js</a> and <a href="http://jquery.com/">jQuery</a> which are a perfect match for writing concise, readable well structured web applications.</p>
<ul>
<li> The source is <a href="https://github.com/srackham/routeless-backbone-contacts">on Github</a>.<br />
<table style="margin:.2em 0;">
<tr valign="top">
<td style="padding:.5em;">
<p><b><u>Note</u></b></p>
</td>
<td style="border-left:3px solid #e8e8e8;padding:.5em;">This release described in this post is at the <em>1.0</em> tag.</td>
</tr>
</table>
</li>
<li> Uses DOM events exclusively for UI navigation. </li>
<li> The contacts data is persisted locally using browser <a href="http://en.wikipedia.org/wiki/Web_Storage">Web&nbsp;Storage</a>. </li>
<li> Templates are written using <a href="http://documentcloud.github.com/underscore/">Underscore.js</a> templates (included with <a href="http://documentcloud.github.com/backbone/">Backbone.js</a>). </li>
</ul>
<table style="margin:.2em 0;">
<tr valign="top">
<td style="padding:.5em;">
<p><b><u>Note</u></b></p>
</td>
<td style="border-left:3px solid #e8e8e8;padding:.5em;">A second version of this tutorial application [has been posted], it builds on the material covered in this post.</td>
</tr>
</table>
<p><span id="more-636"></span><br />
<hr />
<h2><a name="_screenshots"></a>Screenshots</h2>
<h3><a name="_listcontactview"></a>ListContactView</h3>
<div> <img src="http://srackham.files.wordpress.com/2011/09/contacts-list.png?w=450" style="border-width:0;" alt="contacts-list.png"> </div>
<h3><a name="_showcontactview"></a>ShowContactView</h3>
<div> <img src="http://srackham.files.wordpress.com/2011/09/contacts-show.png?w=450" style="border-width:0;" alt="contacts-show.png"> </div>
<h3><a name="_editcontactview"></a>EditContactView</h3>
<div> <img src="http://srackham.files.wordpress.com/2011/09/contacts-edit.png?w=450" style="border-width:0;" alt="contacts-edit.png"> </div>
<hr />
<h2><a name="_going_routeless"></a>Going routeless</h2>
<p>It&#8217;s a mindset thing. If you come from a server-side web applications background your first instinct is to use a router and <a href="http://en.wikipedia.org/wiki/Fragment_identifier">fragment identifiers</a> to emulate browser page navigation&#8201;&#8212;&#8201;go down this route you soon find that trying to maintain a consistent back-button browser history is time consuming, messy and ultimately unnecessary.  Single page applications don&#8217;t need a back-button (or any browser chrome), especially if they are bundled as pseudo-native mobile apps with something like <a href="http://www.phonegap.com/">PhoneGap</a> or packaged for the desktop, for example as <a href="http://code.google.com/chrome/extensions/apps.html">Google Chrome Packaged Apps</a>.</p>
<p><em>Routeless Backbone.js Contacts</em> resides at a single <a href="http://en.wikipedia.org/wiki/Fragment_identifier">unfragmented URL</a>&#8201;&#8212;&#8201;user interface navigation is managed exclusively by DOM events. Button and link elements deal with the click events client-side (you are not POSTing form data to a server, so <em>form</em> elements and <em>submit</em> buttons are not necessary).  If the application were to persist data externally then then the data POSTS and GETS would be handled transparently by a Backbone database adapter.</p>
<hr />
<h2><a name="_running_the_application"></a>Running the application</h2>
<p>Once you have downloaded the <a href="https://github.com/srackham/routeless-backbone-contacts">source from Github</a> open the <tt>index.html</tt> file in your browser. Press the <em>Import Data</em> button to load the example contacts database.</p>
<table style="margin:.2em 0;">
<tr valign="top">
<td style="padding:.5em;">
<p><b><u>Important</u></b></p>
</td>
<td style="border-left:3px solid #e8e8e8;padding:.5em;">
<p>Unlike Google Chrome, neither Firefox 6 or IE9 like persisting Web Storage from file based URLs and you will need to open the application via a web server. I use <a href="http://code.google.com/p/mongoose/">Mongoose</a> (a neat little single-executable cross-platform web server) for testing.  Once you&#8217;ve installed <em>mongoose</em>:</p>
<ul>
<li> <em>cd</em> to the directory containing <tt>index.html</tt> </li>
<li> Then execute the <em>mongoose</em> command and open your web browser at <em>localhost:8080</em>. </li>
</ul>
</td>
</tr>
</table>
<hr />
<h2><a name="_the_source"></a>The source</h2>
<p>This post should be read side-by-side with the source, it&#8217;s very readable (although a basic understanding of <a href="http://jashkenas.github.com/coffee-script/">CoffeeScript</a>, HTML and <a href="http://jquery.com/">jQuery</a> is recommended).</p>
<dl>
<dt> <a href="https://github.com/srackham/routeless-backbone-contacts/blob/master/index.html">index.html</a> </dt>
<dd> Application page HTML and view templates. </dd>
<dt> <a href="https://github.com/srackham/routeless-backbone-contacts/blob/master/js/application.coffee">application.coffee</a> </dt>
<dd> Application, models and views. </dd>
<dt> <a href="https://github.com/srackham/routeless-backbone-contacts/blob/master/js/data.js">data.js</a> </dt>
<dd> Canned data (100 fictitious contacts) loaded by the <em>Import Data</em> command. </dd>
<dt> <a href="https://github.com/srackham/routeless-backbone-contacts/blob/master/css/main.styl">main.styl</a> </dt>
<dd> Stylus CSS. </dd>
<dt> <a href="https://github.com/srackham/routeless-backbone-contacts/blob/master/css/helpers.styl">helpers.styl</a>, <a href="https://github.com/srackham/routeless-backbone-contacts/blob/master/css/gradients.styl">gradients.styl</a> </dt>
<dd> CSS helper functions. </dd>
</dl>
<p>HTML5 markup is used throughout.  All the logic is confined to <a href="https://github.com/srackham/routeless-backbone-contacts/blob/master/js/application.coffee">application.coffee</a> (around 160 lines of code).  The beauty of <a href="http://jashkenas.github.com/coffee-script/">CoffeeScript</a> is that the code is concise and virtually self-documenting, for example, here&#8217;s the event handler in the ListContactView that responds to the <em>Clear All</em> button click:</p>
<table border="0" bgcolor="#e8e8e8" width="100%" style="margin:.2em 0;">
<tr>
<td style="padding:.5em;">
<pre style="margin:0;padding:0;">clear: (e) -&gt;
    return if not confirm 'About to delete all data.'
    contact.destroy() for contact in @collection.toArray()
    @render()</pre>
</td>
</tr>
</table>
<hr />
<h2><a name="_application_structure"></a>Application structure</h2>
<h3><a name="_the_app_object"></a>The app object</h3>
<p>There is a single global instance <em>app</em> of the <em>App</em> class which:</p>
<ul>
<li> Initializes and namespaces global data (collections and views). </li>
<li> Contains a few generic methods to allow programmatic inter-view navigation&#8201;&#8212;&#8201;this allows views to call one another and not have to share any information about each other. </li>
<li> Starts the application (with <tt>app.start()</tt>). </li>
</ul>
<h3><a name="_models_and_collections"></a>Models and Collections</h3>
<p>A single <tt>app.contacts</tt> collection of Contact models is persisted locally using the <a href="https://github.com/jeromegn/Backbone.localStorage">Backbone&nbsp;localStorage&nbsp;Adapter</a>. A single store is instantiated and attached to the <em>ContactModel</em>, the same store is referenced by the <em>ContactCollection</em>.</p>
<h3><a name="_views"></a>Views</h3>
<p>The CRUD user interface is implemented by three Backbone.js views&#8201;&#8212;&#8201;<em>ListView</em>, <em>ShowView</em> and <em>EditView</em> (the <em>EditView</em> is also used to create new contacts).</p>
<ul>
<li> Each view handles the set of DOM events defined by the View&#8217;s <em>events</em> property. </li>
<li> The <em>events</em> property routes DOM events to a handler within the View. </li>
<li> When a matching DOM event occurs the View handler is called and passed a <a href="http://api.jquery.com/category/events/event-object/">jQuery event object</a>. </li>
</ul>
<p>This example (from the <em>ListContactView</em>)  uses a <a href="http://ejohn.org/blog/html-5-data-attributes/">custom data attribute</a> (<em>data-id</em>) to pass the contact ID from the anchor element via a click event object.</p>
<p>DOM event registration:</p>
<table border="0" bgcolor="#e8e8e8" width="100%" style="margin:.2em 0;">
<tr>
<td style="padding:.5em;">
<pre style="margin:0;padding:0;">events:
    'click a.show': 'show'</pre>
</td>
</tr>
</table>
<p>Link click handler:</p>
<table border="0" bgcolor="#e8e8e8" width="100%" style="margin:.2em 0;">
<tr>
<td style="padding:.5em;">
<pre style="margin:0;padding:0;">show: (e) -&gt;
    @model = @collection.get e.target.getAttribute('data-id')
    @render()</pre>
</td>
</tr>
</table>
<p>Template link markup:</p>
<table border="0" bgcolor="#e8e8e8" width="100%" style="margin:.2em 0;">
<tr>
<td style="padding:.5em;">
<pre style="margin:0;padding:0;">&lt;a class="show" data-id="&lt;%= contact.id %&gt;"&gt;&lt;%= contact.getName() %&gt;&lt;/a&gt;</pre>
</td>
</tr>
</table>
<p>It would have been nice to have used the HTML5 DOM dataset property to retrieve the <em>data-id</em> attribute (<tt>e.target.dataset.id</tt>) but it does not currently work in IE9, Safari or Android browsers.</p>
<h3><a name="_libraries"></a>Libraries</h3>
<p>The app uses the following JavaScript libraries (in the <tt>lib</tt> directory):</p>
<ul>
<li> <a href="http://documentcloud.github.com/backbone/">Backbone.js</a> </li>
<li> <a href="http://jquery.com/">jQuery</a> </li>
<li> <a href="http://documentcloud.github.com/underscore/">Underscore.js</a> </li>
<li> The <a href="https://github.com/jeromegn/Backbone.localStorage">Backbone&nbsp;localStorage&nbsp;Adapter</a> persists models to the local disk using the browser <a href="http://dev.w3.org/html5/webstorage/">Web Storage</a> API. </li>
</ul>
<hr />
<h2><a name="_techniques"></a>Techniques</h2>
<h3><a name="_load_scripts_at_the_end_of_the_page_body"></a>Load scripts at the end of the page body</h3>
<p>Place script tags last in the page body, just before the closing body tag. This ensures the page elements elements have been parsed and can be referenced when the scripts execute and allows you to safely reference page elements from class property initializers. See <a href="http://stackoverflow.com/questions/3037725/is-it-wrong-to-place-the-script-tag-after-the-body-tag">this stackoverflow discussion</a>.</p>
<h3><a name="_intra_application_links_do_not_need_href_8217_s"></a>Intra-application links do not need href&#8217;s</h3>
<p>Dropping the <em>href</em> ensures there are no changes to the browser URL or history.</p>
<hr />
<h2><a name="_css_and_html_tips"></a>CSS and HTML Tips</h2>
<ul>
<li> <a href="http://learnboost.github.com/stylus/">Stylus</a> is to CSS as CoffeeScript is to JavaScript, use it to keep your CSS <a href="http://en.wikipedia.org/wiki/Don&#8217;t_repeat_yourself">DRY</a> and to maintain your sanity. </li>
<li> Use <a href="http://learnboost.github.com/stylus/docs/import.html">Stylus imports</a> to unclutter your main CSS. </li>
<li> CSS padding vs margins:
<ul>
<li> Margins define the element&#8217;s relationship to other elements (spacing) and are context specific i.e. an element&#8217;s margins will change depending on where it is used in the application. </li>
<li> Padding styles an elements appearance and isn&#8217;t a context sensitive as the element margins. </li>
<li> The <em>width</em> property <em>does not include the margins, border or padding</em>. </li>
</ul>
</li>
<li> Use HTML5&#8217;s concise syntax, it may seem wrong after years of XML indoctrination but it&#8217;s not, it&#8217;s easier to read and your fingers will thank you. Examples:
<ul>
<li> Closing tag omission:<br />
<table border="0" bgcolor="#e8e8e8" width="100%" style="margin:.2em 0;">
<tr>
<td style="padding:.5em;">
<pre style="margin:0;padding:0;">&lt;tr&gt;&lt;td&gt;Foo&lt;td&gt;Bar                  YES
&lt;tr&gt;&lt;td&gt;Foo&lt;/td&gt;&lt;td&gt;Bar&lt;/td&gt;&lt;/tr&gt;   NO</pre>
</td>
</tr>
</table>
</li>
<li> Minimized attributes:<br />
<table border="0" bgcolor="#e8e8e8" width="100%" style="margin:.2em 0;">
<tr>
<td style="padding:.5em;">
<pre style="margin:0;padding:0;">readonly                            YES
readonly="readonly"                 NO</pre>
</td>
</tr>
</table>
</li>
<li> Empty elements don&#8217;t need explicit termination:<br />
<table border="0" bgcolor="#e8e8e8" width="100%" style="margin:.2em 0;">
<tr>
<td style="padding:.5em;">
<pre style="margin:0;padding:0;">&lt;img src="me.png"&gt;                  YES
&lt;img src="me.png" /&gt;                NO</pre>
</td>
</tr>
</table>
</li>
</ul>
</li>
<li> Length and size:
<ul>
<li> Use em units to set size properties on elements that display text, it&#8217;ll make it much easier to resize your app. </li>
<li> To get exact placements you&#8217;ll need to use pixels, but this can probably be confined to non-text elements. </li>
<li> Use Stylus arithmetic expressions to maintain the size of interdependent page elements so that changing a single size will ensure the depend sizes are adjusted automatically (DRY again). </li>
</ul>
</li>
<li> Be careful assigning <em>id</em> attributes in templates, do so only if the template will never appear more than once on a page. If in doubt assign <em>class</em> attributes instead of <em>id</em> attributes. </li>
<li> Tables are not bad, in fact they are very good for laying out application pages (which are quite different to document oriented websites). </li>
<li> Don&#8217;t put CSS <em>style</em> attributes in HTML template markup&#8201;&#8212;&#8201;this should be obvious. </li>
<li> Start with a clean slate, reset user-agent (browser) document oriented CSS defaults:<br />
<table border="0" bgcolor="#e8e8e8" width="100%" style="margin:.2em 0;">
<tr>
<td style="padding:.5em;">
<pre style="margin:0;padding:0;">* {
  font-size: 20px;
  font-family: sans-serif;
  margin: 0;
  padding: 0;
}</pre>
</td>
</tr>
</table>
</li>
</ul>
<hr />
<h2><a name="_references"></a>References</h2>
<ul>
<li> E. Mathieu Sternberg&#8217;s <a href="http://www.elfsternberg.com/2011/08/22/backbone-store-version-20-backbonejs-coffeescript-haml-stylus-edition/">The Backbone Store, version 2.0</a>. </li>
</ul>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/srackham.wordpress.com/636/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/srackham.wordpress.com/636/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/srackham.wordpress.com/636/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/srackham.wordpress.com/636/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/srackham.wordpress.com/636/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/srackham.wordpress.com/636/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/srackham.wordpress.com/636/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/srackham.wordpress.com/636/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/srackham.wordpress.com/636/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/srackham.wordpress.com/636/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/srackham.wordpress.com/636/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/srackham.wordpress.com/636/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/srackham.wordpress.com/636/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/srackham.wordpress.com/636/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=srackham.wordpress.com&amp;blog=3711161&amp;post=636&amp;subd=srackham&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://srackham.wordpress.com/2011/09/22/routeless-backbone-contacts/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e74a88a96ce8caecbc7d265e4763e26c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">srackham</media:title>
		</media:content>

		<media:content url="http://srackham.files.wordpress.com/2011/09/contacts-list.png" medium="image">
			<media:title type="html">contacts-list.png</media:title>
		</media:content>

		<media:content url="http://srackham.files.wordpress.com/2011/09/contacts-show.png" medium="image">
			<media:title type="html">contacts-show.png</media:title>
		</media:content>

		<media:content url="http://srackham.files.wordpress.com/2011/09/contacts-edit.png" medium="image">
			<media:title type="html">contacts-edit.png</media:title>
		</media:content>
	</item>
		<item>
		<title>Switching from the iPad to the Asus Transformer</title>
		<link>http://srackham.wordpress.com/2011/08/31/switching-from-the-ipad-to-the-asus-transformer/</link>
		<comments>http://srackham.wordpress.com/2011/08/31/switching-from-the-ipad-to-the-asus-transformer/#comments</comments>
		<pubDate>Wed, 31 Aug 2011 04:15:39 +0000</pubDate>
		<dc:creator>srackham</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[ipad]]></category>
		<category><![CDATA[tablet]]></category>

		<guid isPermaLink="false">http://srackham.wordpress.com/?p=617</guid>
		<description><![CDATA[Published: 2011-08-31 My blogs are usually technical in content and try to be objective in character, this blog is a bit different, it has an unashamed subjective bias (you&#8217;ve been warned). Shortly after the iPad 2 was released I went over to the Dark Side and brought one (my first and only Apple computer). I [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=srackham.wordpress.com&amp;blog=3711161&amp;post=617&amp;subd=srackham&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a name="preamble"></a>
<p><strong>Published</strong>: 2011-08-31</p>
<p>My blogs are usually technical in content and try to be objective in character, this blog is a bit different, it has an unashamed subjective bias (you&#8217;ve been warned).</p>
<p>Shortly after the iPad 2 was released I went over to the Dark Side and brought one (my first and only Apple computer). I was just fed up waiting for a decent Android tablet. At the time my only requirements were a decent ePub reader and a web browser.</p>
<p><span id="more-617"></span>
<p>After two months with the iPad I was still hankering for an Android tablet, I know this probably sounds a bit wishy-washy, but  although I used it every day I never really bonded with the iPad, it always felt like an appliance, a black box, something that you turn on, use, then turn off.  Don&#8217;t get me wrong, the iPad 2 is a nice piece hardware, it&#8217;s easy to pick up and use and the software does what it was designed to do.  The best recommendation I can give the iPad is that it works.</p>
<p>Two weeks ago I bit the Android bullet and tossed up between an Asus Transformer and a Samsung 10.1 tablet.  The Transformer won and I brought the 32GB model with keyboard dock. When I say &#8220;tossed up&#8221; I am being a little flippant&#8201;&#8212;&#8201;I compared specs, read reviews and got to play with a Transformer (I had been leaning towards the iPad-like Samsung 10.1 but the hands-on convinced me that the Transformer was a nice piece of kit and that the keyboard was going to be very useful). The transformer&#8217;s cheaper price was also a plus.</p>
<p>I haven&#8217;t touched my iPad since I got the Transformer, the more I use the Transformer it the more I like it (there&#8217;s a greater depth in Android vs iOS) so much so that I&#8217;ve given the iPad to my wife. It&#8217;s not all sunshine and roses though (see <a href="#X1">the bad parts</a>), but Android is heading in the right direction&#8201;&#8212;&#8201;all it needs is for Google to keep on polishing the rough edges and not to take their eyes off the ball.</p>
<p>Here are some comparative observations&#8201;&#8212;&#8201;things that stood out for me (please bear in mind that these are personal observations, this is not a formal product review):</p>
<dl>
<dt> <strong>Thumb friendly UI</strong> </dt>
<dd> The user interface is very &#8220;thumb friendly&#8221;&#8201;&#8212;&#8201;most of the time I hold the tablet in landscape mode with one hand either side using just my thumbs to execute commands&#8201;&#8212;&#8201;much more efficient that the iPad&#8217;s &#8220;hunt and peck&#8221; UI. I don&#8217;t know if this is serendipity or by design. </dd>
<dt> <strong>Weight and size</strong> </dt>
<dd> This is interesting, the Transformer is marginally heavier than the iPad 2 (680g vs 601g) but it feels lighter, probably because it&#8217;s larger and less dense. The Transformer is also thicker (13mm vs 8.8mm), I thought this would be a biggy (most reviewers think it is)&#8201;&#8212;&#8201;I was wrong, for me there&#8217;s no subjective difference. </dd>
<dt> <strong>Batteries included</strong> </dt>
<dd> The Transformer tablet has a built-in HDMI port and a Micro SD Card slot (iPad memory can&#8217;t be expanded and you need an external adapter for HDMI connectivity).  The first accessories I brought for the Transformer were:
<ul>
<li> A 5m HDMI cable so I could play tablet HD video and audio on my TV. </li>
<li> A 16GB Micro SD card for transferring and storing data. </li>
</ul>
</dd>
<dt> <strong>Cameras</strong> </dt>
<dd> The 5M pixel rear camera produces <strong>much</strong> higher quality photos and movies than the iPad, there&#8217;s just no comparison. </dd>
<dt> <strong>Real keyboard</strong> </dt>
<dd> The Transformer keyboard dock has a real keyboard (plus battery pack plus expansion ports) which turns the Transformer tablet into a Netbook PC and makes it useful for content creation. For me the lack of a real keyboard for the iPad was an increasing source of frustration (I know you can buy keyboards for the iPad but it&#8217;s just not the same as having a beautifully integrated keyboard unit)<br />
<table style="margin:.2em 0;">
<tr valign="top">
<td style="padding:.5em;">
<p><b><u>Note</u></b></p>
</td>
<td style="border-left:3px solid #e8e8e8;padding:.5em;">The tablet lock/unlock slider should be on the left when inserting the tablet (I thought the slider icon meant <em>locked</em>&#8201;&#8212;&#8201;it actually means <em>unlocked</em>).</td>
</tr>
</table>
</dd>
<dt> <strong>Bundled apps</strong> </dt>
<dd> In my opinion all the Asus specific non-Google apps that come loaded on the Transformer are crapware.  I just wish manufacturers would ship vanilla operating systems without including other apps, or at the very least make them optional (there doesn&#8217;t even seem to be any easy way to delete the bundled apps). </dd>
<dt> <strong>The Android platform is relatively open</strong> </dt>
<dd> The freedom to choose and create software without the platform vendor&#8217;s permission is important to me&#8201;&#8212;&#8201;Apple&#8217;s totalitarian control over iPad software installation and distribution is an unpalatable dead end. </dd>
<dt> <strong>What&#8217;s missing</strong> </dt>
<dd> At the moment I&#8217;m mostly using the Transformer without the keyboard dock and what I miss most is the iPad Smart Cover&#8201;&#8212;&#8201;wandering around holding the Transformer in one hand with my fingers on the glass screen doesn&#8217;t feel right and there&#8217;s a constant nagging awareness of always having to be careful to protect the glass screen. </dd>
<dt> <strong><a name="X1"></a> The bad parts</strong> </dt>
<dd> In a word <em>software</em> (my unit is running Android 3.2).
<ul>
<li> Number one problem: The browser is appallingly slow on JavaScript heavy sites (try the <a href="http://jquerymobile.com/">jQuery mobile</a> demos). I also tried FireFox, Opera and Dolphin&#8201;&#8212;&#8201;in all three cases the stability and usability was worst than the Android browser. I don&#8217;t know if this is specific to the Transformer or not (see <a href="http://code.google.com/p/android/issues/detail?id=17353">Issue 17353: Honeycomb 3.1: Slow web browser performance on websites with a lot of JavaScript</a>. This is frustrating because the tabbed Android browser has a better UI and many more features than the iPad&#8217;s browser. </li>
<li> Your TV HDMI inputs may or may not work with the tablet HDMI output. My Philips 42 inch LCD TV didn&#8217;t connect when plugged into the Transformer, it does not support the tablet&#8217;s 1280&#215;800 output. I took the Transformer down to a local TV shop tried two 42 inch LCD TVs: it worked on a Sony but not an LG. <a href="http://forums.bit-tech.net/showpost.php?p=2637974&amp;postcount=83">This post</a> suggest the problem is a software limitation a the moment: &#8220;Tegra 2 supports 1080p output over HDMI, but right now the product is limited to 1280 x 800 output over HDMI&#8221;. </li>
</ul>
</dd>
</dl>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/srackham.wordpress.com/617/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/srackham.wordpress.com/617/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/srackham.wordpress.com/617/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/srackham.wordpress.com/617/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/srackham.wordpress.com/617/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/srackham.wordpress.com/617/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/srackham.wordpress.com/617/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/srackham.wordpress.com/617/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/srackham.wordpress.com/617/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/srackham.wordpress.com/617/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/srackham.wordpress.com/617/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/srackham.wordpress.com/617/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/srackham.wordpress.com/617/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/srackham.wordpress.com/617/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=srackham.wordpress.com&amp;blog=3711161&amp;post=617&amp;subd=srackham&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://srackham.wordpress.com/2011/08/31/switching-from-the-ipad-to-the-asus-transformer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e74a88a96ce8caecbc7d265e4763e26c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">srackham</media:title>
		</media:content>
	</item>
		<item>
		<title>Fossil Backend for AsciiDoc</title>
		<link>http://srackham.wordpress.com/2011/08/30/fossil-backend-for-asciidoc/</link>
		<comments>http://srackham.wordpress.com/2011/08/30/fossil-backend-for-asciidoc/#comments</comments>
		<pubDate>Tue, 30 Aug 2011 03:02:03 +0000</pubDate>
		<dc:creator>srackham</dc:creator>
				<category><![CDATA[AsciiDoc]]></category>
		<category><![CDATA[fossil]]></category>

		<guid isPermaLink="false">http://srackham.wordpress.com/?p=605</guid>
		<description><![CDATA[Published: 2011-08-30 Updated: 2011-09-04 Note The Fossil backend is now hosted at Github. Here is an AsciiDoc configuration file that can be used to create a simple backend plugin for generating Fossil friendly Wiki markup from AsciiDoc source (I wrote it as a proof-of-concept of the new AsciiDoc backend plugins). Fossil is a wonderful distributed [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=srackham.wordpress.com&amp;blog=3711161&amp;post=605&amp;subd=srackham&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a name="preamble"></a>
<p><strong>Published</strong>: 2011-08-30<br /> <strong>Updated</strong>: 2011-09-04</p>
<table style="margin:.2em 0;">
<tr valign="top">
<td style="padding:.5em;">
<p><b><u>Note</u></b></p>
</td>
<td style="border-left:3px solid #e8e8e8;padding:.5em;">The Fossil backend is now <a href="https://github.com/srackham/asciidoc-fossil-backend">hosted at Github</a>.</td>
</tr>
</table>
<p>Here is an <a href="http://www.methods.co.nz/asciidoc/">AsciiDoc</a> configuration file that can be used to create a simple backend plugin for generating <a href="http://www.fossil-scm.org">Fossil</a> friendly Wiki markup from AsciiDoc source (I wrote it as a proof-of-concept of the new AsciiDoc backend plugins).</p>
<p><span id="more-605"></span>
<p><a href="http://www.fossil-scm.org">Fossil</a> is a wonderful distributed version control system (DVCS) by Richard Hipp, the author of SQLite. It is built on SQLite and shares the same small-is-beautiful single stand-alone executable philosophy.</p>
<p>A Fossil repository doesn&#8217;t just manage source, it also supports distributed project bug tracking, wiki and blog&#8201;&#8212;&#8201;all managed by an integrated Web UI. Fossil really deserves more attention than it currently gets.</p>
<p><b><tt>fossil.conf</tt> backend configuration file</b></p>
<table border="0" bgcolor="#e8e8e8" width="100%" style="margin:.2em 0;">
<tr>
<td style="padding:.5em;">
<pre style="margin:0;padding:0;">#
# AsciiDoc configuration file for Fossil DVCS wiki HTML generation.
#

include::{asciidoc-confdir}/html4.conf[]

[footer]
&lt;/nowiki&gt;

#--------------------------------
# article and book document types
#--------------------------------
ifndef::doctype-manpage[]

[header]
&lt;nowiki&gt;
{notitle%}&lt;h1&gt;{doctitle}&lt;/h1&gt;
{doctitle#}&lt;p&gt;
{doctitle#}&lt;strong&gt;{author}&lt;/strong&gt;&lt;br&gt;
{doctitle#}&lt;tt&gt;&amp;lt;&lt;a href="mailto:{email}"&gt;{email}&lt;/a&gt;&amp;gt;&lt;/tt&gt;&lt;br&gt;
{doctitle#}version {revnumber}{revdate?,}
{doctitle#}{revdate}
{doctitle#}&lt;br&gt;{revremark}
{doctitle#}&lt;/p&gt;

endif::doctype-manpage[]

#-------------------------
# manpage document type
#-------------------------
ifdef::doctype-manpage[]

[header]
&lt;nowiki&gt;
&lt;hr&gt;
&lt;h1&gt;
    {doctitle} Manual Page
&lt;/h1&gt;
&lt;hr&gt;

endif::doctype-manpage[]</pre>
</td>
</tr>
</table>
<p>To install the plugin save the listing to <tt>fossil.conf</tt> and put it in a directory named <tt>.asciidoc/backends/fossil</tt> in your home directory. Or you could create a plugin and install it using the <tt>asciidoc(1)</tt> <tt>--backend</tt> option <em>build</em> and <em>install</em> plugin commands.</p>
<p>Use the <em>fossil</em> backend as you would the built-in backends. For example, this command will insert a Wiki page called <em>AsciiDoc</em> into the current Fossil repository:</p>
<pre style="color:gray;padding:.5em;">asciidoc -b fossil -o - asciidoc.txt | fossil wiki commit AsciiDoc</pre>
<table style="margin:.2em 0;">
<tr valign="top">
<td style="padding:.5em;">
<p><b><u>Note</u></b></p>
</td>
<td style="border-left:3px solid #e8e8e8;padding:.5em;">You will need AsciiDoc version 8.6.6 or newer to use the Fossil backend.</td>
</tr>
</table>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/srackham.wordpress.com/605/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/srackham.wordpress.com/605/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/srackham.wordpress.com/605/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/srackham.wordpress.com/605/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/srackham.wordpress.com/605/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/srackham.wordpress.com/605/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/srackham.wordpress.com/605/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/srackham.wordpress.com/605/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/srackham.wordpress.com/605/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/srackham.wordpress.com/605/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/srackham.wordpress.com/605/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/srackham.wordpress.com/605/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/srackham.wordpress.com/605/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/srackham.wordpress.com/605/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=srackham.wordpress.com&amp;blog=3711161&amp;post=605&amp;subd=srackham&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://srackham.wordpress.com/2011/08/30/fossil-backend-for-asciidoc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e74a88a96ce8caecbc7d265e4763e26c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">srackham</media:title>
		</media:content>
	</item>
		<item>
		<title>Keeping a lid on Mobile data</title>
		<link>http://srackham.wordpress.com/2011/07/17/keeping-a-lid-on-mobile-data/</link>
		<comments>http://srackham.wordpress.com/2011/07/17/keeping-a-lid-on-mobile-data/#comments</comments>
		<pubDate>Sun, 17 Jul 2011 04:03:18 +0000</pubDate>
		<dc:creator>srackham</dc:creator>
				<category><![CDATA[Android]]></category>

		<guid isPermaLink="false">http://srackham.wordpress.com/?p=587</guid>
		<description><![CDATA[Published: 2011-07-17 How to configure your Android phone to automatically turn off the mobile data connection once your mobile data limit is reached. Why bother? In New Zealand we have what amounts to a telecommunications duopoly with mobile data charges that make your eyes water&#8201;&#8212;&#8201;Vodafone charges me $1 NZD (0.84 USD) for every megabyte over [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=srackham.wordpress.com&amp;blog=3711161&amp;post=587&amp;subd=srackham&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a name="preamble"></a>
<p><strong>Published</strong>: 2011-07-17</p>
<p>How to configure your Android phone to automatically turn off the mobile data connection once your mobile data limit is reached.</p>
<p><span id="more-587"></span><br />
<table bgcolor="#ffffee" width="100%" style="margin:.2em 0;">
<tr>
<td style="padding:.5em;">
<p style="margin-top:0;"><b>Why bother?</b></p>
<p>In New Zealand we have what amounts to a telecommunications duopoly with mobile data charges that make your eyes water&#8201;&#8212;&#8201;Vodafone charges me $1 NZD (0.84 USD) for every megabyte over my capped limit of 10MB per day (yes you read correctly 10 megabytes!) with no facility to limit overruns.</p>
</td>
</tr>
</table>
<p><b>Here&#8217;s how</b></p>
<ol type="1">
<li> Go to the Android Market and install the <a href="https://market.android.com/details?id=net.rgruet.android.g3watchdog&amp;hl=en">3G Watchdog</a> and <a href="https://market.android.com/details?id=com.google.code.apndroid&amp;hl=en">APNdroid</a> applications (both are great apps). </li>
<li> Configure <em>3G Watchdog</em> with your data limit and configure it to use <em>APNdroid</em> to turn off.
<div> <img src="http://srackham.files.wordpress.com/2011/07/3g-watchdog-config.png?w=450" style="border-width:0;" alt="3g-watchdog-config.png"> </div>
</li>
</ol>
<p><em>3G Watchdog</em> will now use <em>APNdroid</em> to automatically turn off your mobile data connection when the preset level is reached, What&#8217;s nice is that it will automatically reenable data atically at your next data period.</p>
<p>I also set the <em>3G Watchdog</em> update frequency to the shortest possible (30s) because in 30s you can consume a lot of data (relative to my measly limit).</p>
<p>Lastly, a word of warning: Android phones consume mobile data <a href="http://androidforums.com/lg-thrive/330483-why-google-using-my-data.html">even when you&#8217;re not using them</a>&#8201;&#8212;&#8201;this is why I manually turn off mobile data (using <em>APNdroid</em>) when I&#8217;m not using it (most of the time I&#8217;m on WiFi so I don&#8217;t need to have mobile data enabled).</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/srackham.wordpress.com/587/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/srackham.wordpress.com/587/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/srackham.wordpress.com/587/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/srackham.wordpress.com/587/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/srackham.wordpress.com/587/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/srackham.wordpress.com/587/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/srackham.wordpress.com/587/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/srackham.wordpress.com/587/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/srackham.wordpress.com/587/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/srackham.wordpress.com/587/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/srackham.wordpress.com/587/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/srackham.wordpress.com/587/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/srackham.wordpress.com/587/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/srackham.wordpress.com/587/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=srackham.wordpress.com&amp;blog=3711161&amp;post=587&amp;subd=srackham&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://srackham.wordpress.com/2011/07/17/keeping-a-lid-on-mobile-data/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e74a88a96ce8caecbc7d265e4763e26c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">srackham</media:title>
		</media:content>

		<media:content url="http://srackham.files.wordpress.com/2011/07/3g-watchdog-config.png" medium="image">
			<media:title type="html">3g-watchdog-config.png</media:title>
		</media:content>
	</item>
		<item>
		<title>Using an iPad to access remote Windows desktops</title>
		<link>http://srackham.wordpress.com/2011/07/16/using-an-ipad-to-access-remote-windows-desktops/</link>
		<comments>http://srackham.wordpress.com/2011/07/16/using-an-ipad-to-access-remote-windows-desktops/#comments</comments>
		<pubDate>Sat, 16 Jul 2011 05:32:45 +0000</pubDate>
		<dc:creator>srackham</dc:creator>
				<category><![CDATA[ipad]]></category>
		<category><![CDATA[rdp]]></category>
		<category><![CDATA[vnc]]></category>

		<guid isPermaLink="false">http://srackham.wordpress.com/?p=580</guid>
		<description><![CDATA[Published: 2011-07-16 Updated: 2011-07-26 (added Q&#38;A) I went from initial scepticism, when I started looking for a usable iPad remote desktop solution for accessing Windows PCs, to (almost) wild enthusiasm. I evaluated four of the best iPad remote access apps and am delighted to have found one that does exactly what I want. This post [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=srackham.wordpress.com&amp;blog=3711161&amp;post=580&amp;subd=srackham&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a name="preamble"></a>
<p><strong>Published</strong>: 2011-07-16<br /> <strong>Updated</strong>: 2011-07-26 (added Q&amp;A)</p>
<p>I went from initial scepticism, when I started looking for a usable iPad remote desktop solution for accessing Windows PCs, to (almost) wild enthusiasm.</p>
<p>I evaluated four of the best iPad remote access apps and am delighted to have found one that does exactly what I want. This post outlines why I settled on <em>Jump Desktop</em> along with a few usage tips.</p>
<p><span id="more-580"></span>
<p>The four apps I evaluated were:</p>
<ul>
<li> <a href="http://www.mochasoft.dk/iphone_rdp.htm">Remote Desktop Lite &#8211; RDP</a> version 2.7. </li>
<li> <a href="http://itap-mobile.com/itap-rdp/">iTAP RDP</a> version 1.7.3. </li>
<li> <a href="http://www.antecea.com/apps/desktop_conn/overview.html">Desktop Connect</a> version 4.2. </li>
<li> </li>
</ul>
<p>All four have very good RDP (Microsoft Remote Desktop Protocol) clients, the latter two also include VNC clients.  <em>Remote Desktop Lite &#8211; RDP</em> is a free app the others are non-free.</p>
<hr />
<h2><a name="X1"></a>The hard part: getting back into your office</h2>
<p>My principle use case is remote Internet access from a wireless iPad tethered to my mobile phone back into desktops running Microsoft Windows on my (Internet connected) office LAN.  The hard part is locating and securely connecting to desktop PCs from an external location on the Internet. This is because most desktop PCs are isolated from the Internet behind a NAT router/firewall with a dynamic IP address, so you can&#8217;t use DNS to locate the router or the PC. You have two choices:</p>
<ol type="1">
<li> You can manually reconfigure your router NAT and firewall rules; then configure your desktop PC&#8217;s firewall and remote access permissions; then setup dynamic DNS to your router (<a href="http://support.jumpdesktop.com/entries/194620-setup-manual-configuration">this web page</a> outlines the process). </li>
<li> Or you can install a desktop app which sets up and manages your connections automatically. </li>
</ol>
<p>Manual configuration is time consuming and fiddly. It can be downright dangerous if you&#8217;re not careful or don&#8217;t understand what you&#8217;re doing. Of the four apps I tried only <em>Desktop Connect</em> and <em>Jump Desktop</em> support the automatic configuration option (both use Google Talk to facilitate the connection)&#8201;&#8212;&#8201;this is why, for me, the choice was between these two remote access apps.</p>
<table bgcolor="#ffffee" width="100%" style="margin:.2em 0;">
<tr>
<td style="padding:.5em;">
<p style="margin-top:0;"><b>How does the auto-connect feature work?</b></p>
<p>A first it seems like magic&#8201;&#8212;&#8201;how can all this manual jiggery-pokery be obviated by your Google login? The answer is that the auto-connect program on your desktop logs into Google&#8217;s servers and registers your computers address, the remote access client on you iPad also logs into your Google account and retrieves the address of your desktop. Here is <a href="http://support.jumpdesktop.com/entries/223751-general-how-does-jump-desktop-use-my-google-account">some more information</a>.</p>
</td>
</tr>
</table>
<hr />
<h2><a name="_why_i_choose_jump_desktop_over_desktop_connect"></a>Why I choose Jump Desktop over Desktop Connect</h2>
<p>Both <em>Jump Desktop</em> over <em>Desktop Connect</em> have excellent RDP and VNC iPad clients, but <em>Jump Desktop</em> really shines when it comes to the auto-connect functionality.</p>
<ul>
<li> <em>Jump Desktop</em> auto-connect supports both RDP and VNC protocols, <em>Desktop Connect</em> only supports VNC. </li>
<li> The free <a href="http://support.jumpdesktop.com/entries/20097387-jump-desktop-viewer-for-pc">Jump Desktop Viewer</a> is a real gem, it gets installed with the PC <em>Jump Desktop</em> and allows you to use a PC in place of an iPad for the remote access client. </li>
<li> The <em>Jump Desktop</em> PC auto-connect installer is very polished&#8201;&#8212;&#8201;it handles VNC server and .NET dependency installation (if necessary). <em>Desktop Connects</em> PC auto-connect app (<em>Easy Connect</em>) was still in beta at the time of my evaluation. </li>
</ul>
<p>The only thing I would like to see added to <em>Jump Desktop</em> would be built-in help with some sort of first time use wizard or guide. The <em>Jump Desktop</em> website has a very good searchable <a href="http://support.jumpdesktop.com/forums">Knowledge Base</a> which you&#8217;ll probably need to use while learning the app. I had a more favorable initial experience with <em>Desktop Connect</em>, it has built-in help and a more discoverable and attractive user interface.</p>
<p>But at the end of the day my choice of <em>Jump Desktop</em> over <em>Desktop Connect</em> was clear cut and unequivocal.</p>
<p>I evaluated RDP connections to Windows 7 Pro and Windows XP Pro; VNC on Windows 7 Home.</p>
<hr />
<h2><a name="X2"></a>RDP or VNC?</h2>
<p>The target desktop PC must run a remote access server. All current versions of Windows (apart from Windows Home and Starter editions) come with an RDP server and I recommend using RDP over VNC for Windows access:</p>
<ol type="1">
<li> RDP can run the client at different resolution to the host PC, this means you can always view the remote desktop using the iPad&#8217;s native 1024&#215;768 resolution, there&#8217;s no pixel interpolation and the clarity is greater. </li>
<li> I found RDP performed faster and smoother than VNC alongside each other to a Windows 7 desktop (my iPad was connected to the Internet over a fairly slow tethered mobile 3G connection). </li>
<li> The RDP server comes preinstalled and supported by Microsoft. </li>
</ol>
<p>VNC is useful for non-Windows desktops (Linux, OS X) and for Windows Home edition (which does not include an RDP server).</p>
<hr />
<h2><a name="_jump_desktop_tips"></a>Jump Desktop tips</h2>
<p>Unless stated otherwise these comments relate to RDP connections.</p>
<ul>
<li> When using RDP the desktop PC user account that you want to log into must have a password (unless you are prepared to <a href="http://dandar3.blogspot.com/2008/04/windows-vista-allow-remote-desktop.html">change the password policy</a>). You can set the PC&#8217;s <em>autologon</em> to get <em>Jump</em> to automatically submit your logon parameters. </li>
<li> By default the desktop wallpaper is disabled over RDP (see next item) and the solid desktop color will be displayed. The default solid desktop color is black on Windows 7 but you can change it:
<ol type="1">
<li> Right-click on the desktop and select <em>Personalize</em>. </li>
<li> Click the <em>Desktop background</em> link then select <em>Solid colors</em> from the <em>Picture location</em> drop-down list and choose a color. </li>
<li> Click <em>Save Changes</em>. </li>
<li> Optionally restore your wallpaper for local access. </li>
</ol>
</li>
<li> You can enable the desktop wallpaper by editing the Jump <em>quality</em> settings (though this will slow performance and increase data traffic). </li>
<li> Take time out to learn the <em>Jump Desktop</em> <a href="http://support.jumpdesktop.com/entries/280968-ipad-input-methods">gestures and toolbar</a> and experiment with the user interface options to find the ones that suit you best (I disable the cursor and use pinch and zoom when I need pointer accuracy). </li>
<li> The <a href="http://support.jumpdesktop.com/forums">Jump Desktop Knowledge Base</a> is your friend. </li>
</ul>
<hr />
<h2><a name="_q_amp_a"></a>Q &amp; A</h2>
<dl>
<dt> <em>What if I don&#8217;t have an iPad?</em> </dt>
<dd> You don&#8217;t need an iPad for remote access, for example the free <a href="http://support.jumpdesktop.com/entries/20097387-jump-desktop-viewer-for-pc">Jump Desktop Viewer</a> allows you to use a Windows PC in place of an iPad for the remote access client&#8201;&#8212;&#8201;an option if you&#8217;re wanting to dip your toes in the water before deciding on buying an iPad. </dd>
<dt> <em>Don&#8217;t I need an iPad with the 3G option to use a mobile data connection?</em> </dt>
<dd> No, not if you have a mobile phone that supports WiFi tethering. WiFi tethering turns your phone into your own private wireless hotspot, in most new Android phones turning tethering on is a simple one-click option. </dd>
<dt> <em>How can I keep a lid on mobile data costs?</em> </dt>
<dd> Remote access typically uses less data than Web browsing but mobile data is expensive in New Zealand, so only use it when you have to and if, for example, you&#8217;re at home connect the iPad to the Internet over your home WiFi connection. <a href="http://srackham.wordpress.com/2011/07/17/keeping-a-lid-on-mobile-data/">I blogged about this recently</a>. </dd>
<dt> <em>Is it true that remote access won&#8217;t work on a PC running Windows Home edition?</em> </dt>
<dd> Microsoft does not bundle an RDP server with <em>Windows Home</em> editions so you need to install an alternative. Jump Desktop will optionally install a VNC server on Windows Home PCs, but a version of Windows with built-in RDP is preferable. </dd>
<dt> <em>What happens if my desktop PC is powered off?</em> </dt>
<dd> Your desktop PC has to be powered on to access it remotely so you do need to leave your PC on and don&#8217;t enable the <em>Hibernate</em> or <em>Sleep</em> power options.  Most PCs are capable of being turned on by a remote command over the Internet, but getting this configured and working is outside the scope of this post. </dd>
<dt> <em>So now I&#8217;ve got a tablet I don&#8217;t need a desktop PC, right?</em> </dt>
<dd> Not so fast, tablets are content consumers not content creators. The tablet on-screen keyboard and small screen is OK for casual input and browsing but is not suitable for ongoing data entry or document creation. </dd>
</dl>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/srackham.wordpress.com/580/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/srackham.wordpress.com/580/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/srackham.wordpress.com/580/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/srackham.wordpress.com/580/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/srackham.wordpress.com/580/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/srackham.wordpress.com/580/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/srackham.wordpress.com/580/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/srackham.wordpress.com/580/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/srackham.wordpress.com/580/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/srackham.wordpress.com/580/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/srackham.wordpress.com/580/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/srackham.wordpress.com/580/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/srackham.wordpress.com/580/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/srackham.wordpress.com/580/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=srackham.wordpress.com&amp;blog=3711161&amp;post=580&amp;subd=srackham&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://srackham.wordpress.com/2011/07/16/using-an-ipad-to-access-remote-windows-desktops/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e74a88a96ce8caecbc7d265e4763e26c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">srackham</media:title>
		</media:content>
	</item>
	</channel>
</rss>
