Print Creating an AJAX Image Carousel

Ajaxcleanser_thumb

I happened to be looking for a better way to show a preview of my web albums when I came across Prototype-UI 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.

Although the version of Prototype-UI 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 downloading the code (javascript and css files) from their server. Once you have extracted the files, put the carousel.js and prototype-ui.css in your sites public folder. You can also copy their next/back buttons as well, but I went ahead and created my own.

I am going to assume that you have some model that contains an array of photos. In this example that model is called album. In your view that you want the image carousel, put in the following rhtml:

<div id="horizontal_carousel">
      <div class="previous_button"></div>
      <div class="container">
        <ul><!-- AJAX WILL INSERT PHOTOS --></ul>
        <div id="spinner" style="display: none;">Loading ...<br /></div>
      </div>
      <div class="next_button"></div>
    </div>
    <script type="text/javascript">
 // <![CDATA[
      function runTest() {
        carousel = new UI.Ajax.Carousel("horizontal_carousel",
          {url: "/albums/<%= album.id %>/elements", elementSize: 140})
          .observe("request:started", function() {
                    $('spinner').show().morph("opacity:0.8", {duration:0.5});
            })
          .observe("request:ended", function() {
                    $('spinner').morph("opacity:0",
          {duration:0.5, afterFinish: function(obj) { obj.element.hide(); }});
            });
      }

      document.whenReady(runTest);
    // ]]>
    </script>
</div>

The important thing to notice here is the value of the URL passed to the UI.Ajax.Carousel function call. I have decided to call the method that returns the request images elements. It is found in the album controller and is expecting the id of the album that contains the photos to be displayed.

Next we will update our album’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’s not that hard using some Rails magick.

def elements 
  @album = Album.find(params[:id])

  count = @album.photos.size - 1
  to = [params[:to].to_i, count].min
  from = params[:from].to_i
  more = count != to ? true : false
  html = @album.photos[from..to].collect { |photo| 
    "<li><img src='#{photo.public_filename(:thumb)}'></li>"
  }

  data = { :html => html, :from => from, :to => to, :more => more }

  # Rails magick to get output in JSON format
  render :json => data.to_json
end

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:

map.resources :albums, :member => { :elements => :get }

After a quick restart of your server (since we updated the routes file) and you should be ready to go!

Discuss

Was it good for you, too? Join the discussion »


About the Author

Dcoke_thumb

Michael Petnuch is a graduate student who enjoys walking on his hands, drinking diet coke, solving math problems, programming and being silly.