<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" version="2.0">

<channel>
<title>Hackszine: Ajax</title>
<link>http://www.hackszine.com/blog/archive/ajax/</link>
<description>O&apos;Reilly&apos;s Hacks Series reclaims the term &apos;hacking&apos; for the good guys--innovators who explore and experiment, unearth shortcuts, create useful tools, and come up with fun things to try on their own</description>
<language>en-us</language>
<copyright>Copyright 2008, O'Reilly Media, Inc.</copyright>
<lastBuildDate>Thu, 04 Sep 2008 20:26:38 -0800</lastBuildDate>
<pubDate>Thu, 04 Sep 2008 20:58:37 -0800</pubDate>
<generator>http://www.movabletype.org/?v=4.1</generator>
<docs>http://blogs.law.harvard.edu/tech/rss</docs>
<itunes:author>O'Reilly Media, Inc.</itunes:author>
<itunes:subtitle>Clever solutions to interesting problems.</itunes:subtitle>
<itunes:summary>Hackszine Podcast</itunes:summary>
<itunes:owner>
<itunes:email>webmaster@makezine.com</itunes:email>
</itunes:owner>
<category>Technology</category>
<itunes:category text="Technology">
</itunes:category>
<itunes:category text="Technology">
  <itunes:category text="Gadgets" />
</itunes:category>
<itunes:category text="Games &amp; Hobbies" >
</itunes:category>
<itunes:category text="Science">
</itunes:category>
<itunes:image href="http://makezine.com/images/hackszine/rss_icon.jpg" />
<itunes:explicit>no</itunes:explicit>


<item>
<title>Objective-J and Cappuccino released</title>
<itunes:summary> Hackszine reader Math Campbell writes: As promised when they released their demo application 280 Slides, 280 North, the startup that invented a whole new language (Objective-J) to run their Cocoa-like Javascript framework, Cappuccino on, has released both Objective-J and...</itunes:summary>
<description>
<![CDATA[<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="cappucino_20080904.jpg" src="http://www.hackszine.com/cappucino_20080904.jpg" width="600" height="300" class="mt-image-none" style="" /></span></p>

<p>Hackszine reader Math Campbell writes:</p>

<blockquote>As promised when they released their demo application 280 Slides, 280 North, the startup that invented a whole new language (Objective-J) to run their Cocoa-like Javascript framework, Cappuccino on, has released both Objective-J and Cappuccino as open-source under the LGPL.  They're also providing documentation, tutorials and forums to help you master this new and exciting way of writing web-apps.</blockquote>

<p>This project came to my attention in June when 280 North released their web-based, Powerpoint-like presentation application, 280 Slides. The team has re-implemented a significant portion of the Cocoa API in Objective-J, so developers who are familiar with writing applications for Cocoa or GNUstep can easily port over their skill set, and possibly their applications, to the web.</p>

<p>Now I've got both iPhone and Cappuccino development giving me a reason to start kicking around a common development platform for web and mobile applications. Have any of you Hackszine readers started playing with Objective-J/Cappuccino? If so, what's been your experience so far? </p>

<p><a href="http://cappuccino.org/">Cappuccino: open source web application framework</a><br />
<a href="http://cappuccino.org/learn/tutorials/">Cappuccino tutorials</a></p>]]>
[&lt;a href="http://www.hackszine.com/blog/archive/2008/09/objectivej_and_cappuccino_rele.html?CMP=OTC-7G2N43923558" /&gt;Read More&lt;/a&gt;]  
[&lt;a href="http://www.hackszine.com/blog/archive/2008/09/objectivej_and_cappuccino_rele.html?CMP=OTC-7G2N43923558#comments" /&gt;Comments&lt;/a&gt;]
</description>
<link>http://www.hackszine.com/blog/archive/2008/09/objectivej_and_cappuccino_rele.html?CMP=OTC-7G2N43923558</link>
<guid>http://www.hackszine.com/blog/archive/2008/09/objectivej_and_cappuccino_rele.html?CMP=OTC-7G2N43923558</guid>
<category>Ajax</category>
<pubDate>Thu, 04 Sep 2008 20:26:38 -0800</pubDate>

</item>

<item>
<title>Chain.js - data binding for jQuery</title>
<itunes:summary> Rizqi Ahmad, a high-school student in Germany, created a pretty useful data binding service for jQuery called Chain.js. It allows you to easily manipulate data driven content from javascript by directly manipulating the DOM, without resorting to templates or...</itunes:summary>
<description>
<![CDATA[<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="chain_js_20080821.jpg" src="http://www.hackszine.com/chain_js_20080821.jpg" width="600" height="227" class="mt-image-none" style="" /></span></p>

<p>Rizqi Ahmad, a high-school student in Germany, created a pretty useful data binding service for jQuery called Chain.js. It allows you to easily manipulate data driven content from javascript by directly manipulating the DOM, without resorting to templates or a lot of complicated code. You create the markup the way you want the data to display, give class names to DOM elements that should have their content substituted, and pass an associative array containing the variable data to the chain() method.</p>

<p>There is also support for managing lists of elements, allowing you to add and remove elements dynamically inside the defined markup. Rizqi also created the Interaction library that works on top of the data binding library to provide drag, drop, and sort support for lists.</p>

<p>Make sure to check out his demos. They show off some of the flexibility of the library and they're easy to tweak for your own needs.</p>

<p><a href="http://rizqi.namaku.de/2008/08/data-binding-solution-for-jquery/">Data Binding Solution for jQuery</a><br />
<a href="http://github.com/raid-ox/chain.js/wikis">Chain.js - Data Binding Service for jQuery</a><br />
<a href="http://github.com/raid-ox/interaction.js/wikis">Interaction.js - drag/drop/sort support for Chain.js</a></p>]]>
[&lt;a href="http://www.hackszine.com/blog/archive/2008/08/chainjs_data_binding_for_jquer.html?CMP=OTC-7G2N43923558" /&gt;Read More&lt;/a&gt;]  
[&lt;a href="http://www.hackszine.com/blog/archive/2008/08/chainjs_data_binding_for_jquer.html?CMP=OTC-7G2N43923558#comments" /&gt;Comments&lt;/a&gt;]
</description>
<link>http://www.hackszine.com/blog/archive/2008/08/chainjs_data_binding_for_jquer.html?CMP=OTC-7G2N43923558</link>
<guid>http://www.hackszine.com/blog/archive/2008/08/chainjs_data_binding_for_jquer.html?CMP=OTC-7G2N43923558</guid>
<category>Ajax</category>
<pubDate>Thu, 21 Aug 2008 22:42:35 -0800</pubDate>

</item>

<item>
<title>Web application hotkeys with Javascript</title>
<itunes:summary>It&apos;s unfortunate, but there are only a few sites that have done a good job of enhancing the user experience with hotkey support. In searching for the easiest way to do this in my own applications, I stumbled across the...</itunes:summary>
<description>
<![CDATA[<p>It's unfortunate, but there are only a few sites that have done a good job of enhancing the user experience with hotkey support. In searching for the easiest way to do this in my own applications, I stumbled across the Hotkeys plugin for jQuery. In typical jQuery form it lets you do something moderately complicated, like capturing keyboard events, with a single line of Javascript code. You use the hotkeys.add method to bind a keyboard event to a callback function and the hotkeys.remove method to remove the handler.</p>

<p>Here's an example that will create an alert box when you press control-c:</p>

<blockquote><code>$.hotkeys.add('Ctrl+c', function(){ alert('ctrl-c pressed');});</code></blockquote>

<p>You remove the handler like this:</p>

<blockquote><code>$.hotkeys.remove('Ctrl+c');</code></blockquote>

<p>hotkeys.add can also has a 3 parameter evocation: <code>hotkeys.add(key, options, handler)</code>. The options parameter is just an associative array which you can use to pass options such as the target DOM path or the type of key press event (keyup or keydown). The key parameter is a string representing the key combination. Instead of using scan codes, you send in the names of the key combination, such as "a", "Shift+b", "f9", or "pageup". It's really that easy.</p>

<p><a href="http://code.google.com/p/js-hotkeys/">Javascript jQuery Hotkeys Plugin</a><br />
<a href="http://code.google.com/p/js-hotkeys/wiki/about">Using jQuery Hotkeys</a></p>]]>
[&lt;a href="http://www.hackszine.com/blog/archive/2008/07/web_application_hotkeys_with_j.html?CMP=OTC-7G2N43923558" /&gt;Read More&lt;/a&gt;]  
[&lt;a href="http://www.hackszine.com/blog/archive/2008/07/web_application_hotkeys_with_j.html?CMP=OTC-7G2N43923558#comments" /&gt;Comments&lt;/a&gt;]
</description>
<link>http://www.hackszine.com/blog/archive/2008/07/web_application_hotkeys_with_j.html?CMP=OTC-7G2N43923558</link>
<guid>http://www.hackszine.com/blog/archive/2008/07/web_application_hotkeys_with_j.html?CMP=OTC-7G2N43923558</guid>
<category>Ajax</category>
<pubDate>Mon, 28 Jul 2008 21:28:52 -0800</pubDate>

</item>

<item>
<title>Reverse autocomplete</title>
<itunes:summary>Traditional autocomplete is such a powerful tool that it&apos;s managed to work its way into most desktop and a significant number of web applications. Type a URL into your browser, and the address bar will offer suggestions for all of...</itunes:summary>
<description>
<![CDATA[<p>Traditional autocomplete is such a powerful tool that it's managed to work its way into most desktop and a significant number of web applications. Type a URL into your browser, and the address bar will offer suggestions for all of the URLs in your browsing history that begin with the text that precedes your cursor. Autocomplete works well, but it could be better.</p>

<p>László Kozma brought up a problem that tends to crop up in a number of scenarios: if you move the cursor back to correct or change part of the entry string, traditional autocomplete completely ignores any context to the right of the cursor. In some applications, this means everything to the right of the cursor is ignored and overwritten instead of being part of the search. In Safari, if you type anything between "www." and ".com", autocomplete fails entirely, offering no results unless you clear out everything to the right of the cursor.</p>

<p>One solution, which László termed "reverse autocomplete", is to split the string at the cursor position and attempt to find matches for both anything <em>after</em> the first half and <em>before</em> the second half. Any matches that show up in both sets are the final autocomplete suggestions. The result is that if I type in "www.h|.com" (where my cursor position is represented by the "|" character) the smarter autocomplete might return "www.hackszine.com" as a suggestion but omit from telling me about "www.h-is-aitch.org".</p>

<p>You can take it one step further and also match against the beginning and ends of the entire string. This solves a really common problem that I run into regularly when searching through a large contact list, say the typical corporate email system. If you don't know the correct spelling of someone's name, or if you only can recall initials, you can fill in the parts you know. The system would be smart enough to turn "J|S" into "Jason Striegel" instead of forcing you to page through a huge list of J names.</p>

<p><a href="http://www.lkozma.net/autocomplete.html">Reverse autocomplete</a></p>]]>
[&lt;a href="http://www.hackszine.com/blog/archive/2008/07/reverse_autocomplete.html?CMP=OTC-7G2N43923558" /&gt;Read More&lt;/a&gt;]  
[&lt;a href="http://www.hackszine.com/blog/archive/2008/07/reverse_autocomplete.html?CMP=OTC-7G2N43923558#comments" /&gt;Comments&lt;/a&gt;]
</description>
<link>http://www.hackszine.com/blog/archive/2008/07/reverse_autocomplete.html?CMP=OTC-7G2N43923558</link>
<guid>http://www.hackszine.com/blog/archive/2008/07/reverse_autocomplete.html?CMP=OTC-7G2N43923558</guid>
<category>Software Engineering</category>
<pubDate>Fri, 11 Jul 2008 22:30:08 -0800</pubDate>

</item>

<item>
<title>Crawling AJAX</title>
<itunes:summary>Traditionally, a web spider system is tasked with connecting to a server, pulling down the HTML document, scanning the document for anchor links to other HTTP URLs and repeating the same process on all of the discovered URLs. Each URL...</itunes:summary>
<description>
<![CDATA[<p>Traditionally, a web spider system is tasked with connecting to a server, pulling down the HTML document, scanning the document for anchor links to other HTTP URLs and repeating the same process on all of the discovered URLs. Each URL represents a different state of the traditional web site. In an AJAX application, much of the page content isn't contained in the HTML document, but is dynamically inserted by Javascript during page load. Furthermore, anchor links can trigger javascript events instead of pointing to other documents. The state of the application is defined by the series of Javascript events that were triggered after page load. The result is that the traditional spider is only able to see a small fraction of the site's content and is unable to index any of the application's state information. </p>

<p>So how do we go about fixing the problem?</p>

<p><strong>Crawl AJAX Like A Human Would</strong><br />
To crawl AJAX, the spider needs to understand more about a page than just its HTML. It needs to be able to understand the structure of the document as well as the Javascript that manipulates it. To be able to investigate the deeper state of an application, the crawling process also needs to be able to recognize and execute events within the document to simulate the paths that might be taken by a real user.</p>

<p>Shreeraj Shah's paper, Crawling Ajax-driven Web 2.0 Applications, does a nice job of describing the "event-driven" approach to web crawling. It's about creating a smarter class of web crawling software which is able to retrieve, execute, and parse dynamic, Javascript-driven DOM content, much like a human would operate a full-featured web browser.</p>

<blockquote>The "protocol-driven" approach does not work when the crawler comes across an Ajax embedded page. This is because all target resources are part of JavaScript code and are embedded in the DOM context. It is important to both understand and trigger this DOM-based activity. In the process, this has lead to another approach called "event-driven" crawling. It has following three key components 
 
<ol><li>Javascript analysis and interpretation with linking to Ajax </li><li>DOM event handling and dispatching </li><li>Dynamic DOM content extraction</li</ol>
</blockquote>

<p><strong>The Necessary Tools</strong><br />
The easiest way to implement an AJAX-enabled, event-driven crawler is to use a modern browser as the underlying platform. There are a couple of tools available, namely Watir and Crowbar, that will allow you to control Firefox or IE from code, allowing you to extract page data <em>after</em> it has processed any Javascript. </p>

<p>Watir is a library that enables browser automation using Ruby. It was originally built for IE, but it's been ported to both Firefox and Safari as well. The Watir API allows you to launch a browser process and then directly extract and click on anchor links from your Ruby application. This application alone makes me want to get more familiar with Ruby.</p>

<p>Crowbar is another interesting tool which uses a headless version of Firefox to render and parse web content. What's cool is that it provides a web server interface to the browser, so you can issue simple GET or POST requests from any language and then scrape the results as needed. This lets you interact with the browser from even simple command line scripts, using curl or wget.</p>

<p>Which tool you use depends on the needs of your crawler. Crowbar has the benefit of being language agnostic and simple to integrate into a traditional crawler design to extract page information that would only be present after a page has completed loading. Watir, on the other hand, gives you deeper, interactive access to the browser, allowing you to trigger subsequent Javascript events. The downside is that the logic behind a crawler that can dig deep into application state is quite a bit more complicated, and with Watir you are tied to Ruby which may or may not be your cup of tea.</p>

<p><br />
<a href="http://simile.mit.edu/wiki/Crowbar">Crowbar - server-side headless Firefox</a><br />
<a href="http://wtr.rubyforge.org/">Watir - browser remote control in Ruby</a><br />
<a href="http://www.infosecwriters.com/text_resources/pdf/Crawling_AJAX_SShah.pdf">Crawling Ajax-driven Web 2.0 Applications (PDF)</a></p>]]>
[&lt;a href="http://www.hackszine.com/blog/archive/2008/07/crawling_ajax.html?CMP=OTC-7G2N43923558" /&gt;Read More&lt;/a&gt;]  
[&lt;a href="http://www.hackszine.com/blog/archive/2008/07/crawling_ajax.html?CMP=OTC-7G2N43923558#comments" /&gt;Comments&lt;/a&gt;]
</description>
<link>http://www.hackszine.com/blog/archive/2008/07/crawling_ajax.html?CMP=OTC-7G2N43923558</link>
<guid>http://www.hackszine.com/blog/archive/2008/07/crawling_ajax.html?CMP=OTC-7G2N43923558</guid>
<category>Ajax</category>
<pubDate>Sat, 05 Jul 2008 12:57:11 -0800</pubDate>
<enclosure url="http://www.infosecwriters.com/text_resources/pdf/Crawling_AJAX_SShah.pdf" length="134246" type="application/pdf" />
</item>

<item>
<title>Algorithm Ink and ContextFree.js - generative art with Javascript</title>
<itunes:summary> Currently Firefox, Safari and Opera have reasonable support for the Canvas HTML element. With IE the only major remaining laggard, there are a lot of people starting to experiment with Javascript&apos;s new graphical capabilities. I mentioned John Resig&apos;s Processing.js...</itunes:summary>
<description>
<![CDATA[<p><object width="500" height="380">	<param name="allowfullscreen" value="true" />	<param name="allowscriptaccess" value="always" />	<param name="movie" value="http://www.vimeo.com/moogaloop.swf?clip_id=1202830&amp;server=www.vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" />	<embed src="http://www.vimeo.com/moogaloop.swf?clip_id=1202830&amp;server=www.vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="500" height="380"></embed></object></p>

<p>Currently Firefox, Safari and Opera have reasonable support for the Canvas HTML element. With IE the only major remaining laggard, there are a lot of people starting to experiment with Javascript's new graphical capabilities. I mentioned John Resig's Processing.js library in May, and now Aza Raskin has released the ContextFree.js library, which brings another generative drawing language to web-standards software development.</p>

<blockquote>Besides being pretty, why is ContextFree.js interesting? Because it shows the power of Open web technologies for making graphically-enabled, compelling interaction. The true power of the web revolves around anyone being able to dive in, see what someone else has done, and expand upon it. Canvas lowers the cost of entry to creating graphical mashups and other dynamic, graphical content. It also shows the progress the web has made: a year ago, this demo would not have been possible. Canvas wasn't ready, and Javascript interpreters weren't fast enough. Looking at the qualitative difference in speed from Firefox 2 to Firefox 3 indicates the amazing and substantial progress made towards speeding up Javascript since the last major browser release cycle.</blockquote>

<p>ContextFree.js is a Javascript port of the Context Free open source generative art application by Chris Coyne. It basically defines an extremely simple grammar that is designed to generate rule-based artwork with very few lines of code.</p>

<p>Aza has also released the Algorithm Ink website, which uses ContextFree.js to create an open source art gallery. Using Algorithm Ink, you can load, tweak, and share generative art through a web interface. When you see something you like, you can view the source for the artwork and use it in your own creations. Very cool.</p>

<p><a href="http://azarask.in/blog/post/contextfreejs-algorithm-ink-making-art-with-javascript/">ContextFree.js &amp; Algorithm Ink: Making Art with Javascript</a><br />
<a href="http://code.google.com/p/contextfree/">ContextFree.js at Google Code</a><br />
<a href="http://azarask.in/projects/algorithm-ink/">Algorithm Ink</a><br />
<a href="http://www.contextfreeart.org/">The original Context Free by Chris Coyne</a><br />
<a href="http://developer.mozilla.org/en/docs/Drawing_Graphics_with_Canvas">Drawing Graphics with Canvas</a><br />
<a href="http://www.hackszine.com/blog/archive/2008/05/processingjs_visualization_lib.html">Processing.js - visualization library for Javascript</a></p>]]>
[&lt;a href="http://www.hackszine.com/blog/archive/2008/07/algorithm_ink_and_contextfreej.html?CMP=OTC-7G2N43923558" /&gt;Read More&lt;/a&gt;]  
[&lt;a href="http://www.hackszine.com/blog/archive/2008/07/algorithm_ink_and_contextfreej.html?CMP=OTC-7G2N43923558#comments" /&gt;Comments&lt;/a&gt;]
</description>
<link>http://www.hackszine.com/blog/archive/2008/07/algorithm_ink_and_contextfreej.html?CMP=OTC-7G2N43923558</link>
<guid>http://www.hackszine.com/blog/archive/2008/07/algorithm_ink_and_contextfreej.html?CMP=OTC-7G2N43923558</guid>
<category>Ajax</category>
<pubDate>Wed, 02 Jul 2008 20:59:11 -0800</pubDate>

</item>

<item>
<title>Objective-J and Cappuccino: Cocoa for the web</title>
<itunes:summary> There&apos;s a neat article over at Ars Technica that takes a look at 280 North&apos;s 3-person development team, their recent release of a keynote-like web application called 280 Slides, and the framework that they constructed to make the application....</itunes:summary>
<description>
<![CDATA[<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="objective-j_20080629.jpg" src="http://www.hackszine.com/objective-j_20080629.jpg" width="500" height="392" class="mt-image-none" style="" /></span></p>

<p>There's a neat article over at Ars Technica that takes a look at 280 North's 3-person development team, their recent release of a keynote-like web application called 280 Slides, and the framework that they constructed to make the application. Some time before 280 Slides was developed, the team created an Objective-C-like superset of the Javascript language called Objective-J which implements message passing and a Smalltalk-style syntax. Building on that, they re-implemented much of the Cocoa framework in Objective-J, allowing Cocoa-style applications to be developed that will run natively in the browser. </p>

<p>With Objective-J and Cappuccino, you don't create applications with a mixture of HTML, CSS and Javascript. Instead, apps are written entirely in Objective-J, following a development model that's similar to creating desktop applications for OS X. From the article:<br />
<blockquote>"Cappuccino is a re-implementation of Cocoa in Objective-J, which means we reimplemented AppKit, Foundation, CoreGraphics, and parts of CoreAnimation," Boucher told us. With it, developers familiar with desktop GUI applications can create a rich, desktop-like web app with the same relative ease Cocoa programmers can create a rich desktop app. "Coming from a background of desktop programming, and Cocoa in particular, we realized how much harder building a web application was. So we wanted to try to make things just a little bit easier."</blockquote></p>

<p>280 Slides stands on its own as a powerful web-based presentation tool. It's simplified when compared to its desktop cousins, but it does exactly what most people need in a presentation tool, and it can export to PPT for fine tuning and end-presentation use. The fact that its development inspired the creation of a new language as well as bringing a desktop application development framework to the web just blows my mind.</p>

<p>Objective-J will be released to the public soon as an open source project. On the one hand, I'm not sure if I'm comfortable moving away from the web development technologies I've grown accustomed to. On the other, it would be cool to work in a language that allows you to seamlessly port your applications between the desktop and the web. </p>

<p>If you have experience with both Cocoa and AJAX development, please share your thoughts in the comment area.</p>

<p><a href="http://arstechnica.com/journals/apple.ars/2008/06/26/cocoa-on-the-web-280-north-objective-j-and-cappuccino">Cocoa on the web: 280 North, Objective-J, and Cappuccino</a> [via <a href="http://developers.slashdot.org/developers/08/06/29/167232.shtml">Slashdot</a>]<br />
<a href="http://blog.280north.com/">280 North Blog</a><br />
<a href="http://280slides.com/">280 Slides</a><br />
<a href="http://objective-j.org/">Objective-J.org</a></p>]]>
[&lt;a href="http://www.hackszine.com/blog/archive/2008/06/objectivej_and_cappuccino_coco.html?CMP=OTC-7G2N43923558" /&gt;Read More&lt;/a&gt;]  
[&lt;a href="http://www.hackszine.com/blog/archive/2008/06/objectivej_and_cappuccino_coco.html?CMP=OTC-7G2N43923558#comments" /&gt;Comments&lt;/a&gt;]
</description>
<link>http://www.hackszine.com/blog/archive/2008/06/objectivej_and_cappuccino_coco.html?CMP=OTC-7G2N43923558</link>
<guid>http://www.hackszine.com/blog/archive/2008/06/objectivej_and_cappuccino_coco.html?CMP=OTC-7G2N43923558</guid>
<category>Ajax</category>
<pubDate>Sun, 29 Jun 2008 20:36:07 -0800</pubDate>

</item>

<item>
<title>JSVI - Javascript Vi for web forms</title>
<itunes:summary> There are so many WYSIWYG editors for html forms, it&apos;s about time someone put together a decent web version of the Vi editor. JSVI is written in Javascript and seems to be fairly cross-browser compatible. With a few tweaks...</itunes:summary>
<description>
<![CDATA[<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="jsvi_20080628.jpg" src="http://www.hackszine.com/jsvi_20080628.jpg" width="500" height="353" class="mt-image-none" style="" /></span></p>

<p>There are so many WYSIWYG editors for html forms, it's about time someone put together a decent web version of the Vi editor. JSVI is written in Javascript and seems to be fairly cross-browser compatible.  With a few tweaks to your code, you can now make any textarea behave exactly like Vi. How cool is that?</p>

<p>To use it, download the GPLed vi.js file from the link below, include it in your html document, and then add an <b>onfocus="editor(this);"</b> to any textarea that you want vi enabled. If your textarea contains any preset information, the text will be loaded into the editor when the field is clicked. Saving the file with :wq will exit the editor and store the changes back in the input field.</p>

<p>Somewhere there must be a unix blog or forum that will adopt this for their submission and comment fields. Shame on them if they don't. That is, unless they are waiting for the emacs version.</p>

<p><a href="http://gpl.internetconnection.net/vi/">JSVI - VI in JavaScript (demo)</a><br />
<a href="http://gpl.internetconnection.net/vi/vi.js">Download vi.js</a></p>]]>
[&lt;a href="http://www.hackszine.com/blog/archive/2008/06/jsvi_javascript_vi_for_web_for.html?CMP=OTC-7G2N43923558" /&gt;Read More&lt;/a&gt;]  
[&lt;a href="http://www.hackszine.com/blog/archive/2008/06/jsvi_javascript_vi_for_web_for.html?CMP=OTC-7G2N43923558#comments" /&gt;Comments&lt;/a&gt;]
</description>
<link>http://www.hackszine.com/blog/archive/2008/06/jsvi_javascript_vi_for_web_for.html?CMP=OTC-7G2N43923558</link>
<guid>http://www.hackszine.com/blog/archive/2008/06/jsvi_javascript_vi_for_web_for.html?CMP=OTC-7G2N43923558</guid>
<category>Ajax</category>
<pubDate>Sat, 28 Jun 2008 20:39:33 -0800</pubDate>

</item>

<item>
<title>Parallax scrolling in jQuery</title>
<itunes:summary>Wynn Netherland wrote a plugin for jQuery that makes it easy to add a slick Parallax effect to a web site. For anyone who missed video games of the 80s, this is the old sidescroller technique that simulates depth by...</itunes:summary>
<description>
<![CDATA[<p>Wynn Netherland wrote a plugin for jQuery that makes it easy to add a slick Parallax effect to a web site. For anyone who missed video games of the 80s, this is the old sidescroller technique that simulates depth by making things in the foreground move faster than the background. The jQuery Parallax plugin does this by easing the background position across several div layers, all at different rates.</p>

<p>To make it work, you just make a horizontally tile-able background image, and a horizontally tile-able alpha-transparent PNG for each foreground layer. These are each set as the background image of a separate div with the repeat-x attribute. The divs are absolutely positioned right on top of each other, and then a single line of jQuery code is used to set the animation speed for each layer.</p>

<p>It's a subtle and bandwidth friendly way to add a bit of visual polish to your site. Netherland is using this effect for his blog's masthead, and it looks pretty cool.</p>

<p><a href="http://locomotivation.com/2008/06/18/jquery-parallax-scrolling-build-your-own-1980s-video-game">jQuery Parallax Scrolling</a> (<a href="http://locomotivation.com/javascripts/theme/jquery.parallax.js">download</a>)<br />
<a href="http://www.jquery.com/">jQuery</a><br />
<a href="http://plugins.jquery.com/project/Easing">jQuery Easing library</a> - you'll need this too</p>]]>
[&lt;a href="http://www.hackszine.com/blog/archive/2008/06/parallax_scrolling_in_jquery.html?CMP=OTC-7G2N43923558" /&gt;Read More&lt;/a&gt;]  
[&lt;a href="http://www.hackszine.com/blog/archive/2008/06/parallax_scrolling_in_jquery.html?CMP=OTC-7G2N43923558#comments" /&gt;Comments&lt;/a&gt;]
</description>
<link>http://www.hackszine.com/blog/archive/2008/06/parallax_scrolling_in_jquery.html?CMP=OTC-7G2N43923558</link>
<guid>http://www.hackszine.com/blog/archive/2008/06/parallax_scrolling_in_jquery.html?CMP=OTC-7G2N43923558</guid>
<category>Ajax</category>
<pubDate>Sun, 22 Jun 2008 18:10:02 -0800</pubDate>

</item>

<item>
<title>Google Earth has a Javascript API</title>
<itunes:summary> Google released a plug-in, currently for Windows browsers only, that allows you to embed the Earth application inside the browser. Existing Google Maps mashups can use some of the functionality right away just by adding the G_SATELLITE_3D_MAP map type....</itunes:summary>
<description>
<![CDATA[<p><object width="500" height="405"><param name="movie" value="http://www.youtube.com/v/6mrG_bsqC6k&hl=en"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/6mrG_bsqC6k&hl=en" type="application/x-shockwave-flash" wmode="transparent" width="500" height="405"></embed></object></p>

<p>Google released a plug-in, currently for Windows browsers only, that allows you to embed the Earth application inside the browser. Existing Google Maps mashups can use some of the functionality right away just by adding the G_SATELLITE_3D_MAP map type. Even more exciting is that you can interact more deeply with the map&mdash;including camera angles, KML layers, and 3D models&mdash;right from Javascript. I'm so eager to go find a PC to play around with this that I'll let the video speak for itself.</p>

<p>Also worth noting is that Google just released an official Maps API for Flash AS3. Call me a fanboy, but I think my head is spinning.</p>

<p><a href="http://code.google.com/apis/earth/">Google Earth API</a><br />
<a href="http://code.google.com/apis/earth/documentation/examples.html">Some Example Applications</a><br />
<a href="http://code.google.com/apis/maps/documentation/flash/">Maps API for Flash</a></p>]]>
[&lt;a href="http://www.hackszine.com/blog/archive/2008/06/google_earth_has_a_javascript.html?CMP=OTC-7G2N43923558" /&gt;Read More&lt;/a&gt;]  
[&lt;a href="http://www.hackszine.com/blog/archive/2008/06/google_earth_has_a_javascript.html?CMP=OTC-7G2N43923558#comments" /&gt;Comments&lt;/a&gt;]
</description>
<link>http://www.hackszine.com/blog/archive/2008/06/google_earth_has_a_javascript.html?CMP=OTC-7G2N43923558</link>
<guid>http://www.hackszine.com/blog/archive/2008/06/google_earth_has_a_javascript.html?CMP=OTC-7G2N43923558</guid>
<category>Ajax</category>
<pubDate>Tue, 03 Jun 2008 21:12:58 -0800</pubDate>

</item>

<item>
<title>Detect which sites a web user visits</title>
<itunes:summary> Aza Raskin&apos;s SocialHistory Javascript library allows you to do something incredibly cool: detect which sites your web users have visited on a per-user basis. The javascript runtime isn&apos;t supposed to be privy to the information in a user&apos;s browser...</itunes:summary>
<description>
<![CDATA[<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="socialdetect_20080528.jpg" src="http://www.hackszine.com/socialdetect_20080528.jpg" width="500" height="147" class="mt-image-none" style="" /></span></p>

<p>Aza Raskin's SocialHistory Javascript library allows you to do something incredibly cool: detect which sites your web users have visited on a per-user basis. The javascript runtime isn't supposed to be privy to the information in a user's browser history, but there's an information backchannel common to all major browsers which allows you to effectively interrogate the browsing history and determine if a particular URL has been visited before. </p>

<p>It works by creating an anchor link to the site in question and applying a CSS style to the link, specifying a different display property for "a:visited". By reading the computed style back from the anchor element, you can then determine the property's value, and consequently if the user had visited the URL or not.</p>

<p>This could probably be used for a number of devious purposes, but Aza's concept for the SocialHistory library is actually really useful. By querying the default URLs that belong to all the major social network sites, you can figure out which sites a particular user visits and custom tailor any social badges that you display. If they use del.icio.us, you show a del.icio.us link.  If they visit Digg, you show the Digg button. It's an awesome feature made possible by a pretty freaky security leak.</p>

<p>Now, it's not perfect. It requires that you query the exact URLs that a user may have visited. You can't figure out everywhere they've been, how frequently, or in what order, only whether a particular URL that you know about has been visited before. On the other hand, it's a pretty useful tool considering you aren't even supposed to be able to do this.</p>

<p><a href="http://azarask.in/blog/post/socialhistoryjs/">How to Detect the Social Sites Your Visitors Use</a><br />
<a href="http://code.google.com/p/aza/source/browse/trunk/SocialHistory/SocialHistory.js">SocialHistory.js</a></p>]]>
[&lt;a href="http://www.hackszine.com/blog/archive/2008/05/detect_which_sites_a_web_user.html?CMP=OTC-7G2N43923558" /&gt;Read More&lt;/a&gt;]  
[&lt;a href="http://www.hackszine.com/blog/archive/2008/05/detect_which_sites_a_web_user.html?CMP=OTC-7G2N43923558#comments" /&gt;Comments&lt;/a&gt;]
</description>
<link>http://www.hackszine.com/blog/archive/2008/05/detect_which_sites_a_web_user.html?CMP=OTC-7G2N43923558</link>
<guid>http://www.hackszine.com/blog/archive/2008/05/detect_which_sites_a_web_user.html?CMP=OTC-7G2N43923558</guid>
<category>Ajax</category>
<pubDate>Wed, 28 May 2008 19:44:20 -0800</pubDate>

</item>

<item>
<title>Cross browser session data with Javascript</title>
<itunes:summary>By storing data in the window.name property, you can store data between page loads and across domains without ever sending a cookie to a server. Thomas Frank created the sessvars.js library which makes use of this browser quirk, allowing you...</itunes:summary>
<description>
<![CDATA[<p>By storing data in the window.name property, you can store data between page loads and across domains without ever sending a cookie to a server. Thomas Frank created the sessvars.js library which makes use of this browser quirk, allowing you to store up to 2 MB of client-side session data.</p>

<p>This is really powerful for a few reasons:<br />
<ul><li>client-side, you can store way more data than allowed by traditional cookies</li><li>none of the data is transferred explicitly to the server, minimizing bandwidth used for each page request</li><li>allows you to talk between pages in different domains</li></ul></p>

<p>Keep in mind that anything you store via this mechanism will be visible to any other site that a person visits, so this is best for storing non-sensitive data that you want to retain between page loads. This would be great for caching returned AJAX data that you would otherwise have to refetch and reprocess.</p>

<p><a href="http://www.thomasfrank.se/sessionvars.html">Session variables without cookies</a></p>]]>
[&lt;a href="http://www.hackszine.com/blog/archive/2008/05/cross_browser_session_data_wit.html?CMP=OTC-7G2N43923558" /&gt;Read More&lt;/a&gt;]  
[&lt;a href="http://www.hackszine.com/blog/archive/2008/05/cross_browser_session_data_wit.html?CMP=OTC-7G2N43923558#comments" /&gt;Comments&lt;/a&gt;]
</description>
<link>http://www.hackszine.com/blog/archive/2008/05/cross_browser_session_data_wit.html?CMP=OTC-7G2N43923558</link>
<guid>http://www.hackszine.com/blog/archive/2008/05/cross_browser_session_data_wit.html?CMP=OTC-7G2N43923558</guid>
<category>Ajax</category>
<pubDate>Mon, 12 May 2008 19:26:32 -0800</pubDate>

</item>

<item>
<title>Reading EXIF data from images in Javascript</title>
<itunes:summary> Jacob Seidelin figured out a way to obtain EXIF data from images in Javascript, allowing AJAX applications to pull information about the make and model of camera used, as well as any aperture, focal length, or description information that...</itunes:summary>
<description>
<![CDATA[<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="javascriptexif_20080510.jpg" src="http://www.hackszine.com/javascriptexif_20080510.jpg" width="500" height="372" class="mt-image-none" style="" /></span></p>

<p>Jacob Seidelin figured out a way to obtain EXIF data from images in Javascript, allowing AJAX applications to pull information about the make and model of camera used, as well as any aperture, focal length, or description information that may have been tagged to an image by the camera or a photo editor.</p>

<p>The exif.js javascript library scans through all IMG tags in your HTML document, looking for the custom exif="true" parameter to be set. The DOM image object doesn't contain the necessary raw image data, so XMLHttpRequest is used to fetch the image data. In Safari and Firefox, the responseText property contains the binary image data. This isn't available in IE, however, but Jacob was able to put together a VBScript alternative that is still able to pull the data from the response.</p>

<p>From your code, pulling the EXIF data for an image becomes as simple as this:</p>

<blockquote><code>
var theimg = document.getElementById("imageid");  

<p>alert("Image Make: " + EXIF.getTag(theimg, "Make") + "\nImage Model: " + EXIF.getTag(theimg, "Model")); <br />
</code></blockquote></p>

<p>How cool is that?  I expect we'll see this in every ajax photo gallery soon.</p>

<p><a href="http://blog.nihilogic.dk/2008/05/reading-exif-data-with-javascript.html">Reading EXIF data with Javascript</a></p>]]>
[&lt;a href="http://www.hackszine.com/blog/archive/2008/05/reading_exif_data_from_images.html?CMP=OTC-7G2N43923558" /&gt;Read More&lt;/a&gt;]  
[&lt;a href="http://www.hackszine.com/blog/archive/2008/05/reading_exif_data_from_images.html?CMP=OTC-7G2N43923558#comments" /&gt;Comments&lt;/a&gt;]
</description>
<link>http://www.hackszine.com/blog/archive/2008/05/reading_exif_data_from_images.html?CMP=OTC-7G2N43923558</link>
<guid>http://www.hackszine.com/blog/archive/2008/05/reading_exif_data_from_images.html?CMP=OTC-7G2N43923558</guid>
<category>Ajax</category>
<pubDate>Sat, 10 May 2008 20:52:29 -0800</pubDate>

</item>

<item>
<title>Processing.js - visualization library for Javascript</title>
<itunes:summary> John Resig, of jQuery fame, released a port of the Processing visualization language for Javascript. Seriously, John is on fire: The first portion of the project was writing a parser to dynamically convert code written in the Processing language,...</itunes:summary>
<description>
<![CDATA[<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="jsprocessing_20080509.jpg" src="http://www.hackszine.com/jsprocessing_20080509.jpg" width="500" height="149" class="mt-image-none" style="" /></span></p>

<p>John Resig, of jQuery fame, released a port of the Processing visualization language for Javascript.  Seriously, John is on fire:</p>

<blockquote>The first portion of the project was writing a parser to dynamically convert code written in the Processing language, to JavaScript. This involves a lot of gnarly regular expressions chewing up the code, spitting it out in a format that the browser understands.

<p>It works "fairly well" (in that it's able to handle anything that the processing.org web site throws at it) but I'm sure its total scope is limited (until a proper parser is involved). I felt bad about tackling this using regular expressions until I found out that the original Processing code base did it in the same manner (they now use a real parser, naturally).</blockquote></p>

<p>The full 2D API is implemented, with the exclusion of some features here and there between browsers (Firefox 3 is pretty full featured). You can interact with the Processing API directly from standard Javascript. This lets you make use of these drawing features by simply instantiating a Processing object, and then calling its various drawing methods.</p>

<p>Another capability is to write code natively in the Processing language. This allows you to make use of extended language features such as method overloading and classic inheritance, though it looks like type information is pretty much ignored.</p>

<p>John has many of the demos from processing.org working. Most of them are going to peg your CPU, but this is some seriously cool stuff to see working in a first release. </p>

<p>Javascript just got a lot more interesting.</p>

<p><a href="http://dev.jquery.com/~john/processing.js/">Processing.js</a><br />
<a href="http://processing.org/">Processing: open source data visualization language</a></p>]]>
[&lt;a href="http://www.hackszine.com/blog/archive/2008/05/processingjs_visualization_lib.html?CMP=OTC-7G2N43923558" /&gt;Read More&lt;/a&gt;]  
[&lt;a href="http://www.hackszine.com/blog/archive/2008/05/processingjs_visualization_lib.html?CMP=OTC-7G2N43923558#comments" /&gt;Comments&lt;/a&gt;]
</description>
<link>http://www.hackszine.com/blog/archive/2008/05/processingjs_visualization_lib.html?CMP=OTC-7G2N43923558</link>
<guid>http://www.hackszine.com/blog/archive/2008/05/processingjs_visualization_lib.html?CMP=OTC-7G2N43923558</guid>
<category>Ajax</category>
<pubDate>Fri, 09 May 2008 21:36:09 -0800</pubDate>

</item>

<item>
<title>Nice overview of the YouTube API</title>
<itunes:summary> I caught this self-referential tutorial on YouTube today which walks you through the basics of the YouTube API. It appears to be quite simple to develop Javascript or Flash applications that can control or interact with the YouTube player,...</itunes:summary>
<description>
<![CDATA[<p><object width="500" height="400"><param name="movie" value="http://www.youtube.com/v/I8xZBfVsMzs&hl=en"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/I8xZBfVsMzs&hl=en" type="application/x-shockwave-flash" wmode="transparent" width="500" height="400"></embed></object></p>

<p>I caught this self-referential tutorial on YouTube today which walks you through the basics of the YouTube API. It appears to be quite simple to develop Javascript or Flash applications that can control or interact with the YouTube player, or even completely reskin the interface.</p>

<p>What I didn't know until recently was that the API has provisions for allowing your application to upload videos and post comments.  You can even authenticate users and allow them to interact with the YouTube backend through your private application.  It looks like you can do just about everything programatically except remove the YouTube watermark on the video.</p>

<p><a href="http://code.google.com/apis/youtube/developers_guide_protocol.html">YouTube Developer's Guide</a><br />
<a href="http://apiblog.youtube.com/">Developer API Blog</a></p>]]>
[&lt;a href="http://www.hackszine.com/blog/archive/2008/04/nice_overview_of_the_youtube_a.html?CMP=OTC-7G2N43923558" /&gt;Read More&lt;/a&gt;]  
[&lt;a href="http://www.hackszine.com/blog/archive/2008/04/nice_overview_of_the_youtube_a.html?CMP=OTC-7G2N43923558#comments" /&gt;Comments&lt;/a&gt;]
</description>
<link>http://www.hackszine.com/blog/archive/2008/04/nice_overview_of_the_youtube_a.html?CMP=OTC-7G2N43923558</link>
<guid>http://www.hackszine.com/blog/archive/2008/04/nice_overview_of_the_youtube_a.html?CMP=OTC-7G2N43923558</guid>
<category>YouTube</category>
<pubDate>Sun, 13 Apr 2008 23:12:23 -0800</pubDate>

</item>

<item>
<title>Automatic outbound link analytics with jQuery</title>
<itunes:summary>I had the challenge of adding Google Analytics tracking code to all the outbound links on a site I&apos;ve been working on. There are hundreds of these links scattered around the site, so rather than try and edit a bunch...</itunes:summary>
<description>
<![CDATA[<p>I had the challenge of adding Google Analytics tracking code to all the outbound links on a site I've been working on.  There are hundreds of these links scattered around the site, so rather than try and edit a bunch of links, manually adding onclick handlers in an error-prone fashion, I decided to get lazy and write some code to handle it for me.</p>

<p>First I was thinking about doing some sort of regular expression search and replace throughout the site and database, but that reminded me of CSS3 selectors and their ability to do simple pattern matching. I've seen people apply a special style to outbound links this way, so after a few minutes of monkeying around with things, I now have a chunk of jQuery that will automatically track clicks on all outbound links.</p>

<p>Here it is, in a nutshell:</p>

<blockquote><code>
jQuery(function($){

<p>&nbsp;&nbsp;  // Match all anchor tags in the "maincontent" div with<br />
&nbsp;&nbsp;  // urls that begin with "http" but don't contain the<br />
&nbsp;&nbsp;  // string "yourwebsite.com"<br />
&nbsp;&nbsp;  $('#maincontent a[href^="http"]').not('a[href*="yourwebsite.com"]').click(function(){</p>

<p>&nbsp;&nbsp;&nbsp;&nbsp;     try {</p>

<p>&nbsp;&nbsp;&nbsp;&nbsp;        // Get the href url and toss out the "http://"<br />
&nbsp;&nbsp;&nbsp;&nbsp;        var href = $(this).attr('href');<br />
&nbsp;&nbsp;&nbsp;&nbsp;       if ( href.indexOf("://") &gt; 0 ) {</p>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;             // Track the page in Google Analytics as <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;             // "/tracking/outbound/www.somesite.com/foo"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;             var outbound = '/tracking/outbound/' + href.split("://",2)[1];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;             pageTracker._trackPageview(outbound);</p>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;        }<br />
&nbsp;&nbsp;&nbsp;&nbsp;     } catch( e ) {}<br />
&nbsp;&nbsp;  }<br />
}<br />
</code></blockquote></p>

<p>With this running, all of my internal pages get tracked as usual, and any external links will appear as pageviews that look like "/tracking/outbound/www.somesite.com/foo".</p>

<p>If you link out to many different pages on several sites, keeping the full site url in the tracking code and building these deep paths is particularly useful.  Google Analytics will allow you to drill down into the tree like it was normal content and quickly pull numbers on how many total outbound clicks you received (/tracking/outbound), how many went to www.somesite.com (/tracking/outbound/www.somesite.com), and how many people clicked out to a particular page on the site.</p>

<p>This saved me quite a bit of time and is immensely more flexible than any other outbound tracking method I've used.  I hope this helps someone else.  Drop me a line in the comments if this works out for you.</p>

<p><strong>Update:</strong> it looks like I wasn't the first to do this. <a href="http://blog.rebeccamurphey.com/2008/01/06/track-outbound-clicks-with-google-analytics-and-jquery/">An article by Rebecca Murphey</a> shows how to do something similar, while also adding the referring post title to the tracking code.  Pretty cool stuff, I must say.</p>]]>
[&lt;a href="http://www.hackszine.com/blog/archive/2008/04/automatic_outbound_link_analyt.html?CMP=OTC-7G2N43923558" /&gt;Read More&lt;/a&gt;]  
[&lt;a href="http://www.hackszine.com/blog/archive/2008/04/automatic_outbound_link_analyt.html?CMP=OTC-7G2N43923558#comments" /&gt;Comments&lt;/a&gt;]
</description>
<link>http://www.hackszine.com/blog/archive/2008/04/automatic_outbound_link_analyt.html?CMP=OTC-7G2N43923558</link>
<guid>http://www.hackszine.com/blog/archive/2008/04/automatic_outbound_link_analyt.html?CMP=OTC-7G2N43923558</guid>
<category>Ajax</category>
<pubDate>Fri, 11 Apr 2008 22:57:30 -0800</pubDate>

</item>

<item>
<title>Relational database using jQuery and HTML tables</title>
<itunes:summary><![CDATA[Here's a novel use for the HTML &lt;TABLE&gt; tag: storing client side database tables. Nick Kallen came up with a slick hack that uses the jQuery syntax to perform simple selects and joins on HTML tables. By using CSS3 selectors,...]]></itunes:summary>
<description>
<![CDATA[<p>Here's a novel use for the HTML &lt;TABLE&gt; tag: storing client side database tables. Nick Kallen came up with a slick hack that uses the jQuery syntax to perform simple selects and joins on HTML tables. By using CSS3 selectors, you can easily target fields which match or contain your search terms, and Nick's jQuery-based API provides a simple query language, similar to a rudimentary SQL:</p>

<blockquote>
Today I was thinking aloud about <a href="http://research.microsoft.com/Users/luca/Slides/2003-11-132s2n2g2s20&amp;#40;Lisbon&amp;#41;.pdf">Tree Regular Expressions</a> and how they might make a nice query language for document databases like CouchDB. Someone pointed out that CSS3 selectors might make a great concrete syntax for this. One thing lead to another and I thought, why not build a relational database in HTML? So I did. I even got <strong>inner joins</strong> working.

<p>Let's start with a few tables:</p>

<pre><code>&lt;table class="users"&gt;
  &lt;tr&gt;
    &lt;td class="id"&gt;1&lt;/td&gt;
    &lt;td class="first_name"&gt;amy&lt;/td&gt;
    &lt;td class="last_name"&gt;bobamy&lt;/td&gt;
  &lt;/tr&gt; 
  ...
&lt;/table&gt;
&lt;table class="photos"&gt;
  &lt;tr&gt;
    &lt;td class="id"&gt;1&lt;/td&gt;
    &lt;td class="user_id"&gt;1&lt;/td&gt;
    &lt;td class="url"&gt;http://www.example.com/foo.png&lt;/td&gt;
  &lt;/tr&gt; 
&lt;/table&gt;
</code></pre>

<p>Now we can express some queries:</p>

<pre><code>$&#40;'.users'&#41;
  .where&#40;'.id:eq&#40;1&#41;'&#41;
  .select&#40;'*'&#41;
</code></pre>

<p>This is equivalent to <code>SELECT * FROM users WHERE id = 1</code></p>

<pre><code>$&#40;'.users'&#41;
  .where&#40;'.id:eq&#40;1&#41;'&#41;
  .select&#40;'.id, .name'&#41;
</code></pre>

<p>This is equivalent to <code>SELECT id, name FROM users WHERE id = 1</code><br />
</blockquote></p>

<p>How cool is that? Check out Nick's blog post for an example of text search and an inner join. The API in his jquery.db.js is quite straightforward and only about 50 lines of code. Adding a sort function shouldn't be too difficult. </p>

<p>I'm pretty much convinced now that jQuery is black magic.</p>

<p><br />
<a href="http://pivots.pivotallabs.com/users/nick/blog/articles/434-now-i-understand-what-they-mean-by-tabular-data-or-building-a-relational-database-using-jquery-and-lt-table-gt-tags-">Building a relational database using jQuery and &lt;TABLE&gt; tags</a><br />
<a href="http://github.com/nkallen/jquery-database/tree/master">Download the jquery.db.js library</a></p>]]>
[&lt;a href="http://www.hackszine.com/blog/archive/2008/04/relational_database_using_jque.html?CMP=OTC-7G2N43923558" /&gt;Read More&lt;/a&gt;]  
[&lt;a href="http://www.hackszine.com/blog/archive/2008/04/relational_database_using_jque.html?CMP=OTC-7G2N43923558#comments" /&gt;Comments&lt;/a&gt;]
</description>
<link>http://www.hackszine.com/blog/archive/2008/04/relational_database_using_jque.html?CMP=OTC-7G2N43923558</link>
<guid>http://www.hackszine.com/blog/archive/2008/04/relational_database_using_jque.html?CMP=OTC-7G2N43923558</guid>
<category>Ajax</category>
<pubDate>Tue, 08 Apr 2008 22:02:21 -0800</pubDate>

</item>

<item>
<title>Homebrew Google Analytics API</title>
<itunes:summary> It&apos;s too bad that Google Analytics doesn&apos;t have an official API, but Chris Riley came up with a fun solution for pushing analytics content into a format that is easily accessible from your web applications. Using Google Analytics&apos; scheduled...</itunes:summary>
<description>
<![CDATA[<p><img alt="analyticsapi_20080118.jpg" src="http://www.hackszine.com/analyticsapi_20080118.jpg" width="500" height="339" /></p>

<p>It's too bad that Google Analytics doesn't have an official API, but Chris Riley came up with a fun solution for pushing analytics content into a format that is easily accessible from your web applications.</p>

<p>Using Google Analytics' scheduled reporting feature, you can have an analytics report automatically sent to a public, read-only Google Group in XML format. From there, the group's latest post can be pulled in through Yahoo pipes where it is filtered and exposed as a JSON service, ready for you to pull into a web application via Javascript. Yoikes!</p>

<p>Chris' example shows you how to do this to add a popular posts feature to your blog. You should be able to tweak the code to export other information from Analytics as well, including geographic distribution, popular search terms, or even visitor and pageview data.</p>

<p>No Google Analytics API? No Problem! - <a href="http://blogoscoped.com/archive/2008-01-17-n73.html">Link</a></p>]]>
[&lt;a href="http://www.hackszine.com/blog/archive/2008/01/homebrew_google_analytics_api.html?CMP=OTC-7G2N43923558" /&gt;Read More&lt;/a&gt;]  
[&lt;a href="http://www.hackszine.com/blog/archive/2008/01/homebrew_google_analytics_api.html?CMP=OTC-7G2N43923558#comments" /&gt;Comments&lt;/a&gt;]
</description>
<link>http://www.hackszine.com/blog/archive/2008/01/homebrew_google_analytics_api.html?CMP=OTC-7G2N43923558</link>
<guid>http://www.hackszine.com/blog/archive/2008/01/homebrew_google_analytics_api.html?CMP=OTC-7G2N43923558</guid>
<category>Google</category>
<pubDate>Fri, 18 Jan 2008 21:04:43 -0800</pubDate>

</item>

<item>
<title>Server-side Javascript/DOM - search friendly AJAX?</title>
<itunes:summary>John Resig posted yesterday about his experiments with creating a full Javascript/DOM pseudo-browser environment that runs from the command line: This weekend I took a big step in upping the ante for JavaScript as a Language. At some point last...</itunes:summary>
<description>
<![CDATA[<p>John Resig posted yesterday about his experiments with creating a full Javascript/DOM pseudo-browser environment that runs from the command line:</p>

<blockquote>This weekend I took a big step in upping the ante for JavaScript as a Language. At some point last Friday evening I started coding and didn't stop until sometime mid-Monday. The result is a good-enough browser/DOM environment, written in JavaScript, that runs on top of Rhino; capable of running jQuery, Prototype, and MochiKit (at the very least).</blockquote>

<p>The really nice touch is that you can issue PUT and DELETE requests on the XMLHttpRequest object to manipulate files on the local file system!  Here's an example script that scrapes post titles from alistapart.com and stores them in a file (remember, this runs on the server like a shell script):</p>

<blockquote><pre>load("env.js");
window.location = "http://alistapart.com/";
window.onload = function(){
  load("dist/jquery.js");
  var str = "Newest A List Apart Posts:\n";
  $("h4.title").each(function(){
    str += " - " + this.textContent + "\n";
  });
  var out = new XMLHttpRequest();
  out.open("PUT", "file:/tmp/alist.txt");
  out.send( str );
};</pre></blockquote>]]>
[&lt;a href="http://www.hackszine.com/blog/archive/2007/07/serverside_javascriptdom_searc.html?CMP=OTC-7G2N43923558" /&gt;Read More&lt;/a&gt;]  
[&lt;a href="http://www.hackszine.com/blog/archive/2007/07/serverside_javascriptdom_searc.html?CMP=OTC-7G2N43923558#comments" /&gt;Comments&lt;/a&gt;]
</description>
<link>http://www.hackszine.com/blog/archive/2007/07/serverside_javascriptdom_searc.html?CMP=OTC-7G2N43923558</link>
<guid>http://www.hackszine.com/blog/archive/2007/07/serverside_javascriptdom_searc.html?CMP=OTC-7G2N43923558</guid>
<category>Ajax</category>
<pubDate>Tue, 10 Jul 2007 22:23:04 -0800</pubDate>

</item>

<item>
<title>Client-side SQL database in Javascript</title>
<itunes:summary> I was thinking today about how a person might go about creating a rich offline web application for devices like the iPhone, where your application may need to run entirely from cache from time to time. In the extreme...</itunes:summary>
<description>
<![CDATA[<p><img alt="trimquery_20070702.jpg" src="http://hackszine.com/trimquery_20070702.jpg" width="500" height="123" /></p>

<p>I was thinking today about how a person might go about creating a rich offline web application for devices like the iPhone, where your application may need to run entirely from cache from time to time.</p>

<p>In the extreme example, you could imagine an application that stored its data entirely on the client side, and used cached html and javascript files to manipulate that data.  Assuming you could get around the storage issue -- either via cookies, a Flash shared object (not available for the iPhone), Firefox or IEs storage objects, or some trickery with browser form autocompletion -- you'd still run into the task of manipulating that data.</p>

<p>Web developers are used to using an SQL database for the retrieval, joining and sorting of data, so it's convenient that similar functionality exists within Javascript, thanks to a small Javascript library called TrimQuery.  After defining a simple table schema, you can use TrimQuery to issue a subset of the standard SELECT syntax.  This will let you do something like the following, all within Javascript:</p>

<blockquote><pre>
selectStatement = queryLang.parseSQL( "SELECT table1.columna, table2.columnb 
  FROM table1, table2 
  WHERE table1.id = table2.fkid 
  ORDER BY table1.columna" );
var results = selectStatement.filter( tabledata );
for (var i = 0; i < results.length; i++) {
  var record = results[i];
  // ...
}
</pre></blockquote>

<p>TrimQuery Demo - <a href="http://trimpath.com/demos/test1/trimpath/query_demo.html">Link</a><br />
TrimQuery: Javascript SQL Library - <a href="http://code.google.com/p/trimpath/wiki/TrimQuery">Link</a></p>]]>
[&lt;a href="http://www.hackszine.com/blog/archive/2007/07/clientside_sql_database_in_jav.html?CMP=OTC-7G2N43923558" /&gt;Read More&lt;/a&gt;]  
[&lt;a href="http://www.hackszine.com/blog/archive/2007/07/clientside_sql_database_in_jav.html?CMP=OTC-7G2N43923558#comments" /&gt;Comments&lt;/a&gt;]
</description>
<link>http://www.hackszine.com/blog/archive/2007/07/clientside_sql_database_in_jav.html?CMP=OTC-7G2N43923558</link>
<guid>http://www.hackszine.com/blog/archive/2007/07/clientside_sql_database_in_jav.html?CMP=OTC-7G2N43923558</guid>
<category>Ajax</category>
<pubDate>Mon, 02 Jul 2007 19:45:50 -0800</pubDate>

</item>

<item>
<title>HOWTO use the Wiimote buttons in Flash</title>
<itunes:summary> A while back, WiiNintendo posted the keycodes that are detectable by Javascript when the Wii&apos;s buttons are pressed. With this ability, you can create Javascript games that will play on your Wii. Unfortunately, even though the Wii browser ships...</itunes:summary>
<description>
<![CDATA[<p><img alt="wiimote_20070620-1.jpg" src="http://hackszine.com/wiimote_20070620-1.jpg" width="500" height="381" /><br />
A while back, WiiNintendo posted the keycodes that are detectable by Javascript when the Wii's buttons are pressed.  With this ability, you can create Javascript games that will play on your Wii.  Unfortunately, even though the Wii browser ships with the Flash plugin, those keycodes cannot be detected natively in the Flash environment.</p>

<p>Quasimondo came up with a really clever hack that solves the problem.  You can create a second flash movie and use Javascript to resize it to specific widths for particular keycodes.  Even though Flash cannot detect the keycodes, it does receive an onResize event.  When it receives this event, it then retrieves its current width, which was set to the value of the keycode.  This second swf file can then use Flash's LocalConnection to communicate that value to the primary swf.</p>

<p>How to Make the Wiimote Work in Flash - <a href="http://www.quasimondo.com/archives/000638.php">Link</a><br />
Aral Balkan's discussion on using the Wiimote in Flash - <a href="http://aralbalkan.com/825">Link</a><br />
Wiimote Key Codes @ WiiNintendo - <a href="http://wiinintendo.net/2006/12/27/wiimote-d-pad-works-in-javascript-or-flash-games/">Link</a></p>]]>
[&lt;a href="http://www.hackszine.com/blog/archive/2007/06/howto_use_the_wiimote_buttons.html?CMP=OTC-7G2N43923558" /&gt;Read More&lt;/a&gt;]  
[&lt;a href="http://www.hackszine.com/blog/archive/2007/06/howto_use_the_wiimote_buttons.html?CMP=OTC-7G2N43923558#comments" /&gt;Comments&lt;/a&gt;]
</description>
<link>http://www.hackszine.com/blog/archive/2007/06/howto_use_the_wiimote_buttons.html?CMP=OTC-7G2N43923558</link>
<guid>http://www.hackszine.com/blog/archive/2007/06/howto_use_the_wiimote_buttons.html?CMP=OTC-7G2N43923558</guid>
<category>Gaming</category>
<pubDate>Wed, 20 Jun 2007 20:24:32 -0800</pubDate>

</item>

<item>
<title>Gears API: create web apps that work offline</title>
<itunes:summary> Google released a new Javascript API today called Gears that makes it possible to write modeless web applications that will function offline. A browser plugin is available for IE and Firefox (OS X, Linux, and Windows), with Safari support...</itunes:summary>
<description>
<![CDATA[<p><img alt="gears_20070530.jpg" src="http://hackszine.com/gears_20070530.jpg" width="500" height="205" /><br />
Google released a new Javascript API today called Gears that makes it possible to write modeless web applications that will function offline.  A browser plugin is available for IE and Firefox (OS X, Linux, and Windows), with Safari support planned for the near future.  The plugin will need to be installed by users of Gears-enabled applications.</p>

<p>From what I can see--and keep in mind that I haven't used the API yet--there are 3 basic services that the API provides:<br />
<ul><li>local file resource storage and caching so that you can view files after disconnecting</li><li>a client-side SQL database that can be used by Javascript to store and fetch data</li><li>a worker pool module for running asynchronous background processes</li></ul></p>

<p>The obvious use for this is to make stateful applications that continue to operate when you're offline, but maybe there are some privacy opportunities here too.  Today, applications come in primarily two varieties: apps with user data and software stored locally, and web-based applications that execute and store data on the server.  What I'm curious to see is if developers will begin making a third, hybrid category of application, where software release and maintenance is web-based and global data is available for local consumption, but the storage and processing of user-specific data takes place on the client side, safe from unwanted profiling.</p>

<p>Google Gears API Developer's Guide - <a href="http://code.google.com/apis/gears/index.html">Link</a></p>]]>
[&lt;a href="http://www.hackszine.com/blog/archive/2007/05/gears_api_create_web_apps_that.html?CMP=OTC-7G2N43923558" /&gt;Read More&lt;/a&gt;]  
[&lt;a href="http://www.hackszine.com/blog/archive/2007/05/gears_api_create_web_apps_that.html?CMP=OTC-7G2N43923558#comments" /&gt;Comments&lt;/a&gt;]
</description>
<link>http://www.hackszine.com/blog/archive/2007/05/gears_api_create_web_apps_that.html?CMP=OTC-7G2N43923558</link>
<guid>http://www.hackszine.com/blog/archive/2007/05/gears_api_create_web_apps_that.html?CMP=OTC-7G2N43923558</guid>
<category>Ajax</category>
<pubDate>Wed, 30 May 2007 19:36:14 -0800</pubDate>

</item>

<item>
<title>Unofficial Google Translate API</title>
<itunes:summary> The Unofficial Google Translate API is a combination javascript library and php service that allows you to do AJAX-style language translation. The PHP script serves as proxy to Google&apos;s Translate utility, passing data to and from Google on behalf...</itunes:summary>
<description>
<![CDATA[<p><img alt="gtranslate_20070425.jpg" src="http://hackszine.com/gtranslate_20070425.jpg" width="500" height="106" /><br />
The Unofficial Google Translate API is a combination javascript library and php service that allows you to do AJAX-style language translation.  The PHP script serves as proxy to Google's Translate utility, passing data to and from Google on behalf of the javascript code.</p>

<p>Unofficial Google Translate API -<a href="http://googlified.com/2006unofficial-google-translate-api/">Link.</a><br />
Inspired by Philipp Lenssen's Google Translate API "Announcement From 2009" -<a href="http://blog.outer-court.com/archive/2006-11-12-n11.html">Link.</a></p>]]>
[&lt;a href="http://www.hackszine.com/blog/archive/2007/04/unofficial_google_translate_ap.html?CMP=OTC-7G2N43923558" /&gt;Read More&lt;/a&gt;]  
[&lt;a href="http://www.hackszine.com/blog/archive/2007/04/unofficial_google_translate_ap.html?CMP=OTC-7G2N43923558#comments" /&gt;Comments&lt;/a&gt;]
</description>
<link>http://www.hackszine.com/blog/archive/2007/04/unofficial_google_translate_ap.html?CMP=OTC-7G2N43923558</link>
<guid>http://www.hackszine.com/blog/archive/2007/04/unofficial_google_translate_ap.html?CMP=OTC-7G2N43923558</guid>
<category>Language</category>
<pubDate>Wed, 25 Apr 2007 21:10:01 -0800</pubDate>

</item>

<item>
<title>Dynamic Javascript Chart Plotting With PlotKit</title>
<itunes:summary> PlotKit is a slick javascript library that allows you to easily generate line, bar, and pie charts with a few lines of javascript code. It supports rendering to both Canvas and SVG, so you can use it to add...</itunes:summary>
<description>
<![CDATA[<p><img alt="plotkit_20070418.jpg" src="http://hackszine.com/plotkit_20070418.jpg" width="500" height="539" /><br />
PlotKit is a slick javascript library that allows you to easily generate line, bar, and pie charts with a few lines of javascript code.  It supports rendering to both Canvas and SVG, so you can use it to add charting to your application and still be able to support a fair amount of browsers.</p>

<p>I'm glossing over some of the more advanced features, but check out how easy it is to generate a simple graph:<br />
<blockquote><code><br />
var data = [[0,0], [1,2], [2,3], [3, 7], [4, 8], [5, 6]];<br />
var plotter = EasyPlot("line", {}, $("example"), [data]);<br />
</code></blockquote><br />
That will plot the values from the "data" array and display it in a div with the ID "example".  Cool, no?</p>

<p>Charting from javascript is interesting, because it allows you to link in to data APIs that are provided by other services.  There's a link below to a tool that will pull in data from a published Google Spreadsheet and generate the necessary javascript to display widget graphs on another site.  It reminds me of how you can pull Excel graphs into a Word document, except javascript is the new, better OLE.  With output tools like PlotKit, online services like Google Spreadsheets, and open data APIs in between, there are just so many possibilities now for creating information that can be shared in a variety of formats.</p>

<ul><li><a href="http://www.liquidx.net/plotkit/">PlotKit</a></li><li><a href="http://imagine-it.org/google/spreadsheets/makechart.htm">Create a chart from a Google Spreadsheet</a></li></ul>]]>
[&lt;a href="http://www.hackszine.com/blog/archive/2007/04/dynamic_javascript_chart_plott.html?CMP=OTC-7G2N43923558" /&gt;Read More&lt;/a&gt;]  
[&lt;a href="http://www.hackszine.com/blog/archive/2007/04/dynamic_javascript_chart_plott.html?CMP=OTC-7G2N43923558#comments" /&gt;Comments&lt;/a&gt;]
</description>
<link>http://www.hackszine.com/blog/archive/2007/04/dynamic_javascript_chart_plott.html?CMP=OTC-7G2N43923558</link>
<guid>http://www.hackszine.com/blog/archive/2007/04/dynamic_javascript_chart_plott.html?CMP=OTC-7G2N43923558</guid>
<category>Ajax</category>
<pubDate>Wed, 18 Apr 2007 20:18:00 -0800</pubDate>

</item>

<item>
<title>Picasa Data API</title>
<itunes:summary>Take a peek at Google&apos;s new GData API for Picasa. In addition to providing RSS feeds for albums, tagged photos and user comments, you can use the API to add and remove photos, albums, comments and tags from your own...</itunes:summary>
<description>
<![CDATA[<p>Take a peek at Google's new GData API for Picasa.  In addition to providing RSS feeds for albums, tagged photos and user comments, you can use the API to add and remove photos, albums, comments and tags from your own applications.  This might be a nice way to manage image data (and offload image storage) within a web app.</p>

<p><b>Resources:</b><br />
<ul><li><a href="http://code.google.com/apis/picasaweb/gdata.html">Picasa API documentation</a></li><li><a href="http://code.google.com/apis/gdata/clientlibs.html">Picasa client libraries for PHP, Java, and .Net</a></li></ul></p>]]>
[&lt;a href="http://www.hackszine.com/blog/archive/2007/03/picasa_data_api.html?CMP=OTC-7G2N43923558" /&gt;Read More&lt;/a&gt;]  
[&lt;a href="http://www.hackszine.com/blog/archive/2007/03/picasa_data_api.html?CMP=OTC-7G2N43923558#comments" /&gt;Comments&lt;/a&gt;]
</description>
<link>http://www.hackszine.com/blog/archive/2007/03/picasa_data_api.html?CMP=OTC-7G2N43923558</link>
<guid>http://www.hackszine.com/blog/archive/2007/03/picasa_data_api.html?CMP=OTC-7G2N43923558</guid>
<category>Google</category>
<pubDate>Mon, 26 Mar 2007 20:06:47 -0800</pubDate>

</item>

<item>
<title>Simple Zip Code Geocoding</title>
<itunes:summary> The ability to geocode, or translate into latitude and longitude, postal codes is a fairly useful hack to have in your programming toolbox. Quick and dirty zip geocoding allows you to do some neat things fairly efficiently and with...</itunes:summary>
<description>
<![CDATA[<p><img alt="mpls_20070203.jpg" src="http://www.hackszine.com/blog/archive/mpls_20070203.jpg" width="500" height="212" /></p>

<p>The ability to geocode, or translate into latitude and longitude, postal codes is a fairly useful hack to have in your programming toolbox.  Quick and dirty zip geocoding allows you to do some neat things fairly efficiently and with a minimal amount of code.  Though it's U.S. centric, it allows you to add location-based functionality to your apps without requiring any real personal information to be transfered or stored.</p>

<p>If your application only needs to convert a zip code (or any address) into a lat/lon coordinate, say for simple mapping purposes, the easiest solution is  to use the <a href="http://www.google.com/apis/maps/documentation/#Geocoding_Examples">Google Maps Geocoding API</a>.  In addition to the client-side javascript functionality, you can directly query the geocoding system from php using an http request like this:</p>

<p><code>http://maps.google.com/maps/geo?q=12345&output=xml&key=yourkeyhere</code></p>

<p>Just change 12345 to the zip (or any address) that you are looking up, and "yourkeyhere" should be your Google Map API key, which you can obtain <a href="http://www.google.com/apis/maps/signup.html">here</a>.  Developer.com has a good <a href="http://www.developer.com/db/article.php/3621981">PHP example</a> for making use of the returned XML in your server-side code.</p>

<p>Often times, it's useful to be able to do zip lookups based on a geographic region.  Maybe you want a list of all zip codes within a certain radius or bounding box.  Applications for this could include clustering map items that are near eachother, or searching a database for items that are nearest to a given location.  For this, it's really nice to have a MySQL table that contains zip codes along with their lat/lon coordinates.  Fortunately, several people have compiled this sort of information from public domain data, and you can even download a full <a href="http://nerdvittles.com/index.php?p=160">MySQL table dump here</a>, for free.</p>

<p>At this point, it's a pretty simple matter to query the database for location-based information.  For instance, let's say you have a web site with a guestbook that allows guests to leave their name and zip.  You could easily whip up an application that tells your guests how many other guests are in their area by using a basic bounding box with a query like this:</p>

<p><code>SELECT guest.name from guest, zipcode<br />
WHERE guest.zip = zipcode.zip<br />
AND zipcode.lat < [maxlat] AND zipcode.lat > [minlat]<br />
AND zipcode.lng < [maxlng] AND zipcode.lng > [minlng]</code></p>

<p>These are just a few ideas, but hopefully this should be enough to get you started.  If you have some good ideas for other geocoding applications (or any mapping/gis hacks in general), please give us a shout in the comments.</p>]]>
[&lt;a href="http://www.hackszine.com/blog/archive/2007/02/simple_zip_code_geocoding.html?CMP=OTC-7G2N43923558" /&gt;Read More&lt;/a&gt;]  
[&lt;a href="http://www.hackszine.com/blog/archive/2007/02/simple_zip_code_geocoding.html?CMP=OTC-7G2N43923558#comments" /&gt;Comments&lt;/a&gt;]
</description>
<link>http://www.hackszine.com/blog/archive/2007/02/simple_zip_code_geocoding.html?CMP=OTC-7G2N43923558</link>
<guid>http://www.hackszine.com/blog/archive/2007/02/simple_zip_code_geocoding.html?CMP=OTC-7G2N43923558</guid>
<category>Mapping</category>
<pubDate>Sat, 03 Feb 2007 21:42:45 -0800</pubDate>

</item>


</channel>
</rss>