<?xml version="1.0" encoding="UTF-8"?>
<post>
  <body>&lt;p&gt;Although the version of &lt;a href=&quot;http://prototype-ui.com/&quot;&gt;Prototype-UI&lt;/a&gt; that is currently available is considered a release candidate, I found their carousel to be quite stable. I have yet to try out some of their other components, but the autocomplete does look quite promising. You can start off by &lt;a href=&quot;http://prototype-ui.com/download/rc0/carousel.zip&quot;&gt;downloading&lt;/a&gt; the code (javascript and css files) from their  server. Once you have extracted the files, put the &lt;strong&gt;carousel.js&lt;/strong&gt; and &lt;strong&gt;prototype-ui.css&lt;/strong&gt; in your sites public folder. You can also copy their next/back buttons as well, but I went ahead and created my own.&lt;/p&gt;
&lt;p&gt;I am going to assume that you have some model that contains an array of photos. In this example that model is called &lt;code&gt;album&lt;/code&gt;. In your view that you want the image carousel, put in the following rhtml:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;multiline_code&quot;&gt;&lt;span class=&quot;ta&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;id&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;horizontal_carousel&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;ta&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;ta&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;previous_button&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;ta&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;ta&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;ta&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;ta&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;ta&quot;&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;&amp;lt;!-- AJAX WILL INSERT PHOTOS --&amp;gt;&lt;/span&gt;&lt;span class=&quot;ta&quot;&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;ta&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;id&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;spinner&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;style&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;display: none;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;ta&quot;&gt;&amp;gt;&lt;/span&gt;Loading ...&lt;span class=&quot;ta&quot;&gt;&amp;lt;br&lt;/span&gt; &lt;span class=&quot;ta&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;span class=&quot;ta&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;ta&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;ta&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;next_button&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;ta&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;ta&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;ta&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;ta&quot;&gt;&amp;lt;script&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;text/javascript&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;ta&quot;&gt;&amp;gt;&lt;/span&gt;
 // &lt;span class=&quot;er&quot;&gt;&amp;lt;&lt;/span&gt;![CDATA[
      function runTest() {
        carousel = new UI.Ajax.Carousel(&amp;quot;horizontal_carousel&amp;quot;,
          {url: &amp;quot;/albums/&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;idl&quot;&gt;&amp;lt;%=&lt;/span&gt; album.id &lt;span class=&quot;idl&quot;&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;/elements&amp;quot;, elementSize: 140})
          .observe(&amp;quot;request:started&amp;quot;, function() {
                    $('spinner').show().morph(&amp;quot;opacity:0.8&amp;quot;, {duration:0.5});
            })
          .observe(&amp;quot;request:ended&amp;quot;, function() {
                    $('spinner').morph(&amp;quot;opacity:0&amp;quot;,
          {duration:0.5, afterFinish: function(obj) { obj.element.hide(); }});
            });
      }

      document.whenReady(runTest);
    // ]]&lt;span class=&quot;er&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;ta&quot;&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class=&quot;ta&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The important thing to notice here is the value of the URL passed to the &lt;code&gt;UI.Ajax.Carousel&lt;/code&gt; function call. I have decided to call the method that returns the request images &lt;code&gt;elements&lt;/code&gt;. It is found in the &lt;code&gt;album&lt;/code&gt; controller and is expecting the id of the album that contains the photos to be displayed.&lt;/p&gt;
&lt;p&gt;Next we will update our album&amp;#8217;s controller. This is the part that gave me the most trouble. I orignally though I just had to supply the HTML that should be inserted inside the UL element, however after some digging I found out that it was actually accepting JSON. Luckly for us, it&amp;#8217;s not that hard using some Rails magick.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;multiline_code&quot;&gt;&lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;elements&lt;/span&gt; 
  &lt;span class=&quot;iv&quot;&gt;@album&lt;/span&gt; = &lt;span class=&quot;co&quot;&gt;Album&lt;/span&gt;.find(params[&lt;span class=&quot;sy&quot;&gt;:id&lt;/span&gt;])

  count = &lt;span class=&quot;iv&quot;&gt;@album&lt;/span&gt;.photos.size - &lt;span class=&quot;i&quot;&gt;1&lt;/span&gt;
  to = [params[&lt;span class=&quot;sy&quot;&gt;:to&lt;/span&gt;].to_i, count].min
  from = params[&lt;span class=&quot;sy&quot;&gt;:from&lt;/span&gt;].to_i
  more = count != to ? &lt;span class=&quot;pc&quot;&gt;true&lt;/span&gt; : &lt;span class=&quot;pc&quot;&gt;false&lt;/span&gt;
  html = &lt;span class=&quot;iv&quot;&gt;@album&lt;/span&gt;.photos[from..to].collect { |photo| 
    &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;&amp;lt;li&amp;gt;&amp;lt;img src='&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;idl&quot;&gt;#{&lt;/span&gt;photo.public_filename(&lt;span class=&quot;sy&quot;&gt;:thumb&lt;/span&gt;)&lt;span class=&quot;idl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;'&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  }

  data = { &lt;span class=&quot;sy&quot;&gt;:html&lt;/span&gt; =&amp;gt; html, &lt;span class=&quot;sy&quot;&gt;:from&lt;/span&gt; =&amp;gt; from, &lt;span class=&quot;sy&quot;&gt;:to&lt;/span&gt; =&amp;gt; to, &lt;span class=&quot;sy&quot;&gt;:more&lt;/span&gt; =&amp;gt; more }

  &lt;span class=&quot;c&quot;&gt;# Rails magick to get output in JSON format&lt;/span&gt;
  render &lt;span class=&quot;sy&quot;&gt;:json&lt;/span&gt; =&amp;gt; data.to_json
&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The last thing we need to do is update our routes file so that the path /albums/:id/elements is recognized by our Rails application. Add the following line to your routes.rb config file:&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;multiline_code&quot;&gt;map.resources &lt;span class=&quot;sy&quot;&gt;:albums&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:member&lt;/span&gt; =&amp;gt; { &lt;span class=&quot;sy&quot;&gt;:elements&lt;/span&gt; =&amp;gt; &lt;span class=&quot;sy&quot;&gt;:get&lt;/span&gt; }&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;After a quick restart of your server (since we updated the routes file) and you should be ready to go!&lt;/p&gt;      <script type="text/javascript">
      var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
      document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
      </script>
      <script type="text/javascript">
      var pageTracker = _gat._getTracker("UA-4701682-1");
      pageTracker._initData();
      pageTracker._trackPageview();
      </script>
</body>
  <created-at type="datetime">2009-02-20T10:04:49Z</created-at>
  <id type="integer">15</id>
  <introduction>&lt;p&gt;I happened to be looking for a better way to show a preview of my web albums when I came across &lt;a href=&quot;http://prototype-ui.com/&quot;&gt;Prototype-UI&lt;/a&gt; which is a suite of user-interface components. Their carousel component was just want I need to spruce up my site design. The only problem was that documentation on the site is quite sparse and it took me a while to get things sorted out.&lt;/p&gt;</introduction>
  <permalink>creating-an-ajax-image-carousel</permalink>
  <title>Creating an AJAX Image Carousel</title>
  <topic-id type="integer">1</topic-id>
  <updated-at type="datetime">2010-01-15T13:17:38Z</updated-at>
  <user-id type="integer">1</user-id>
  <version type="integer">23</version>
</post>
