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

<channel>
	<title>Christophe Coenraets &#187; Backbone.js</title>
	<atom:link href="http://coenraets.org/blog/category/backbone-js/feed/" rel="self" type="application/rss+xml" />
	<link>http://coenraets.org/blog</link>
	<description>Web Platform, Cloud and Mobile Application Development</description>
	<lastBuildDate>Mon, 13 May 2013 16:05:20 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Sample App: Storing your Application Data in the Cloud with Parse.com and the JavaScript SDK</title>
		<link>http://coenraets.org/blog/2013/04/sample-app-storing-your-application-data-in-the-cloud-with-parse-com-and-the-javascript-sdk/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sample-app-storing-your-application-data-in-the-cloud-with-parse-com-and-the-javascript-sdk</link>
		<comments>http://coenraets.org/blog/2013/04/sample-app-storing-your-application-data-in-the-cloud-with-parse-com-and-the-javascript-sdk/#comments</comments>
		<pubDate>Fri, 19 Apr 2013 16:54:14 +0000</pubDate>
		<dc:creator>Christophe Coenraets</dc:creator>
				<category><![CDATA[Backbone.js]]></category>
		<category><![CDATA[Parse.com]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=5629</guid>
		<description><![CDATA[A couple of days ago, I shared a new version of the Employee Directory sample application. By default, the application uses an in-memory data store to provide a “download and run” experience (no need to set up a server or a database). In this post, I’ll show how to replace the in-memory data store with [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://coenraets.org/blog/wp-content/uploads/2013/04/employee-directory-parse.jpg"><img src="http://coenraets.org/blog/wp-content/uploads/2013/04/employee-directory-parse.jpg" alt="" title="employee-directory-parse" width="640" height="462" class="alignleft size-full wp-image-5659" /></a></p>
<p>A couple of days ago, I shared a new version of the <a href="http://coenraets.org/blog/2013/04/sample-application-with-backbone-js-and-twitter-bootstrap-updated-and-improved/">Employee Directory</a> sample application. By default, the application uses an in-memory data store to provide a “download and run” experience (no need to set up a server or a database). In this post, I’ll show how to replace the in-memory data store with a database hosted on Parse.com.</p>
<h4>Step 1: Sign Up for Parse.com</h4>
<p>Go to <a href="http://parse.com">http://parse.com</a> and sign up for Parse.</p>
<p><a href="http://coenraets.org/blog/wp-content/uploads/2013/04/parse1.gif"><img src="http://coenraets.org/blog/wp-content/uploads/2013/04/parse1.gif" alt="" title="parse1" width="640" height="340" class="alignleft size-full wp-image-5634" /></a></p>
<h4>Step 2: Create an Application</h4>
<p>On the next screen, create an application as follows:</p>
<p><a href="http://coenraets.org/blog/wp-content/uploads/2013/04/parse22.gif"><img src="http://coenraets.org/blog/wp-content/uploads/2013/04/parse22.gif" alt="" title="parse2" width="640" height="340" class="alignleft size-full wp-image-5640" /></a></p>
<h4>Step 3: Get your Application Keys</h4>
<p>In the dashboard, go to Settings and grab the Application ID and the JavaScript key.</p>
<p><a href="http://coenraets.org/blog/wp-content/uploads/2013/04/parse3.jpg"><img src="http://coenraets.org/blog/wp-content/uploads/2013/04/parse3.jpg" alt="" title="parse3" width="640" height="393" class="alignleft size-full wp-image-5642" /></a></p>
<h4>Step 4: Populate the Database</h4>
<p>There are two ways to populate the database:</p>
<ol>
<li>Import a .json, .csv, .xls, or .txt file from the Data Browser interface. This approach works well for simple data structures.</li>
<li>Programmatically, using the the Parse SDK.</li>
</ol>
<p>For the employee directory application I wrote the quick script below to populate the database:</p>
<p><script src="https://gist.github.com/ccoenraets/5421386.js"></script></p>
<h4>Step 5: Run the Employee Directory App using the Parse.com Cloud Data</h4>
<ol>
<li>Download the source code for the Employee Directory client application available in <a href="https://github.com/ccoenraets/directory-backbone-bootstrap">this</a> repository.</li>
<li>Extract the application files to a directory you can reach using a local or hosted web server.<br />
<div class="woo-sc-box note   ">
Because the templates of this application are loaded using XMLHTTPRequest, you will get a cross domain error (Access-Control-Allow-Origin) if you load index.html from the file system (with the file:// protocol). Make sure you load the application from a web server. For example: http://localhost/directory-backbone-bootstrap.<br />
</div>
</li>
<li>Open index.html in your code editor.</li>
<li>Comment out the &#8220;model-in-memory.js&#8221; script, and uncomment the &#8220;parse-1.2.2.min.js&#8221; and &#8220;model-parse-com.js&#8221; scripts.</li>
<li>Open index.html in a Browser and test the application.</li>
</ol>
<h4>Step 6: Secure the Database</h4>
<p>Parse.com offers different security options. A complete discussion of these options is beyond the scope of this article. Since Employee Directory is a read-only and public application, we will simply:</p>
<p>1. Prevent client class creation (In Settings > General Settings):<br />
<a href="http://coenraets.org/blog/wp-content/uploads/2013/04/parse-security1b.gif"><img src="http://coenraets.org/blog/wp-content/uploads/2013/04/parse-security1b.gif" alt="" title="parse-security1b" width="636" height="186" class="alignleft size-full wp-image-5672" /></a></p>
<p>2. Disable create, update, delete operations (In Data Browser > More > Set Permissions):</p>
<p><a href="http://coenraets.org/blog/wp-content/uploads/2013/04/parse-security2.jpg"><img src="http://coenraets.org/blog/wp-content/uploads/2013/04/parse-security2.jpg" alt="" title="parse-security2" width="640" height="458" class="alignleft size-full wp-image-5666" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2013/04/sample-app-storing-your-application-data-in-the-cloud-with-parse-com-and-the-javascript-sdk/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Implementing RESTFul Services with Node.js and MongoDB</title>
		<link>http://coenraets.org/blog/2013/04/implementing-restful-services-with-node-js-and-mongodb/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=implementing-restful-services-with-node-js-and-mongodb</link>
		<comments>http://coenraets.org/blog/2013/04/implementing-restful-services-with-node-js-and-mongodb/#comments</comments>
		<pubDate>Thu, 18 Apr 2013 17:04:19 +0000</pubDate>
		<dc:creator>Christophe Coenraets</dc:creator>
				<category><![CDATA[Backbone.js]]></category>
		<category><![CDATA[Express]]></category>
		<category><![CDATA[MongoDB]]></category>
		<category><![CDATA[Node.js]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=5516</guid>
		<description><![CDATA[In my previous post, I shared a new version of the Employee Directory sample application. By default, the application uses an in-memory data store to provide a &#8220;download and run&#8221; experience (no need to set up a server or a database). In this post, I&#8217;ll show how to replace the in-memory data store with RESTful [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://coenraets.org/blog/wp-content/uploads/2013/04/nodejs-mongodb.png"><img src="http://coenraets.org/blog/wp-content/uploads/2013/04/nodejs-mongodb.png" alt="" title="nodejs-mongodb" width="640" height="120" class="alignleft size-full wp-image-5614" /></a><br />
In my <a href="http://coenraets.org/blog/2013/04/sample-application-with-backbone-js-and-twitter-bootstrap-updated-and-improved/">previous post</a>, I shared a new version of the Employee Directory sample application. By default, the application uses an in-memory data store to provide a &#8220;download and run&#8221; experience (no need to set up a server or a database). In this post, I&#8217;ll show how to replace the in-memory data store with RESTful services powered by Node.js, MongoDB and the Express framework. </p>
<div class="woo-sc-box info   ">
If you are not using the Employee Directory sample application, you can still use this post on its own to learn how to implement RESTful services with Node.js, MongoDB and the Express framework.<br />
</div>
<h4>Step 1: Install Node.js</h4>
<p>If it&#8217;s not already installed on your system, follow the steps below to install Node.js:</p>
<ol>
<li>Go to <a href="http://nodejs.org">http://nodejs.org</a>, and click the <em>Install</em> button.</li>
<li>Run the installer that you just downloaded. When the installer completes, a message indicates that <em>Node was installed at /usr/local/bin/node</em> and <em>npm was installed at /usr/local/bin/npm</em>. At this point node.js is ready to use.</li>
</ol>
<h4>Step 2: Install MongoDB</h4>
<p>If MongoDB is not already installed on your system, refer to the <a href="http://www.mongodb.org/display/DOCS/Quickstart">MongoDB QuickStart</a> for platform-specific installation instructions. Here are some quick steps to install MongoDB on a Mac:</p>
<ol>
<li>Go to <a href="http://www.mongodb.org/downloads">http://www.mongodb.org/downloads</a> and download the latest OS X 64-bit production release (2.4.2 at the time of this writing).</li>
<li>In Finder, double-click mongodb-osx-x86_64-2.4.2.tgz to extract its contents. (Alternatively you can use: tar -zxvf mongodb-osx-x86_64-2.4.2.tgz)</li>
<li>Move the mongodb-osx-x86_64-2.4.2 folder to /usr/local (or another folder according to your personal preferences):
<pre class="brush: bash; light: true; title: ; notranslate">
sudo mv -n mongodb-osx-x86_64-2.4.2/ /usr/local/
</pre>
</li>
<li>(Optional) Create a symbolic link to make it easier to access:
<pre class="brush: bash; light: true; title: ; notranslate">
sudo ln -s /usr/local/mongodb-osx-x86_64-2.4.2 /usr/local/mongodb
</pre>
</li>
<li>Create a folder for MongoDB&#8217;s data and set the appropriate permissions:
<pre class="brush: bash; light: true; title: ; notranslate">
sudo mkdir -p /data/db
sudo chown `id -u` /data/db
</pre>
</li>
<li>Start mongodb
<pre class="brush: bash; light: true; title: ; notranslate">
cd /usr/local/mongodb
./bin/mongod
</pre>
</li>
</ol>
<h4>Step 3: Download the Code</h4>
<p>The Node.js code for the Employee Directory RESTful services is available in <a href="https://github.com/ccoenraets/directory-rest-nodejs">this<a/> GitHub repository. Download it <a href="https://github.com/ccoenraets/directory-rest-nodejs/archive/master.zip">here</a> and unzip the file anywhere on your file system.</p>
<p>Open server.js and routes/employee.js in a code editor. The RESTFul API is defined as follows:</p>
<table style="margin-bottom:24px;">
<tr>
<th>Method</th>
<th>URL</th>
<th>Action</th>
</tr>
<tr>
<td>GET</td>
<td>/employees</td>
<td>Retrieve all employees</td>
</tr>
<tr>
<td>GET</td>
<td>/employees?name=j</td>
<td>Retrieve employees whose name includes the letter &#8220;j&#8221;</td>
</tr>
<tr>
<td>GET</td>
<td>/employees/3</td>
<td>Retrieve employee with id=3</td>
</tr>
<tr>
<td>GET</td>
<td>/employees/3/reports</td>
<td>Retrieve employees that are direct reports of employee number 3</td>
</tr>
</table>
<div class="woo-sc-box info   ">
In routes/employee.js, the use of res.jsonp() makes the services work for both JSON and JSONP requests. If the request includes a query parameter named “callback”, a JSONP response is returned, otherwise, a regular JSON response is returned.<br />
</div>
<h4>Step 4: Install dependencies (Express Framework and MongoDB driver)</h4>
<p>Open package.json in a code editor and note that the application has two dependencies: the Express framework and the MongoDB driver. To install these dependencies, open a command line (terminal window), cd to the directory where you extracted the source code, and type:</p>
<pre class="brush: bash; light: true; title: ; notranslate">
npm install
</pre>
<h4>Step 5: Start the server</h4>
<p>Make sure MongoDB is started (Step 2 point 6 above) before you start your Node.js server as follows:</p>
<pre class="brush: bash; light: true; title: ; notranslate">
node server.js
</pre>
<h4>Step 6: Testing the API in your Browser</h4>
<ul>
<li>Retrieve all employees
<p><a href="http://localhost:3000/employees">http://localhost:3000/employees</a></p>
</li>
<li>Retrieve all employees whose name includes the letter &#8220;j&#8221;
<p><a href="http://localhost:3000/employees?name=j">http://localhost:3000/employees?name=j</a></p>
</li>
<li>Retrieve employee with id == 1
<p><a href="http://localhost:3000/employees/1">http://localhost:3000/employees/1</a></p>
</li>
<li>Retrieve employees that are direct reports of employee number 1
<p><a href="http://localhost:3000/employees/1/reports">http://localhost:3000/employees/1/reports</a></p>
</li>
</ul>
<h4>Step 7: Test the API with the Employee Directory Client Application</h4>
<ol>
<li>Download the source code for the Employee Directory client application available in <a href="https://github.com/ccoenraets/directory-backbone-bootstrap">this</a> repository.</li>
<li>Unzip the file anywhere on your file system.</li>
<li>Open index.html in your code editor.</li>
<li>Comment out the &#8220;model-in-memory.js&#8221; script, and uncomment the &#8220;model-jsonp.js&#8221; script to use the JSONP adapter that connects to your Node.js server.</li>
<li>Make sure the MongoDB and Node.js servers are started</li>
<li>Open index.html in a Browser and test the application</li>
</ol>
<div class="woo-sc-box note   ">
Because the templates of this application are loaded using XMLHTTPRequest, you will get a cross domain error (Access-Control-Allow-Origin) if you load index.html from the file system (with the file:// protocol). Make sure you load the application from a web server. For example: http://localhost/directory-backbone-bootstrap.<br />
</div>
<h4>Related Post</h4>
<p>Check out <a href="http://coenraets.org/blog/2012/10/creating-a-rest-api-using-node-js-express-and-mongodb/">this post</a> for another Node.js example with a more complete RESTful API including the ability to add, modify and delete items (POST, PUT, and DELETE HTTP methods). </p>
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2013/04/implementing-restful-services-with-node-js-and-mongodb/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Sample Application with Backbone.js and Twitter Bootstrap: Updated and Improved</title>
		<link>http://coenraets.org/blog/2013/04/sample-application-with-backbone-js-and-twitter-bootstrap-updated-and-improved/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sample-application-with-backbone-js-and-twitter-bootstrap-updated-and-improved</link>
		<comments>http://coenraets.org/blog/2013/04/sample-application-with-backbone-js-and-twitter-bootstrap-updated-and-improved/#comments</comments>
		<pubDate>Wed, 17 Apr 2013 15:27:49 +0000</pubDate>
		<dc:creator>Christophe Coenraets</dc:creator>
				<category><![CDATA[Backbone.js]]></category>
		<category><![CDATA[Twitter Bootstrap]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=5183</guid>
		<description><![CDATA[A year ago, I blogged Employee Directory, a sample application that demonstrates how to build modern web apps with Backbone.js and Twitter Bootstrap. With 1200+ stars and 300+ forks on GitHub, it has been my most popular sample application to date. Because of the continued interest in the application as a starting point and a [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://coenraets.org/directory/"><img src="http://coenraets.org/blog/wp-content/uploads/2013/04/directory-screenshot3.gif" alt="" title="directory-screenshot3" width="640" height="554" class="alignleft size-full wp-image-5422" /></a></p>
<p>A year ago, I blogged <a href="http://coenraets.org/blog/2012/02/sample-app-with-backbone-js-and-twitter-bootstrap/">Employee Directory</a>, a sample application that demonstrates how to build modern web apps with <a href="http://backbonejs.org/">Backbone.js</a> and <a href="http://twitter.github.io/bootstrap/">Twitter Bootstrap</a>. With 1200+ stars and 300+ forks on GitHub, it has been my most popular sample application to date. </p>
<p>Because of the continued interest in the application as a starting point and a reference for Backbone.js and Twitter Bootstrap, I decided to give it a well deserved update.</p>
<p>New in this version:</p>
<ul>
<li>Latest version of Backbone.js (1.0)</li>
<li>Latest version of Twitter Bootstrap (2.3.1)</li>
<li>Layout is now responsive</li>
<li>Data persistence layer is now abstracted (see below)</li>
<li>Additional data persistence options: In-memory datastore, Node.js/MongoDB, Parse.com (In addition to PHP and Java)</li>
<li>New GitHub repository organization (see below)</li>
<li>Bug fixes and cleaner code</li>
</ul>
<h3>Running the Application</h3>
<p>You can test the hosted version of the application <a href="http://coenraets.org/directory/">here</a>, or you can download the code (see GitHub repository information below) and test the application locally.</p>
<h3>Data Persistence Abstraction</h3>
<p>Among the great feedback I received, a number of you mentioned you wanted a self-contained version of the app with no dependency on a specific back end to be able to &#8220;download and run&#8221; without having to set up a server and a database. So I rearchitected the persistence layer with simple and pluggable data adapters. By default the application now uses an in-memory data store, but other adapters are available. To change the data persistence strategy, just comment out model-in-memory.js in index.html and uncomment one of the other data adapters using the table below as a reference.</p>
<p>I initially published the application with two implementations of a RESTful back end: A Java version using Jersey, and a PHP version using Slim.  A year later, I&#8217;m adding the long overdue Node.js/MongoDB back end.</p>
<table>
<tr style="font-weight:bold;">
<td>Adapter</td>
<td>Description</td>
<td>Back end Repo</td>
</tr>
<tr>
<td style="width:140px">model-in-memory.js</td>
<td>In-memory data store</td>
<td style="width:170px">No server required</td>
</tr>
<tr>
<td>model-rest-json.js</td>
<td>Backbone.js default behavior. The application gets data through RESTFul services.</td>
<td><a href="https://github.com/ccoenraets/directory-rest-nodejs">directory-server-nodejs</a><br/><br />
<a href="https://github.com/ccoenraets/directory-rest-php">directory-server-php</a><br/><br />
directory-server-java
</td>
</tr>
<tr>
<td>model-rest-jsonp.js</td>
<td>If the server serving your pages and the server serving your data are on different domains, use this adapter instead to avoid the same origin policy error.</td>
<td><a href="https://github.com/ccoenraets/directory-rest-nodejs">directory-server-nodejs</a><br/><br />
<a href="https://github.com/ccoenraets/directory-rest-php">directory-server-php</a><br/><br />
directory-server-java
</td>
</tr>
<tr>
<td>model-websql.js</td>
<td>Uses local database using the WebSQL api.</td>
<td>No server required</td>
</tr>
<tr>
<td>model-parse-dot-com.js</td>
<td>Don&#8217;t want to host your own data infrastructure? Parse.com is a cloud service that will host your data for you. Use this adapter to test your app with  sample data I deployed on Parse.com.</td>
<td>No server required</td>
</tr>
</table>
<p>The Node.js, Java, and PHP RESTful back ends work with both JSON and JSONP. If the request includes a query parameter named &#8220;callback&#8221;, a JSONP response is returned, otherwise, a regular JSON response is returned.</p>
<h3>New GitHub Repositories</h3>
<p>The original repository (<a href="https://github.com/ccoenraets/backbone-directory">backbone-directory</a>) grew somewhat chaotically as I kept adding different versions and different data persistence options. So I decided to start fresh with new repositories.</p>
<p>The client code for the application is available in the new <a href="https://github.com/ccoenraets/directory-backbone-bootstrap">directory-backbone-bootstrap</a> repository. In the future, this new repository naming scheme will allow me to add different versions of the app (for example, directory-backbone-foundation or directory-angular-bootstrap)  while keeping each repository clean and focused. </p>
<div class="woo-sc-box note   ">
Because the templates of this application are loaded using XMLHTTPRequest, you will get a cross domain error (Access-Control-Allow-Origin) if you load index.html from the file system (with the file:// protocol). Make sure you load the application from a web server. For example: http://localhost/directory-backbone-bootstrap.<br />
</div>
<p>If you want to go beyond the in-memory datastore, you can download the REST services in the following repositories:</p>
<p><a href="https://github.com/ccoenraets/directory-rest-nodejs">directory-rest-nodejs</a> (Node.js/MongoDB implementation)<br />
<a href="https://github.com/ccoenraets/directory-rest-php">directory-rest-php</a> (PHP implementation)<br />
directory-rest-java (Java implementation coming soon)</p>
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2013/04/sample-application-with-backbone-js-and-twitter-bootstrap-updated-and-improved/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Sociogram: A Sample Application Exploring the Facebook SDK and the Graph API</title>
		<link>http://coenraets.org/blog/2013/02/sociogram-a-sample-application-exploring-the-facebook-sdk-and-the-graph-api/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sociogram-a-sample-application-exploring-the-facebook-sdk-and-the-graph-api</link>
		<comments>http://coenraets.org/blog/2013/02/sociogram-a-sample-application-exploring-the-facebook-sdk-and-the-graph-api/#comments</comments>
		<pubDate>Thu, 07 Feb 2013 16:08:45 +0000</pubDate>
		<dc:creator>Christophe Coenraets</dc:creator>
				<category><![CDATA[Backbone.js]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=4917</guid>
		<description><![CDATA[I&#8217;ve recently been working on a few applications that integrate with Facebook. As a reference for myself and other developers building similar applications, I thought it would be useful to put together a sample application that demonstrates some commonly used integration scenarios and workflows when using the Facebook JavaScript SDK and the Graph API. So, [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://coenraets.org/blog/wp-content/uploads/2013/02/sociogram2.jpg"><img style="padding:0;margin:0;border: solid 1px #ddd" src="http://coenraets.org/blog/wp-content/uploads/2013/02/sociogram2.jpg" alt="" title="sociogram2" width="640" height="444" class="aligncenter size-full wp-image-4934" /></a></p>
<p>I&#8217;ve recently been working on a few applications that integrate with Facebook. As a reference for myself and other developers building similar applications, I thought it would be useful to put together a sample application that demonstrates some commonly used integration scenarios and workflows when using the <a href="http://developers.facebook.com/docs/reference/javascript/">Facebook JavaScript SDK</a> and the <a href="http://developers.facebook.com/docs/reference/api/">Graph API</a>. So, Sociogram is a sample application that demonstrates how to:<br />
<span id="more-4917"></span></p>
<ul>
<li>Load the Facebook SDK</li>
<li>Login with Facebook</li>
<li>Request specific permissions</li>
<li>Revoke permissions</li>
<li>Get data (list of friends, mutual friends, feed items, etc.)</li>
<li>Post to the wall using your application&#8217;s custom UI or the Facebook dialogs</li>
<li>Listen to Facebook events such as status change, etc</li>
</ul>
<p>The Graph API provides access to a lot more data and actions, but you are essentially always using the same API with a different path into the graph.</p>
<p>There are <a href="http://developers.facebook.com/docs/samples/">other examples</a> out there, each of them built around different use cases. This application is built with <a href="http://backbonejs.org/">Backbone.js</a> using a single page architecture, but the code can easily be reused in a different context.</p>
<h3>Running the Application</h3>
<p>Click <a href="http://coenraets.org/sociogram">here</a> to run the application in your browser.</p>
<h3>Source Code</h3>
<p>The source code is available in <a href="https://github.com/ccoenraets/sociogram">this GitHub repository</a>.</p>
<h3>Mobile App Version</h3>
<p>In my next post, I will share a PhoneGap version of the same application (using the PhoneGap Facebook plugin).</p>
<h3>Disclaimer</h3>
<p>This is a sample application, not a production application. Some trade-offs were made to keep the code generic, simple and readable.</p>
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2013/02/sociogram-a-sample-application-exploring-the-facebook-sdk-and-the-graph-api/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>NodeCellar: Sample Application with Backbone.js, Twitter Bootstrap, Node.js, Express, and MongoDB</title>
		<link>http://coenraets.org/blog/2012/10/nodecellar-sample-application-with-backbone-js-twitter-bootstrap-node-js-express-and-mongodb/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=nodecellar-sample-application-with-backbone-js-twitter-bootstrap-node-js-express-and-mongodb</link>
		<comments>http://coenraets.org/blog/2012/10/nodecellar-sample-application-with-backbone-js-twitter-bootstrap-node-js-express-and-mongodb/#comments</comments>
		<pubDate>Thu, 04 Oct 2012 15:39:03 +0000</pubDate>
		<dc:creator>Christophe Coenraets</dc:creator>
				<category><![CDATA[Backbone.js]]></category>
		<category><![CDATA[Express]]></category>
		<category><![CDATA[HTML 5]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[MongoDB]]></category>
		<category><![CDATA[Node.js]]></category>
		<category><![CDATA[Twitter Bootstrap]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=4183</guid>
		<description><![CDATA[In my previous post, I shared my recent experience building a RESTful API with Node.js, MongoDB, and Express. In this post, I&#8217;m sharing the client application that uses that RESTful API. The Node Cellar application allows you to manage (retrieve, create, update, delete) the wines in a wine cellar database. The client application is built [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://nodecellar.coenraets.org"><img src="http://coenraets.org/blog/wp-content/uploads/2012/10/nodecellar.gif" alt="" title="nodecellar" width="640" height="463" class="aligncenter size-full wp-image-4197" /></a></p>
<p>In my <a href="http://coenraets.org/blog/2012/10/creating-a-rest-api-using-node-js-express-and-mongodb/">previous post</a>, I shared my recent experience building a RESTful API with <a href="http://nodejs.org">Node.js</a>, <a href="http://www.mongodb.org/">MongoDB</a>, and <a href="http://expressjs.com/">Express</a>.</p>
<p>In this post, I&#8217;m sharing the client application that uses that RESTful API. The Node Cellar application allows you to manage (retrieve, create, update, delete) the wines in a wine cellar database.<br />
<span id="more-4183"></span><br />
The client application is built with <a href="http://backbonejs.org/">Backbone.js</a> and <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap</a>.</p>
<h4>Run the Application</h4>
<p>You can run the application <a href="http://nodecellar.coenraets.org">here</a>. For obvious reasons, the create, update, delete features have been disabled in this hosted version. </p>
<p>NOTE: <span style="text-decoration: line-through;">Node.js is running on port 3000 on my EC2 Instance.</span> My friend <a href="http://www.jamesward.com/">James Ward</a> convinced me to host the application on their service over at Heroku. It&#8217;s now running on port 80 at <a href="http://nodecellar.coenraets.org">http://nodecellar.coenraets.org</a>. Thanks James!</p>
<p><a href="http://nodecellar.coenraets.org"><img src="http://coenraets.org/blog/wp-content/uploads/2012/10/nodecellar2.gif" alt="" title="nodecellar2" width="640" height="463" class="aligncenter size-full wp-image-4203" /></a></p>
<h4>Server-Side</h4>
<p>The details of the Node.js, MongoDB, and Express implementation are documented in my <a href="http://coenraets.org/blog/2012/10/creating-a-rest-api-using-node-js-express-and-mongodb/">previous post</a>.</p>
<h4>Client-Side</h4>
<p>In this application, Node.js is used to provide the RESTful services that the client application needs to manipulate the data. Node.js is not used to generate HTML/Views at the server-side. Instead, the Views are created dynamically at the client-side using Backbone.js and Underscore.js templates. They are injected into- and removed from the DOM as needed as you navigate through the application. Node Cellar is a &#8220;single page application&#8221;.</p>
<p>This is a Node.js and MongoDB powered version of an application I initially posted <a href="http://coenraets.org/blog/2012/05/single-page-crud-application-with-backbone-js-and-twitter-bootstrap/">here</a> with PHP and Java backends. The original post provides some additional Backbone.js context. This Node.js version also provides an improved user experience with the latest version of Twitter Bootstrap (2.1.1), and a <a href="http://twitter.github.com/bootstrap/scaffolding.html#responsive">responsive</a> layout. It also uses <a href="http://html.adobe.com/edge/webfonts/">Adobe Edge Web Fonts</a>.</p>
<h4>Source Code</h4>
<p>The source code is available in <a href="https://github.com/ccoenraets/nodecellar">this repository</a> on GitHub.</p>
<p><a href="http://nodecellar.coenraets.org"><img src="http://coenraets.org/blog/wp-content/uploads/2012/10/nodecellar3.gif" alt="" title="nodecellar3" width="640" height="463" class="aligncenter size-full wp-image-4204" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2012/10/nodecellar-sample-application-with-backbone-js-twitter-bootstrap-node-js-express-and-mongodb/feed/</wfw:commentRss>
		<slash:comments>71</slash:comments>
		</item>
		<item>
		<title>Employee Directory is now available on the App Store</title>
		<link>http://coenraets.org/blog/2012/06/employee-directory-is-now-available-on-the-app-store/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=employee-directory-is-now-available-on-the-app-store</link>
		<comments>http://coenraets.org/blog/2012/06/employee-directory-is-now-available-on-the-app-store/#comments</comments>
		<pubDate>Tue, 26 Jun 2012 15:37:06 +0000</pubDate>
		<dc:creator>Christophe Coenraets</dc:creator>
				<category><![CDATA[Backbone.js]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[PhoneGap]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=3788</guid>
		<description><![CDATA[My employee directory app is now available on the App Store. The application allows you to synchronize with your own data, look for employees by name, view their details, add them to your contacts, and see their manager and direct reports, as well as call, text, or email them. You can watch a short video [...]]]></description>
				<content:encoded><![CDATA[<p>My employee directory app is now <a href="http://itunes.apple.com/gb/app/employee-directory/id536343553?mt=8">available on the App Store</a>. The application allows you to synchronize with your own data, look for employees by name, view their details, add them to your contacts, and see their manager and direct reports, as well as call, text, or email them.</p>
<p><a href="http://itunes.apple.com/gb/app/employee-directory/id536343553?mt=8"><img src="http://employeedirectory.org/app/appstore.png" width="150"/></a></p>
<p>You can watch a short video below. In particular, at the end of the video, you will see how to reset the local database (to get rid of the sample dataset), and synchronize with your own data. Go full screen for a better viewing experience.</p>
<p><iframe width="640" height="360" src="http://www.youtube.com/embed/lG2rJtGQ32E?rel=0" frameborder="0" allowfullscreen></iframe></p>
<p>The application was built with <a href="http://backbonejs.org/">Backbone.js</a> and <a href="http://phonegap.com/">PhoneGap</a>.<br />
<span id="more-3788"></span></p>
<h3>Synchronizing with your own data</h3>
<p>Employee Directory always accesses the employee data from a local database on your iPhone. The information is always available, even when you are offline. The application comes with a sample dataset to provide an “out-of-the-box” experience, and with a simple offline synchronization mechanism to sync with your own data.</p>
<p>I created  a companion microsite for the application (<a href="http://employeedirectory.org/app">http://employeedirectory.org/app</a>) that provides the steps to synchronize with your own data.</p>
<p>The offline synchronization strategy used in the application is documented in a previous post: <a href="http://coenraets.org/blog/2012/05/simple-offline-data-synchronization-for-mobile-web-and-phonegap-applications/">Simple Offline Data Synchronization for Mobile Web and PhoneGap Applications</a>.</p>
<h3>User Interface</h3>
<p>The styling and skinning of the application is documented in another post: <a href="http://coenraets.org/blog/2012/03/crafting-native-looking-ios-apps-with-html-backbone-js-and-phonegap/">Crafting Native Looking iOS Apps with HTML, Backbone.js, and PhoneGap</a>.</p>
<h3>Source Code</h3>
<p>I&#8217;m also making the source code for this application available in <a href="https://github.com/ccoenraets/employee-directory-app">this repository</a> on GitHub.</p>
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2012/06/employee-directory-is-now-available-on-the-app-store/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Simple Offline Data Synchronization for Mobile Web and PhoneGap Applications</title>
		<link>http://coenraets.org/blog/2012/05/simple-offline-data-synchronization-for-mobile-web-and-phonegap-applications/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=simple-offline-data-synchronization-for-mobile-web-and-phonegap-applications</link>
		<comments>http://coenraets.org/blog/2012/05/simple-offline-data-synchronization-for-mobile-web-and-phonegap-applications/#comments</comments>
		<pubDate>Wed, 16 May 2012 19:36:45 +0000</pubDate>
		<dc:creator>Christophe Coenraets</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Backbone.js]]></category>
		<category><![CDATA[HTML 5]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[PhoneGap]]></category>
		<category><![CDATA[Twitter Bootstrap]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=3652</guid>
		<description><![CDATA[Being able to work offline is an expected feature of mobile applications. For data-driven applications, it means that you &#8212; the developer &#8212; will have to store (a subset of) your application data locally, and implement a data synchronization mechanism that keeps your local and server data in sync. In this article, I describe a [...]]]></description>
				<content:encoded><![CDATA[<p>Being able to work offline is an expected feature of mobile applications. For data-driven applications, it means that you &#8212; the developer &#8212; will have to store (a subset of) your application data locally, and implement a data synchronization mechanism that keeps your local and server data in sync.</p>
<p>In this article, I describe a simple data synchronization strategy that uses the device&#8217;s (or browser&#8217;s) SQLite database. The implementation currently leverages the Web SQL API (even though the W3C is no longer actively maintaining the spec) because both iOS and Android support it, but they don&#8217;t support IndexedDB, the official alternative. However, the API described below &#8212; getLastSync(), getChanges(), applyChanges() &#8212; defines a generic synchronization contract, and the solution can be expanded and made &#8220;pluggable&#8221;: You could create different synchronization objects, each providing a different implementation of these methods. You could then choose which object to plug in based on the context and the platform your application is running on.</p>
<h3>Try it in the Playground</h3>
<p><a href="http://coenraets.org/offline-sync/client-app"><img src="http://coenraets.org/blog/wp-content/uploads/2012/05/Screen-Shot-2012-05-16-at-21.jpg" alt="" title="Screen Shot 2012-05-16 at 2" width="640" height="760" class="aligncenter size-full wp-image-3734" /></a><br />
<span id="more-3652"></span><br />
Before looking at the code, you can try some offline syncing in this a hosted playground:</p>
<ol>
<li>Open the <a href="http://coenraets.org/offline-sync/client-app">Offline Client Playground</a> in Chrome or Safari (they both support Web SQL).</li>
<li>Click the Synchronize button.</li>
<li>Look at the log (the textarea in the middle of the screen): Because it&#8217;s the first time you use the application, all the employees have been downloaded from the server and inserted in your local SQLite database.</li>
<li>Clear the log, click the Synchronize button, and look at the log again: because you now have an up-to-date local version of the data, the server didn&#8217;t return any change and your local database remains unchanged.</li>
<li>In another tab, open the <a href="http://coenraets.org/offline-sync/server-app">Server Admin PlayGround</a>.</li>
<li>Modify an existing employee and click Save. (Don&#8217;t worry, it&#8217;s using your own session-based data set).</li>
<li>Go back to the Offline Client tab, click Synchronize, and notice that the server returned one change,  and that it was applied to your local database.</li>
<li>Go back to the Server Admin tab and modify (create, update, delete) other employees. Switch back to the Offline Client tab, click Synchronize, and see how these changes are applied to your local database.</li>
<li>You can also use the Resources Tab in the Chrome Developer Tools to inspect your local database.</li>
</ol>
<h3>Server API</h3>
<p>The only piece of infrastructure you need at the server side is an API that returns the items that have changed (created, updated, or deleted) since a specific moment in time expressed as a timestamp. </p>
<p>Here is the RESTful API call used in my application:</p>
<p><a href="http://coenraets.org/offline-sync/api/employees?modifiedSince=2012-03-01 10:20:56">http://coenraets.org/offline-sync/api/employees?modifiedSince=2012-03-01 10:20:56</a></p>
<p>The format of the data returned by the server is up to you and is part of the contract between the client and the server. In this application, the server returns the changes as an array of JSON objects. The server-side technology (RoR, PHP, Java, .NET, &#8230;) and database system (SQL, NoSQL, &#8230;) you use to generate the list of changes is also totally up to you. I provide a simple PHP implementation as part of the source code. That implementation manages a session-based data set that provides an isolated and transient playground. In a real-life application, you&#8217;d obviously get the data from some sort of database.</p>
<h3>Client API</h3>
<p>At the client side, our synchronization API consists of three methods.</p>
<h4>getLastSync()</h4>
<p>A method that returns a timestamp to be used as the query parameter for the next synchronization request. A common practice is to persist a timestamp after each synchronization request. But things can go wrong and the timestamp itself can get out-of-sync. I prefer to &#8220;recalculate&#8221; the lastSync timestamp before each synchronization request.   </p>
<pre class="brush: jscript; title: ; notranslate">
getLastSync: function(callback) {
    this.db.transaction(
        function(tx) {
            var sql = &quot;SELECT MAX(lastModified) as lastSync FROM employee&quot;;
            tx.executeSql(sql, this.txErrorHandler,
                function(tx, results) {
                    var lastSync = results.rows.item(0).lastSync;
                    callback(lastSync);
                }
            );
        }
    );
}
</pre>
<h4>getChanges()</h4>
<p>This is a wrapper around an Ajax call to the server-side API that returns the items that have changed (created, updated, or deleted) since a specific moment in time defined in the modifiedSince parameter. </p>
<pre class="brush: jscript; title: ; notranslate">
getChanges: function(syncURL, modifiedSince, callback) {

    $.ajax({
        url: syncURL,
        data: {modifiedSince: modifiedSince},
        dataType:&quot;json&quot;,
        success:function (changes) {
            callback(changes);
        },
        error: function(model, response) {
            alert(response.responseText);
        }
    });

}
</pre>
<h4>applyChanges()</h4>
<p>A method that persists the changes in your local data store. Notice that SQLite supports a convenient &#8220;INSERT OR REPLACE&#8221; statement so that you don&#8217;t have to determine if you are dealing with a new or existing employee before persisting it.</p>
<pre class="brush: jscript; title: ; notranslate">
applyChanges: function(employees, callback) {
    this.db.transaction(
        function(tx) {
            var l = employees.length;
            var sql =
                &quot;INSERT OR REPLACE INTO employee (id, firstName, lastName, title, officePhone, deleted, lastModified) &quot; +
                &quot;VALUES (?, ?, ?, ?, ?, ?, ?)&quot;;
            var e;
            for (var i = 0; i &lt; l; i++) {
                e = employees[i];
                var params = [e.id, e.firstName, e.lastName, e.title, e.officePhone, e.deleted, e.lastModified];
                tx.executeSql(sql, params);
            }
        },
        this.txErrorHandler,
        function(tx) {
            callback();
        }
    );
}
</pre>
<h3>Synchronization Logic</h3>
<p>With these server and client APIs in place, you can choreograph a data synchronization process as follows: </p>
<pre class="brush: jscript; title: ; notranslate">
sync: function(syncURL, callback) {

    var self = this;
    this.getLastSync(function(lastSync){
        self.getChanges(syncURL, lastSync,
            function (changes) {
                self.applyChanges(changes, callback);
            }
        );
    });

}
</pre>
<h3>Final Notes</h3>
<ul>
<li>This solution currently supports unidirectional (server to client) data synchronization. It could easily be expanded to support bidirectional synchronization.</li>
<li>This solution currently implements &#8220;logical deletes&#8221;: items are not physically deleted from the table, but the value of their &#8220;deleted&#8221; column is set to true.</li>
<li>As mentioned above, you could replace the Web SQL implementation with another data access strategy. For example, take a look at <a href="http://brian.io/lawnchair/">Brian Leroux&#8217; Lawnchair</a> for another local persistence solution.</li>
</ul>
<h3>Source Code</h3>
<p>The source code is available in <a href="https://github.com/ccoenraets/offline-sync">this GitHub repository</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2012/05/simple-offline-data-synchronization-for-mobile-web-and-phonegap-applications/feed/</wfw:commentRss>
		<slash:comments>37</slash:comments>
		</item>
		<item>
		<title>Single-Page CRUD Application with Backbone.js and Twitter Bootstrap</title>
		<link>http://coenraets.org/blog/2012/05/single-page-crud-application-with-backbone-js-and-twitter-bootstrap/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=single-page-crud-application-with-backbone-js-and-twitter-bootstrap</link>
		<comments>http://coenraets.org/blog/2012/05/single-page-crud-application-with-backbone-js-and-twitter-bootstrap/#comments</comments>
		<pubDate>Thu, 03 May 2012 14:23:34 +0000</pubDate>
		<dc:creator>Christophe Coenraets</dc:creator>
				<category><![CDATA[Backbone.js]]></category>
		<category><![CDATA[JQuery]]></category>
		<category><![CDATA[Twitter Bootstrap]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=3575</guid>
		<description><![CDATA[A few weeks weeks ago, I posted a first Backbone.js and Twitter Bootstrap sample application. While interesting, &#8220;Employee Directory&#8221; is a read-only application. As such, it doesn’t show off the full power of Backbone&#8217;s models or the coolness of some of Bootstrap&#8217;s data entry features such as forms, validation, etc. To demonstrate these features, I [...]]]></description>
				<content:encoded><![CDATA[<p>A few weeks weeks ago, I <a href="http://coenraets.org/blog/2012/02/sample-app-with-backbone-js-and-twitter-bootstrap/">posted</a> a first <a href="http://documentcloud.github.com/backbone/">Backbone.js</a> and <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap</a> sample application. While interesting, &#8220;Employee Directory&#8221; is a read-only application. As such, it doesn’t show off the full power of Backbone&#8217;s models or the coolness of some of Bootstrap&#8217;s data entry features such as forms, validation, etc.</p>
<p>To demonstrate these features, I decided to revisit my <a href="http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-1-getting-started/">wine cellar application</a>, which was in need of a serious UI makeover.</p>
<p>You can run the application <a href="http://coenraets.org/backbone-cellar/bootstrap">here</a>.</p>
<p><a href="http://coenraets.org/backbone-cellar/bootstrap"><img src="http://coenraets.org/blog/wp-content/uploads/2012/05/cellar012.jpg" alt="" width="640" height="553" class="aligncenter size-full wp-image-3600" /></a></p>
<p><a href="http://coenraets.org/backbone-cellar/bootstrap"><img src="http://coenraets.org/blog/wp-content/uploads/2012/05/cellar021.jpg" alt="" title="cellar02" width="640" height="584"  class="aligncenter size-full wp-image-3603" /></a><br />
<span id="more-3575"></span><br />
This online version uses an in-memory datastore: all your changes will be lost the next time you start the application or hit your browser’s refresh button. The image upload feature is also disabled, but you can still drag an image from your file system and drop it  in the Wine Form, which is pretty cool (see the note about browser support below). The <a href="https://github.com/ccoenraets/backbone-cellar">source code</a> available on GitHub includes a persistent back-end (in addition to the in-memory datastore), and a fully functional implementation of the file upload feature.</p>
<h3>Code Highlights</h3>
<h4>Template Loader</h4>
<p>This application features a template loader that now uses jQuery “deferreds” to load the HTML templates more efficiently.</p>
<h4>Drag-and-Drop File Upload and HTML 5 File API</h4>
<p>To upload an image file for a Wine, drag a file from your file system and drop it in the image box inside the Wine Form: The image is automatically displayed inside the img tag. This is done using the HTML 5 File API and doesn’t require a server roundtrip. </p>
<p>NOTE: This feature only works in Chrome at this time. I will implement an alternative implementation in a future version of the application to provide a consistent behavior across browsers.</p>
<p>The image is uploaded to the server using Ajax (XHR) when you save the form: no page refresh or iframe hack.</p>
<p><h>Paging</h4>
<p>Twitter Bootstrap provides easy markup and styles to create paginated lists. In this application, the Bootstrap markup and styles are “componentized” or “widgetized” into a Backbone View (Paginator), which adds the appropriate pagination behavior.</p>
<p>NOTE: In the current implementation of this application, the entire data set is always retrieved from the server and paging is provided for a cosmetic/layout reason. You could easily replace this implementation with a true paging strategy where pages are lazy-loaded from the server as needed.</p>
<h4>Forms</h4>
<p>Backbone Cellar also uses Twitter Bootstrap’s forms, which greatly help with form layouts (see WineView). </p>
<h4>Validation</h4>
<p>Twitter Bootstrap also provides simple markup and styles to highlight validation errors in forms. In Backbone Cellar, Bootstrap’s validation markup and styles are wired with validation rules defined in the Backbone model. Note that at this time, the application doesn’t use the Backbone model’s default validate() method, but custom validateItem() and validateAll() methods instead. </p>
<p>The application also uses other Twitter Bootstrap features including thumbnails, dropdowns, alerts, etc.</p>
<h3>Source Code</h3>
<p>The source code is available in the <a href="https://github.com/ccoenraets/backbone-cellar/bootstrap">bootstrap</a> folder of the <a href="https://github.com/ccoenraets/backbone-cellar">backbone-cellar</a> repository on GitHub.</p>
<h3>Disclaimer</h3>
<p>This is a sample application, not a production application. Some trade-offs were made to keep the code generic, simple and readable. In a real-life application, you should consider implementing a namespacing scheme to keep the global namespace clean, and other optimization techniques such as view and/or data caching.</p>
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2012/05/single-page-crud-application-with-backbone-js-and-twitter-bootstrap/feed/</wfw:commentRss>
		<slash:comments>36</slash:comments>
		</item>
		<item>
		<title>Building Mobile Apps with HTML and a Local Database</title>
		<link>http://coenraets.org/blog/2012/04/building-mobile-apps-with-html-and-a-local-database/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=building-mobile-apps-with-html-and-a-local-database</link>
		<comments>http://coenraets.org/blog/2012/04/building-mobile-apps-with-html-and-a-local-database/#comments</comments>
		<pubDate>Wed, 11 Apr 2012 16:03:22 +0000</pubDate>
		<dc:creator>Christophe Coenraets</dc:creator>
				<category><![CDATA[Backbone.js]]></category>
		<category><![CDATA[HTML 5]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[PhoneGap]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=3474</guid>
		<description><![CDATA[After my recent post, Crafting Native Looking iOS Apps with HTML, a number of you asked for an offline version that would use a Local Database (instead of the simple in-memory store) and provide a mechanism to automatically keep the local database in sync with a server database. I&#8217;ll save automatic data synchronization strategies for [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://coenraets.org/blog/wp-content/uploads/2012/04/empdirdb4.jpg"><img src="http://coenraets.org/blog/wp-content/uploads/2012/04/empdirdb4.jpg" alt="" title="empdirdb4" width="436" height="607" class="aligncenter size-full wp-image-3555" /></a></p>
<p>After my recent post, <a href="http://coenraets.org/blog/2012/03/crafting-native-looking-ios-apps-with-html-backbone-js-and-phonegap/">Crafting Native Looking iOS Apps with HTML</a>, a number of you asked for an offline version that would use a Local Database (instead of the simple in-memory store) and provide a mechanism to automatically keep the local database in sync with a server database.<br />
<span id="more-3474"></span><br />
I&#8217;ll save automatic data synchronization strategies for a future post, but here is the first step: an &#8220;offline&#8221; version of the application that uses the device&#8217;s or the browser&#8217;s local database as its data provider. This version still uses <a href="http://backbonejs.org/">Backbone.js</a> as its architectural framework. Backbone.js makes it easy to change its default data access mechanism (which assumes RESTful services). You just replace the default <strong>Backbone.sync</strong> implementation and provide your own data access logic: in this case, some local SQL logic.</p>
<h3>Web SQL vs IndexedDB</h3>
<p>As you probably know, there have been two competing database APIs for HTML. From the W3C web site:</p>
<ul>
<li>The <a href="http://dev.w3.org/html5/webdatabase/">Web SQL specification</a> defines an API for storing data in databases that can be queried using a variant of SQL. This specification is no longer in active maintenance and the Web Applications Working Group does not intend to maintain it further.</li>
<li>The <a href="http://www.w3.org/TR/IndexedDB/">Indexed Database specification</a> defines APIs for a database of records holding simple values and hierarchical objects. It is a working draft, and &#8220;work in progress&#8221;.</li>
</ul>
<p>Even though the W3C is no longer actively maintaining the spec, this application uses the Web SQL API because, as a mobile <em>app</em>, its two main target platforms are iOS and Android, which both currently support Web SQL but not IndexedDB. More detailed platform support information can be found on caniuse.com (<a href="http://caniuse.com/#feat=sql-storage">Web SQL</a> and <a href="http://caniuse.com/indexeddb">IndexedDB</a>).</p>
<p>Chrome, Safari, and Opera on the desktop also support Web SQL, which means that you can run the application in these browsers. Try it <a href="http://coenraets.org/backbone/directory/localdb">here</a>. For example, using the Chrome Developer Tools you could debug the application and inspect the database as shown in this screenshot:</p>
<p><a href="http://coenraets.org/blog/wp-content/uploads/2012/04/debugdb2.gif"><img src="http://coenraets.org/blog/wp-content/uploads/2012/04/debugdb2.gif" alt="" title="debugdb2" width="640" height="469" class="alignnone size-full wp-image-3516" /></a></p>
<p>Firefox and IE don&#8217;t support Web SQL. You could easily create an alternative version of EmployeeDAO (described below) that uses IndexedDB instead. You could also create a version of the application that uses either Web SQL or IndexedDB depending on the platform it&#8217;s running on.</p>
<h3>Code Highlights</h3>
<p>The source code is available in the <a href="https://github.com/ccoenraets/backbone-directory/tree/master/localdb">localdb</a> folder of the <a href="https://github.com/ccoenraets/backbone-directory">backbone-directory</a> repository on GitHub. Here is a quick walkthrough&#8230;</p>
<p>The data access logic is encapsulated in EmployeeDAO, which also has a “populate” function to populate the employee table with sample data.</p>
<pre class="brush: jscript; title: ; notranslate">
directory.dao.EmployeeDAO = function(db) {
    this.db = db;
};

_.extend(directory.dao.EmployeeDAO.prototype, {

    findByName: function(key, callback) {
        this.db.transaction(
            function(tx) {

                var sql = &quot;SELECT e.id, e.firstName, e.lastName, e.title, count(r.id) reportCount &quot; +
                    &quot;FROM employee e LEFT JOIN employee r ON r.managerId = e.id &quot; +
                    &quot;WHERE e.firstName || ' ' || e.lastName LIKE ? &quot; +
                    &quot;GROUP BY e.id ORDER BY e.lastName, e.firstName&quot;;

                tx.executeSql(sql, ['%' + key + '%'], function(tx, results) {
                    var len = results.rows.length,
                        employees = [],
                        i = 0;
                    for (; i &lt; len; i = i + 1) {
                        employees[i] = results.rows.item(i);
                    }
                    callback(employees);
                });
            },
            function(tx, error) {
                alert(&quot;Transaction Error: &quot; + error);
            }
        );
    },

    findById: function(id, callback) {
        // removed for brevity
    },

    findByManager: function(managerId, callback) {
        // removed for brevity
    },

    populate: function(callback) {
        // removed for brevity
    }
});
</pre>
<p>Models are annotated with a “dao” attribute to indicate which data object to use to access their underlying data.</p>
<pre class="brush: jscript; title: ; notranslate">
directory.models.Employee = Backbone.Model.extend({

    dao: directory.dao.EmployeeDAO,

});

directory.models.EmployeeCollection = Backbone.Collection.extend({

    dao: directory.dao.EmployeeDAO,

    model: directory.models.Employee,

});
</pre>
<p>With that infrastructure in place, you can then override Backbone.sync to access data from the local database instead of RESTful services:</p>
<pre class="brush: jscript; title: ; notranslate">
Backbone.sync = function(method, model, options) {

    var dao = new model.dao(directory.db);

    if (method === &quot;read&quot;) {
        if (model.id) {
            dao.findById(model.id, function(data) {
                options.success(data);
            });
        } else if (model.managerId) {
            dao.findByManager(model.managerId, function(data) {
                options.success(data);
            });
        } 
        // removed for brevity
    }

};
</pre>
<h3>Source Code</h3>
<p>The source code is available in the <a href="https://github.com/ccoenraets/backbone-directory/tree/master/localdb">localdb</a> folder of the <a href="https://github.com/ccoenraets/backbone-directory">backbone-directory</a> repository on GitHub.</p>
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2012/04/building-mobile-apps-with-html-and-a-local-database/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Crafting Native Looking iOS Apps with HTML, Backbone.js, and PhoneGap</title>
		<link>http://coenraets.org/blog/2012/03/crafting-native-looking-ios-apps-with-html-backbone-js-and-phonegap/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=crafting-native-looking-ios-apps-with-html-backbone-js-and-phonegap</link>
		<comments>http://coenraets.org/blog/2012/03/crafting-native-looking-ios-apps-with-html-backbone-js-and-phonegap/#comments</comments>
		<pubDate>Wed, 28 Mar 2012 18:00:04 +0000</pubDate>
		<dc:creator>Christophe Coenraets</dc:creator>
				<category><![CDATA[Backbone.js]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[PhoneGap]]></category>

		<guid isPermaLink="false">http://coenraets.org/blog/?p=3359</guid>
		<description><![CDATA[If you just want to try the application in your browser, click here. The data is based on Dwight&#8217;s original org chart :) I&#8217;ve been blogging a lot about Backbone.js recently. Backbone.js is a lightweight architectural framework that brings structure to your Web applications. Backbone is not, however, a user interface framework that helps you [...]]]></description>
				<content:encoded><![CDATA[<p>If you just want to try the application in your browser, click <a href="http://coenraets.org/backbone/directory/iphone">here</a>. The data is based on Dwight&#8217;s original <a href="http://www.nbc.com/The_Office/downloads/dunder_mifflin_org_chart.pdf">org chart</a> :)</p>
<p><a href="http://coenraets.org/backbone/directory/iphone"><img src="http://coenraets.org/blog/wp-content/uploads/2012/03/empdirios04.jpg" alt="" title="empdirios04" width="300" height="574" style="float: left;" /></a></p>
<p><a href="http://coenraets.org/backbone/directory/iphone"><img src="http://coenraets.org/blog/wp-content/uploads/2012/03/empdirios05.jpg" alt="" title="empdirios05" width="300" height="574"/></a></p>
<p>I&#8217;ve been blogging a lot about Backbone.js recently. Backbone.js is a lightweight architectural framework that brings structure to your Web applications. Backbone is not, however, a user interface framework that helps you with the way your application looks.</p>
<p><em>So, where do you turn to for help when you need to make your application look good? </em><br />
<span id="more-3359"></span><br />
For traditional web apps (delivered through a browser), Twitter Bootstrap can help (read <a href="http://coenraets.org/blog/2012/02/sample-app-with-backbone-js-and-twitter-bootstrap/">here</a>). But what about Mobile apps? I explored Backbone.js + jQuery Mobile <a href="http://coenraets.org/blog/2012/03/employee-directory-sample-app-with-backbone-js-and-jquery-mobile/">here</a>. Depending on what you are looking for, it may or may not be the right solution: jQM provides mobile skins, but they don&#8217;t look native. It&#8217;s also more of a full stack framework than a lightweight UI toolkit that you can easily layer on top of your app.  </p>
<p>The alternative to using an existing UI toolkit is to roll your own styles to make your application look and behave like a native app. Sounds easy enough, but when you consider all the details and want to achieve &#8220;pixel perfection&#8221;, it becomes a daunting task. </p>
<p>As I was getting ready to tackle the challenge, and build a new native looking version of my Employee Directory app, I came across <a href="http://cheeaun.com/blog/2012/03/how-i-built-hacker-news-mobile-web-app">this great blog post</a> by Chee Aun where he documents the process he went through to build his own Hacker News mobile app. His post is a real gem, and I ended up reusing a lot of the Hacker News app styles.</p>
<p>Compared to the Hacker News app, the Employee Directory page flow is more random. Here are a few examples:</p>
<ol>
<li>SearchPage -> EmployeePage -> ReportsPage -> EmployeePage -> &#8230; </li>
<li>SearchPage -> EmployeePage -> EmployeePage (manager) -> Reports -> &#8230; </li>
<li>SearchPage -> EmployeePage -> EmployeePage (manager) -> EmployeePage (manager&#8217;s manager) -> &#8230; </li>
</ol>
<p>As you can see, the page flow includes &#8220;same page transitions&#8221;, when the user navigates from one employee to his/her manager. To accommodate the Employee Directory page flow requirements, my Backbone.js infrastructure creates and destroys pages as needed with the appropriate slide-in/slide-out transitions. The implementation of these transitions was inspired by Wesley Hales&#8217; <a href="http://www.html5rocks.com/en/mobile/optimization-and-performance/">article</a>.</p>
<h3>PhoneGap</h3>
<p>Even though you can run this application in a browser (<a href="http://coenraets.org/backbone/directory/iphone">here</a>), I built it with the intention of packaging it as a native app with <a href="http://phonegap.com/">PhoneGap</a> so  that you could start it like any other app from your iPhone home screen. If you are not familiar with PhoneGap, I&#8217;ll provide more details on packaging this app as a native app in my next post.</p>
<h3>Source Code</h3>
<p>I updated the <a href="https://github.com/ccoenraets/backbone-directory">backbone-directory</a> GitHub repository to include this version: It is available in the <a href="https://github.com/ccoenraets/backbone-directory/tree/master/iphone">iphone</a> directory.<br />
<br/><br/></p>
]]></content:encoded>
			<wfw:commentRss>http://coenraets.org/blog/2012/03/crafting-native-looking-ios-apps-with-html-backbone-js-and-phonegap/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
	</channel>
</rss>
