<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/rss2full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><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:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>BenCurtis.com</title>
	
	<link>http://www.bencurtis.com</link>
	<description>Speculations on Web Development by Benjamin Curtis</description>
	<pubDate>Sat, 15 Nov 2008 16:23:44 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.3</generator>
	<language>en</language>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/bencurtis" type="application/rss+xml" /><item>
		<title>Drag and Drop Sorting with JQuery and Rails</title>
		<link>http://feeds.feedburner.com/~r/bencurtis/~3/438329203/</link>
		<comments>http://www.bencurtis.com/archives/2008/10/drag-and-drop-sorting-with-jquery-and-rails/#comments</comments>
		<pubDate>Fri, 31 Oct 2008 18:52:46 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
		
		<category><![CDATA[JQuery]]></category>

		<category><![CDATA[Javascript]]></category>

		<category><![CDATA[Plugins]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<category><![CDATA[Web Development]]></category>

		<category><![CDATA[web2.0]]></category>

		<guid isPermaLink="false">http://www.bencurtis.com/?p=162</guid>
		<description><![CDATA[	I decided to switch to JQuery recently, and I&#8217;ve been enjoying it.  Part of the fun is trying out all the plugins that are available. :)  This past week I needed to do drag and drop reordering for the first time since moving over to JQuery, so I thought I&#8217;d share some of [...]]]></description>
			<content:encoded><![CDATA[	<p>I decided to switch to JQuery recently, and I&#8217;ve been enjoying it.  Part of the fun is trying out all the plugins that are available. :)  This past week I needed to do drag and drop reordering for the first time since moving over to JQuery, so I thought I&#8217;d share some of the code that makes this really easy.</p>
	<p>With Prototype, you can use the javascript that comes with the Rails distribution, but for this case I decided to go with the <a href="http://www.isocra.com/2008/02/table-drag-and-drop-jquery-plugin/">Table Drag and Drop JQuery plugin</a>, as it had the right combination of functionality and ease of use.  Once the plugin is in your project, getting a sortable table is very simple.</p>
	<p>First up is the view, with the javascript injected into the head section of the document by using content_for.  You&#8217;ll note that for this simplified example an unordered list actually would have been better than a table, but in the original app I wanted to use a table for this list of items, so I wanted to make sure to use a plugin that supported that.</p>
	<p>After creating the table, we simply use the document ready event to add some behavior to it.  The plugin serializes the ids of the table rows in an array and sends that array, named after the table id, as a parameter to the controller.  I add the authenticity token to the parameters sent via AJAX, and if the action was successful I just pop up an alert.  </p>
	<p><script src="http://gist.github.com/21378.js"></script></p>
	<p>The controller iterates over all the specifications, checking the position in the db (see the <a href="http://github.com/rails/acts_as_list/tree/master">acts_as_list plugin</a>) versus the position in the array that was sent in the request.  For the items that are affected, it updates the position in the db.  Since we are only calling this action via AJAX, we just render nothing and indicate a successful status.</p>
	<p>Of course there are few bits you can pretty up, both in the view and the controller, but that&#8217;s the basic approach.  Fast, easy, and client-approved. :)</p>

 <div class="feedflare">
<a href="http://feeds.feedburner.com/~f/bencurtis?a=9UtjM"><img src="http://feeds.feedburner.com/~f/bencurtis?i=9UtjM" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/bencurtis/~4/438329203" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.bencurtis.com/archives/2008/10/drag-and-drop-sorting-with-jquery-and-rails/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.bencurtis.com/archives/2008/10/drag-and-drop-sorting-with-jquery-and-rails/</feedburner:origLink></item>
		<item>
		<title>Go to MerbCamp for free!</title>
		<link>http://feeds.feedburner.com/~r/bencurtis/~3/400420042/</link>
		<comments>http://www.bencurtis.com/archives/2008/09/go-to-merbcamp-for-free/#comments</comments>
		<pubDate>Tue, 23 Sep 2008 03:54:49 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
		
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.bencurtis.com/?p=159</guid>
		<description><![CDATA[	Kudos to the guys organizing MerbCamp for putting together an event that you can attend without breaking the bank.  But why spend even $50 when you can get in for free?
	I am sponsoring MerbCamp, but unfortunately I can&#8217;t make it there myself, and by being a sponsor I get two passes to attend MerbCamp [...]]]></description>
			<content:encoded><![CDATA[	<p>Kudos to the guys organizing <a href="http://www.merbcamp.com/">MerbCamp</a> for putting together an event that you can attend without breaking the bank.  But why spend even $50 when you can get in for free?</p>
	<p>I am sponsoring MerbCamp, but unfortunately I can&#8217;t make it there myself, and by being a sponsor I get two passes to attend MerbCamp that I won&#8217;t be able to use.  So, instead of wasting them, I thought I&#8217;d offer them to anyone who wants them.  So, if you want a free pass to MerbCamp, here&#8217;s what you need to do:</p>
	<p>Enter your name and email address via <a href="https://spreadsheets.google.com/viewform?key=pB-sq6nquUnBppmh46yPFHw">this Google doc</a> by 12:01 AM Pacific Time on Thursday, the 25th of September.  On Thursday morning, I will randomly select two people who submitted their info and let them know via email how to get the passes.  That&#8217;s all you have to do.</p>
	<p>While you&#8217;re dropping your name in the hat (as it were), do feel free to also drop a suggestion in the box if you have an idea for a Rails application that would make a great Rails Kit.  </p>
	<p>It&#8217;s a pleasure to be able to sponsor MerbCamp.  If you have a Ruby- or Rails-related event you&#8217;re coordinating that could use a sponsor, feel free to drop me a line.</p>


 <div class="feedflare">
<a href="http://feeds.feedburner.com/~f/bencurtis?a=NXabL"><img src="http://feeds.feedburner.com/~f/bencurtis?i=NXabL" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/bencurtis/~4/400420042" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.bencurtis.com/archives/2008/09/go-to-merbcamp-for-free/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.bencurtis.com/archives/2008/09/go-to-merbcamp-for-free/</feedburner:origLink></item>
		<item>
		<title>Find an office close to home</title>
		<link>http://feeds.feedburner.com/~r/bencurtis/~3/398142772/</link>
		<comments>http://www.bencurtis.com/archives/2008/09/find-an-office-close-to-home/#comments</comments>
		<pubDate>Sat, 20 Sep 2008 14:22:06 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
		
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.bencurtis.com/?p=157</guid>
		<description><![CDATA[	After I got a hold of Jacques&#8217; Map Rails Kit, I decided to try it out by scratching my own itch: I&#8217;m looking for a new office close to my home.  
	My current lease will be ending soon, so I figured it was a good time to do some comparison shopping.  So I [...]]]></description>
			<content:encoded><![CDATA[	<p>After I got a hold of Jacques&#8217; <a href="http://railskits.com/map/">Map Rails Kit</a>, I decided to try it out by scratching my own itch: I&#8217;m looking for a new office close to my home.  </p>
	<p>My current lease will be ending soon, so I figured it was a good time to do some comparison shopping.  So I turned to Craigslist to find out if there were any sweet sublease deals available.  The problem was that it&#8217;s a bit of a pain to use the Craigslist interface when your primary concern is proximity, as you have to click through to each post and then look at the address or click on the map link.  So, I wrote a script to do that for me, and used the <a href="http://railskits.com/map/">Map Rails Kit</a> to plot the locations.  And thus, <a href="http://officemapper.com/">OfficeMapper</a> was born.</p>
	<p><a href="http://officemapper.com/">OfficeMapper</a> shows you a map, with all the available office postings from Craigslist (that have an address listed) plotted on the map, making it easy for you to find what&#8217;s available near you.  Some Craigslist posting don&#8217;t have addresses, so I can&#8217;t show you those, but I find the site quite handy for those that do.  Once you click on a map location, you&#8217;ll get summary info about the listing, and a link back to Craigslist for more information.  It&#8217;s fun, useful, and a good example of how easy it is to create a map visualization in Rails.  All I had to do was find addresses, like &#8216;411 Market St Kirkland WA&#8217;, and create markers with those addresses.  The Map Kit took care of the rest.  </p>
	<p>I like easy. :)</p>

 <div class="feedflare">
<a href="http://feeds.feedburner.com/~f/bencurtis?a=QIsaL"><img src="http://feeds.feedburner.com/~f/bencurtis?i=QIsaL" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/bencurtis/~4/398142772" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.bencurtis.com/archives/2008/09/find-an-office-close-to-home/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.bencurtis.com/archives/2008/09/find-an-office-close-to-home/</feedburner:origLink></item>
		<item>
		<title>Populating more than one text box with Prototype’s Autocompleter</title>
		<link>http://feeds.feedburner.com/~r/bencurtis/~3/390077915/</link>
		<comments>http://www.bencurtis.com/archives/2008/09/populating-more-than-one-text-box-with-prototypes-autocompleter/#comments</comments>
		<pubDate>Thu, 11 Sep 2008 22:30:30 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
		
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.bencurtis.com/?p=148</guid>
		<description><![CDATA[	It took more than 30 seconds of digging to get this done, so I thought I&#8217;d share a quick-n-dirty way to use Prototype&#8217;s Autocompleter to update more than one text box when making a selection from the suggestion list.  As an added twist, I&#8217;ll also show you how to do this for a list [...]]]></description>
			<content:encoded><![CDATA[	<p>It took more than 30 seconds of digging to get this done, so I thought I&#8217;d share a quick-n-dirty way to use Prototype&#8217;s Autocompleter to update more than one text box when making a selection from the suggestion list.  As an added twist, I&#8217;ll also show you how to do this for a list of text boxes that can grow dynamically, so the text box&#8217;s id isn&#8217;t known.</p>
	<p>Here&#8217;s the scenario.  Imagine you are creating an admin UI for a CD store, and when editing a CD you want to allow the admin the edit the tracks that belong to the CD.  Additionally, you want to be able to click a button to add a new row via a javascript, so the admin can add multiple tracks with just one submit.  A snippet of your view on the CD edit page might look something like this:</p>
<div class="codesnip-container" ><div class="codesnip" style="font-family: monospace;"><span class="sc1">&lt;</span>table<span class="sc1">&gt;</span><br />

&nbsp; <span class="sc1">&lt;</span>thead<span class="sc1">&gt;</span><br />

&nbsp; &nbsp; <span class="sc1">&lt;</span>tr<span class="sc1">&gt;</span><br />

&nbsp; &nbsp; &nbsp; <span class="sc1">&lt;</span>th<span class="sc1">&gt;</span>Song Name<span class="sc1">&lt;</span>/th<span class="sc1">&gt;</span><br />

&nbsp; &nbsp; &nbsp; <span class="sc1">&lt;</span>th<span class="sc1">&gt;</span>Artist Name<span class="sc1">&lt;</span>/th<span class="sc1">&gt;</span><br />

&nbsp; &nbsp; <span class="sc1">&lt;</span>/tr<span class="sc1">&gt;</span><br />

&nbsp; <span class="sc1">&lt;</span>/thead<span class="sc1">&gt;</span><br />

&nbsp; <span class="sc1">&lt;</span>tbody id=<span class="sc1">&quot;</span>songs<span class="sc1">&quot;</span><span class="sc1">&gt;</span><br />

&nbsp; &nbsp; <span class="sc1">&lt;</span>%= render :partial =<span class="sc1">&gt;</span> <span class="sc1">&quot;</span>song<span class="sc1">&quot;</span>, :collection =<span class="sc1">&gt;</span> @cd.songs <span><span class="sc1">&gt;</span><br />

&nbsp; <span class="sc1">&lt;</span>/tbody<span class="sc1">&gt;</span><br />

<span class="sc1">&lt;</span>/table<span class="sc1">&gt;</span><br />

<span class="sc1">&lt;</span>p<span class="sc1">&gt;</span><br />

&nbsp; <span class="sc1">&lt;</span></span>= link_to_function(<span class="sc1">&quot;</span>Add a song<span class="sc1">&quot;</span>, <span class="sc1">&quot;</span>addRow()<span class="sc1">&quot;</span>) <span><span class="sc1">&gt;</span><br />

<span class="sc1">&lt;</span>/p<span class="sc1">&gt;</span><br />

<span class="sc1">&lt;</span>p<span class="sc1">&gt;</span><br />

&nbsp; <span class="sc1">&lt;</span></span>= f.submit <span class="sc1">&quot;</span>Save Changes<span class="sc1">&quot;</span> %<span class="sc1">&gt;</span><br />

<span class="sc1">&lt;</span>/p<span class="sc1">&gt;</span></div></div>
	<p>This is fairly standard stuff.  You have a list of songs in a table rendered by a partial.  The &#8220;Add a song&#8221; button calls the addRow function to insert some HTML in the table:</p>
<div class="codesnip-container" ><div class="codesnip" style="font-family: monospace;"><span class="kw2">function</span> addRow<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />

&nbsp; <span class="kw2">new</span> Insertion.<span class="me1">Bottom</span><span class="br0">&#40;</span><span class="st0">&#8216;songs&#8217;</span>, <span class="st0">&#8216;< %= escape_javascript(render(:partial => &quot;shared/song&quot;, :object => Song.new)) %>&#8216;</span><span class="br0">&#41;</span>;<br />

&nbsp; ...<br />

<span class="br0">&#125;</span></div></div>  
	<p>The partial has your typical text inputs rendered by the text_field helper.  To make the song title auto-complete-able, though, we add the class &#8220;text_complete&#8221; to it, and add a div with the class &#8220;auto_complete&#8221; (which will hold the suggestions) right after it.  And now, for the magic that allows you to auto-complete more than one text box at a time, when the text boxes are dynamically generated.  Let&#8217;s revisit that javascript:</p>
<div class="codesnip-container" ><div class="codesnip" style="font-family: monospace;"><span class="kw2">var</span> autocomplete_names = < %= Song.<span class="me1">all</span>.<span class="me1">collect</span> <span class="br0">&#123;</span>|s| %Q<span class="br0">&#123;</span><span <span class="kw2">class</span>=<span class="st0">&quot;song_name&quot;</span>>#<span class="br0">&#123;</span>s.<span class="kw3">name</span><span class="br0">&#125;</span><span <span class="kw2">class</span>=<span class="st0">&quot;artist_name&quot;</span>>#<span class="br0">&#123;</span>s.<span class="me1">artist_name</span><span class="br0">&#125;</span></span><span class="br0">&#125;</span> <span class="br0">&#125;</span>.<span class="me1">to_json</span> %><br />

<br />

<span class="kw2">function</span> addRow<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />

&nbsp; <span class="kw2">new</span> Insertion.<span class="me1">Bottom</span><span class="br0">&#40;</span><span class="st0">&#8216;songs&#8217;</span>, <span class="st0">&#8216;< %= escape_javascript(render(:partial => &quot;shared/song&quot;, :object => Song.new)) %>&#8216;</span><span class="br0">&#41;</span>;<br />

&nbsp; <span class="kw2">new</span> Autocompleter.<span class="me1">Local</span><span class="br0">&#40;</span>$$<span class="br0">&#40;</span><span class="st0">&#8217;.text_complete&#8217;</span><span class="br0">&#41;</span>.<span class="me1">last</span><span class="br0">&#40;</span><span class="br0">&#41;</span>, <br />

&nbsp; &nbsp; $$<span class="br0">&#40;</span><span class="st0">&#8217;.auto_complete&#8217;</span><span class="br0">&#41;</span>.<span class="me1">last</span><span class="br0">&#40;</span><span class="br0">&#41;</span>, <br />

&nbsp; &nbsp; autocomplete_names, <br />

&nbsp; &nbsp; <span class="br0">&#123;</span><br />

&nbsp; &nbsp; &nbsp; frequency: <span class="nu0">0.1</span>, <br />

&nbsp; &nbsp; &nbsp; select: <span class="st0">&#8216;song_name&#8217;</span>,<br />

&nbsp; &nbsp; &nbsp; afterUpdateElement: <span class="kw2">function</span><span class="br0">&#40;</span>target, selected<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />

&nbsp; &nbsp; &nbsp; &nbsp; target.<span class="me1">up</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">next</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">firstChild</span>.<span class="me1">value</span> = Element.<span class="me1">collectTextNodes</span><span class="br0">&#40;</span>$<span class="br0">&#40;</span>selected<span class="br0">&#41;</span>.<span class="me1">select</span><span class="br0">&#40;</span><span class="st0">&#8217;.artist_name&#8217;</span><span class="br0">&#41;</span><span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span>;<br />

&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />

&nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span>;<br />

<span class="br0">&#125;</span></div></div>
	<p>I&#8217;m using the Autocompleter.Local class here, as I like to pre-load the page with the suggestions to keep things snappy.  The first line of that javascript block does this, wrapping the song and artist names in spans that I can style and select on later when populating the text boxes.  After the HTML from the partial is inserted, a new Autocompleter.Local is create that populates the last text box with the &#8220;auto_complete&#8221; class&#8212;the one that just got inserted.  Likewise, the just-inserted div is used for displaying the suggestions.  The third argument is the array of song and artist names to use for the suggestion search.  The select option in the fourth argument tells the completer which class to use to populate the primary text box (the song name), and the afterUpdateElement option uses an anonymous function to populate the artist name text box, which lives in the table cell next to the song name text box, if there is an artist name.</p>
	<p>There are two caveats to this approach, though:<br />
<ol><br />
<li>I had to change line 455 of controls.js to match on \W rather than \s to still match at the beginning of the song name (ignoring the HTML markup in the array of suggestions)</li><br />
<li>Since both the artist name and song name are in the search string, the auto-suggest could find artists matching what you typed in the song name input box.  If I cared, I could solve this problem, but it&#8217;s not a big deal in my case.</li><br />
</ol></p>
 There you have it&#8212;easy updating of more than one text box with suggestions, even for text inputs created on the fly.  Enjoy!

 <div class="feedflare">
<a href="http://feeds.feedburner.com/~f/bencurtis?a=78G3L"><img src="http://feeds.feedburner.com/~f/bencurtis?i=78G3L" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/bencurtis/~4/390077915" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.bencurtis.com/archives/2008/09/populating-more-than-one-text-box-with-prototypes-autocompleter/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.bencurtis.com/archives/2008/09/populating-more-than-one-text-box-with-prototypes-autocompleter/</feedburner:origLink></item>
		<item>
		<title>Easy Google Maps Mashups with Rails</title>
		<link>http://feeds.feedburner.com/~r/bencurtis/~3/384351491/</link>
		<comments>http://www.bencurtis.com/archives/2008/09/easy-google-maps-mashups-with-rails/#comments</comments>
		<pubDate>Fri, 05 Sep 2008 17:15:12 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
		
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.bencurtis.com/?p=146</guid>
		<description><![CDATA[	Google has some great APIs for putting together mapping applications&#8230; but who wants to be bothered with having to read APIs? :)  Now you can have a map mashup with hardly any work at all, with the new Map Rails Kit.
	Created by Jacques Crocker, this Rails Kit makes it so easy to quickly build [...]]]></description>
			<content:encoded><![CDATA[	<p>Google has some great APIs for putting together mapping applications&#8230; but who wants to be bothered with having to read APIs? :)  Now you can have a map mashup with hardly any work at all, with the new <a href="http://railskits.com/map/">Map Rails Kit</a>.</p>
	<p>Created by <a href="http://railsjedi.com/">Jacques Crocker</a>, this Rails Kit makes it so easy to quickly build a Rails application with a mapping component.  I took this new Kit, wrote a script to fetch some addresses (which I&#8217;ll be blogging more about soon), and had a map with markers running within 10 minutes.  You don&#8217;t have to worry about geocoding, the javascript APIs, and so on&#8230; You just create a Marker record in the database with an address, and the Kit will geocode it for you and place the marker on the map.  It&#8217;s fun stuff.</p>
	<p>So, if you want to add some sort of mapping to your Rails application, make sure you check out the <a href="http://railskits.com/map/">Map Rails Kit</a>&#8212;it will save you a ton of time.</p>
	<p><strong>P.S.</strong> Another cool thing about this Kit is that I didn&#8217;t create it. :)  If, like Jacques, you have an idea for an application that would make a great Kit, feel free to <a href="http://www.bencurtis.com/contact/">drop me a line</a>, and maybe you can be the next Rails Kits author!</p>

 <div class="feedflare">
<a href="http://feeds.feedburner.com/~f/bencurtis?a=kozvL"><img src="http://feeds.feedburner.com/~f/bencurtis?i=kozvL" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/bencurtis/~4/384351491" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.bencurtis.com/archives/2008/09/easy-google-maps-mashups-with-rails/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.bencurtis.com/archives/2008/09/easy-google-maps-mashups-with-rails/</feedburner:origLink></item>
	</channel>
</rss>
