<?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>Gen X Design &#124; Ian Selby &#187; JavaScript</title>
	<atom:link href="http://www.gen-x-design.com/categories/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.gen-x-design.com</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Fri, 15 Jan 2010 21:41:43 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Installing Aptana Jaxer on Ubuntu</title>
		<link>http://www.gen-x-design.com/archives/installing-aptana-jaxer-on-ubuntu/</link>
		<comments>http://www.gen-x-design.com/archives/installing-aptana-jaxer-on-ubuntu/#comments</comments>
		<pubDate>Tue, 06 Jan 2009 22:44:25 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[Aptana]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Jaxer]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://www.gen-x-design.com/?p=150</guid>
		<description><![CDATA[
It&#8217;s been a while since I&#8217;ve written about Jaxer, and it&#8217;s a shame, because there&#8217;s been a lot of major changes over the past several months.  Anyway, I&#8217;ve been getting back into server-side javascript hacking, and found myself needing to get Jaxer up and running on a local dev server (and subsequently this one). [...]]]></description>
			<content:encoded><![CDATA[<div style="text-align: center"><img style="margin-top: 10px; margin-bottom: 10px; padding: 2px; border: 1px solid #ccc;"src="http://www.gen-x-design.com/wp-content/uploads/2009/01/jaxer-and-ubuntu.png" alt="Install Aptana Jaxer on Ubuntu" title="Install Aptana Jaxer on Ubuntu" width="580" height="120" /></div>
<p>It&#8217;s been a while since I&#8217;ve written about Jaxer, and it&#8217;s a shame, because there&#8217;s been a lot of major changes over the past several months.  Anyway, I&#8217;ve been getting back into server-side javascript hacking, and found myself needing to get Jaxer up and running on a local dev server (and subsequently this one).  You could also always work with Jaxer in Aptana&#8217;s <a href="http://www.aptana.com/cloud" target="_blank">cloud</a>, where you&#8217;d get all the benefits of Jaxer integration with Aptana Studio and deployment workflows (SVN, staging, production, and just plain awesomeness) if you don&#8217;t want to (or need to) install Jaxer yourself.  However, my needs (and presumably yours) required me to go down this route.</p>
<p>So, before we get started, let&#8217;s go over the list of prerequisites and assumptions:</p>
<ul>
<li>You&#8217;re on Ubuntu 8.04 (newer versions should work the same as well)</li>
<li>You&#8217;ve got Apache installed (via aptitude, or you will have to adjust paths accordingly)</li>
<li>You&#8217;ve got root access to your server</li>
</ul>
<p>That&#8217;s about it.  MySQL is also good to have, but not required.  Last thing before we start: many of the steps outlined here came from <a href="http://doc.integrasoftware.it/tec/sis/pub/jaxer" target="_blank">this site</a>, which was contributed by a Jaxer user at Aptana&#8217;s forums.  Right, let&#8217;s get busy&#8230;<br />
<span id="more-150"></span></p>
<h3>Step 1: Get Jaxer</h3>
<p>As you would expect, the first thing we&#8217;ll do is grab the latest version of Jaxer.  However, before we do so, let&#8217;s make sure we know whether we&#8217;re on a 64 or 32-bit version of Ubuntu.  Easy enough, from the command line:</p>
<pre>uname -a</pre>
<p>which outputs something like:</p>
<pre>Linux genxdesign 2.6.24-19-xen #1 SMP Sat Jul 12 00:15:59 UTC 2008 x86_64 GNU/Linux</pre>
<p>You can see, in my case I&#8217;m on 64 bit, as indicated by the &#8220;x86_64&#8243;.  Now that we&#8217;ve got that, we can head over to <a href="http://aptana.com/jaxer/download" target="_blank">http://aptana.com/jaxer/download</a>, and grab the appropriate linux distribution.  Easiest way to do so is to right-click on the link, select &#8220;Copy link location&#8221;, and then use it in the following command on your sever:</p>
<pre>wget [pasted url]</pre>
<p>Of course, you could also download it locally, then unzip and upload it to your server.  I am assuming that you&#8217;re doing all this in your home directory on the server.  Note also that the way the downloads work with Jaxer currently may give you a goofy file with wget.  For example, at the time of writing, my wget url was &#8220;http://ec2-67-202-37-218.compute-1.amazonaws.com/downloads/jaxer/ubu64/Jaxer_package_withApache.zip?version=1.0.1.4310&#038;cb=1000&#8243; which gave me a file called: &#8220;Jaxer_package_withApache.zip?version=1.0.1.4310&#8243; on the file system.  Not an issue, I can fix this by doing:</p>
<pre>mv Jaxer_package_withApache.zip\?version\=1.0.1.4310 jaxer.zip</pre>
<p>Finally, on the server, simply type:</p>
<pre>unzip jaxer.zip</pre>
<p>to unzip the file.</p>
<p>Once the file&#8217;s unzipped or uploaded to your server, we&#8217;ll need to move the contents to their final home in /opt.  So, back in your home directory:</p>
<pre>sudo mv AptanaJaxer/ /opt</pre>
<p>and we&#8217;re golden!</p>
<h3>Step 2: Get the Mozilla Stuff</h3>
<p>This is a bit easier than grabbing Jaxer itself, just one command:</p>
<pre>sudo apt-get install firefox-3.0-dev firefox-dev</pre>
<p>which we&#8217;ll follow with on more to make sure our libraries line up properly:</p>
<pre>sudo ln -s /usr/lib/libexpat.so.1 /usr/lib/libexpat.so.0</pre>
<p>That&#8217;s all we&#8217;ve got to do for Mozilla.  Onward&#8230;</p>
<h3>Step 3: Configure and Start</h3>
<p>Believe it or not, we&#8217;re nearly done.  At this point, we need to slurp out the Apache module configs from the Jaxer directory, and put them in the appropriate place for our Apache on Ubuntu.  Two simple commands will take care of this:</p>
<pre>sudo sh -c "grep '^LoadModule' /opt/AptanaJaxer/jaxer/confs/jaxer-linux.httpd.conf > /etc/apache2/mods-available/jaxer-linux.httpd.load"
sudo sh -c "grep -v '^LoadModule' /opt/AptanaJaxer/jaxer/confs/jaxer-linux.httpd.conf > /etc/apache2/mods-available/jaxer-linux.httpd.conf"</pre>
<p>Now that we&#8217;ve got the module configs in the right place, we can enable the module for Apache by doing the following:</p>
<pre>sudo a2enmod jaxer-linux.httpd</pre>
<p>It will tell you that you need to reload apache.  Don&#8217;t do that just yet.  First, we need to let Jaxer create some directories, so let&#8217;s start Jaxer:</p>
<pre>sudo JAXERBASE=/opt/AptanaJaxer /opt/AptanaJaxer/scripts/startJaxer.sh</pre>
<p>Don&#8217;t worry about any warnings you see, those are just about Jaxer setting things up for the first time (similar to the first run of MySQL in a fresh install).  We can go ahead and stop jaxer now, and then restart Apache:</p>
<pre>sudo JAXERBASE=/opt/AptanaJaxer /opt/AptanaJaxer/scripts/stopJaxer.sh
sudo /etc/init.d/apache2 restart</pre>
<p>if you don&#8217;t get any warnings or errors from Apache, go ahead and start Jaxer again:</p>
<pre>sudo JAXERBASE=/opt/AptanaJaxer /opt/AptanaJaxer/scripts/startJaxer.sh</pre>
<p>and you should be all set!  If there aren&#8217;t any errors being spit out by anything, you can now browse to the Jaxer url on your server: http://yourdomain.com/aptana, and then run the server diagnostics.  If everything&#8217;s working right, you&#8217;ll see some spinners, and then a screen that looks similar to this one:</p>
<div style="text-align: center; margin: 10px; font-size: 10px;"><a href="http://www.gen-x-design.com/wp-content/uploads/2009/01/picture-3.png"><img src="http://www.gen-x-design.com/wp-content/uploads/2009/01/picture-3-300x201.png" alt="Jaxer Server Diagnostics" title="Jaxer Server Diagnostics" width="300" height="201" style="border: 1px solid #ccc; padding: 2px;" /></a><br />click image for larger view</div>
<p>Just a few more things to do now&#8230;</p>
<h3>Step 4: Configure Apache</h3>
<p>Well, what we&#8217;ve currently got is Jaxer set up and running properly, but it isn&#8217;t set up for any of our sites.  To do this, you&#8217;ll have to add a few lines to your vhost configuration(s) wherever you&#8217;d like Jaxer to actually run on your web site.  For this example, I&#8217;ll assume you&#8217;re using the &#8220;default&#8221; site that comes with the standard Apache install on Ubuntu, but you can simply put these lines wherever you need them in your vhost files.</p>
<p>So, what we&#8217;re basically going to do here is tell Apache to use Jaxer as a filter for certain files in our web site.  We do this by adding some directives in the appropriate &#8220;<Directory>&#8221; area of our config.  Let&#8217;s take a look at what a typical config might look like.  If you type the following:</p>
<pre>sudo vi /etc/apache2/sites-available/default</pre>
<p>we&#8217;re looking for a section of the file that looks like:</p>
<pre>&lt;Directory /var/www/>
        Options Indexes FollowSymLinks MultiViews
        AllowOverride All 

        Order allow,deny
        allow from all
&lt;/Directory></pre>
<p>Yours will probably be a bit different, but we&#8217;re basically looking for the directory directive that refers to the document root for this vhost (&#8217;/var/www&#8217; in this case).  Once you&#8217;ve located that, you need to add the following lines anywhere in there:</p>
<pre>JaxerFilter html xhtml htm php
JaxerFilterContentType text/html application/xhtml+xml</pre>
<p>What we&#8217;ve done is told Apache to run any html, xhtml, or php page through Jaxer as a filter (which is what we typically want).  Once you&#8217;ve added these lines, you can stop Jaxer, restart Apache, and start Jaxer again:</p>
<pre>sudo JAXERBASE=/opt/AptanaJaxer /opt/AptanaJaxer/scripts/stopJaxer.sh
sudo /etc/init.d/apache2 restart
sudo JAXERBASE=/opt/AptanaJaxer /opt/AptanaJaxer/scripts/startJaxer.sh</pre>
<p>And that&#8217;s all there is to it!</p>
<h3>A Few More Things&#8230;</h3>
<p>Now that we&#8217;ve got everything running properly, I wanted to share a script to make starting / stopping Jaxer a bit easier, and a gotcha with URL re-writes you need to watch out for.</p>
<p>First, the control script.  I am by no means a bash guru, and this script could use some major improvement.  If you would like to improve upon it, let me know, I&#8217;d greatly appreciate it.  Anyway, it does get the job done just fine.  So, let&#8217;s go ahead and install it:</p>
<pre>wget http://www.gen-x-design.com/downloads/jaxer_control.txt
sudo cp jaxer_control.txt /etc/init.d/jaxer
sudo chmod +x /etc/init.d/jaxer</pre>
<p>Now, you can simply type &#8220;sudo /etc/init.d/jaxer [start|stop]&#8221; to start or stop Jaxer!  Much easier than remembering that crazy sh file location.</p>
<p>Second, URL re-write gotchas.  When I installed Jaxer on this server, I discovered the wordpress rewrite rules were breaking some special Jaxer urls needed for everything to function properly.  Here&#8217;s what a typical offending set of rewrite rules could look like (in a .htaccess file, for example):</p>
<pre>&lt;IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
&lt;/IfModule></pre>
<p>Well, this breaks Jaxer, because the URL rewrites take precedence over the LocationMatch directives in the jaxer module configuration.  As I said, we can luckily fix this problem by adding one line, thus making our rewrite rules look like:</p>
<pre>&lt;IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !^/jaxer-.*\b
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
&lt;/IfModule></pre>
<p>So that the special Jaxer URLs aren&#8217;t redirected (in this case) to index.php.</p>
<h3>Wrapping Up</h3>
<p>And that&#8217;s it!  Hopefully you find this quick and easy, and then you can get started with Jaxer, thus discovering how damn cool server-side javascript is.  If you&#8217;d like to learn more about Jaxer, or need help, here are some useful URLs:</p>
<ul>
<li><strong>Jaxer Docs</strong> &#8211; <a href="http://www.aptana.com/jaxer/guide/" target="_blank">http://www.aptana.com/jaxer/guide/</a></li>
<li><strong>Jaxer Forums</strong> &#8211; <a href="http://forums.aptana.com/viewforum.php?f=51" target="_blank">http://forums.aptana.com/viewforum.php?f=51</a></li>
<li><strong>Jaxer Home Page</strong> &#8211; <a href="http://www.aptana.com/jaxer" target="_blank">http://www.aptana.com/jaxer</a></li>
<li><strong>Aptana Cloud</strong> &#8211; The much better, easier way to work with Jaxer.  Get a free trial! <a href="http://www.aptana.com/cloud" target="_blank">http://www.aptana.com/cloud</a>.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.gen-x-design.com/archives/installing-aptana-jaxer-on-ubuntu/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Hello Gen-X-Design</title>
		<link>http://www.gen-x-design.com/archives/hello-gen-x-design/</link>
		<comments>http://www.gen-x-design.com/archives/hello-gen-x-design/#comments</comments>
		<pubDate>Thu, 27 Nov 2008 06:10:19 +0000</pubDate>
		<dc:creator>Davey</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Jaxer]]></category>
		<category><![CDATA[davey]]></category>

		<guid isPermaLink="false">http://www.gen-x-design.com/?p=74</guid>
		<description><![CDATA[Hi all.
This is just a short post to introduce myself. The talented Mr Selby has kindly invited me on board to blog about my experiences with mad scientist level JavaScript.

My names Davey and I work with Ian at Aptana, my role there is JavaScript Architect and as I result I spend a lot of time [...]]]></description>
			<content:encoded><![CDATA[<p>Hi all.</p>
<p>This is just a short post to introduce myself. The talented Mr Selby has kindly invited me on board to blog about my experiences with mad scientist level JavaScript.</p>
<p style="center;"><a href="http://gxdlabs.com/wp-content/uploads/2008/11/img_05571.jpg"><img class="size-medium wp-image-75 aligncenter" src="http://www.gen-x-design.com/wp-content/uploads/2008/11/img_0557-300x225.jpg" alt="" width="300" height="225" /></a></p>
<p>My names Davey and I work with Ian at Aptana, my role there is JavaScript Architect and as I result I spend a lot of time rooting around in the arcane depths of spidermonkey. I&#8217;m predominately interested in the topic of server side JS as it appears in our Jaxer product but occasionally venture out into the hostile environment that exists on the client.</p>
<p>I have an article primed and ready to go, but just need to put some finishing touches to it before publishing, In it I explore how to reproduce some of the interesting PHP capabilities that Ian is the master of. So it you have ever wanted to have the equivalent of __FILE__ or the __autoload function in javascript, keep watching all will be revealed soon.</p>
<p>As a first tip to any would-be JavaScript ninja, I heartily recommend The Douglas Crockford book &#8216;JavaScript, the good parts&#8217;, it&#8217;s just choc full o&#8217; goodness.</p>
<p>cheers</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gen-x-design.com/archives/hello-gen-x-design/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Server-Side JavaScript Talk Slides &amp; Source</title>
		<link>http://www.gen-x-design.com/archives/server-side-javascript-talk-slides-source/</link>
		<comments>http://www.gen-x-design.com/archives/server-side-javascript-talk-slides-source/#comments</comments>
		<pubDate>Wed, 29 Oct 2008 20:38:12 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Jaxer]]></category>

		<guid isPermaLink="false">http://www.gen-x-design.com/?p=67</guid>
		<description><![CDATA[It&#8217;s well overdue, but I&#8217;ve finally managed to get this stuff up.  Here are the slides from my presentation on Server-Side JavaScript, as well as the source code for the Jaxer REST API provider and consumers that I wrote.
I will do a post in the near future going over the code, and some of [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s well overdue, but I&#8217;ve finally managed to get this stuff up.  Here are the slides from my presentation on Server-Side JavaScript, as well as the source code for the Jaxer REST API provider and consumers that I wrote.</p>
<p>I will do a post in the near future going over the code, and some of the configuration tweaks that I made, but hopefully this will hold you over until then.</p>
<p><a href="http://www.gen-x-design.com/downloads/jaxer_rest_api.zip">Source Code</a></p>
<div style="width:425px;text-align:left" id="__ss_702151"><a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/ianselby/serverside-javascript-presentation?type=powerpoint" title="Server-Side JavaScript">Server-Side JavaScript</a><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=ssjs-presentation-1225296059165368-8&#038;stripped_title=serverside-javascript-presentation" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=ssjs-presentation-1225296059165368-8&#038;stripped_title=serverside-javascript-presentation" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object>
<div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;">View SlideShare <a style="text-decoration:underline;" href="http://www.slideshare.net/ianselby/serverside-javascript-presentation?type=powerpoint" title="View Server-Side JavaScript on SlideShare">presentation</a> or <a style="text-decoration:underline;" href="http://www.slideshare.net/upload?type=powerpoint">Upload</a> your own. (tags: <a style="text-decoration:underline;" href="http://slideshare.net/tag/javascript">javascript</a> <a style="text-decoration:underline;" href="http://slideshare.net/tag/server">server</a>)</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.gen-x-design.com/archives/server-side-javascript-talk-slides-source/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Jaxer 1.0 Now Available (RC B)</title>
		<link>http://www.gen-x-design.com/archives/jaxer-10-now-available-rc-b/</link>
		<comments>http://www.gen-x-design.com/archives/jaxer-10-now-available-rc-b/#comments</comments>
		<pubDate>Tue, 05 Aug 2008 18:46:04 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Jaxer]]></category>

		<guid isPermaLink="false">http://www.gen-x-design.com/archives/jaxer-10-now-available-rc-b/</guid>
		<description><![CDATA[It&#8217;s been awhile since I&#8217;ve made any mention of Jaxer, and for good reason. The Jaxer team at Aptana has been hard at work getting Jaxer ready for 1.0 Release. That day has come, and I&#8217;m proud the first publicly available version of Jaxer 1.0: Jaxer 1.0 RCB. As far as functionality goes, this release [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been awhile since I&#8217;ve made any mention of Jaxer, and for good reason. The Jaxer team at <a href="http://www.aptana.com" target="_blank">Aptana</a> has been hard at work getting Jaxer ready for 1.0 Release. That day has come, and I&#8217;m proud the first publicly available version of Jaxer 1.0: Jaxer 1.0 RCB. As far as functionality goes, this release is pretty much feature-complete, and we just need some people to kick the tires a bit before we officially tag it as 1.0.</p>
<p>So, what&#8217;s new in this version of Jaxer? Quite a bit, actually, and if you&#8217;ve been using 0.9x releases of Jaxer until now, a lot has changed for you as well. As usual, Jaxer is available bundled into <a href="http://www.aptana.com/studio" target="_blank">studio</a> (starting with the recently released 1.2 version), as well as the usual stand-alone. Read on for a full summary of what&#8217;s new&#8230;</p>
<p><span id="more-60"></span></p>
<p>So, here&#8217;s a quick run-down of the shiny new version of Jaxer:</p>
<ul>
<li>Application context settings that allowing for easier app configuration, app properties, database settings, etc&#8230;</li>
<li>Database API enhancements with richer APIs for working with result sets.</li>
<li>Server-side image manipulation including server-side canvas support and ability to convert to other image types.</li>
<li>Native command execution API so that you can run system commands and handle the output from those.</li>
<li>Asynchronous server-side JavaScript processing lets you implement callbacks in your server-side code too.</li>
<li>Ability to return custom content types (e.g. json, xml, gif, html, etc&#8230;)</li>
<li>Full control of the request/response lifecycle including setting redirects, headers, content, etc&#8230;</li>
<li>Secure sandbox supporting cross domain calls, sandboxed JavaScript execution, META refreshes, &#8230;</li>
<li>Serialization support for JavaScript objects to and from XML, E4X and JSON</li>
</ul>
<p>Pretty cool stuff, huh? What&#8217;s really exciting to me (outside the functionality that was already there previously, such as database and filesystem access), is the ability to return custom content types, specifically JSON. JSON returns are nice since the server-side is already natively JavaScript, as well as the fact that this means creating JSON data services for your existing apps becomes a snap. If JSON&#8217;s not your cup of tea (and you&#8217;re crazy if it isn&#8217;t), or perhaps you need to deal with XML for whatever reason, the E4X (native XML for JS) support being baked in is also nice. This essentially means that you can use Jaxer as a JSON or XML service provider to not only Ajax clients, but other things like flash / flex, Silverlight, and more. Writing your own RESTful API in JavaScript = crazy delicious!</p>
<p>Another interesting feature that I have yet to play with personally is the new secure sandbox. What this essentially lets you do is load pages (or page fragments) on the server from other domains and let their JS execute without giving them access to the Jaxer API, or any of your other server-side code. Why is this neat, you may ask? Well, if you are aggregating content from a site (news.com in several of the Jaxer samples), the content you&#8217;re retrieving may have some JS code that could get evaluated. Before the sandbox existed, this meant a bunch of JS errors would bubble up to the client-side related to this JS code. No longer&#8230; and obviously this is also important as it means nobody could try and compromise your system by modifying the content you fetch to try and execute destructive statements (i.e. &#8220;DROP DATABASE&#8221;). Obviously, there&#8217;s a lot of room for neat mash-ups with this new goodness, and Uri Sarid has written a nice article on <a href="http://www.aptana.com/blog/uri/dom_scraping_with_jaxer_part_2" target="_blank">DOM Scraping with Jaxer</a>.</p>
<p>I hope to be cooking up some new articles related to this release in the coming days, and will definitely be covering this stuff in my upcoming speaking engagements. For now, enjoy these links:</p>
<ul>
<li><a href="http://www.aptana.com/studio/download" target="_blank">Download Aptana Studio w/ Jaxer 1.0 RC B</a></li>
<li><a href="http://www.aptana.com/jaxer/download" target="_blank">Download Jaxer 1.0 RC B Server and Stand-Alone</a></li>
<li><a href="http://www.aptana.com/docs/index.php/Migrating_from_Jaxer_beta" target="_blank">Learn about all the new goodness, and how to migrate from 0.x releases of Jaxer</a></li>
<li><a href="http://forums.aptana.com/index.php?c=12" target="_blank">Tell us what you love, or hate in the forums</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.gen-x-design.com/archives/jaxer-10-now-available-rc-b/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Server-Side JavaScript &#8211; All the Cool Kids Are Doing It!</title>
		<link>http://www.gen-x-design.com/archives/server-side-javascript-all-the-cool-kids-are-doing-it/</link>
		<comments>http://www.gen-x-design.com/archives/server-side-javascript-all-the-cool-kids-are-doing-it/#comments</comments>
		<pubDate>Fri, 06 Jun 2008 23:30:42 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Jaxer]]></category>

		<guid isPermaLink="false">http://www.gen-x-design.com/?p=53</guid>
		<description><![CDATA[That&#8217;s right kids, I&#8217;m speaking at the 6th International AJAX World RIA Conference &#038; Expo!  I&#8217;ll be giving a session on server-side javascript, and how it will make your life better, your apps cooler, and your friends jealous!
Read the full entry for details on the session, but here&#8217;s a little introductory overview (for the [...]]]></description>
			<content:encoded><![CDATA[<p>That&#8217;s right kids, I&#8217;m speaking at the 6th International AJAX World RIA Conference &#038; Expo!  I&#8217;ll be giving a session on server-side javascript, and how it will make your life better, your apps cooler, and your friends jealous!</p>
<p>Read the full entry for details on the session, but here&#8217;s a little introductory overview (for the sake of not re-writing everything, I have just copied and pasted the announcement)&#8230;</p>
<blockquote><p>Server-side JavaScript (SSJS) is growing in popularity fast since developers realize it can drastically simplify Web app creation by letting you use using the same technology stack on both the client and the server. While server-side JavaScript is not new &#8211; it was a part of Netscape’s vision 10 years ago &#8211; times have significantly changed with 10x faster hardware and networks, making that original vision for the Web now a reality.</p>
<p>In this session delegates will learn how to:</p>
<ul>
<li>Overcome common hurdles and pitfalls of client-side only JavaScript development.</li>
<li>Speed up development time by cutting out extra server-side code and processing scripts that are no longer necessary.</li>
<li>Clean up your code base by reducing (or even eliminating) the number of languages needed to leverage to accomplish common tasks (i.e. Why bother with server-side PHP scripts to fetch database results when you can do it all in JavaScript on the server? Why mess with Curl to fetch content that your JavaScript code can grab in one line?)</li>
</ul>
</blockquote>
<p><span id="more-53"></span><br />
Selby will also get hands-on with a live demonstration of how to:</p>
<ul>
<li>Create JSON data services for your Ajax, Flash, Flex and Silverlight apps</li>
<li>Implement JavaScript RMI</li>
<li>Use your favorite Ajax libraries server-side.</li>
<li>Manipulate the DOM server-side</li>
<li>Talk to databases, file systems, networks, and remote sites or services (cross-domain XHRs are now a possibility!</li>
</ul>
<p>The session will show Web developers how they can put their JavaScript skills to work on the server side using technologies like Mozilla Rhino and <a href="http://www.aptana.com/jaxer" target="_blank">Aptana Jaxer</a>, which embeds the entire Mozilla browser on the server side.</p>
<h2>About AjaxWorld&#8230;</h2>
<p>AJAXWorld RIA Conference &#038; Expo 2008 West<br />
The days when AJAX is the only game in town are over, and the 6th International AJAXWorld RIA Conference &#038; Expo in San Jose, CA, on October 20-22, 2008 is your chance to come and see it and hear it for yourself.</p>
<p>Because it&#8217;s easy to misjudge priorities and invest in the wrong technology, AJAXWorld will help you invest in the right one for your particular business. It will help you find the optimal balance between business needs, technology potential, and enhanced user experience. AJAXWorld RIA Conference &#038; Expo 2008 West is where you can find what you&#8217;re going to need for business survival and Web success in 2008, 2009 and beyond.</p>
<p>AJAXWorld&#8217;s 80+ technical sessions, Keynotes, Power Panels and General Session Demos will help you determine which Rich Internet Technology will provide the most meaningful impact in your business, organization or service. The conference program aims to inform and inspire you toward the detailed implementation plan that you&#8217;re going to need in the next 12 months in your own initiative whether that&#8217;s SaaS, financial services, healthcare, enterprise portals, ISV applications, or whatever.</p>
<p>The Expo floor additionally will allow you to follow up on the premier solutions already available and to choose which best suits your needs.</p>
<p><a href="http://www.ajaxworld.com/" target="_blank">http://www.ajaxworld.com/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.gen-x-design.com/archives/server-side-javascript-all-the-cool-kids-are-doing-it/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Make Your JavaScript Data Model Smarter &#8211; With Object.Event</title>
		<link>http://www.gen-x-design.com/archives/make-your-data-javascript-data-model-smarter/</link>
		<comments>http://www.gen-x-design.com/archives/make-your-data-javascript-data-model-smarter/#comments</comments>
		<pubDate>Fri, 06 Jun 2008 17:26:26 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.gen-x-design.com/?p=50</guid>
		<description><![CDATA[As today&#8217;s web applications continue to evolve and get more complex, it has become a lot more commonplace to keep a data model present inside of your javascript.  You would then write various widgets, modules, or whatever that would get their data from the model, rather than querying some other web service independently (and [...]]]></description>
			<content:encoded><![CDATA[<p>As today&#8217;s web applications continue to evolve and get more complex, it has become a lot more commonplace to keep a data model present inside of your javascript.  You would then write various widgets, modules, or whatever that would get their data from the model, rather than querying some other web service independently (and if you aren&#8217;t doing this, you should!).  While centralizing all your data into a nice, organized model that different parts of your code can access, it&#8217;s often a challenge to integrate an efficient way to notify the code that depends on these models when the stored data is updated.  Lucky for us, <a href="http://livepipe.net/" target="_blank">Ryan Johnson</a> has created a  surprisingly small library that will allow our data model to notify anything that depends on it that it has updated (or loaded, or whatever you&#8217;d like in fact).</p>
<p>Before we dig in to the notifications, let&#8217;s do a little work to set up an example and some assumptions we&#8217;ll be operating under for the sake of this article.  First, as <a href="http://prototypejs.org" target="_blank">prototype</a> is my weapon of choice, that&#8217;s what we&#8217;ll be using.  We&#8217;ll also be using prototype as Object.Event uses it as well!  Now, let&#8217;s pretend that we have a website that has some social networking aspect of some kind.  We want to display a short list of who&#8217;s currently online (say the 6 most recently active people) in some sort of side bar, and perhaps a count of the total members online in a footer element.  Rather than having both these elements poll the server at some interval to update their information, let&#8217;s create a little data model that these areas can use instead.<br />
<span id="more-50"></span></p>
<h2>Step 1 &#8211; Create a Data Model</h2>
<p>For the sake of brevity, this will be stubbed out in a lot of places, but we&#8217;ll create enough functionality to get the concepts across.</p>
<pre name="code" class="javascript">var WhosOnlineSummary = Class.create(
{
    initialize: function initialize()
    {
        this.totalOnlineUsers   = 0;
        this.whosOnline         = new Hash();
        this.loading            = true;

        // do our initial fetch
        this.fetchUsers();

        // set this up to poll for new data every thirty seconds...
        this.dataPoller = new PeriodicalExecuter(function(pe)
        {
            this.fetchUsers();
        }.bind(this), 30);
    },

    fetchUsers: function fetchUsers()
    {
        // this would probably do some other stuff too

        new Ajax.Request('/your/data/service',
        {
            onComplete: function(response)
            {
                this.update(response.responseText);
            }.bind(this)
        })
    },

    update: function update(data)
    {
        // and you'd have some sort of logic
        // here to update the data... here's a stub..

        // I'm assuming the data returned is a JSON object here...

        if('totalOnlineUsers' in data)
        {
            this.totalOnlineUsers = data.totalOnlineUsers;
        }

        // and update our "who's online" stuff...
        if('onlineUsers' in data)
        {
            // simple way to refresh, just kill the current list
            this.whosOnline = new Hash();

            // pretend online users is an array of json objects here...
            // [ { id: userId, name: username, etc.}, {...}, ... ]
            data.onlineUsers.each(function(user)
            {
                this.whosOnline.set(user.id, user);
            }.bind(this));
        }

        if(this.loading)
        {
            this.loading = false;
        }
    }
});

// get this globally namespaced... we'll just declare it here for
// the sake of keeping things easy... you probably shouldn't do
// this in real life
var whosOnline = '';

Event.observe(window, 'load', function() {
    whosOnline = new WhosOnlineSummary();
});
</pre>
<p>OK, as you can see, we&#8217;ve got a very simple data model that updates itself every thirty seconds, and that our other &#8220;widgets&#8221; can easily tap into for their information.  I&#8217;m not going to write these widgets out to any great extent, but I will create a small stub for the total online users functionality to help us out here.</p>
<h2>Step 2 &#8211; Create Some Widgets</h2>
<p>Now that we have a model, let&#8217;s start leveraging it to do something meaningful.  As I just mentioned, this is only a stub, but it should give you a nice idea of where we&#8217;re going&#8230;</p>
<pre name="code" class="javascript">var TotalOnlineUsers = Class.create(
{
    initialize: function(element)
    {
        this.domElement = element;

        // any other useful variables could go here...

        this.parseOnlineUsers();
    },

    parseOnlineUsers: function parseOnlineUsers()
    {
        // nice and simple
        this.domElement.update('Currently ' + whosOnline.totalOnlineUsers + ' users online');
    }
});</pre>
<p>And now we&#8217;re essentially ready to do some fun stuff.  As you can see, all this looks nice, but our TotalOnlineUsers widget has no way of knowing when it needs to update the display, as there&#8217;s no way to know when the data model has changed.  Enter Object.Event&#8230;</p>
<h2>Step 3 &#8211; Make Your Data Model Smart</h2>
<p>So, we need to get our data model publishing events that our widgets can listen for.  This is actually pretty darn simple since all the heavy lifting has been done for us.  Let&#8217;s go ahead and leverage the power of Object.Event (I&#8217;ll provide download links at the end of this article).  The first thing we need to do is provide the data model with the &#8220;event&#8221; functionality.  This is a simple one-liner that we can put right after our class declaration.  It looks like this:</p>
<pre name="code" class="javascript">...
 if(this.loading)
        {
            this.loading = false;
        }
    }
});

Object.Event.extend(WhosOnlineSummary);
</pre>
<p>That&#8217;s it!  Now, all that remains for us to do is to create events inside this object that can be observed (we&#8217;ll cover the actual observing shortly).  This is done through simple additions of &#8220;notify&#8221; functions.  Since we&#8217;ve extended our data model class, this is also a cinch.  I&#8217;ll modify the update function to include two &#8220;events&#8221;:</p>
<pre name="code" class="javascript">...
    update: function update(data)
    {
        // and you'd have some sort of logic
        // here to update the data... here's a stub..

        // I'm assuming the data returned is a JSON object here...

        if('totalOnlineUsers' in data)
        {
            this.totalOnlineUsers = data.totalOnlineUsers;
        }

        // and update our "who's online" stuff...
        if('onlineUsers' in data)
        {
            // simple way to refresh, just kill the current list
            this.whosOnline = new Hash();

            // pretend online users is an array of json objects here...
            // [ { id: userId, name: username, etc.}, {...}, ... ]
            data.onlineUsers.each(function(user)
            {
                this.whosOnline.set(user.id, user);
            }.bind(this));
        }

        if(this.loading)
        {
            this.loading = false;
            this.notify('whosOnlineLoaded');
        }

        this.notify('whosOnlineUpdate');
    }
...</pre>
<p>As you can see, we can create any custom events that we want, and we can name them whatever we want.  Pretty cool stuff, huh?  So, there&#8217;s only one thing that remains, and that&#8217;s making our widget listen for these events.</p>
<h2>Step 4 &#8211; Make our Widgets Listen for Events</h2>
<p>You&#8217;ll notice I created two events in our data model, but we&#8217;re only going to use one for this example.  Let&#8217;s get right to it, as there&#8217;s no real need for explanation here&#8230;</p>
<pre name="code" class="javascript">
var TotalOnlineUsers = Class.create(
{
    initialize: function(element)
    {
        this.domElement = element;

        // any other useful variables could go here...

        // watch for updates from the data model
        whoseOnline.observe('whosOnlineUpdate', function()
        {
            this.parseOnlineUsers()
        }.bind(this));

        this.parseOnlineUsers();
    },

    parseOnlineUsers: function parseOnlineUsers()
    {
        // nice and simple
        this.domElement.update('Currently ' + whosOnline.totalOnlineUsers + ' users online');
    }
});
</pre>
<p>Done.  It&#8217;s really that easy!</p>
<h2>Wrapping Up</h2>
<p>Hopefully, you can see the huge benefit of approaching your apps this way, and integrating Object.Event.  If you&#8217;ll remember, our so-called page also has a who&#8217;s online list.  You could create a widget that also observes the &#8220;whosOnlineUpdate&#8221; event, so it will update whenever the model changes as well.  We&#8217;ve effectively made the load on the server smaller, since we&#8217;ve only got one thing calling our data service, instead of 2 (in this case, but I&#8217;m sure there are many practical applications that would have many more somewhat redundant calls).  We also know that our presentation will be in sync across all the different elements on this page, which leads to a much slicker user experience.  The best part of all this? We&#8217;ve made very, very small tweaks to our code, and they were very unobtrusive as well.  Enjoy, and thank Ryan for his bad-ass javascript kung-fu if you&#8217;ve got a moment!</p>
<p>As promised, here are your links to all the required libraries:</p>
<ul>
<li><a href="http://livepipe.net/projects/object_event/" target="_blank">Object.Event &#8211; Created by Ryan Johnson</a></li>
<li><a href="http://prototypejs.org" target="_blank">Prototype Framework</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.gen-x-design.com/archives/make-your-data-javascript-data-model-smarter/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>JavaScript &amp; MySQL With Jaxer</title>
		<link>http://www.gen-x-design.com/archives/javascript-mysql-with-jaxer/</link>
		<comments>http://www.gen-x-design.com/archives/javascript-mysql-with-jaxer/#comments</comments>
		<pubDate>Sun, 23 Mar 2008 18:52:03 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Jaxer]]></category>

		<guid isPermaLink="false">http://www.gen-x-design.com/?p=29</guid>
		<description><![CDATA[Wouldn&#8217;t it be cool if you could work with MySQL within your JavaScript code?  Think about it, you wouldn&#8217;t have to spend extra time writing extra server-side code for connecting to, querying, and parsing results, you could just write a little bit more code in your JavaScript and be done with it.  Of [...]]]></description>
			<content:encoded><![CDATA[<p>Wouldn&#8217;t it be cool if you could work with MySQL within your JavaScript code?  Think about it, you wouldn&#8217;t have to spend extra time writing extra server-side code for connecting to, querying, and parsing results, you could just write a little bit more code in your JavaScript and be done with it.  Of course, we wouldn&#8217;t want any of this SQL exposed to the end-user, as that would be a major security issue, but what if that problem was solved as well?  You might also raise the point that you&#8217;d still need the ability to prepare your SQL statements that take dynamic input to prevent SQL injection attacks, but if that weren&#8217;t an issue, wouldn&#8217;t that be awesome as well?</p>
<p>Seriously, take a look over an existing AJAX app you may have written.  You&#8217;ve probably got a bunch of different functions for making AJAX calls to PHP scripts (or something similar), which process the input, and deal with the database, then return either parsed results, or results to be parsed by JavaScript.  Wouldn&#8217;t it be nice if you could consolidate all that stuff into some smaller, simpler JavaScript code?  Fewer files, less overhead&#8230; sounds good to me.</p>
<p>That&#8217;s one of the great things about Jaxer.  If you&#8217;ve done any reading, you probably know that Jaxer works with SQLite out of the box, and you might be aware that it&#8217;s also able to work with MySQL, but most of the people I&#8217;ve talked to have stopped there.  Aside from the above objections (which I&#8217;ll smash shortly <img src='http://www.gen-x-design.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> ), I&#8217;ve also heard that they simply don&#8217;t want to learn another complex API.  Well, the time for silly excuses is over, and I&#8217;m going to show you how easy all this stuff can be.  I would suggest that you first <a href="http://www.gen-x-design.com/archives/jaxer-xampp-javascript-bliss/" target="_blank">set up Jaxer with XAMPP</a> so you can follow along, but if you want to use the stand-alone Jaxer and Apache, you&#8217;ll be just fine. Let&#8217;s get our hands dirty&#8230;<br />
<span id="more-29"></span></p>
<h2>Setting up Jaxer to Use MySQL</h2>
<p>This is actually pretty simple, and already <a href="http://www.aptana.com/node/143" target="_blank">documented</a> in the Jaxer documentation, but I&#8217;ll go over it here as well.  First, some background on how Jaxer works internally with databases.  Whether you&#8217;re using SQLite or MySQL, Jaxer leverages a database for some of its own internal functionality (session management and other goodness).  As such, it needs a database for its own stuff, which it will create if it doesn&#8217;t exist.  We&#8217;re also going to need a default application database for Jaxer to connect to when it spins up, but it won&#8217;t be writing anything to it.</p>
<p>So, let&#8217;s tell Jaxer to use MySQL.  If you&#8217;re set up according to my Jaxer+XAMPP tutorial, we&#8217;re going to edit:</p>
<pre>/Applications/xampp/xamppfiles/local_jaxer/conf/config.js</pre>
<p>If you&#8217;re working with the standalone, browse to wherever you&#8217;ve installed it and edit:</p>
<pre>Path-to-Aptana_Jaxer/local_jaxer/conf/config.js</pre>
<p>What we&#8217;re looking for is around line 44 (it should be commented out):</p>
<pre name="code" class="javascript">Config.DB_IMPLEMENATION = "MySQL";</pre>
<p>Now, some more assumptions:</p>
<ul>
<li>You&#8217;ve got a database created for your app, and one for jaxer itself.  For my &#8220;sandbox&#8221; testing, these are the same&#8230; I use &#8220;jaxer_db&#8221;</li>
<li>You know what port MySQL is using (unless you&#8217;ve changed something, it&#8217;s 3306).  If you&#8217;re using XAMPP, you&#8217;re good to go</li>
</ul>
<p>OK, so let&#8217;s uncomment all the MySQL-specific stuff and change our default stuff.  Here&#8217;s what I&#8217;ve got:</p>
<pre name="code" class="javascript">Config.DB_IMPLEMENTATION = "MySQL";
Config.DB_CONNECTION_PARAMS =
    {
        HOST: "127.0.0.1",
        PORT: 3306,
        NAME: "jaxer_db",
        USER: "root",
        PASS: "",
        CLOSE_AFTER_EXECUTE: false,
        CLOSE_AFTER_REQUEST: true
    };
    Config.DB_FRAMEWORK_IMPLEMENTATION = "MySQL";
    Config.DB_FRAMEWORK_CONNECTION_PARAMS =
    {
        HOST: "127.0.0.1",
        PORT: 3306,
        NAME: "jaxer_db",
        USER: "root",
        PASS: "",
        CLOSE_AFTER_EXECUTE: false,
        CLOSE_AFTER_REQUEST: true
    }; </pre>
<p>If you&#8217;re going to use (and you should for production stuff) a different Jaxer internal database, change the Config.DB_FRAMEWORK_CONNECTION_PARAMS to reflect this appropriately.  Now that we&#8217;ve changed everything, restart Jaxer, then restart Apache.  If everything&#8217;s good, you should be able to browse to the Jaxer Unit Tests (located in the Server Diagnostics&#8230;  usually located at http://localhost/aptana or the start page from the Jaxer control panel for stand-alone users), and run the &#8220;DB &#8211; test_DB_MySQL.html&#8221; test (just click on that link).  If all is well, you&#8217;ll see a bunch of passes:</p>
<div align="center" style="font-size: 10px;"><img src='http://gxdlabs.com/wp-content/uploads/2008/03/picture-25.png' alt='picture-1.png' /><br />Jaxer MySQL Unit Tests</div>
<h2>Getting a Few Things Set Up</h2>
<p>Awesome, now that we&#8217;re up and running, let&#8217;s set up some test data to play around with.  Let&#8217;s create a test table and populate it with some data&#8230; just copy and paste this code in your MySQL client of choice:</p>
<pre name="code" class="SQL">create table if not exists `users` (
user_id int(10) unsigned NOT NULL auto_increment,
first_name varchar(50) NOT NULL,
last_name varchar(50) NOT NULL,
username varchar(50) NOT NULL,
date_created datetime NOT NULL default '0000-00-00 00:00:00',
date_updated timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
primary key (`user_id`));
INSERT INTO users SET first_name='Ian', last_name='Selby', username='iselby', date_created=NOW();
INSERT INTO users SET first_name='John', last_name='Doe', username='jdoe', date_created=NOW();</pre>
<p>Of course, you could certainly add more, but we&#8217;re not writing an app, so this should suffice just fine.</p>
<p>One last little bit of groundwork, let&#8217;s set up the page that&#8217;s going to contain some of our test code.  Basically, it&#8217;s just going to be a sandbox page of sorts, so there&#8217;s nothing too tough here:</p>
<pre name="code" class="xml">&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
&lt;html xmlns="http://www.w3.org/1999/xhtml">
&lt;head>
	&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	&lt;title>Sample Jaxer DB Stuff</title>

	&lt;script type="text/javascript" runat="server-proxy">
	// we'll add our sample code here
	&lt;/script>
&lt;/head>
&lt;body>
	&lt;div id="results">&lt;/div>
&lt;/body>
&lt;/html></pre>
<p>Great!  Now we&#8217;re ready to start working with the Jaxer &#038; MySQL API.</p>
<h2>Getting Our Feet Wet&#8230; Connecting to MySQL and Basic API Functions</h2>
<p>First thing we need to do (obviously), is to set up a connection to the database.  While we have set up a default database in our Jaxer configuration, we can connect to any database that we want to.  So, let&#8217;s set up that connection now.  Place the following between our script tags:</p>
<pre name="code" class="javascript">var dbConnection = new Jaxer.DB.MySQL.Connection({
	'HOST': 'localhost',
	'PORT': 3306,
	'USER': 'root',
	'PASS': '',
	'NAME': 'jaxer_db',	// the name of the db to use
	'CLOSE_AFTER_EXECUTE': false
});</pre>
<p>So far, pretty simple, no?  Obviously, you can change any of these parameters to suit your needs.  Remember, the end user will not see any of this as we&#8217;re running it at the server level (which we defined with the runat= in our script tags).  Now that we&#8217;ve got a connection, we can start running queries.  Before we build anything practical, let&#8217;s take a look at our basic API stuff.</p>
<p><strong>Queries</strong><br />
As stated in the introduction to this article, there is, in fact, a way to prepare statements to prevent SQL injection.  Let&#8217;s take a look at a basic example, then a prepared query:</p>
<pre name="code" class="javascript">// assuming we are using the above connection...
var query_string = 'SELECT * FROM user';
var result = dbConnection.execute(query_string);
// and now a prepared statement
var query_string = 'SELECT * FROM user WHERE first_name LIKE ? OR last_name LIKE ?';
var result = dbConnection.execute(query_string, ['%' + someInput + '%', '%' + someOtherInput + '%']);</pre>
<p>It&#8217;s really that easy!  Of course, if you aren&#8217;t interested in a result, you can omit the &#8220;var result =&#8221; (such as update or insert statements).  Again, as long as your queries are in a runat=&#8221;server&#8221; or runat=&#8221;server-proxy&#8221; script block (or .js include), the end user will never see your code.  So, everything&#8217;s nice and secure.<br />
<strong>Result Sets</strong><br />
If you&#8217;re a PHP developer, you are probably familiar with the mysql_fetch_object() or mysql_fetch_array() functions for traversing result sets (shame on you for not using mysqli tho <img src='http://www.gen-x-design.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> ).  If you&#8217;re not, don&#8217;t worry, I&#8217;m not going to be referring to them here.  Anyway, regarding those functions, you&#8217;re in luck!  The fine folks who programmed Jaxer were kind enough to provide results similar to those of PHP (and other languages I would imagine).  I&#8217;ll go over a sample result set in a moment, but here&#8217;s a quick look at what the &#8220;result&#8221; variable from the examples above would contain:</p>
<ul>
<li>columns &#8211; An array of column names for all rows in this resultSet.</li>
<li>hasData &#8211; I&#8217;ll give you three guesses (true / false folks!)</li>
<li>rows &#8211; The array of rows in the resultSet in the order retrieved from the database.</li>
<li>rowsAsArrays &#8211; An alternate representation of the rows of the resultSet</li>
<li>singleResult &#8211; The value in the first column of the first row of the resultSet (think SELECT COUNT(*) FROM&#8230;)</li>
</ul>
<p>As you can see, it&#8217;s about as robust as you could possibly hope for.  So, based on our sample data, and the sample SELECT * FROM user query above, what would a resultSet object look like in real life?  It looks like this:</p>
<pre name="code" class="javascript">result =
{
	"rows":
	[
		{"user_id":1,"first_name":"Ian","last_name":"Selby","username":"iselby","date_created":"2008-02-23T17:46:24","date_updated":"2008-02-23T17:46:24","$values":[1,"Ian","Selby","iselby","2008-02-23T17:46:24","2008-02-23T17:46:24"]},
		{"user_id":2,"first_name":"John","last_name":"Doe","username":"jdoe","date_created":"2008-02-23T17:46:35","date_updated":"2008-02-23T17:46:35","$values":[2,"John","Doe","jdoe","2008-02-23T17:46:35","2008-02-23T17:46:35"]}
	],
	"rowsAsArrays":
	[
		[1,"Ian","Selby","iselby","2008-02-23T17:46:24","2008-02-23T17:46:24"],
		[2,"John","Doe","jdoe","2008-02-23T17:46:35","2008-02-23T17:46:35"]
	],
	"columns":
	[
		"user_id","first_name","last_name","username","date_created","date_updated"
	],
	"singleResult":1,
	"hasData":true
}</pre>
<p>We&#8217;ve also got a bunch of functions we can execute on a result set.  Rather than go over them in detail, you can check them out online or in your local instance of Jaxer&#8217;s API documentation:</p>
<ul>
<li><a href="http://www.aptana.com/reference/jaxer/api/Jaxer.DB.ResultSet.html" target="_blank">Online at Aptana</a></li>
<li><a href="http://localhost/aptana/doc/api/Jaxer.DB.ResultSet.html" target="_blank">Locally (If you installed according to my tutorial</a></li>
</ul>
<p>OK, go take a look over that goodness (I suggest locally if you can, as it will be more up-to-date), and then let&#8217;s take a look at how we could do this in a more real-world environment.</p>
<h2>Doing Something Practical</h2>
<p>Alright, to do something practical, we&#8217;re going to need to wrap our stuff in some functions, so we can call them when we need them.  So, go ahead and remove everything in our &lt;script> block, and create the following function:</p>
<pre name="code" class="javascript">function fetchUsers(search_for)
{
	var dbConnection = new Jaxer.DB.MySQL.Connection({
		'HOST': '127.0.0.1',
		'PORT': 3306,
		'USER': 'root',
		'PASS': '',
		'NAME': 'jaxer_db', // the name of the db to use
		'CLOSE_AFTER_EXECUTE': false
	});

	// if we've been provided with search params
	if (search_for)
	{
		search_for = '%' + search_for + '%';
		var query_string = 'SELECT * FROM user WHERE first_name LIKE ? OR last_name LIKE ? ORDER BY last_name';
		var params = [search_for, search_for];

		var result = dbConnection.execute(query_string, params);
	}
	// default result set
	else
	{
		var query_string = 'SELECT * FROM user ORDER BY last_name';
		var result = dbConnection.execute(query_string);
	}

	return result.toHTML();
}</pre>
<p>Pretty straight-forward, right?  OK, one last thing, and we&#8217;ll actually have something that works.  In order for this to execute on load, we can do one of two things: onload or onserverload.  Basically, these are the same thing, except the onserverload is evaluated when the server-side DOM is created (essentially before it ends up on the client-side of things&#8230; where all our runat=&#8221;server&#8221; stuff is executed).  So, let&#8217;s alter our <body> tag:</p>
<pre name="code" class="xml">&lt;body onserverload="document.getElementById('results').innerHTML = fetchUsers();"></pre>
<p>Save your page, reload it, and if everything works, you&#8217;ll have a really ugly HTML table of results!  Pretty damn cool, right?  If you&#8217;re sharp, you can see that we&#8217;re working our way towards a simple search, so let&#8217;s dive right into that.  Rather than go over it step-by-step, I&#8217;ll just show you the final HTML (because this really isn&#8217;t rocket science <img src='http://www.gen-x-design.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ):</p>
<pre name="code" class="xml">&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
&lt;html xmlns="http://www.w3.org/1999/xhtml">
&lt;head>
	&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	&lt;title>Sample Jaxer DB Stuff</title>

	&lt;style type="text/css">
		body, td, p { font-family: Lucida Grande, Arial; font-size: 11px; }
		td { border: 1px solid #ccc; padding: 3px; }
	&lt;/style>

	&lt;script type="text/javascript" runat="server-proxy">

	function fetchUsers(search_for)
	{
		var dbConnection = new Jaxer.DB.MySQL.Connection({
			'HOST': '127.0.0.1',
			'PORT': 3306,
			'USER': 'root',
			'PASS': '',
			'NAME': 'jaxer_db', // the name of the db to use
			'CLOSE_AFTER_EXECUTE': false
		});

		// if we've been provided with search params
		if (search_for)
		{
			search_for = '%' + search_for + '%';
			var query_string = 'SELECT * FROM user WHERE first_name LIKE ? OR last_name LIKE ? ORDER BY last_name';
			var params = [search_for, search_for];

			var result = dbConnection.execute(query_string, params);
		}
		// default result set
		else
		{
			var query_string = 'SELECT * FROM user ORDER BY last_name';
			var result = dbConnection.execute(query_string);
		}

		return result.toHTML();
	}

	&lt;/script>
	&lt;script type="text/javascript" runat="client">
		function doSearch()
		{
			var search_for = document.getElementById('searchFor').value;
			document.getElementById('results').innerHTML = fetchUsers(search_for);
		}
	&lt;/script>
&lt;/head>
&lt;body onserverload="document.getElementById('results').innerHTML = fetchUsers();">
	&lt;label for="searchFor">Search For: &lt;/label>&lt;input name="searchFor" id="searchFor" />
	&nbsp;&lt;button onclick="doSearch();">Search&lt;/button>
	&lt;div id="results">&lt;/div>
&lt;/body>
&lt;/html></pre>
<p>Most of this stuff should be pretty self-explanatory, but I&#8217;ll go over a few things of note.  The first thing you should notice is that I&#8217;ve created a new client-side script tag.  This is so I can create a function that will have access to the results div, as well as our server-side function.  Remember, after the server-side DOM and functions are evaluated, that DOM goes away.  So, the server-side functions will no longer have access to the DOM when we&#8217;re doing our search, regardless of the fact we proxy that function.  All the proxy does is allow the functions to be executed from the client-side without exposing any of the server-side code (so our SQL statements won&#8217;t be seen or anything like that).</p>
<div align="center" style="font-size: 10px;"><img src="http://gxdlabs.com/wp-content/uploads/2008/03/picture-13.png" alt="" title="Everything Works!" width="400" height="50" /><br />DB-Driven Search Using JavaScript&#8230; WOW! (Jaxer rules folks)</div>
<h2>Wrapping Up</h2>
<p>As you can see, it&#8217;s really darn easy to work with MySQL in Jaxer.  It&#8217;s also perfectly safe, and there are no real causes for concern from a security standpoint.  As Jaxer is still in its beta stage, there&#8217;s a lot of feature development currently taking place, but we (at Aptana) would love your feedback and suggestions.  You can certainly provide feedback with comments here and I&#8217;ll pass them along, but the best place to do so is in the <a href="http://forums.aptana.com/" target="_blank">Aptana Forums</a>.  I&#8217;m currently cooking up a prototype database abstraction class that is essentially like a PHP class in order to obviously make things easier development-wise, but should also provide a bit of a familiar environment for PHP developers looking to make the jump to Jaxer.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gen-x-design.com/archives/javascript-mysql-with-jaxer/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Ajax Activity Indicators &#8211; Make Them Global and Unobtrusive</title>
		<link>http://www.gen-x-design.com/archives/ajax-activity-indicators-make-them-global-and-unobtrusive/</link>
		<comments>http://www.gen-x-design.com/archives/ajax-activity-indicators-make-them-global-and-unobtrusive/#comments</comments>
		<pubDate>Sat, 08 Jul 2006 21:09:53 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.gen-x-design.com/?p=34</guid>
		<description><![CDATA[EDIT (7/10/2006):  After much feedback, both on this site and ajaxian, I feel that I failed to properly explain where this implementation would be useful.  If you have a page with a single action, say a live search for example, separating the indicator from the action is poor form from a usability standpoint. [...]]]></description>
			<content:encoded><![CDATA[<div class="downloadBox" style="margin-top: 5px;">EDIT (7/10/2006):  After much feedback, both on this site and ajaxian, I feel that I failed to properly explain where this implementation would be useful.  If you have a page with a single action, say a live search for example, separating the indicator from the action is poor form from a usability standpoint.  However, a dashboard page with a couple widgets and some live updating data, or some other instance where a lot of ajax may be happening on a page at once would be a perfect use for what I write about.  Thanks to everyone for their comments, feedback, and advice.</div>
<p>One of the coolest things about developing ajax-enabled applications and sites is the level of interactivity that you can bring to your users.  And perhaps one of the most crucial aspects of this process is adding activity indicators to your site.  While a lot of ajax requests can be very fast, it&#8217;s still important to let your users know that something is happening.  All too often I see people forgetting to add these indicators, purposefully omitting them because there wasn&#8217;t a good place to include them in the design, or implementing them poorly.  One of the biggest omissions that I see is with live searches and auto-completion widgets, but not without good reason.  Activity indicators can break up a good layout, as they can require a fair amount of page real estate.  They&#8217;re also a major pain to incorporate into your apps, as you often end up writing a lot of redundant code to display and hide different indicators on different pages or parts of a page.</p>
<p>So, what can we do about these problems?  Well, if you&#8217;re using prototype as a part of your framework, you can register global indicator functions.  These get executed when there are active requests, and when the requests complete.  However, there&#8217;s another dilemma with this method too: Where do you place a indicator that can potentially appear often and keep it from being obtrusive, or, even worse, not being seen as it&#8217;s placed outside of the content that&#8217;s currently in view?  I had to tackle that issue this week while starting development on a new project at work.  I wanted to create an indicator that would be in the same place on every page, and that I never had to write extra code to use.  <a href="http://www.gen-x-design.com/demos/activity_indicator/" target="_blank">View a demo of the solution here.</a></p>
<p>The solution, in hindsight, seems very obvious and I can&#8217;t believe that I hadn&#8217;t come up with it earlier: Place a div that spans the entire width of the window at the bottom of the window and make it stick there when the user scrolled.  Then use scriptaculous, or moo.fx (whichever you prefer) to show/hide the indicator when ajax requests were made/completed respectively.  So how did I do it?  Read on&#8230;<br />
<span id="more-34"></span></p>
<h2><strong>Step 1:  Gather the Tools</strong></h2>
<p>Before we write any code, we need to grab some javascript libraries.  For this implementation, I use the latest versions of scriptaculous (1.6.1 at the time of writing) and Prototype (1.5.0_rc0 at the time of writing).  If you don&#8217;t have them, head over to the scriptaculous website and grab the latest version.  Prototype comes bundled with it, so that ought to save you some time.</p>
<div class="downloadBox" style="margin-top: 15px;">
<a href="http://script.aculo.us">Download Scriptaculous</a>
</div>
<p>Once you have the file, grab everything in the src folder (the scriptaculous files) and prototype from the lib directory and place them in whatever directory you would like in your site.  This example will assume they are in the root.</p>
<h2><strong>Step 2:  Laying the Groundwork: The CSS</strong></h2>
<p>Now for the tricky part.  The key to this whole solution is to keep the div at the bottom of the window, not the page.  We want to make sure the user always sees the indicator.  The solution is actually a slightly modified version of <a href="http://www.sitepoint.com/blogs/2005/10/18/the-catfish-part-1/" target="_blank">SitePoint&#8217;s Catfish Script</a>.  If you&#8217;ve been to their site lately, you have probably noticed their cool little ads that appear at the bottom of the screen after a few seconds.  Well, they call that a catfish, which makes complete sense to me now, but was of no use to me when I was searching for their solution.  As usual, I&#8217;m going to summarize and borrow from their article, but I suggest you stop reading now and read their full post before continuing.  Also, just to be perfectly clear, I&#8217;m not trying to steal their work, or claim it as my own, I&#8217;m just using it to achieve our goal (don&#8217;t need people thinking I&#8217;m plaigarizing!).</p>
<p>Anyway, here&#8217;s the css for the notification area to work, at least in everything but IE:</p>
<pre name="code" class="css">#notification {
	position: fixed;
	bottom: 0;
	padding: 0;
	height: 20px;
	margin: 0;
	width: 100%;
	background-color: #FFFF99;
	display: block;
	text-align: center;
	font-weight: bold;
	font-size: 1.3em;
	font-family: Verdana, Arial, Helvetica, sans-serif;
	padding-top: 5px;
}
html,body {
	height: 100%;
}

html {
	padding: 0 0 25px 0;  /* create area for notification area */
}</pre>
<p>I&#8217;ll take an excerpt from the sitepoint article to explain why this won&#8217;t work in IE, and what we need to do to fix it:</p>
<blockquote><p>
At this point the major issue became the small matter that it didn?t work at all in Internet Explorer. If you&#8217;re viewing the demo in IE you&#8217;ll see that the DIV is behaving exactly as if it were &#8220;position: static&#8221; (the default).<br />
[...]<br />
We also made another decision at this point. Since FireFox, Opera and Safari do a dandy job with the W3C standard &#8220;position:fixed&#8221;, why throw extra markup at them?only IE would be getting the extra markup.
</p></blockquote>
<p>The article goes into greater detail, and explains the problem further, but for the sake of continuity, I&#8217;ll just post the code we need to get IE to play nice on the next page</p>
<p>First, we need to create a separate css file for IE.  Let&#8217;s call it IEhack.css:</p>
<pre name="code" class="css">#header {
	width: auto; /*needed to keep IE from throwing a horizontal scrollbar in the page */
}
#notification {
     position: absolute;
     z-index: 100;
     overflow: hidden;
}
html, body {
     height:100%;
     overflow: hidden;
     width:auto;
}

div#zip {
     width: 100%;
     padding:0;
     margin:0;
     height: 100%;
     overflow: auto;
     position: relative;
}</pre>
<p>Now, we need to write a bit of javascript:</p>
<pre name="code" class="javascript">function wrapFish() {
	var catfish = document.getElementById('notification');
	var subelements = [];
	for (var i = 0; i < document.body.childNodes.length; i++) {
 		subelements[i] = document.body.childNodes[i];
	}

	var zip = document.createElement('div');    // Create the outer-most div (zip)
	zip.id = 'zip';                      // call it zip

	for (var i = 0; i < subelements.length; i++) {
	zip.appendChild(subelements[i]);
	}
	document.body.appendChild(zip); // add the major div
	document.body.appendChild(catfish); // add the catfish after the zip
}

addLoadEvent(function() {
	wrapFish();
});</pre>
<p>Finally, as mentioned by the SitePoint article, we need to create a way to serve this css and js to only IE users.  Here's the code:</p>
<pre name="code" class="xml">&lt;!--[if IE]>
&lt;link rel="stylesheet" href="IEHack.css" type="text/css" />
&lt;script type="text/javascript" src="notification.js">&lt;/script>
&lt;![endif]--></pre>
<p>So, we've got our CSS, we've got our IE hacks, but we still need our HTML, and the main JavaScript that sets this all up for us.  Let's get into the HTML next...</p>
<h2><strong>Step 3: The HTML</strong></h2>
<p>There's no real need for explanation here, as the HTML is pretty basic.  I'm just going to give you the HTML from my demo page, but you should be able to easily modify it to suit your needs:</p>
<pre name="code" class="xml">&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
&lt;html>
&lt;head>
&lt;meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
&lt;title>Global Ajax Activity Indicator Demo&lt;/title>
&lt;script type="text/javascript" src="prototype.js">&lt;/script>
&lt;script type="text/javascript" src="scriptaculous.js?load=effects">&lt;/script>
&lt;script type="text/javascript" src="responder.js">&lt;/script>
&lt;style type="text/css">
&lt;!--
html,body {
	height: 100%;
}

html {
	padding: 0 0 25px 0;  /* create area for notification area */
}
body,td,th,p {
	font-family: Verdana, Arial, Helvetica, sans-serif;
	font-size: 12px;
	color: #333333;
}
body {
	margin-left: 0px;
	margin-top: 0px;
	margin-right: 0px;
	margin-bottom: 0px;
}
#notification {
	position: fixed;
	bottom: 0;
	padding: 0;
	height: 20px;
	margin: 0;
	width: 100%;
	background-color: #FFFF99;
	display: block;
	text-align: center;
	font-weight: bold;
	font-size: 1.3em;
	font-family: Verdana, Arial, Helvetica, sans-serif;
	padding-top: 5px;
}
#header {
	padding: 5px;
	background-color: #CCCCCC;
	font-size: 15px;
	font-weight: bold;
}
#content {
	padding: 5px;
}
-->
&lt;/style>
&lt;!--[if IE]>
&lt;link rel="stylesheet" href="IEHack.css" type="text/css" />
&lt;script type="text/javascript" src="notification.js">&lt;/script>
&lt;![endif]-->
&lt;/head>
&lt;body>
&lt;div id="header">This would be your fancy header!&lt;/div>
&lt;div id="content">
And all your site content could go here! Notice that if you keep executing requests so that the page gets longer than the window, you the notification stays &quot;stuck&quot; to the bottom.&lt;br />
&lt;br />
&lt;a onClick="testClass.demoRequest();" style="cursor: pointer; color: #0066CC;">Click Here to Execute a Request&lt;/a>&lt;br />
&lt;/div>
&lt;div id="notification" style="display: none;">&lt;img src="ajax_indicator.gif" width="16" height="16" align="absmiddle">&nbsp;Working...&lt;/div>
&lt;/body>
&lt;/html></pre>
<p>Let's take a look at the HTML.  In the header, we've included all our necessary javascript, including the file that we'll create in the next step.  We've also included the IE-specific code, and the base css.  This could, of course, be a part of your main CSS file, I just put it in the header for clarity.  In the body, the only two necessary elements are the header and notification divs.  The only other thing we need before we start writing the javascript, is the indicator:</p>
<div class="downloadBox"><a class="imagelink" href="http://www.gen-x-design.com/wp-content/uploads/2006/07/ajax_indicator.gif" title="Ajax Indicator"><img id="image25" src="http://www.gen-x-design.com/wp-content/uploads/2006/07/ajax_indicator.gif" alt="Ajax Indicator" style="border: none;" align="absmiddle" /></a> The activity indicator</div>
<p>Alright, let's get to the fun stuff: the javascript!</p>
<h2><strong>Step 4: The JavaScript</strong></h2>
<p>OK, so all that's left for us to do is to create the javascript that will show/hide our notification area when there are active/complete requests.  What we're going to do is use prototype's ajax responder functions to display the notification area when there are any open requests, and then hide it when all requests complete.  The code is pretty straightforward:</p>
<pre name="code" class="javascript">Ajax.Responders.register({
	onCreate: function() {
		if($('notification') &#038;&#038; Ajax.activeRequestCount > 0)
			Effect.Appear('notification',{duration: 0.25, queue: 'end'});
	},
	onComplete: function() {
		if($('notification') &#038;&#038; Ajax.activeRequestCount == 0)
			Effect.Fade('notification',{duration: 0.25, queue: 'end'});
	}
});</pre>
<p>This code can either be placed in a file that you include on every page, or, as I prefer to do, place it at the top of the file that contains all my javascript for a particular page.  It's completely up to you how you do it, just make sure that it gets included once on every page you want the notification area to work with.  You can also change the scriptaculous effects to whatever you would like, I simply prefer the fading, but the blind effects could work nicely as well.  Of course, you could also use another effects package, such as moo.fx, or simply change the display from none to block.</p>
<h2><strong>Wrapping Up</strong></h2>
<p>That's all there is to it!  A simple, unobtrusive, but extremely useful notification area that will stick to the bottom of your window.  You could also use this area for other notifications, such as successful saves, or any other event that occurs in your app.  Like I said before, this saves you the effort of writing function-specific indicators, and of trying to find a place to put the indicator in your design.  If you have any comments, suggestions, or improvements, don't hesitate to let me know.  Enjoy!</p>
<p><strong>Resources</strong></p>
<div class="downloadBox" style="margin-top: 15px;">
<ul>
<li><a href="http://gen-x-design.com/demos/activity_indicator/" target="_blank">Demo of the script</a></li>
<li><a href="http://script.aculo.us" target="_blank">Download scriptaculous and prototype</a></li>
<li><a href="http://www.mad4milk.com" target="_blank">Download moo.fx</a></li>
<li><a href="http://www.sitepoint.com/blogs/2005/10/18/the-catfish-part-1/" target="_blank">SitePoint's Catfish Article</a></li>
<li><a href="http://www.ajaxload.info/" target="_blank">Create Your Own Activity Indicators</a></li>
</ul>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.gen-x-design.com/archives/ajax-activity-indicators-make-them-global-and-unobtrusive/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
