<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" version="2.0">

<channel>
	<title>solnic on blog</title>
	
	<link>http://blog.solnic.eu</link>
	<description>web development, ruby, javascript and other crazy things</description>
	<lastBuildDate>Mon, 19 Oct 2009 06:24:32 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/solnic-on-blog" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="solnic-on-blog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>My development setup</title>
		<link>http://blog.solnic.eu/2009/10/18/my-development-setup</link>
		<comments>http://blog.solnic.eu/2009/10/18/my-development-setup#comments</comments>
		<pubDate>Sun, 18 Oct 2009 08:10:53 +0000</pubDate>
		<dc:creator>solnic</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[arch]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[osx]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://blog.solnic.eu/?p=216</guid>
		<description><![CDATA[
			
				
			
		It&#8217;s something I always wanted to write about and also a response to Peter Cooper&#8217;s post on RubyFlow calling to write about tools that we use everyday to do Ruby on Rails development. I like the idea since there are a lot of options and finding right tool for the job is essential.

Let&#8217;s start:

Hardware



MacBook Pro [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a  href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.solnic.eu%2F2009%2F10%2F18%2Fmy-development-setup">
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.solnic.eu%2F2009%2F10%2F18%2Fmy-development-setup&amp;source=s0lnic&amp;style=normal&amp;service=bit.ly" height="61" width="50" />
			</a>
		</div><p>It&#8217;s something I always wanted to write about and also a response to <a  href="http://rubyflow.com/items/2865">Peter Cooper&#8217;s post on RubyFlow</a> calling to write about tools that we use everyday to do Ruby on Rails development. I like the idea since there are a lot of options and finding right tool for the job is essential.</p>

<p>Let&#8217;s start:</p>

<h2>Hardware</h2>


<ul>
<li>MacBook Pro 15&#8243; with Intel Core 2 Duo 2.40GHz and 2 gigs of <span class="caps">RAM </span>- absolutely enough. This is a decent laptop, the only thing which bothers me is its temperature, sometime it burns my hands, literally&#8230;</li>
<li>Logitech VX Nano Cordless Notebook Mouse &#8211; <strong>the best</strong> notebook mouse ever, has <strong>the smaller</strong> receiver out there + I change batteries like twice a year, love it</li>
</ul>



<h2>Base software</h2>


<ul>
<li><a  href="http://www.archlinux.org">Arch Linux</a> &#8211; it&#8217;s my 6 day with this distro actually, I&#8217;m a Gentoo fanatic but from time to time I try to use something different. I usually go back to Gentoo after a month or so. We&#8217;ll see how I&#8217;ll end up now. So far I really like Arch, it&#8217;s extremely lightweight, fast and stable. Software availability is as good as in Gentoo. It&#8217;s also easy to make your own packages which is crucial for Ruby developers since it happens that we need various non-standard stuff, like let&#8217;s say Nginx with Passenger support. I&#8217;ve got a feeling that this time I won&#8217;t go back to Gentoo</li>
</ul>




<ul>
<li><a  href="http://www.kde.org"><span class="caps">KDE</span></a> &#8211; it&#8217;s my desktop environment and one of the most important reasons why I&#8217;ve switched back from <span class="caps">OSX </span>to Linux. <span class="caps">KDE&#8217;</span>s window manager is highly configurable and gives you features like moving and resizing of windows via a special key + mouse move/click, custom settings per application / window class so for instance you can configure that console window will always appear on the third virtual desktop snapped to the upper-right corner of the screen, useful desktop effects ie &#8220;Present windows&#8221; which is something like Expose in <span class="caps">OSX </span><strong>but</strong> you can filter out windows by typing key words, cool window transparency (you can alt+mouse scroll to change window&#8217;s opacity&#8230;it&#8217;s useful, believe me) and much, much more&#8230;I just can&#8217;t work without those things. Here are <span class="caps">KDE&#8217;</span>s apps that I use:
<ul>
<li>Konsole &#8211; terminal emulator, very powerful, has tabs, horizontal / vertical view splitting, bookmarks and fully customizable look&#8217;n'feel</li>
<li>KRunner &#8211; something like quicksilver for <span class="caps">OSX</span></li>
<li>Dolphin &#8211; file manager, supports remote protocols, in my opinion the best file manager ever</li>
<li>KDiff3 &#8211; <span class="caps">GUI </span>for displaying diffs and merging, it&#8217;s my mergetool in Git</li>
<li>KColorEdit &#8211; color picker and editor</li>
<li>KRuler &#8211; on-screen ruler</li>
<li>KSnapshot &#8211; for doing screenshots</li>
<li>Klipper &#8211; a handy clipboard manager, supports custom actions</li>
<li>Amarok &#8211; music player</li>
</ul>
</li>
</ul>




<ul>
<li><a  href="http://www.netbeans.org">NetBeans</a> &#8211; I use this great <span class="caps">IDE </span>even for writing tiny scripts, for me it&#8217;s the best choice. I&#8217;ve tried many other <span class="caps">IDE</span>s/editors including Eclipse, JEdit, RubyMine, TextMate and others that I don&#8217;t remember now and NetBeans works best for me. Key features are powerful editor with macros and great shortcuts, ctrl+click navigation, fantastic JavaScript support, debugger, test/spec runner and&#8230;support for multiple projects in the same window, something that most of the <span class="caps">IDE</span>s don&#8217;t have and I really need it. I use following plugins:
<ul>
<li>Ruby and Rails &#8211; what a surprise <img src='http://blog.solnic.eu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
<li>Database &#8211; to access databases via a <span class="caps">GUI</span></li>
<li>OpenFileFast &#8211; written by my friend from <a  href="http://www.lunarlogicpolska.com"><span class="caps">LLP</span></a>, Marcin Kulik. Works like the open file dialog in TextMate, highly recommended. You can read more <a  href="http://sickill.net/projects/off">here</a></li>
</ul>
</li>
</ul>




<ul>
<li><a  href="http://www.firefox.com">Firefox</a> &#8211; I&#8217;ve switched from Opera a long time ago because of Firebug, now I&#8217;m about to try out Chromium for normal web browsing and use Firefox only for the development. Plugins that I find useful:
<ul>
<li>Firebug &#8211; must-have for every web-developer</li>
<li>Web Developer &#8211; easy access to things like clearing cache, disabling JavaScript etc.</li>
<li>Chat Zilla &#8211; <span class="caps">IRC</span></li>
<li>Read it Later &#8211; I never have time to read interesting things from Google Reader in the moment I find them so&#8230;I read them later</li>
<li>Delicious &#8211; I still use it but rather for sharing bookmarks between work and home</li>
</ul>
</li>
</ul>



<h2>Dev tools:</h2>


<ul>
<li><span class="caps">GIT </span>- probably the best <span class="caps">SCM </span>in the world</li>
<li>QGit4 &#8211; sometimes I use this git gui to view history of a project</li>
<li><span class="caps">ZSH </span>with a <a  href="http://github.com/jcorbin/zsh-git">pimped prompt for <span class="caps">GIT</span></a></li>
<li>Nginx with Passanger &#8211; better then script/server</li>
<li>VirtualBox &#8211; I have 3 Windows virtual machines each with different version of Internet Explorer, only for testing of course</li>
</ul>



<h2>Communication:</h2>


<ul>
<li>Skype &#8211; Linux version is very crappy, unfortunately I&#8217;m forced to use it</li>
<li><span class="caps">PSI </span>- great Jabber client</li>
<li>TweetDeck &#8211; powerful Twitter client, Adobe <span class="caps">AIR </span>based</li>
</ul>



<p>That would be it!</p>]]></content:encoded>
			<wfw:commentRss>http://blog.solnic.eu/2009/10/18/my-development-setup/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Rack Middleware Contest</title>
		<link>http://blog.solnic.eu/2009/10/12/rack-middleware-contest</link>
		<comments>http://blog.solnic.eu/2009/10/12/rack-middleware-contest#comments</comments>
		<pubDate>Mon, 12 Oct 2009 19:35:11 +0000</pubDate>
		<dc:creator>solnic</dc:creator>
				<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://blog.solnic.eu/?p=207</guid>
		<description><![CDATA[
			
				
			
		CodeRack is a coding contest dreamed up by a group of the Ruby programmers at Lunar Logic Polska who were excited about the possibilities of Rack middleware. The team wants to encourage Ruby developers to explore the possibilities and what better way than to hold a contest? The secondary goal of the contest is to [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a  href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.solnic.eu%2F2009%2F10%2F12%2Frack-middleware-contest">
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.solnic.eu%2F2009%2F10%2F12%2Frack-middleware-contest&amp;source=s0lnic&amp;style=normal&amp;service=bit.ly" height="61" width="50" />
			</a>
		</div><p>CodeRack is a coding contest dreamed up by a group of the Ruby programmers at <a  href="http://www.lunarlogicpolska.com">Lunar Logic Polska</a> who were excited about the possibilities of Rack middleware. The team wants to encourage Ruby developers to explore the possibilities and what better way than to hold a contest? The secondary goal of the contest is to generate a set of open source solutions that will solve real problems and inspire others. Every entry will be released under the <span class="caps">MIT </span>open source license.</p>

<p>Programmers are encouraged to submit contest entries that will be judged based on the cleverness of the application and the elegance of the code. Entries can be submitted at <a  href="http://www.coderack.org">coderack.org</a> until midnight <span class="caps">EST</span> November 15th. Finalists are scheduled to be announced on the 1st of December and public voting will run for one month. The final winners will be announced on the 5th of January.</p>

<p>The first round of the contest will be judged by an elite panel of judges including Ben Bangert of <span class="caps">O&#8217;R</span>eilly Media, Chris Wanstrath and PJ Hyett of GitHub, Joshua Peek of 37Signals, Yehuda Katz of Engine Yard and Rails core team member, Ryan Tomayko of Heroku, Core Rails team member Matt Aimonetti, and the Rails Envy team of Gregg Pollack and Jason Seifer.</p>

<p>Once the finalists have been selected by the panel, the public will vote for the top prize winners.</p>

<p>Prizes have been donated by Bytemark Hosting, GitHub, Jetbrains, Mindmeister, Freelance Total, Heroku, Rackspace Hosting, Peepcode, <span class="caps">BDDC</span>asts, and Zenbe Shareflow. The top prize includes a dedicated quad core server package and is valued at over $3000. Every entrant will receive a credit from bddcasts.com and $30 credit from Heroku. All finalists will receive a package including Zenbe Shareflow subscriptions, a RubyMine license from JetBrains, and five credits from bddcasts.com. Details of all of the prize packages will soon be available on the coderack.org website.</p>

<p>More information about the contest, including the contest rules, can be found at <a  href="http://coderack.org">coderack.org</a>.</p>

<p>ps. This post is a copy from <a  href="http://www.lunarlogicpolska.com/2009/10/8/lunar-logic-polska-launches-coderack-global-coding-contest">Lunar Logic Polska blog</a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.solnic.eu/2009/10/12/rack-middleware-contest/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unobtrusive JavaScript helpers in Rails 3</title>
		<link>http://blog.solnic.eu/2009/09/08/unobtrusive-javascript-helpers-in-rails-3</link>
		<comments>http://blog.solnic.eu/2009/09/08/unobtrusive-javascript-helpers-in-rails-3#comments</comments>
		<pubDate>Mon, 07 Sep 2009 22:10:46 +0000</pubDate>
		<dc:creator>solnic</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[rails3]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[unobtrusive]]></category>

		<guid isPermaLink="false">http://blog.solnic.eu/?p=186</guid>
		<description><![CDATA[
			
				
			
		A while ago I have written a post about JavaScript helpers in Ruby on Rails and tried to explain why they are a bad idea. It&#8217;s hard to believe for me that it was almost 2 years ago! Since then so many things have happened in the Ruby world&#8230;Now Rails 3 is on its way [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a  href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.solnic.eu%2F2009%2F09%2F08%2Funobtrusive-javascript-helpers-in-rails-3">
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.solnic.eu%2F2009%2F09%2F08%2Funobtrusive-javascript-helpers-in-rails-3&amp;source=s0lnic&amp;style=normal&amp;service=bit.ly" height="61" width="50" />
			</a>
		</div><p>A while ago I have written a post about <a  href="http://blog.solnic.eu/2007/10/30/why-javascript-helpers-in-rails-are-evil">JavaScript helpers in Ruby on Rails</a> and tried to explain why they are a bad idea. It&#8217;s hard to believe for me that it was almost 2 years ago! Since then so many things have happened in the Ruby world&#8230;Now Rails 3 is on its way and we already know what significant improvements and changes it will include. One of them is related to JavaScript helpers and the way how remote links and forms will be handled and I must admit that the new idea is absolutely great.</p>

<p>The new way is based on unobtrusive approach to JavaScript. This means that <span class="caps">HTML </span>code will be separated from JavaScript. I have checked out the latest sources of Ruby on Rails and found out that some of the work is already done. There is a new helper called AjaxHelper, it implements link_to_remote method which in the moment of writing this post looks like this:</p>


<div class="wp_codebox"><table><tr id="p1864"><td class="code" id="p186code4"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> link_to_remote<span style="color:#006600; font-weight:bold;">&#40;</span>name, url, options = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  html = options.<span style="color:#9900CC;">delete</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:html</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">||</span> <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
  update = options.<span style="color:#9900CC;">delete</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:update</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">if</span> update.<span style="color:#9900CC;">is_a</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">Hash</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    html<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;data-update-success&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span> = update<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:success</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    html<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;data-update-failure&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span> = update<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:failure</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  <span style="color:#9966CC; font-weight:bold;">else</span>
    html<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;data-update-success&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span> = update
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  html<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;data-update-position&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span> = options.<span style="color:#9900CC;">delete</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:position</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  html<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;data-method&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>          = options.<span style="color:#9900CC;">delete</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:method</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  html<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;data-remote&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>          = <span style="color:#996600;">&quot;true&quot;</span>
&nbsp;
  html.<span style="color:#9900CC;">merge</span>!<span style="color:#006600; font-weight:bold;">&#40;</span>options<span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
  url = url_for<span style="color:#006600; font-weight:bold;">&#40;</span>url<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> url.<span style="color:#9900CC;">is_a</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">Hash</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  link_to<span style="color:#006600; font-weight:bold;">&#40;</span>name, url, html<span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>




<p>What you see here will generate a clean markup with <span class="caps">HTML5</span>-compliant attributes prefixed with a word &#8220;data-&#8221;. If you are not familiar with them you can checkout a nice article by John Resig <a  href="http://ejohn.org/blog/html-5-data-attributes"><span class="caps">HTML</span> 5 data- Attributes</a>. Those attributes will instruct the additional JavaScript code how it should handle the behavior. Basically all links, buttons and forms that have the special attribute &#8220;data-remote&#8221; set to &#8220;true&#8221; will issue an <span class="caps">AJAX </span>request. There has been a discussion on <a  href="http://www.mail-archive.com/rubyonrails-core@googlegroups.com/msg09122.html">the Rails on Rails Core group</a> about how to implement corresponding JavaScript code. People are worried about its performance since finding all elements with data-remote=true appears to be slow in case of Prototype and jQuery. Moreover there is a problem of new elements that may be dynamically inserted after the page was loaded and all the event listeners were attached. Fortunately there is no need to be worried as our situation is a perfect example where we should use <a  href="http://www.sitepoint.com/blogs/2008/07/23/javascript-event-delegation-is-easier-than-you-think/">Event Delegation</a>. <span class="caps">DHH </span>has already showed in his <a  href="http://www.scribd.com/doc/15010095/Rails-3-and-the-Real-Secret-to-High-Productivity">Rails 3 and the Real Secret to High Productivity</a> presentation how links and buttons can be handled by <a  href="http://www.prototypejs.org">Prototype</a> library and it looks absolutely reasonable to me.</p>

<p>I would like to focus on jQuery though as it&#8217;s getting more popular even in the Rails community. Great example is <a  href="http://www.lunarlogicpolska.com">my job</a> where we use jQuery in every of our new projects. So how can we handle new remote links and forms using this popular library? Actually it&#8217;s ridiculously easy. Thanks to <a  href="http://docs.jquery.com/Events/live">jQuery.live</a> function we can easily use <a  href="http://www.sitepoint.com/blogs/2008/07/23/javascript-event-delegation-is-easier-than-you-think">Event Delegation</a> to handle <span class="caps">AJAX </span>calls. Just take a look at this sample of a markup that new helpers in Rails 3 will generate:</p>


<div class="wp_codebox"><table><tr id="p1865"><td class="code" id="p186code5"><pre class="html" style="font-family:monospace;">&lt;!-- the new link to remote --&gt;
&lt;a href=&quot;/users&quot; data-remote=&quot;true&quot;&gt;Users&lt;/a&gt;
&nbsp;
&lt;!-- the new remote form --&gt;
&lt;form action=&quot;/users&quot; method=&quot;post&quot; data-remote=&quot;true&quot;&gt;
  &lt;input type=&quot;text&quot; name=&quot;login&quot;/&gt;
  &lt;input type=&quot;submit&quot;/&gt;
&lt;/form&gt;</pre></td></tr></table></div>




<p>Pretty clean, I really like it! Now let&#8217;s see how we can implement jQuery handler that will send <span class="caps">AJAX </span>requests:</p>


<div class="wp_codebox"><table><tr id="p1866"><td class="code" id="p186code6"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> request <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>options<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  $.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span>$.<span style="color: #660066;">extend</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> url <span style="color: #339933;">:</span> options.<span style="color: #660066;">url</span><span style="color: #339933;">,</span> type <span style="color: #339933;">:</span> <span style="color: #3366CC;">'get'</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> options<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// remote links handler</span>
$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'a[data-remote=true]'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">live</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'click'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">return</span> request<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> url <span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">href</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// remote forms handler</span>
$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'form[data-remote=true]'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">live</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'submit'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">return</span> request<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> url <span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">action</span><span style="color: #339933;">,</span> type <span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">method</span><span style="color: #339933;">,</span> data <span style="color: #339933;">:</span> $<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">serialize</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>




<p>The above code will send an <span class="caps">AJAX </span>request when you click on a remote link or submit a remote form. Note that it will work also with new elements dynamically inserted to the <span class="caps">DOM.</span> The example JavaScript code is the bare minimum of course, we could have something much more sophisticated. We will be able to specify success and failure handlers and also elements that should be updated with an <span class="caps">AJAX </span>response text (and probably much more!), hence the JavaScript is going to be more complicated.</p>

<p>This is definitely a step into the right direction. I&#8217;m looking forward to Rails 3!</p>]]></content:encoded>
			<wfw:commentRss>http://blog.solnic.eu/2009/09/08/unobtrusive-javascript-helpers-in-rails-3/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Back From the Dead – a batch update</title>
		<link>http://blog.solnic.eu/2009/06/24/back-from-the-dead-a-batch-update</link>
		<comments>http://blog.solnic.eu/2009/06/24/back-from-the-dead-a-batch-update#comments</comments>
		<pubDate>Tue, 23 Jun 2009 23:46:25 +0000</pubDate>
		<dc:creator>solnic</dc:creator>
				<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://blog.solnic.eu/?p=176</guid>
		<description><![CDATA[
			
				
			
		Wow, it&#8217;s been a while since I wrote last post. I guess I suck at writing posts on a regular basis. Hopefully I will be able to change that   So&#8230;a lot has happened recently and I&#8217;ve been quite busy. First of all about 3 months ago I bought my very own apartment. The [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a  href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.solnic.eu%2F2009%2F06%2F24%2Fback-from-the-dead-a-batch-update">
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.solnic.eu%2F2009%2F06%2F24%2Fback-from-the-dead-a-batch-update&amp;source=s0lnic&amp;style=normal&amp;service=bit.ly" height="61" width="50" />
			</a>
		</div><p>Wow, it&#8217;s been a while since I wrote last post. I guess I suck at writing posts on a regular basis. Hopefully I will be able to change that <img src='http://blog.solnic.eu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  So&#8230;a lot has happened recently and I&#8217;ve been quite busy. First of all about 3 months ago I bought my very own apartment. The whole process of getting a bank credit took 2 months and it was sucking my energy without any mercy. But&#8230;I did it and I&#8217;m alive <img src='http://blog.solnic.eu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  No more renting, I&#8217;ve got my own home. Me and the bank of course, haha.</p>

<p>Anyway now it&#8217;s time to get back to the Web and let people know what I&#8217;ve been working on.</p>

<h4>Utype</h4>

<p>At Lunar Logic Polska we&#8217;ve migrated <a  href="http://www.lunarlogicpolska.com">our site</a> to <a  href="http://www.utype.org">Utype</a> which aims to be a modern, flexible, user <strong>and</strong> developer friendly <span class="caps">CMS.</span> It&#8217;s currently based on Merb and DataMapper. Our plan is to migrate it to Rails3 later this year. If you are interested in the development please have a look at the official <a  href="http://github.com/LunarLogicPolska/utype">GitHub repository</a></p>

<h4>RubyTime</h4>

<p>Again, at Lunar Logic Polska we&#8217;ve spent last couple of months working on a new version of our time tracking system. Version 3.1 will include some new features and many bug fixes. We should release it in July. You can see the progress <a  href="http://rubytime.lighthouseapp.com/projects/19293/milestones/40471-release-31">at LightHouse site</a>. The release will support external clients too &#8211; an iPhone app (by <a  href="http://psionides.jogger.pl">Kuba Suder</a>) and a <span class="caps">KDE4 </span>plasmoid (by <a  href="http://sickill.net/">Marcin Kulik</a>). RubyTime is an open source project, sources can be found at the official <a  href="http://github.com/LunarLogicPolska/rubytime">GitHub repository</a></p>

<h4>DataMapper related goodies</h4>

<p>That&#8217;s a fresh meat for me. I&#8217;ve resurrected a plugin that I&#8217;ve originally created to use with Utype and now after some hacking <a  href="http://github.com/solnic/dm-is-configurable">dm-is-configurable</a> is compatible with DataMapper 0.10.0 <span class="caps">RC1 </span>and will be officially released whenever DataMapper 0.10 is finished, which should happen soon.</p>

<p>During my recent work for <a  href="http://www.ideeli.com">Ideeli</a> I had to deal with Google Data <span class="caps">API </span>which I&#8217;ve found relatively simple to use via <a  href="http://code.google.com/apis/gdata/articles/using_ruby.html">Ruby GData lib</a>; however I would love to have even better way to access that <span class="caps">API, </span>hence I&#8217;ve created <a  href="http://github.com/solnic/dm-gdata-adapters">dm-gdata-adapters</a>. The only thing that works there is loging in, but stay tuned! I&#8217;m going to write a wrapper around Spreadsheet <span class="caps">API </span>for a good start and hopefully I will find some people to help me with the rest of the <span class="caps">API</span>s. If you are interested just drop me a line.</p>

<h4><span class="caps">KDE4 </span>related goodies</h4>

<p>I&#8217;ve been experimenting with Plasma and trying to write a simple plasmoid (in Ruby or Python) which would replace Skype notifications. Current status is&#8230;double fail. I&#8217;m using an <span class="caps">SVN </span>snapshot of the upcoming <span class="caps">KDE</span> 4.3 and I&#8217;m having various issues with Ruby and Python bindings. pykde4 doesn&#8217;t work well with the <a  href="https://developer.skype.com/wiki/Skype4Py">Skype4Py</a> library so I&#8217;m trying to use Ruby which seems to be unstable at the moment&#8230;oh well. We will see how it goes when <span class="caps">KDE</span> 4.3 <span class="caps">RC1 </span>is released (which will happen in a week <img src='http://blog.solnic.eu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ).</p>

<h4>Me at Lunar Logic Polska</h4>

<p>A couple of weeks ago I became responsible for implementing high standards of development at our company. We&#8217;ve created a list of various best practices that we&#8217;re following and now I&#8217;m one of the persons that make sure we&#8217;re really doing it. The process includes things like organizing regular code reviews, keeping track on the test coverage status for each of the projects that we&#8217;re working on, sharing knowledge between the teams etc&#8230;We will write a blog post on <a  href="http://www.lunarlogicpolska.com/blog">our site</a> soon which will describe everything in detail as we believe it might be useful for other companies.</p>

<p><span class="caps">OK.</span> Batch mode turned off. I&#8217;m glad I finally have the time (and energy) to write something here! G&#8217;nite</p>]]></content:encoded>
			<wfw:commentRss>http://blog.solnic.eu/2009/06/24/back-from-the-dead-a-batch-update/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My sweet desktop environment – KDE 4.2 RC</title>
		<link>http://blog.solnic.eu/2009/01/18/my-sweet-desktop-environment-kde-42-rc</link>
		<comments>http://blog.solnic.eu/2009/01/18/my-sweet-desktop-environment-kde-42-rc#comments</comments>
		<pubDate>Sun, 18 Jan 2009 22:09:15 +0000</pubDate>
		<dc:creator>solnic</dc:creator>
				<category><![CDATA[KDE]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[linux gentoo kde]]></category>

		<guid isPermaLink="false">http://blog.solnic.eu/?p=94</guid>
		<description><![CDATA[
			
				
			
		About a month ago I installed Gentoo Linux on my MacBook Pro as I&#8217;ve become really disappointed with OSX. Being a linux user for a few years it&#8217;s hard to get used to such a limited operating system like OSX&#8230;Anyway I just want to show you some screenshots of a just released KDE 4.2 RC [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a  href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.solnic.eu%2F2009%2F01%2F18%2Fmy-sweet-desktop-environment-kde-42-rc">
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.solnic.eu%2F2009%2F01%2F18%2Fmy-sweet-desktop-environment-kde-42-rc&amp;source=s0lnic&amp;style=normal&amp;service=bit.ly" height="61" width="50" />
			</a>
		</div><p>About a month ago I installed Gentoo Linux on my MacBook Pro as I&#8217;ve become really disappointed with <span class="caps">OSX.</span> Being a linux user for a few years it&#8217;s hard to get used to such a limited operating system like <span class="caps">OSX&#8230;A</span>nyway I just want to show you some screenshots of <a  href="http://www.kde.org/announcements/announce-4.2-rc.php">a just released <span class="caps">KDE</span> 4.2 RC</a> that is totally amazing&#8230;</p>

<h4>Main Desktop Activity</h4>

<p>This is where I work. I have two &#8220;Folder Views&#8221; with my Home and Downloads folders. There&#8217;s also a trash plasmoid, a big one so I can easily drop files there even when I&#8217;m drunk <img src='http://blog.solnic.eu/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>

<p><a  href="http://www.flickr.com/photos/11849631@N03/3206984239/" title="KDE4 - My Main Desktop Activity" class="flickr-image" rel="flickr-mgr"><img src="http://farm4.static.flickr.com/3115/3206984239_c6f67f14c1.jpg" alt="KDE4 - My Main Desktop Activity" class="flickr-large aligncenter"   /></a></p>

<h4>Multimedia Activity</h4>

<p>Here I have &#8220;Folder Views&#8221; of my Music and Video folders and a filtered Downloads &#8220;Folder View&#8221; where only multimedia files and folders are displayed. Those 2 icons in the upper-right corner are Amarok and <span class="caps">SMP</span>layer shortcuts. Next to them is a &#8220;Now Playing&#8221; plasmoid. This is just the beginning of my Multimedia activity, but it&#8217;s already quite useful.</p>

<p><a  href="http://www.flickr.com/photos/11849631@N03/3206986799/" title="KDE4 - My Multimedia Activity" class="flickr-image" rel="flickr-mgr"><img src="http://farm4.static.flickr.com/3389/3206986799_0aeb1201dd.jpg" alt="KDE4 - My Multimedia Activity" class="flickr-large aligncenter"   /></a></p>

<h4>Tools Activity</h4>

<p>When my Mac is on fire I go here to see the temperatures of the hardware, as well as the <span class="caps">CPU </span>load and system messages from the log file. I can also check out my disk usage. Oh, and there are also calendar, dictionary and calculator plasmoids.</p>

<p><a  href="http://www.flickr.com/photos/11849631@N03/3206989033/" title="KDE4 - My Tools Activity" class="flickr-image" rel="flickr-mgr"><img src="http://farm4.static.flickr.com/3512/3206989033_56c9e38198.jpg" alt="KDE4 - My Tools Activity" class="flickr-large aligncenter"   /></a></p>

<h4>File manager &#8211; Dolphin</h4>

<p>I love this little yet powerful piece of an application. Dolphin <strong>is</strong> the best file manager I&#8217;ve ever used. It&#8217;s tiny, has all of the crucial features <strong><span class="caps">AND</span></strong> supports remote protocols. It also has &#8220;split view&#8221; which makes me so happy, that I don&#8217;t use Krusader (a twin panel file manager) anymore.</p>

<p><a  href="http://www.flickr.com/photos/11849631@N03/3207835768/" title="KDE4 - Dolphin" class="flickr-image" rel="flickr-mgr"><img src="http://farm4.static.flickr.com/3301/3207835768_578610dc97.jpg" alt="KDE4 - Dolphin" class="flickr-medium aligncenter"   /></a></p>

<h4>Music player &#8211; Amarok2</h4>

<p>There are people whining about the new Amarok2. Personally I love it. Simplified playlist view, extended context view (with activity-like zooming!), fantastic collection browser and a decent integration with Last <span class="caps">FM.</span> I don&#8217;t need anything more.</p>

<p><a  href="http://www.flickr.com/photos/11849631@N03/3207838088/" title="KDE4 - Amarok2" class="flickr-image" rel="flickr-mgr"><img src="http://farm4.static.flickr.com/3348/3207838088_8b0ca58974.jpg" alt="KDE4 - Amarok2" class="flickr-medium aligncenter"   /></a></p>

<h4>Document viewer &#8211; Okular</h4>

<p>Perfect for my needs and it doesn&#8217;t start 3 minutes like Adobe Reader.</p>

<p><a  href="http://www.flickr.com/photos/11849631@N03/3206995761/" title="KDE4 - Okular" class="flickr-image" rel="flickr-mgr"><img src="http://farm4.static.flickr.com/3323/3206995761_552376bfe1.jpg" alt="KDE4 - Okular" class="flickr-medium aligncenter"   /></a></p>

<h4>Image viewer &#8211; Gwenview</h4>

<p>Gwenview is terrible in <span class="caps">KDE</span> 3.x series, but in <span class="caps">KDE4 </span>it&#8217;s superior! It&#8217;s integrated with semantic desktop feature of <span class="caps">KDE4 </span>too so you can search and filter by tags and ratings.</p>

<p><a  href="http://www.flickr.com/photos/11849631@N03/3207843092/" title="KDe4 - Gwenview" class="flickr-image" rel="flickr-mgr"><img src="http://farm4.static.flickr.com/3509/3207843092_2b55c5c006.jpg" alt="KDe4 - Gwenview" class="flickr-medium aligncenter"   /></a></p>

<h4>Quick Access &#8211; KRunner</h4>

<p>This is something like QuickSilver in <span class="caps">OSX.</span> I use KRunner to open applications or access files, but you can use it for many other tasks like calculations, spell checking, opening web bookmarks etc.</p>

<p><a  href="http://www.flickr.com/photos/11849631@N03/3206994179/" title="KDE4 - KRunner" class="flickr-image" rel="flickr-mgr"><img src="http://farm4.static.flickr.com/3446/3206994179_76664978bd.jpg" alt="KDE4 - KRunner" class="flickr-large aligncenter"   /></a></p>

<p>&#8230;it&#8217;s so good to use <span class="caps">KDE </span>again, I feel I can breath again.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.solnic.eu/2009/01/18/my-sweet-desktop-environment-kde-42-rc/feed</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Client-side rendering with Prototype</title>
		<link>http://blog.solnic.eu/2009/01/15/client-side-rendering-with-prototype</link>
		<comments>http://blog.solnic.eu/2009/01/15/client-side-rendering-with-prototype#comments</comments>
		<pubDate>Thu, 15 Jan 2009 21:49:49 +0000</pubDate>
		<dc:creator>solnic</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[prototype]]></category>

		<guid isPermaLink="false">http://blog.solnic.eu/?p=71</guid>
		<description><![CDATA[
			
				
			
		Web applications are getting more and more complex. The user interface of a modern web application can be as rich as its desktop equivalent. If we use JavaScript/HTML/CSS trio to build this UI then we definitely want to use AJAX. A typical approach is to use AJAX to update parts of our page using an [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a  href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.solnic.eu%2F2009%2F01%2F15%2Fclient-side-rendering-with-prototype">
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.solnic.eu%2F2009%2F01%2F15%2Fclient-side-rendering-with-prototype&amp;source=s0lnic&amp;style=normal&amp;service=bit.ly" height="61" width="50" />
			</a>
		</div><p>Web applications are getting more and more complex. The user interface of a modern web application can be as rich as its desktop equivalent. If we use JavaScript/HTML/CSS trio to build this UI then we definitely want to use <span class="caps">AJAX.</span> A typical approach is to use <span class="caps">AJAX </span>to update parts of our page using an <span class="caps">HTML </span>response, everyone knows that, right? Does this approach allow us to create a responsive, fast and flexible UI? The answer is no.</p>

<p>Here are 4 main downsides of using <span class="caps">AJAX </span>requests to load UI parts:</p>


<ul>
<li>You increase the server load &#8211; yes, you make an <span class="caps">AJAX </span>request only because you need a piece of <span class="caps">HTML </span>code that you want to insert to an already rendered page. That was cool a few years ago when <span class="caps">AJAX </span>was such a great innovation. Nowadays it should be considered as a less efficient solution.</li>
</ul>




<ul>
<li>You complicate the server-side code &#8211; because you need parts of your page to be returned by the server you, obviously, need to handle that by writing more server-side code. You end up having many actions in your controllers that return different fragments of <span class="caps">HTML.</span> I know, you think it&#8217;s normal, everyone does that.</li>
</ul>




<ul>
<li>You loose a lot of control over the UI &#8211; you use <span class="caps">DHTML </span>techniques to deal with the UI and in the same time you need the server to get parts of that <span class="caps">UI.</span> This leads to a code duplication and in many cases ends up with a big mess.</li>
</ul>




<ul>
<li>A user will have to wait until a request is done &#8211; that just sucks, that poor guy has to wait because you went back to the server for a little piece of <span class="caps">HTML.</span> How you are going to implement a responsive UI this way? &#8220;Your servers are fast&#8221;. Of course they are, but what if user&#8217;s <span class="caps">ISP </span>sucks? What if the user is downloading something and 99% of his bandwidth is gone?</li>
</ul>



<p>Rendering <span class="caps">HTML </span>on the client-side is ridiculously simple. Consider the following example. Let&#8217;s say we have a page with a list of some people, the list is just a simple <span class="caps">HTML </span>table. It could look like this:</p>


<div class="wp_codebox"><table><tr id="p7110"><td class="code" id="p71code10"><pre class="html" style="font-family:monospace;">&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;First Name&lt;/th&gt;
      &lt;th&gt;Last Name&lt;/th&gt;
      &lt;th&gt;E-Mail&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody id=&quot;people&quot;&gt;
    &lt;!-- here go people --&gt;
  &lt;tbody&gt;
  &lt;tfoot&gt;
    &lt;tr colspan=&quot;4&quot;&gt;
      &lt;td&gt;
        &lt;a id=&quot;previous&quot; href=&quot;#&quot;&gt;Previous&lt;/a&gt; 
        &lt;a id=&quot;next&quot; href=&quot;#&quot;&gt;Next&lt;/a&gt;
      &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tfoot&gt;
&lt;/table&gt;</pre></td></tr></table></div>




<p>As you can see the tbody element is empty, we will load its content after the entire page is loaded. Instead of a bunch of &#8220;tr&#8221; elements the server should return a nice <span class="caps">JSON </span>data which could look like this:</p>


<div class="wp_codebox"><table><tr id="p7111"><td class="code" id="p71code11"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> people <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span>
 <span style="color: #009900;">&#123;</span> id <span style="color: #339933;">:</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> first_name <span style="color: #339933;">:</span> <span style="color: #3366CC;">'John'</span><span style="color: #339933;">,</span> last_name <span style="color: #339933;">:</span> <span style="color: #3366CC;">'Doe'</span><span style="color: #339933;">,</span> email <span style="color: #339933;">:</span> <span style="color: #3366CC;">'john.doe@somewhere.com'</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
 <span style="color: #009900;">&#123;</span> id <span style="color: #339933;">:</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">,</span> first_name <span style="color: #339933;">:</span> <span style="color: #3366CC;">'Jane'</span><span style="color: #339933;">,</span> last_name <span style="color: #339933;">:</span> <span style="color: #3366CC;">'Doe'</span><span style="color: #339933;">,</span> email <span style="color: #339933;">:</span> <span style="color: #3366CC;">'jane.doe@anywhere.com'</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
 <span style="color: #009900;">&#123;</span> id <span style="color: #339933;">:</span> <span style="color: #CC0000;">3</span><span style="color: #339933;">,</span> first_name <span style="color: #339933;">:</span> <span style="color: #3366CC;">'Third'</span><span style="color: #339933;">,</span> last_name <span style="color: #339933;">:</span> <span style="color: #3366CC;">'Guy'</span><span style="color: #339933;">,</span> email <span style="color: #339933;">:</span> <span style="color: #3366CC;">'third.guy@nowhere.com'</span> <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>




<p>To render these data we obviously need a template. Prototype gives us a handy class called <a  href="http://prototypejs.org/api/template">Template</a> which is perfect for our needs. To create a template and render the list of people we need a few lines of JavaScript:</p>


<div class="wp_codebox"><table><tr id="p7112"><td class="code" id="p71code12"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> personRowTemplate <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Template<span style="color: #009900;">&#40;</span>
  <span style="color: #3366CC;">'&lt;tr id=&quot;person_#{id}&quot;&gt;&lt;td&gt;#{first_name}&lt;/td&gt;&lt;td&gt;#{last_name}&lt;/td&gt;&lt;td&gt;#{email}&lt;/td&gt;&lt;/tr&gt;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> peopleRows <span style="color: #339933;">=</span> <span style="color: #3366CC;">''</span><span style="color: #339933;">;</span>
&nbsp;
people.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>person<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> 
  peopleRows <span style="color: #339933;">+=</span> personRowTemplate.<span style="color: #660066;">evaluate</span><span style="color: #009900;">&#40;</span>person<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'people'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">update</span><span style="color: #009900;">&#40;</span>peopleRows<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>




<p>That&#8217;s pretty much it. It doesn&#8217;t look spectacular, huh? Now just think about the benefits of this approach:</p>


<ul>
<li>You have the data in <span class="caps">JSON </span>format, you can use them to render things like an edit form without going back to the server, thus user experience will be better</li>
</ul>




<ul>
<li>You can be focused on building a nice <span class="caps">JSON API </span>for accessing data instead of implementing actions that return small pieces of <span class="caps">HTML</span></li>
</ul>




<ul>
<li>Your client-side code is cleaner and more consistent</li>
</ul>



<p>Sounds like a good deal, doesn&#8217;t it? <img src='http://blog.solnic.eu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>]]></content:encoded>
			<wfw:commentRss>http://blog.solnic.eu/2009/01/15/client-side-rendering-with-prototype/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>My brand new blog and WordPress</title>
		<link>http://blog.solnic.eu/2008/12/31/my-brand-new-blog-and-wordpress</link>
		<comments>http://blog.solnic.eu/2008/12/31/my-brand-new-blog-and-wordpress#comments</comments>
		<pubDate>Wed, 31 Dec 2008 13:54:04 +0000</pubDate>
		<dc:creator>solnic</dc:creator>
				<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://blog.solnic.eu/?p=65</guid>
		<description><![CDATA[
			
				
			
		Because of the rails &#38; merb merge thing I have decided to hold off on working on Utype until the merge is finished. Unfortunately I don&#8217;t have enough time to finish Utype using Merb 1.x just to port it to Merb 2.x and then to Rails 3.0. As a side effect of my decision I [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a  href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.solnic.eu%2F2008%2F12%2F31%2Fmy-brand-new-blog-and-wordpress">
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.solnic.eu%2F2008%2F12%2F31%2Fmy-brand-new-blog-and-wordpress&amp;source=s0lnic&amp;style=normal&amp;service=bit.ly" height="61" width="50" />
			</a>
		</div><p>Because of <a  href="http://yehudakatz.com/2008/12/23/rails-and-merb-merge">the rails &amp; merb merge thing</a> I have decided to hold off on working on <a  href="http://github.com/solnic/utype">Utype</a> until the merge is finished. Unfortunately I don&#8217;t have enough time to finish Utype using Merb 1.x just to port it to Merb 2.x and then to Rails 3.0. As a side effect of my decision I have migrated my Utype-based blog to Wordpress, which is a scary <span class="caps">PHP</span>-based piece of software with one important advantage &#8211; it does the job right. It&#8217;s not as cool as I thought but I will be using it anyway since it&#8217;s probably the best <span class="caps">CMS </span>out there (at the moment&#8230;:)).</p>

<p>The fact that I&#8217;m using Wordpress now and I don&#8217;t spend hours working on my own <span class="caps">CMS </span>system means that finally I will have time to write something here more frequently.</p>

<p>&#8230;and <span class="caps">BTW </span>- Happy New Year Everyone <img src='http://blog.solnic.eu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>]]></content:encoded>
			<wfw:commentRss>http://blog.solnic.eu/2008/12/31/my-brand-new-blog-and-wordpress/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>jQuery vs Prototype – part II</title>
		<link>http://blog.solnic.eu/2008/02/03/jquery-vs-prototype-part-ii</link>
		<comments>http://blog.solnic.eu/2008/02/03/jquery-vs-prototype-part-ii#comments</comments>
		<pubDate>Sun, 03 Feb 2008 18:15:00 +0000</pubDate>
		<dc:creator>solnic</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[prototype]]></category>

		<guid isPermaLink="false">http://blog.solnic.eu/2008/2/3/jquery-vs-prototype-part-ii</guid>
		<description><![CDATA[
			
				
			
		Recently, new versions of jQuery and Prototype have been released &#8211; it&#8217;s a perfect moment for a part number 2. On the official Prototype blog we can read that the general performance of CSS selectors is now improved, unfortunately only for Safari 3, but Element#up/#down/#next/#previous should now be faster on all browsers, it&#8217;s a good [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a  href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.solnic.eu%2F2008%2F02%2F03%2Fjquery-vs-prototype-part-ii">
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.solnic.eu%2F2008%2F02%2F03%2Fjquery-vs-prototype-part-ii&amp;source=s0lnic&amp;style=normal&amp;service=bit.ly" height="61" width="50" />
			</a>
		</div><p>Recently, new versions of jQuery and Prototype have been released &#8211; it&#8217;s a perfect moment for a part number 2. On the official Prototype blog we <a  href="http://www.prototypejs.org/2008/1/25/prototype-1-6-0-2-bug-fixes-performance-improvements-and-security">can read</a> that the general performance of <span class="caps">CSS </span>selectors is now improved, unfortunately only for Safari 3, but Element#up/#down/#next/#previous should now be faster on all browsers, it&#8217;s a good news as they were really slow. On the other hand we have jQuery <a  href="http://jquery.com/blog/2008/01/15/jquery-122-2nd-birthday-present">official announcement</a> with information that jQuery is now 300% faster &#8211; we&#8217;ll see!</p>

<p>This time I made a step forward and decided to use a custom JavaScript-based testing environment instead of running tests using Firebug profiler. The obvious advantage is that I was able to run all the tests on 4 different browsers. New test cases aren&#8217;t much different then in the first part, let&#8217;s say it&#8217;s a modification of the previous ones with some extra operations and a little more complex <span class="caps">HTML </span>structure.</p>

<h3>Test environment setup</h3>

<p>Libraries:</p>


<ul>
<li>jQuery 1.2.2</li>
<li>Prototype 1.6.0.2</li>
</ul>



<p>All the tests were run on the following browsers:</p>


<ul>
<li>Firefox 2.0.0.11</li>
<li>Konqueror 4.00.00</li>
<li>Opera 9.50_beta1</li>
<li>Internet Explorer 7 (*but using Windows on VirtualBox!*)</li>
</ul>



<p>A tiny piece of JavaScript code is responsible for running the tests, each operation is called only once inside a try-catch block, so the essential part looks like this:</p>


<div class="wp_codebox"><table><tr id="p2132"><td class="code" id="p21code32"><pre class="javascript" style="font-family:monospace;">    <span style="color: #000066; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #003366; font-weight: bold;">var</span> start <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #339933;">;</span>
      test<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #003366; font-weight: bold;">var</span> end <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Date <span style="color: #339933;">-</span> start<span style="color: #339933;">;</span>
      <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">writeResults</span><span style="color: #009900;">&#40;</span>test<span style="color: #339933;">,</span> end<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">catch</span><span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      test.<span style="color: #660066;">resultCell</span>.<span style="color: #660066;">innerHTML</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'&lt;div style=&quot;color: red&quot;&gt;Exception caught: '</span><span style="color: #339933;">+</span>e.<span style="color: #660066;">message</span><span style="color: #339933;">+</span><span style="color: #3366CC;">'&lt;/div&gt;'</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></td></tr></table></div>




<p>There is a 3 seconds break between each test run, results are automatically inserted into the results table. If you want, you can check it out on your own, just go <a  href="/test_runner/index.html">right here</a> and hit the &#8216;run tests!&#8217; button.</p>

<h3>The results</h3>

<p>I&#8217;m happy to see that all tests pass on the latest Konqueror, previous version from <span class="caps">KDE3 </span>fails on some Prototype tests. I don&#8217;t own Mac, so you won&#8217;t see Safari results here, although I&#8217;ve run the tests on my friend&#8217;s MacBook with very similar hardware as my laptop has (Intel Core Duo 2ghz + 2 gigs of <span class="caps">RAM</span>), and it was faster even then Konqueror (no, it doesn&#8217;t mean his MacBook is faster then my laptop!!!! <img src='http://blog.solnic.eu/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> ).</p>

<p>I&#8217;ve run everything 3 times, here are average results in ms:</p>

<table id="test_results" class="test_results">
  <col style="width:12px"/><br />
  <col style="width:55px"/><br />
  <col style="width:220px"/><br />
  <col style="width:24px"/><br />
  <col style="width:24px"/><br />
  <col style="width:24px"/><br />
  <col style="width:24px"/><br />
  <tbody><br />
  <tr>
    <th>#</th>
    <th>Library</th>
    <th>Test</th>
    <th>Firefox</th>
    <th>Konqueror</th>
    <th><span class="caps">IE7</span></th>
    <th>Opera</th>
  </tr>
  <tr>
    <td rowspan="2"><b>1</b></td>
    <td style="color: red;">jQuery</td>
    <td>


<div class="wp_codebox"><table><tr id="p2133"><td class="code" id="p21code33"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.counter'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">addClass</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'marked'</span><span style="color: #009900;">&#41;</span></pre></td></tr></table></div>


</td>
    <td>96.6</td>
    <td>32.3</td>
    <td class="jq_faster">70</td>
    <td class="jq_faster">37</td>
  </tr>
  <tr>
    <td style="color: blue;">Prototype</td>
    <td>


<div class="wp_codebox"><table><tr id="p2134"><td class="code" id="p21code34"><pre class="javascript" style="font-family:monospace;">$$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.counter'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>el<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> 
  el.<span style="color: #660066;">addClassName</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'marked'</span><span style="color: #009900;">&#41;</span> 
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span></pre></td></tr></table></div>


</td>
    <td>108.3</td>
    <td>49.6</td>
    <td>858</td>
    <td>75.7</td>
  </tr>
  <tr>
    <td rowspan="2"><b>2</b></td>
    <td style="color: red;">jQuery</td>
    <td>


<div class="wp_codebox"><table><tr id="p2135"><td class="code" id="p21code35"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.counter span.special'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">removeClass</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'special'</span><span style="color: #009900;">&#41;</span></pre></td></tr></table></div>


</td>
    <td>62</td>
    <td>23.6</td>
    <td class="jq_faster">46.6</td>
    <td>25.6</td>
  </tr>
  <tr>
    <td style="color: blue;">Prototype</td>
    <td>


<div class="wp_codebox"><table><tr id="p2136"><td class="code" id="p21code36"><pre class="javascript" style="font-family:monospace;">$$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.counter span.special'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>el<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> 
  el.<span style="color: #660066;">removeClassName</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'special'</span><span style="color: #009900;">&#41;</span> 
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span></pre></td></tr></table></div>


</td>
    <td class="proto_faster">28</td>
    <td>23.7</td>
    <td>167</td>
    <td>24.7</td>
  </tr>
  <tr>
    <td rowspan="2"><b>3</b></td>
    <td style="color: red;">jQuery</td>
    <td>


<div class="wp_codebox"><table><tr id="p2137"><td class="code" id="p21code37"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.content span.odd'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">css</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'color'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'red'</span><span style="color: #009900;">&#41;</span></pre></td></tr></table></div>


</td>
    <td>124.7</td>
    <td>40.3</td>
    <td class="jq_faster">63.7</td>
    <td>38.3</td>
  </tr>
  <tr>
    <td style="color: blue;">Prototype</td>
    <td>


<div class="wp_codebox"><table><tr id="p2138"><td class="code" id="p21code38"><pre class="javascript" style="font-family:monospace;">$$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.content span.odd'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>el<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> 
  el.<span style="color: #660066;">setStyle</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'color: red'</span><span style="color: #009900;">&#41;</span> 
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span></pre></td></tr></table></div>


</td>
    <td class="proto_faster">55.7</td>
    <td>31</td>
    <td>297</td>
    <td>33.7</td>
  </tr>
  <tr>
    <td rowspan="2"><b>4</b></td>
    <td style="color: red;">jQuery</td>
    <td>


<div class="wp_codebox"><table><tr id="p2139"><td class="code" id="p21code39"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.content span.even'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">before</span><span style="color: #009900;">&#40;</span>
  <span style="color: #3366CC;">'&lt;h3 style=&quot;display: none&quot;&gt;text&lt;/h3&gt;'</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">&lt;/</span>code</pre></td></tr></table></div>


</pre></td>
    <td>382.7</td>
    <td>177.3</td>
    <td>373.7</td>
    <td>205.3</td>
  </tr>
  <tr>
    <td style="color: blue;">Prototype</td>
    <td>


<div class="wp_codebox"><table><tr id="p2140"><td class="code" id="p21code40"><pre class="javascript" style="font-family:monospace;">$$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.content span.even'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>el<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> 
  el.<span style="color: #660066;">insert</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> 
    before<span style="color: #339933;">:</span><span style="color: #3366CC;">'&lt;h3 style=&quot;display:none&quot;&gt;text&lt;/h3&gt;'</span> 
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span> 
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span></pre></td></tr></table></div>


</td>
    <td>359</td>
    <td class="proto_faster">90.7</td>
    <td>527</td>
    <td class="proto_faster">138.7</td>
  </tr>
  <tr>
    <td rowspan="2"><b>5</b></td>
    <td style="color: red;">jQuery</td>
    <td>


<div class="wp_codebox"><table><tr id="p2141"><td class="code" id="p21code41"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.content h3'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">show</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span></pre></td></tr></table></div>


</td>
    <td>178.7</td>
    <td>227.7</td>
    <td class="jq_faster">83.3</td>
    <td>1161.7</td>
  </tr>
  <tr>
    <td style="color: blue;">Prototype</td>
    <td>


<div class="wp_codebox"><table><tr id="p2142"><td class="code" id="p21code42"><pre class="javascript" style="font-family:monospace;">$$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.content h3'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span>Element.<span style="color: #660066;">show</span><span style="color: #009900;">&#41;</span></pre></td></tr></table></div>


</td>
    <td class="proto_faster">38</td>
    <td class="proto_faster">21</td>
    <td>250.7</td>
    <td class="proto_faster">19</td>
  </tr>
  <tr>
    <td rowspan="2"><b>6</b></td>
    <td style="color: red;">jQuery</td>
    <td>


<div class="wp_codebox"><table><tr id="p2143"><td class="code" id="p21code43"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'div.special'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">hide</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span></pre></td></tr></table></div>


</td>
    <td>90</td>
    <td>81.3</td>
    <td class="jq_faster">33.7</td>
    <td>375.3</td>
  </tr>
  <tr>
    <td style="color: blue;">Prototype</td>
    <td>


<div class="wp_codebox"><table><tr id="p2144"><td class="code" id="p21code44"><pre class="javascript" style="font-family:monospace;">$$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'div.special'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span>Element.<span style="color: #660066;">hide</span><span style="color: #009900;">&#41;</span></pre></td></tr></table></div>


</td>
    <td>18</td>
    <td>7</td>
    <td>73.3</td>
    <td>12</td>
  </tr>
  <tr>
    <td rowspan="2"><b>7</b></td>
    <td style="color: red;">jQuery</td>
    <td>


<div class="wp_codebox"><table><tr id="p2145"><td class="code" id="p21code45"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'div.special, td.content .odd'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toggle</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span></pre></td></tr></table></div>


</td>
    <td>637.7</td>
    <td>431.7</td>
    <td>517</td>
    <td>1360.3</td>
  </tr>
  <tr>
    <td style="color: blue;">Prototype</td>
    <td>


<div class="wp_codebox"><table><tr id="p2146"><td class="code" id="p21code46"><pre class="javascript" style="font-family:monospace;">$$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'div.special, td.content .odd'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span>Element.<span style="color: #660066;">toggle</span><span style="color: #009900;">&#41;</span></pre></td></tr></table></div>


</td>
    <td class="proto_faster">71</td>
    <td class="proto_faster">43.7</td>
    <td class="proto_faster">106.7</td>
    <td class="proto_faster">43</td>
  </tr>
  <tr>
    <td rowspan="2"><b>8</b></td>
    <td style="color: red;">jQuery</td>
    <td>


<div class="wp_codebox"><table><tr id="p2147"><td class="code" id="p21code47"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'span.odd'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">remove</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span></pre></td></tr></table></div>


</td>
    <td>132.7</td>
    <td>59.3</td>
    <td>123.3</td>
    <td>66.7</td>
  </tr>
  <tr>
    <td style="color: blue;">Prototype</td>
    <td>


<div class="wp_codebox"><table><tr id="p2148"><td class="code" id="p21code48"><pre class="javascript" style="font-family:monospace;">$$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'span.odd'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span>Element.<span style="color: #660066;">remove</span><span style="color: #009900;">&#41;</span></pre></td></tr></table></div>


</td>
    <td class="proto_faster">29</td>
    <td class="proto_faster">11.7</td>
    <td class="proto_faster">36.7</td>
    <td class="proto_faster">19.3</td>
  </tr>
  <tr>
    <td rowspan="2"><b>9</b></td>
    <td style="color: red;">jQuery</td>
    <td>


<div class="wp_codebox"><table><tr id="p2149"><td class="code" id="p21code49"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#data p.lost:first'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">html</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'gotcha!'</span><span style="color: #009900;">&#41;</span></pre></td></tr></table></div>


</td>
    <td class="jq_faster">5</td>
    <td>1.7</td>
    <td>10</td>
    <td class="jq_faster">3.3</td>
  </tr>
  <tr>
    <td style="color: blue;">Prototype</td>
    <td>


<div class="wp_codebox"><table><tr id="p2150"><td class="code" id="p21code50"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'data'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">down</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'p.lost'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">update</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'gotcha!'</span><span style="color: #009900;">&#41;</span></pre></td></tr></table></div>


</td>
    <td>11.7</td>
    <td>2</td>
    <td>10</td>
    <td>7.3</td>
  </tr>
</tbody><br />
</table>

<script src="/javascripts/results_table.js" type="text/javascript"></script>

<h3>Conclusion #2</h3>

<p>Prototype was at least 2 times faster then jQuery in 15 cases, and jQuery was faster then Prototype in 8 cases. What library should I choose? In my case I will stick with Prototype, because it offers the same functionality as jQuery does + more and it's faster. jQuery is probably better for projects where there's a need for some fancy UI effects and that's it, but it's just an assumption, correct me if I'm wrong...</p>]]></content:encoded>
			<wfw:commentRss>http://blog.solnic.eu/2008/02/03/jquery-vs-prototype-part-ii/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>jQuery vs Prototype – part I</title>
		<link>http://blog.solnic.eu/2007/11/11/jquery-vs-prototype-part-i</link>
		<comments>http://blog.solnic.eu/2007/11/11/jquery-vs-prototype-part-i#comments</comments>
		<pubDate>Sun, 11 Nov 2007 21:30:00 +0000</pubDate>
		<dc:creator>solnic</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[prototype]]></category>

		<guid isPermaLink="false">http://blog.solnic.eu/2007/11/11/jquery-vs-prototype-part-i</guid>
		<description><![CDATA[
			
				
			
		Prototype 1.6.0 was released to the public 4 days ago, at first I decided to check its performance and new features in comparison to the previous version, but being interested in other JavaScript libraries, I&#8217;ve changed my mind. Lets see how you can accomplish same tasks with the latest Prototype and jQuery libraries and simply [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a  href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.solnic.eu%2F2007%2F11%2F11%2Fjquery-vs-prototype-part-i">
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.solnic.eu%2F2007%2F11%2F11%2Fjquery-vs-prototype-part-i&amp;source=s0lnic&amp;style=normal&amp;service=bit.ly" height="61" width="50" />
			</a>
		</div><p>Prototype 1.6.0 was released to the public 4 days ago, at first I decided to check its performance and new features in comparison to the previous version, but being interested in other JavaScript libraries, I&#8217;ve changed my mind. Lets see how you can accomplish same tasks with the latest <a  href="http://www.prototypejs.org">Prototype</a> and <a  href="http://jquery.com">jQuery</a> libraries and simply see which one is faster. In this part I&#8217;m going to show the results of running single operations, in next part(s) I will prepare a sample website and write more complex test cases and, again, check how fast jQuery and Prototype can be (or how slow&#8230;).</p>

<h3>Test environment setup</h3>

<p>The following software was used:</p>


<ul>
<li>Prototype 1.6.0</li>
<li>jQuery 1.2.1</li>
<li>Firefox 2.0.0.9</li>
<li>Firebug 1.05</li>
<li>Webdeveloper 1.1.4</li>
</ul>



<p>Test page contains only one table with 500 rows, it&#8217;s generated using the following <span class="caps">RHTML </span>template:</p>


<div class="wp_codebox"><table><tr id="p2275"><td class="code" id="p22code75"><pre class="html" style="font-family:monospace;">&lt;table&gt;
&lt;% (1..500).each do |i| %&gt;
  &lt;tr&gt;
    &lt;td class=&quot;first&quot;&gt;
      &lt;div&gt;&lt;%= i %&gt;&lt;/div&gt;
    &lt;/td&gt;
    &lt;td class=&quot;second&quot;&gt;
      &lt;div&gt;&lt;%= &quot;hello from #{i}&quot; %&gt;&lt;/div&gt;
    &lt;/td&gt;
  &lt;/tr&gt;
&lt;% end %&gt;
&lt;/table&gt;</pre></td></tr></table></div>




<h3>Running the tests</h3>

<p>Each operation was executed using Firebug&#8217;s console with Profiler turned on and repeated 3 times, between each execution the page was reloaded. Cache in Firefox was disabled using Webdeveloper plugin. Here are the results of 7 test operations showing average times and number of method calls in each operation:</p>

<p>1. Adding &#8216;marked&#8217; <span class="caps">CSS </span>class to every cell having &#8216;first&#8217; <span class="caps">CSS </span>class:</p>

<table class="test_results" id="test_results">
  <tr>
    <th>Library</th>
    <th>Operation</th>
    <th>Time (ms)</th>
    <th>Method Calls</th>
  </tr>
  <tr>
    <td>jQuery</td>
    <td class="code">


<div class="wp_codebox"><table><tr id="p2276"><td class="code" id="p22code76"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.first'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">addClass</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'marked'</span><span style="color: #009900;">&#41;</span></pre></td></tr></table></div>


</td>
    <td>102.495</td>
    <td>3032</td>
  </tr>
  <tr>
    <td>Prototype #1</td>
    <td class="code">


<div class="wp_codebox"><table><tr id="p2277"><td class="code" id="p22code77"><pre class="javascript" style="font-family:monospace;">$$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.first'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>cell<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> cell.<span style="color: #660066;">addClassName</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'marked'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>


</td>
    <td>117.162</td>
    <td>7056</td>
  </tr>
  <tr>
    <td>Prototype #2</td>

    <td class="code">


<div class="wp_codebox"><table><tr id="p2278"><td class="code" id="p22code78"><pre class="javascript" style="font-family:monospace;">$$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.first'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">invoke</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'addClassName'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'marked'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>


</td>
    <td>129.972</td>
    <td>8062</td>
  </tr>
</table>

<p><em>Comment</em>: no practical difference, although jQuery is a little faster.</p>

<p>2. Removing <span class="caps">CSS </span>class from every table cell having &#8220;second&#8221; CSS class:</p>

<table class="test_results" id="test_results">
  <tr>
    <th>Library</th>
    <th>Operation</th>
    <th>Time (ms)</th>
    <th>Method Calls</th>
  </tr>
  <tr>
    <td>jQuery</td>
    <td class="code">


<div class="wp_codebox"><table><tr id="p2279"><td class="code" id="p22code79"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.second'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">removeClass</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'second'</span><span style="color: #009900;">&#41;</span></pre></td></tr></table></div>


</td>
    <td>109.855</td>
    <td>3032</td>
  </tr>
  <tr>
    <td>Prototype #1</td>
    <td class="code">


<div class="wp_codebox"><table><tr id="p2280"><td class="code" id="p22code80"><pre class="javascript" style="font-family:monospace;">$$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.second'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>cell<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> cell.<span style="color: #660066;">removeClassName</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'second'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>


</td>
    <td>87.445</td>
    <td>4551</td>
  </tr>
  <tr>
    <td>Prototype #2</td>
    <td class="code">


<div class="wp_codebox"><table><tr id="p2281"><td class="code" id="p22code81"><pre class="javascript" style="font-family:monospace;">$$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.second'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">invoke</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'removeClassName'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'second'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>


</td>
    <td>100.64</td>
    <td>5557</td>
  </tr>
</table>

<p><em>Comment</em>: No big difference, especially when comparing Prototype #2 option with jQuery.</p>

<p>3. Setting &#8216;color&#8217; <span class="caps">CSS </span>property in every div element which is inside a cell having &#8217;second&#8217; <span class="caps">CSS </span>class:</p>

<table class="test_results" id="test_results">
  <tr>
    <th>Library</th>
    <th>Operation</th>
    <th>Time (ms)</th>
    <th>Method Calls</th>
  </tr>
  <tr>
    <td>jQuery</td>
    <td class="code">


<div class="wp_codebox"><table><tr id="p2282"><td class="code" id="p22code82"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.second div'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">css</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'color'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'red'</span><span style="color: #009900;">&#41;</span></pre></td></tr></table></div>


</td>
    <td>173.906</td>
    <td>3536</td>
  </tr>
  <tr>
    <td>Prototype #1</td>
    <td class="code">


<div class="wp_codebox"><table><tr id="p2283"><td class="code" id="p22code83"><pre class="javascript" style="font-family:monospace;">$$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.second div'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>el<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> el.<span style="color: #660066;">setStyle</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> color <span style="color: #339933;">:</span> <span style="color: #3366CC;">'red'</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>


</td>
    <td>87.585</td>
    <td>4563</td>
  </tr>
  <tr>
    <td>Prototype #2</td>
    <td class="code">


<div class="wp_codebox"><table><tr id="p2284"><td class="code" id="p22code84"><pre class="javascript" style="font-family:monospace;">$$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.second div'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>el<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> el.<span style="color: #660066;">setStyle</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'color : red'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>


</td>
    <td>98.283</td>
    <td>5064</td>
  </tr>
  <tr>
    <td>Prototype #3</td>
    <td class="code">


<div class="wp_codebox"><table><tr id="p2285"><td class="code" id="p22code85"><pre class="javascript" style="font-family:monospace;">$$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.second div'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">invoke</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'setStyle'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'color : red'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>


</td>

    <td>107.81</td>
    <td>6070</td>
  </tr>
</table>

<p><em>Comment</em>: Same here, Prototype 2 x faster</p>

<p>4. Adding new elements before every div element which is inside a cell having &#8217;second&#8217; <span class="caps">CSS </span>class:</p>

<table class="test_results" id="test_results">
  <tr>
    <th>Library</th>
    <th>Operation</th>
    <th>Time (ms)</th>
    <th>Method Calls</th>
  </tr>
  <tr>
    <td>jQuery</td>
    <td class="code">


<div class="wp_codebox"><table><tr id="p2286"><td class="code" id="p22code86"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.second div'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">before</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&amp;lt;h3&amp;gt;text&amp;lt;/h3&amp;gt;'</span><span style="color: #009900;">&#41;</span></pre></td></tr></table></div>


</td>
    <td>368.611</td>
    <td>15066</td>
  </tr>
  <tr>
    <td>Prototype #1</td>
    <td class="code">


<div class="wp_codebox"><table><tr id="p2287"><td class="code" id="p22code87"><pre class="javascript" style="font-family:monospace;">$$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.second div'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>el<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> el.<span style="color: #660066;">insert</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> before<span style="color: #339933;">:</span> <span style="color: #3366CC;">'&amp;lt;h3&amp;gt;text&amp;lt;/h3&amp;gt;'</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>


</td>
    <td>1252.016</td>
    <td>17088</td>
  </tr>
  <tr>
    <td>Prototype #2</td>
    <td class="code">


<div class="wp_codebox"><table><tr id="p2288"><td class="code" id="p22code88"><pre class="javascript" style="font-family:monospace;">$$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.second div'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">invoke</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'insert'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> before<span style="color: #339933;">:</span> <span style="color: #3366CC;">'&amp;lt;h3&amp;gt;text&amp;lt;/h3&amp;gt;'</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>


</td>

    <td>1316.969</td>
    <td>19096</td>
  </tr>
</table>

<p><em>Comment</em>: Wow&#8230;jQuery is almost 4 times faster, I should point out that <a  href="http://www.prototypejs.org/api/element/insert">Element#insert</a> is a new method introduced in Prototype 1.6.0.</p>

<p>5. Removing all div elements which are inside cells having &#8217;second&#8217; <span class="caps">CSS </span>class:</p>

<table class="test_results" id="test_results">
  <tr>
    <th>Library</th>
    <th>Operation</th>
    <th>Time (ms)</th>
    <th>Method Calls</th>
  </tr>
  <tr>
    <td>jQuery</td>
    <td class="code">


<div class="wp_codebox"><table><tr id="p2289"><td class="code" id="p22code89"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.second div'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">remove</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span></pre></td></tr></table></div>


</td>
    <td>151.955</td>
    <td>2032</td>
  </tr>
  <tr>
    <td>Prototype #1</td>
    <td class="code">


<div class="wp_codebox"><table><tr id="p2290"><td class="code" id="p22code90"><pre class="javascript" style="font-family:monospace;">$$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.second div'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span>Element.<span style="color: #660066;">remove</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>


</td>
    <td>65.785</td>
    <td>3060</td>
  </tr>
  <tr>
    <td>Prototype #2</td>
    <td class="code">


<div class="wp_codebox"><table><tr id="p2291"><td class="code" id="p22code91"><pre class="javascript" style="font-family:monospace;">$$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.second div'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">invoke</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'remove'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>


</td>
    <td>94,105</td>
    <td>5068</td>
  </tr>
  <tr>
    <td>Prototype #3</td>
    <td class="code">


<div class="wp_codebox"><table><tr id="p2292"><td class="code" id="p22code92"><pre class="javascript" style="font-family:monospace;">$$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.second div'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>el<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> el.<span style="color: #660066;">remove</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>


</td>
    <td>83.591</td>
    <td>4062</td>
  </tr>
</table>

<p><em>Comment</em>: Prototype more then 2 times faster.</p>

<p>6. Hiding and un-hiding all div elements which are inside cells having &#8217;second&#8217; <span class="caps">CSS </span>class:</p>

<table class="test_results" id="test_results">
  <tr>
    <th>Library</th>
    <th>Operation</th>
    <th>Time (ms)</th>
    <th>Method Calls</th>
  </tr>
  <tr>
    <td>jQuery</td>
    <td class="code">


<div class="wp_codebox"><table><tr id="p2293"><td class="code" id="p22code93"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.second div'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toggle</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.second div'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toggle</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>


</td>
    <td>1948.825</td>
    <td>47653</td>
  </tr>
  <tr>
    <td>Prototype #1</td>
    <td class="code">


<div class="wp_codebox"><table><tr id="p2294"><td class="code" id="p22code94"><pre class="javascript" style="font-family:monospace;">$$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.second div'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span>Element.<span style="color: #660066;">toggle</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>$$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.second div'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span>Element.<span style="color: #660066;">toggle</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>


</td>
    <td>158.987</td>
    <td>14106</td>
  </tr>
  <tr>
    <td>Prototype #2</td>
    <td class="code">


<div class="wp_codebox"><table><tr id="p2295"><td class="code" id="p22code95"><pre class="javascript" style="font-family:monospace;">$$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.second div'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>el<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> el.<span style="color: #660066;">toggle</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> $$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.second div'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>el<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> el.<span style="color: #660066;">toggle</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>


</td>
    <td>191.096</td>
    <td>16110</td>
  </tr>
</table>


<p><em>Comment</em>: jQuery tragedy, Prototype toggles visibility of 500 divs 10 times faster!</p>

<p>7. Attaching event listeners to all div elements which are inside cells having &#8217;second&#8217; <span class="caps">CSS </span>class:</p>

<table class="test_results" id="test_results">
  <tr>
    <th>Library</th>
    <th>Operation</th>
    <th>Time (ms)</th>
    <th>Method Calls</th>
  </tr>
  <tr>
    <td>jQuery</td>
    <td class="code">


<div class="wp_codebox"><table><tr id="p2296"><td class="code" id="p22code96"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.second div'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">bind</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'click'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">innerHTML</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span></pre></td></tr></table></div>


</td>
    <td>146.19</td>
    <td>3535</td>
  </tr>
  <tr>
    <td>Prototype #1</td>
    <td class="code">


<div class="wp_codebox"><table><tr id="p2297"><td class="code" id="p22code97"><pre class="javascript" style="font-family:monospace;">$$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.second div'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">invoke</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'observe'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'click'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">innerHTML</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>


</td>
    <td>169,889</td>
    <td>11581</td>
  </tr>
  <tr>
    <td>Prototype #2</td>
    <td class="code">


<div class="wp_codebox"><table><tr id="p2298"><td class="code" id="p22code98"><pre class="javascript" style="font-family:monospace;">$$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td.second div'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>el<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> el.<span style="color: #660066;">observe</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'click'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">innerHTML</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>


</td>
    <td>164.456</td>
    <td>10575</td>
  </tr>
</table>


<p><em>Comment</em>: no practical difference.</p>

<h3>General conclusion and impression</h3>

<p>Executed tests show that Prototype seems to be faster then jQuery, with the exception of the new insertion method, which performance should be improved. Although I like jQuery syntax more then Prototype, the performance is way more important then saving few lines of code. Of course tests that I made don&#8217;t show how these libraries act in a real application, which is my task for the next part(s) of this article. Despite the results I must admit that I&#8217;m very excited about jQuery, my general impression is that this library is more mature then Prototype.</p>

<p>You may want to check out <a  href="http://blog.solnic.eu/2008/2/3/jquery-vs-prototype-part-ii">part ||</a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.solnic.eu/2007/11/11/jquery-vs-prototype-part-i/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why JavaScript helpers in rails are evil</title>
		<link>http://blog.solnic.eu/2007/10/30/why-javascript-helpers-in-rails-are-evil</link>
		<comments>http://blog.solnic.eu/2007/10/30/why-javascript-helpers-in-rails-are-evil#comments</comments>
		<pubDate>Tue, 30 Oct 2007 00:00:00 +0000</pubDate>
		<dc:creator>solnic</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://blog.solnic.eu/2007/10/30/why-javascript-helpers-in-rails-are-evil</guid>
		<description><![CDATA[
			
				
			
		Ruby on Rails gained so much attention and appreciation mostly because it simplifies the development process of AJAX-driven applications. When I started to learn Rails I was already very familiar with other MVC-based frameworks, and actually I&#8217;ve created one myself (in PHP5) in my previous work. My framework also uses Prototype JavaScript library, so when [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a  href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.solnic.eu%2F2007%2F10%2F30%2Fwhy-javascript-helpers-in-rails-are-evil">
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.solnic.eu%2F2007%2F10%2F30%2Fwhy-javascript-helpers-in-rails-are-evil&amp;source=s0lnic&amp;style=normal&amp;service=bit.ly" height="61" width="50" />
			</a>
		</div><p>Ruby on Rails gained so much attention and appreciation mostly because it simplifies the development process of <span class="caps">AJAX</span>-driven applications. When I started to learn Rails I was already very familiar with other <span class="caps">MVC</span>-based frameworks, and actually I&#8217;ve created one myself (in <span class="caps">PHP5</span>) in my previous work. My framework also uses Prototype JavaScript library, so when l was learning Rails it was nothing new when I saw &#8220;Ajax.Updater(&#8230;)&#8221;. I remember that when I added first <span class="caps">AJAX</span>-feature in the Depot (it&#8217;s a tutorial application used in well known &#8220;Agile Web Development in Ruby on Rails&#8221; book)  <strong>I was shocked</strong> about how simple it is, but then I looked into the <span class="caps">HTML </span>output and it shocked me once more&#8230;</p>

<h3>JavaScript Helpers</h3>

<p>These nice methods generate for you <span class="caps">HTML </span>with some addition of JavaScript code, one can say &#8220;You don&#8217;t need to know JavaScript to create <span class="caps">AJAX </span>web apps! Just use Ruby on Rails!&#8221;. It&#8217;s a catchy slogan, and in some way it&#8217;s true, you don&#8217;t need to know how Ajax.Request works, you just write link_to_remote and you&#8217;re done. In Rails <span class="caps">API </span>you can find 4 helper modules, all related to JavaScript code generation, and here they are:</p>

<p> * <a  href="http://api.rubyonrails.org/classes/ActionView/Helpers/JavaScriptHelper.html">General JavaScript Helpers</a> &#8211; actually there&#8217;s nothing interesting there<br />
 * <a  href="http://api.rubyonrails.org/classes/ActionView/Helpers/JavaScriptMacrosHelper.html">JavaScript Macros Helpers</a> &#8211; whole thing is deprecated in the upcoming Rails 2.0<br />
 * <a  href="http://api.rubyonrails.org/classes/ActionView/Helpers/PrototypeHelper.html">Prototype Helpers</a> &#8211; probably the most popular methods, including link_to_remote and other <span class="caps">AJAX </span>goodies<br />
 * <a  href="http://api.rubyonrails.org/classes/ActionView/Helpers/ScriptaculousHelper.html">Scriptaculous Helpers</a> &#8211; you know, drag&#8217;n'drop and visual effects goodies</p>

<p>When I first saw what link_to_remote helper creates I was really surprised, back then I said to myself &#8220;hey, that&#8217;s&#8230;just bad!&#8221;. Unfortunately I had quickly forgotten about my negative thoughts on JavaScript helpers, because &#8220;everybody&#8221; use them, and that&#8217;s a shame in my opinion. I don&#8217;t know why JavaScript helpers are included in the Rails core, maybe it was just a pure marketing trick or something <img src='http://blog.solnic.eu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  So, what&#8217;s so evil about JavaScript helpers?</p>

<h3><span class="caps">DRY </span>- ooooh reaaally?</h3>

<p>We, the Ruby on Rails developers, use proudly our favorite <span class="caps">MVC </span>framework, we remember everyday about Don&#8217;t Repeat Yourself principle and other good and well known practices. How come that people like us write scary pieces of code like this:</p>


<div class="wp_codebox"><table><tr id="p23107"><td class="code" id="p23code107"><pre class="xhtml" style="font-family:monospace;">&lt;table id=&quot;users_list&quot;&gt;
  &lt;% @users.each do |user| -%&gt;
  &lt;tr id=&quot;user_&lt;%= user.id %&gt;&quot;&gt;
    &lt;td&gt;&lt;%= user.login %&gt;&lt;/td&gt;
    &lt;td&gt;
      &lt;%= link_to_remote(
             'Delete',
             :url =&gt; user_path(user),
             :method =&gt; 'delete',
             :confirm =&gt; 'Are you sure?',
             :complete =&gt; &quot;Effect.DropOut('user_#{user.id}')&quot;,
             :failure =&gt; 'alert(&quot;Could not delete user: #{user.login}&quot;)'
          )
      %&gt;
    &lt;/td&gt;
  &lt;/tr&gt;
  &lt;% end -%&gt;
&lt;/table&gt;
  &lt;% end %&gt;
&lt;/table&gt;</pre></td></tr></table></div>




<p>Pretty common rhtml snippet, right?? (yes, I know, we use partials, but it&#8217;s just an example) Let&#8217;s have a look at the <span class="caps">HTML </span>output:</p>


<div class="wp_codebox"><table><tr id="p23108"><td class="code" id="p23code108"><pre class="html" style="font-family:monospace;">&lt;table id=&quot;users_list&quot;&gt;
    &lt;tr id=&quot;user_2&quot;&gt;
    &lt;td&gt;jane&lt;/td&gt;
    &lt;td&gt;
      &lt;a href=&quot;#&quot; onclick=&quot;if (confirm('Are you sure?')) { new Ajax.Request('/users/2', {asynchronous:true, evalScripts:true, method: 'delete', onComplete:function(request){Effect.DropOut('user_2')}, onFailure:function(request){alert('Could not delete user: jane')}}); }; return false;&quot;&gt;Delete&lt;/a&gt;
    &lt;/td&gt;
  &lt;/tr&gt;
    &lt;tr id=&quot;user_1&quot;&gt;
    &lt;td&gt;john&lt;/td&gt;
    &lt;td&gt;
      &lt;a href=&quot;#&quot; onclick=&quot;if (confirm('Are you sure?')) { new Ajax.Request('/users/1', {asynchronous:true, evalScripts:true, method: 'delete', onComplete:function(request){Effect.DropOut('user_1')}, onFailure:function(request){alert('Could not delete user: john')}}); }; return false;&quot;&gt;Delete&lt;/a&gt;
    &lt;/td&gt;
  &lt;/tr&gt;
    &lt;tr id=&quot;user_4&quot;&gt;
    &lt;td&gt;paul&lt;/td&gt;
    &lt;td&gt;
      &lt;a href=&quot;#&quot; onclick=&quot;if (confirm('Are you sure?')) { new Ajax.Request('/users/4', {asynchronous:true, evalScripts:true, method: 'delete', onComplete:function(request){Effect.DropOut('user_4')}, onFailure:function(request){alert('Could not delete user: paul')}}); }; return false;&quot;&gt;Delete&lt;/a&gt;
    &lt;/td&gt;
  &lt;/tr&gt;
    &lt;tr id=&quot;user_3&quot;&gt;
    &lt;td&gt;peter&lt;/td&gt;
    &lt;td&gt;
      &lt;a href=&quot;#&quot; onclick=&quot;if (confirm('Are you sure?')) { new Ajax.Request('/users/3', {asynchronous:true, evalScripts:true, method: 'delete', onComplete:function(request){Effect.DropOut('user_3')}, onFailure:function(request){alert('Could not delete user: peter')}}); }; return false;&quot;&gt;Delete&lt;/a&gt;
    &lt;/td&gt;
  &lt;/tr&gt;
  &lt;/table&gt;</pre></td></tr></table></div>




<p><strong>Where did <span class="caps">DRY </span>go?</strong> Hello? Why we don&#8217;t apply our <span class="caps">OOP </span>practices also to JavaScript? &#8220;Why bother!?&#8221; you might ask, well, <span class="caps">BECAUSE</span> IT <span class="caps">MATTERS.</span></p>

<h3>JavaScript won&#8217;t hurt you</h3>

<p>Creating webapps without a good understanding of JavaScript is like working with ActiveRecord and having no idea what <span class="caps">SQL </span>is. I think you know what I mean. There are plenty of great JavaScript libraries, Ruby on Rails comes with <a  href="http://www.prototypejs.org">Prototype</a> and it makes writing JavaScript as easy&amp;cool as writing Ruby code. Okey, here&#8217;s above example without redundancy, the quickest solution would be:</p>


<div class="wp_codebox"><table><tr id="p23109"><td class="code" id="p23code109"><pre class="html" style="font-family:monospace;">&lt;table id=&quot;users_list&quot;&gt;
  &lt;% @users.each do |user| -%&gt;
  &lt;tr id=&quot;user_&lt;%= user.id %&gt;&quot;&gt;
    &lt;td&gt;&lt;%= user.login %&gt;&lt;/td&gt;
    &lt;td&gt;&lt;%= link_to 'Delete', '#', :onclick =&gt; &quot;deleteUser(#{user.id})&quot; %&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;% end -%&gt;
&lt;/table&gt;</pre></td></tr></table></div>




<p>And in application.js (or wherever else):</p>


<div class="wp_codebox"><table><tr id="p23110"><td class="code" id="p23code110"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> deleteUser<span style="color: #009900;">&#40;</span>userId<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000066;">confirm</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Are you sure?'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">new</span> Ajax.<span style="color: #660066;">Request</span><span style="color: #009900;">&#40;</span>
       <span style="color: #3366CC;">'/users/'</span><span style="color: #339933;">+</span>userId<span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
         method <span style="color: #339933;">:</span> <span style="color: #3366CC;">'delete'</span><span style="color: #339933;">,</span>
         on200 <span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> Effect.<span style="color: #660066;">DropOut</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'user_'</span><span style="color: #339933;">+</span>userId<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
         on500 <span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>xhr<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>xhr.<span style="color: #660066;">responseText</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>




<p>Now, our ouput looks like this:</p>


<div class="wp_codebox"><table><tr id="p23111"><td class="code" id="p23code111"><pre class="html" style="font-family:monospace;">&lt;table id=&quot;users_list&quot;&gt;
  &lt;tr&gt;
  &lt;tr id=&quot;user_2&quot;&gt;
    &lt;td&gt;jane&lt;/td&gt;
    &lt;td&gt;&lt;a href=&quot;#&quot; onclick=&quot;deleteUser(2)&quot;&gt;Delete&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr id=&quot;user_1&quot;&gt;
    &lt;td&gt;john&lt;/td&gt;
    &lt;td&gt;&lt;a href=&quot;#&quot; onclick=&quot;deleteUser(1)&quot;&gt;Delete&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr id=&quot;user_4&quot;&gt;
    &lt;td&gt;paul&lt;/td&gt;
    &lt;td&gt;&lt;a href=&quot;#&quot; onclick=&quot;deleteUser(4)&quot;&gt;Delete&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr id=&quot;user_3&quot;&gt;
    &lt;td&gt;peter&lt;/td&gt;
    &lt;td&gt;&lt;a href=&quot;#&quot; onclick=&quot;deleteUser(3)&quot;&gt;Delete&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;</pre></td></tr></table></div>




<p>Advantages:<br />
* We don&#8217;t have a redundant JavaScript code in the <span class="caps">HTML </span>output<br />
* We are not limited to what link_to_remote generates<br />
* We have a generic JavaScript function which deletes a user, we can make it even more generic and use successfully in other places</p>

<p>Disadvantages:<br />
* Obtrusive JavaScript code in <span class="caps">HTML</span></p>

<h3>Progressive enhancement and unobtrusive JavaScript</h3>

<p>I found out about this approach about half a year ago, when I started to use Dan Webb&#8217;s <span class="caps">UJS </span>rails plugin which makes an extensive use of LowPro library. I was very excited about its functionality, thanks to that plugin I&#8217;ve stopped using JavaScript helpers. <span class="caps">UJS </span>is a dead project now, you can find out why <a  href="http://www.danwebb.net/2007/6/16/the-state-and-future-of-the-ujs-plugin">here</a> but it doesn&#8217;t matter, thanks to it I&#8217;ve learned two important things:</p>


<ul>
<li>We can divide View layer into two sub-layers: the presentation (HTML+CSS) and the behaviour (JavaScript)</li>
<li>Presentation layer can be extended using JavaScript by adding various behaviours to the <span class="caps">DOM </span>elements</li>
</ul>



<p>Currently I don&#8217;t use <span class="caps">UJS </span>or pure Low Pro, instead I just code my JavaScript using Prototype and Scriptaculous. Let&#8217;s see how this looks in practice. Here&#8217;s how our users table example could be implemented using progressive enhancement and unobtrusive JavaScript code. First of all, we&#8217;re going to create plain <span class="caps">HTML </span>links, without onclick event and without even href attribute (I assume we&#8217;re writing an application which requires JavaScript to work):</p>


<div class="wp_codebox"><table><tr id="p23112"><td class="code" id="p23code112"><pre class="html" style="font-family:monospace;">&lt;table id=&quot;users_list&quot;&gt;
  &lt;% @users.each do |user| -%&gt;
  &lt;tr id=&quot;user_&lt;%= user.id %&gt;&quot;&gt;
    &lt;td&gt;&lt;%= user.login %&gt;&lt;/td&gt;
    &lt;td&gt;&lt;a&gt;Delete&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;% end -%&gt;
&lt;/table&gt;</pre></td></tr></table></div>




<p>Above rhtml template generates this <span class="caps">HTML </span>output:</p>


<div class="wp_codebox"><table><tr id="p23113"><td class="code" id="p23code113"><pre class="html" style="font-family:monospace;">&lt;table id=&quot;users_list&quot;&gt;
  &lt;tr id=&quot;user_3&quot;&gt;
    &lt;td&gt;peter&lt;/td&gt;
    &lt;td&gt;&lt;a&gt;Delete&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr id=&quot;user_4&quot;&gt;
    &lt;td&gt;paul&lt;/td&gt;
    &lt;td&gt;&lt;a&gt;Delete&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr id=&quot;user_1&quot;&gt;
    &lt;td&gt;john&lt;/td&gt;
    &lt;td&gt;&lt;a&gt;Delete&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr id=&quot;user_2&quot;&gt;
    &lt;td&gt;jane&lt;/td&gt;
    &lt;td&gt;&lt;a&gt;Delete&lt;/a&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;</pre></td></tr></table></div>




<p>The very last thing to do is to add an actual functionality to our plain <span class="caps">HTML </span>code. Let&#8217;s create a simple module called Users, which will include method for deleting users:</p>


<div class="wp_codebox"><table><tr id="p23114"><td class="code" id="p23code114"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> Users <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
  onWindowLoad <span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'users_list'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">getElementsBySelector</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'tr'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>userRow<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
      userRow.<span style="color: #660066;">down</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'a'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">observe</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'click'</span><span style="color: #339933;">,</span> Users.<span style="color: #660066;">onUserDelete</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
  onUserDelete <span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>event<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000066;">confirm</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Are you sure?'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #003366; font-weight: bold;">var</span> userId <span style="color: #339933;">=</span> Event.<span style="color: #660066;">element</span><span style="color: #009900;">&#40;</span>event<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">up</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'tr'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">id</span>.<span style="color: #660066;">split</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'_'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">last</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #003366; font-weight: bold;">new</span> Ajax.<span style="color: #660066;">Request</span><span style="color: #009900;">&#40;</span>
       <span style="color: #3366CC;">'/users/'</span><span style="color: #339933;">+</span>userId<span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
         method <span style="color: #339933;">:</span> <span style="color: #3366CC;">'delete'</span><span style="color: #339933;">,</span>
         on200 <span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> Effect.<span style="color: #660066;">DropOut</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'user_'</span><span style="color: #339933;">+</span>userId<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
         on500 <span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>xhr<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>xhr.<span style="color: #660066;">responseText</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
Event.<span style="color: #660066;">observe</span><span style="color: #009900;">&#40;</span>window<span style="color: #339933;">,</span> <span style="color: #3366CC;">'load'</span><span style="color: #339933;">,</span> Users.<span style="color: #660066;">onWindowLoad</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>




<p>This way we:</p>


<ul>
<li>Write reusable and object oriented code</li>
<li>Create clean and easy to maintain <span class="caps">RHTML </span>templates</li>
<li>Have a clean separation between visual and behavior layers in our applications</li>
<li>Decrease site loading time by writing less JavaScript (you can even <a  href="http://synthesis.sbecker.net/pages/asset_packager">compress it</a> too)</li>
<li>Improve general performance of our application&#8217;s UI</li>
<li>Learn JavaScript! <img src='http://blog.solnic.eu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
</ul>



<h3>The final word</h3>

<p>I didn&#8217;t write anything about so called graceful degradation issue, leaving JavaScript helpers behind was the main reason for this article. If you totally disagree with me or/and you know an even better approach, leave a comment, I&#8217;m always open to a discussion.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.solnic.eu/2007/10/30/why-javascript-helpers-in-rails-are-evil/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
