<?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>Dave Kelly :: Blog &#187; JavaScript</title>
	<atom:link href="http://www.davidkelly.ie/category/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.davidkelly.ie</link>
	<description>www.davidkelly.ie</description>
	<lastBuildDate>Tue, 06 Jul 2010 18:41:50 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=abc</generator>
		<item>
		<title>Live Query Plugin for jQuery</title>
		<link>http://www.davidkelly.ie/2008/10/31/live-query-plugin-for-jquery/</link>
		<comments>http://www.davidkelly.ie/2008/10/31/live-query-plugin-for-jquery/#comments</comments>
		<pubDate>Fri, 31 Oct 2008 10:22:47 +0000</pubDate>
		<dc:creator>Dave</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web Applications]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.davidkelly.ie/blog/?p=326</guid>
		<description><![CDATA[I spent a few hours yesterday trying to solve a jQuery problem that I was having&#8230;until I came across the excellent Live Query Plugin by Brandon Aaron which had already solved it for me. First, the blurb is: Live Query utilizes the power of jQuery selectors by binding events or firing callbacks for matched elements [...]]]></description>
			<content:encoded><![CDATA[<p>I spent a few hours yesterday trying to solve a <a class="zem_slink" title="JQuery" rel="homepage" href="http://jquery.com/">jQuery</a> problem that I was having&#8230;until I came across the excellent <a title="jQuery LiveQuery Plugin Page" href="http://plugins.jquery.com/project/livequery">Live Query Plugin</a> by <a href="http://blog.brandonaaron.net/">Brandon Aaron</a> which had already solved it for me. First, the blurb is:</p>
<blockquote><p>Live Query utilizes the power of jQuery selectors by binding events or firing callbacks for matched elements auto-magically, even after the page has been loaded and the <a class="zem_slink" title="Document Object Model" rel="wikipedia" href="http://en.wikipedia.org/wiki/Document_Object_Model">DOM</a> updated. [<a href="http://brandonaaron.net/docs/livequery/#getting-started">from Docs</a>]</p></blockquote>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-332" style="border: 4px solid #eeeeee; margin: 0px auto; width: 406px; height: 173px; clear: both;" src="http://www.davidkelly.ie/wp-content/uploads/2008/10/pulse_web.jpg" alt="Picture of a Pulse" /></p>
<p>So, why would you need Live Query? <span id="more-326"></span>In cases where you are dynamically adding elements to a page (i.e. DOM) using jQuery, you may want events attached to them. So, for example, I have a page that has been loaded. In response to user actions, I want to add a link that, when clicked on, triggers a &#8220;click&#8221; event. Because this link element has been generated dynamically, it won&#8217;t match any of the CSS declarations or have the same behaviours of elements which were there when the page loaded.</p>
<p>You can see a <a title="Live Query Example" href="http://www.davidkelly.ie/demo/livequery/">live (and very simple) example</a> of this. The code behind the example is:</p>
<p><code>$(document).ready(function()<br />
{<br />
/*<br />
Without Using Live Query:<br />
*/<br />
$('#add_new_box').click(function(){<br />
$('#box_holder').append('&lt;div class="new-box"&gt;&lt;a id="add-again" href="#"&gt;Add Smaller&lt;/a&gt;&lt;/div&gt;');</code><code> });<br />
// a problem here - this doesn't fire as expected...<br />
$('#add-again').click(function(){<br />
$('#add_new_box').append('&lt;div class="small-box"&gt;&lt;/div&gt;');<br />
});<br />
/*<br />
Using Live Query:<br />
*/<br />
$('#lq_add_new_box').click(function(){<br />
$('#lq_box_holder').append('<br />
&lt;div class="lq-new-box"&gt;&lt;a id="lq_add-again" href="#"&gt;Add Smaller&lt;/a&gt;&lt;/div&gt;');<br />
});<br />
$('#lq_add-again').livequery('click', function(){<br />
$('#lq_add_new_box').append(</code><code>'&lt;div class="small-box"&gt;&lt;/div&gt;');<br />
});<br />
});    // end document.ready(function)</code></p>
<p>In the example, the first link clicked adds a &lt;div&gt; with a link inside it. This new link, when clicked, should add a smaller yellow box. However, because the &#8220;Add Smaller&#8221; link was added dynamically, it does not have the click behaviour associated with it. It&#8217;s here that Live Query comes in.</p>
<p>In the second part of the example, Live Query is used to bind a click event to the link that was dynamically added. This ensures that the (my) expected behaviour of clicking the link in the red box and having a smaller yellow box appear goes to plan.</p>
<p>Having a web application be as responsive as possible is a target that should always be set. Doing so can be achieved in lots of ways, one of them being to minimise the number of page reloads the user needs to sit through. For what I am working on at the moment, Live Query just added a big lump of responsiveness to the interface. A great jQuery plugin.</p>
<div class="zemanta-pixie" style="margin-top: 10px; height: 15px;"><a class="zemanta-pixie-a" title="Zemified by Zemanta" href="http://reblog.zemanta.com/zemified/453fe09b-0739-4a67-bc50-1d71cb94e510/"><img class="zemanta-pixie-img" style="border: medium none; float: right;" src="http://img.zemanta.com/reblog_e.png?x-id=453fe09b-0739-4a67-bc50-1d71cb94e510" alt="Reblog this post [with Zemanta]" /></a></div>
]]></content:encoded>
			<wfw:commentRss>http://www.davidkelly.ie/2008/10/31/live-query-plugin-for-jquery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting into Gears: Offline Web App Tutorial &#8211; Part 2</title>
		<link>http://www.davidkelly.ie/2008/08/20/getting-into-gears-offline-web-app-tutorial-part-2/</link>
		<comments>http://www.davidkelly.ie/2008/08/20/getting-into-gears-offline-web-app-tutorial-part-2/#comments</comments>
		<pubDate>Wed, 20 Aug 2008 13:20:27 +0000</pubDate>
		<dc:creator>Dave</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web Applications]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Gears WorkerPool]]></category>
		<category><![CDATA[Web application]]></category>

		<guid isPermaLink="false">http://www.davidkelly.ie/blog/?p=112</guid>
		<description><![CDATA[In the first part of this tutorial I took a look at some of the background to Gears; the code example showed how to initialise Gears, and create a database (with a table definition). Apologies for the delay in getting the second part out of the drafts section of the blog. In this section, I&#8217;ll [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone size-full wp-image-208" style="margin: 0px 1em 1em 0px; float: left; width: 200px; height: 174px;" title="Gears" src="http://www.davidkelly.ie/wp-content/uploads/2008/08/gears_2_web.jpg" alt="Gears" />In the first part of this tutorial I took a look at some of the background to Gears; the code example showed how to initialise Gears, and create a database (with a table definition). Apologies for the delay in getting the second part out of the drafts section of the blog.</p>
<p>In this section, I&#8217;ll show how to use the Gears WorkerPool to carry out operations without affecting the user interface. Also included is a simple example of using the Gears HTTPRequest object to retrieve data from the remote database.<span id="more-112"></span></p>
<p class="block-highlght"><a href="http://www.davidkelly.ie/blog/2008/07/19/getting-into-gears-offline-web-app-tutorial-part-1/">Read the </a><a href="http://www.davidkelly.ie/blog/2008/07/19/getting-into-gears-offline-web-app-tutorial-part-1/">first part of the tu</a><a href="http://www.davidkelly.ie/blog/2008/07/19/getting-into-gears-offline-web-app-tutorial-part-1/">torial</a>.</p>
<h3>Using the WorkerPool</h3>
<p>The Gears <a title="Workerpool API" href="http://code.google.com/apis/gears/api_workerpool.html">Workerpool</a> allows JavaScript to run in the background without affecting the performance of browser window. This means that the user&#8217;s browser won&#8217;t slow down or lock up while there is processing going on behind the scenes. This gives the  opportunity to create more intensive scripts, and to have your web application process information while the user carries on with their other work.</p>
<p><code><br />
// create a workerpool<br />
var workerPool = google.gears.factory.create('beta.workerpool');<br />
// handle messages from the worker<br />
workerPool.onmessage = function(a, b, message) {<br />
console.log('Received message from worker ' + message.sender + ': \n' + message.body);<br />
};<br />
// create a child worker from a URL<br />
var childWorkerId = workerPool.createWorkerFromUrl('/scripts/gears/gears_db_load.js');<br />
// send the child a message... (messageBody, Unique Worker ID)<br />
workerPool.sendMessage("loadAllTreat", childWorkerId);<br />
</code></p>
<p>When the function is called it creates a Workerpool object (more details from the <a title="Gears Workerpool API Docs" href="http://code.google.com/apis/gears/api_workerpool.html">Gears Workerpool API</a>). This is used to create individual Workers that can be set to do different jobs. The Workers do not have access to the Window object, which means that they must interact by sending messages to each other.  The &#8220;workerPool.onmessage&#8221; callback above is an example of how Workers accept messages from each other (in this case, the details of the message (the Worker that sent it, and the message body) are being written to the Firebug console window.</p>
<p>The line:</p>
<p><code>var childWorkerId = workerPool.createWorkerFromUrl('/scripts/gears/gears_db_load.js');</code></p>
<p>is creating a Worker from an external script &#8211; gears_db_load.js (more on that in a moment).  The createWorkerFromUrl method returns a unique id value for the Worker &#8211; it is using this that the destination of messages sent between Workers is known.</p>
<p>The final line above sends a message to the Worker; in this case, telling it what action to take. The second parameter is the id value of the Worker, which allows the message to be routed to the correct place.</p>
<h3>My First Worker</h3>
<p><code><br />
// gears_db_load.js<br />
/*<br />
Workerpool JS to load remote data to local db after Setup<br />
*/<br />
(function(){<br />
var wp = google.gears.workerPool;<br />
var sender;	// Parent Worker ID<br />
// handle incoming messages:<br />
wp.onmessage = function(a, b, message) {<br />
try{<br />
var msg = message.body;    // what was the message<br />
sender = message.sender;  // Where did the message come from<br />
var resp;   // response to be returned to the Parent Worker<br />
switch (msg)<br />
{<br />
case 'loadAllTreat':<br />
getAllTreatments(); /* call a function to do something...*/<br />
break;<br />
default:<br />
resp = 'Oops...no message sent!!';<br />
wp.sendMessage(resp, sender);<br />
break;<br />
}<br />
} // try<br />
catch(ex)<br />
{ // send back an error message if needed<br />
wp.sendMessage('Error in worker: '+ err.message, sender);<br />
}<br />
} // onmessage<br />
</code><br />
<code><br />
// handle any errors that come up...<br />
wp.onerror = function( err ){<br />
wp.sendMessage('Error in worker: '+ err.message, sender);<br />
return true;<br />
}</code></p>
<p>This is creating a new Worker, and uses the onmessage callback to check what message has been passed to it by the sender. A switch statement is used to decide what action is needed, based on the message passed in. In this example, if the message is &#8220;<code>loadAllTreat"</code> the function getAllTreatments() is called, otherwise, a message is passed back to the sender.</p>
<p>Also included is an onerror callback that is used to return an error message to the sender, should an error occur.</p>
<h3>Gears HTTPRequest</h3>
<p>The getAllTreatments() function uses the Gears HTTPRequest to get data from the server using AJAX. The code below demonstrates carrying out the request, and parsing the JSON response from the server. [Note: it stops short of doing anything with the data returned - this will depend on the application in question]<br />
<code><br />
function getAllTreatments(){<br />
var request = google.gears.factory.create('beta.httprequest');<br />
// get Treatment &amp; Treatment Category Data<br />
request.open('GET', '/path/to/my/data/');<br />
request.onreadystatechange = function() {<br />
if (request.readyState == 4) {<br />
try{<br />
response = request.responseText;<br />
var jsResp = json_parse(response); // using http://www.JSON.org/json_parse.js<br />
//...<br />
//  do something with the json response, for example, insert it into local database..<br />
//...<br />
}// try<br />
catch(ex){<br />
wp.sendMessage("Worker Error: line - "+ ex.lineNumber + " Ex: "+ ex.message, sender);<br />
} // catch<br />
}  // readystate<br />
};	// onstatechange<br />
request.send();<br />
} // getAllTreatments()</code></p>
<p>The &#8220;var request&#8221; holds a Gears httpRequest object. It needs a place to request the data from, which is added using &#8220;request.open&#8221;, and supplying request type (&#8220;GET&#8221;) the path to the data (&#8216;/path/to/my/data&#8217;). When the request completes, the if statement within the onreadystatechange callback is triggered. This parses the response (in this example, the server is supplying a JSON response) using json_parse (available from: http://www.JSON.org/json_parse.js.</p>
<p>The example above stops short of doing something with the response after it has been parsed. One example of what could be done with the data, is to insert it into the local database.</p>
<h3>Other Alternatives</h3>
<p>There are a number of options available for implementing offline web apps. Some examples include:</p>
<ul>
<li>Using a client side JavaScript database such as <a href="http://taffydb.com/">TaffyDB</a>, although this doesn&#8217;t allow data to persist between sessions.</li>
<li><a href="http://dojotoolkit.org/offline">Dojo Offline </a>storage &#8211; <a href="http://api.dojotoolkit.org/jsdoc/dojox/HEAD/dojox.off">View API</a></li>
<li>Flash based storage options (used for in-browser storage)</li>
<li><a href="http://www.w3.org/TR/offline-webapps/">HTML 5 offline storage options</a></li>
</ul>
<h3>Related</h3>
<ul>
<li><a href="http://www.ambientage.com/blog/?p=31">Internet-free Web Applications</a> &#8211; Less technical perspective on offline web apps on my <a title="Ambient Age Blog" href="http://www.ambientage.com/blog/">work blog</a>.</li>
<li><a href="http://www.youtube.com/watch?v=xV_22e-Y5OE">What&#8217;s New With Gears</a> -Interesting YouTube Video (54mins long)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.davidkelly.ie/2008/08/20/getting-into-gears-offline-web-app-tutorial-part-2/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Getting into Gears: Offline Web App Tutorial &#8211; Part 1</title>
		<link>http://www.davidkelly.ie/2008/07/19/getting-into-gears-offline-web-app-tutorial-part-1/</link>
		<comments>http://www.davidkelly.ie/2008/07/19/getting-into-gears-offline-web-app-tutorial-part-1/#comments</comments>
		<pubDate>Sat, 19 Jul 2008 12:39:55 +0000</pubDate>
		<dc:creator>Dave</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web Applications]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.davidkelly.ie/blog/?p=80</guid>
		<description><![CDATA[Growing numbers of web applications have been dipping their toes into providing offline access using Gears. Recent examples include Google Reader (Google originally developed Gears before releasing it as an open source project), Remember the Milk, WordPress (in Version 2.6), with planned integrations from MySpace and Gmail. Offline access provides a way for a user [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone size-full wp-image-102" style="width: 200px; height: 174px; float: right; margin-left: 10px; margin-bottom: 10px;" title="Gears" src="http://www.davidkelly.ie/wp-content/uploads/2008/07/gears.jpg" alt="Image of Gears" />Growing numbers of web applications have been dipping their toes into providing offline access using <a title="Gears Homepage" href="http://gears.google.com/">Gears</a>. Recent examples include <a href="http://www.google.com/reader/">Google Reader</a> (Google originally developed Gears before releasing it as an open source project), <a title="To-do Lists" href="http://www.rememberthemilk.com">Remember the Milk</a>, <a href="http://www.wordpress.org">WordPress</a> (in Version 2.6), with <a title="ReadWriteWeb article" href="http://www.readwriteweb.com/archives/google_gears_coming_to_gmail.php">planned integrations</a> from <a href="http://www.myspace.com">MySpace</a> and <a href="http://gmail.google.com">Gmail</a>.</p>
<p>Offline access provides a way for a user to interact with the application when an Internet connection is unavailable, something &#8220;traditional&#8221; web applications cannot do. Gears also provides a means to improve the performance of apps by storing all the files necessary for them to operate on the user&#8217;s computer (meaning no need for downloads of images, script files, css, etc). An example of this is shown below.<br />
<span id="more-80"></span><br />
Gears achieves this by providing a number of features through <a title="Gears Developer Site" href="http://code.google.com/apis/gears/">its API</a>:</p>
<ul>
<li>A &#8220;Localserver&#8221; capable of serving files stored on the user&#8217;s machine, rather than relying on a remote web server;</li>
<li>A local database (SqlLite) for storing information that can be queried &amp; manipulated locally;</li>
<li>Access to a &#8220;Workerpool&#8221; which allows multiple JavaScript processes to run simultaneously &#8211; something which allows scripts to run in the background without causing the user interface to slow down;</li>
<li>Other APIs available include access to HttpRequest (for use in Workerpools using AJAX), the ability to create desktop shortcuts, and a Timer.</li>
</ul>
<p>For Gears to be used, it must firstly be installed on the user&#8217;s machine. To protect users, they must opt-in to allow certain operations to be carried out (for example, installing a desktop shortcut, or creating a local database).</p>
<h3>An Example</h3>
<p>In an application under development, the user needs access to a set of data that is unique to them. The data changes infrequently, but is needed regularly as either a full set, or is queried based on different conditions. In a &#8220;traditional&#8221; web application, this means frequent calls to the server which takes time, bandwidth and server processing power.  However, Gears offers an alternative. By maintaining the data on the client side, and updating it as required, the burden is removed from the server. While using the Gears approach in this situation does allow for offline access, one of the main motivations was to increase the responsiveness of the application. So, how does it all work?</p>
<p>First off, you need to check Gears is installed and available:</p>
<p><code><br />
&lt;script src="gears_init.js"&gt;&lt;/script&gt; &lt;!-- This need to be included every time --&gt;<br />
&lt;script type="text/javascript"&gt;<br />
if (!window.google || !google.gears) {<br />
location.href = "http://gears.google.com/?action=install&amp;message=Please Install Gears ..." +"&amp;return=http://www.example.com/setup/gears/installed/";<br />
}<br />
else{<br />
var db;                // local database<br />
var localServer;    // localServer<br />
}// else<br />
</code><br />
You can see that all the code is in JavaScript &#8211; this makes sense because it is all being run by the user&#8217;s browser, not a web server. The &#8220;gears_init.js&#8221; script makes sure Gears is installed (available from <a href="http://code.google.com/apis/gears/design.html#detecting">Gears documentation site</a>).  If it&#8217;s not available, the user will be redirected to an install site, and then sent back to an address you specify (http://www.example.com/setup/gears/installed/). This script also creates a &#8220;Factory&#8221; object, which is used to create all other objects.</p>
<p>The next step is to create a database to use and add a table to it:<br />
<code>// Datbase Setup<br />
db = google.gears.factory.create('beta.database');<br />
db.open('treatmentDB');<br />
db.execute('create table if not exists treatment ' + '(treatment_id int primary key, treatment_name text, treatment_price decimal, category_id int, timestamp int, toUpdate text)');<br />
db.close();</code></p>
<p>This creates a database object, and opens the database &#8220;treatmentDB&#8221; (or creates it if it doesn&#8217;t exist). The &#8220;execute&#8221; command is used to run SQL commands (SqlLite version) against the database &#8211; in this case, if there is no table called treatment, create one. I also included two fields to ensure the database is up-to-date &#8211; a timestamp, and a toUpdate field (which holds true / false flag depending on whether a record has been added to the local database, but not yet updated in the remote database).</p>
<h3>What&#8217;s Next?</h3>
<p>In the second part of the tutorial, the database will be populated using data on the remote server. I&#8217;ll show an example of using a Workerpool to do this, so that the operation doesn&#8217;t affect the user interface. The data will then be queried and output.</p>
<p class="block-highlght">Update: <a title="Gears Tutorial Part 2" href="http://www.davidkelly.ie/blog/2008/08/20/getting-into-gears-offline-web-app-tutorial-part-2/">Part 2 of the Gears tutorial</a> is now available</p>
]]></content:encoded>
			<wfw:commentRss>http://www.davidkelly.ie/2008/07/19/getting-into-gears-offline-web-app-tutorial-part-1/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
