Making a simple image gallery using Builder

Posted by Eric Artzt Mon, 09 Jun 2008 05:29:00 GMT

I wanted to create a project gallery for myself. Typo supports Lightbox-style galleries, but I wanted something simpler - a simple scrolling list of thumbnails that when clicked, would update a larger gallery photo on the page without going to a modal overlay. I decided to build a gallery using some unobtrusive Javascript techniques employing Builder and a simple Scriptaculous fade-in. You can view my completed javascript include here.

The markup for the galleries is simple: a div wrapper containing an unordered list of links to images. My markup code looks like this:

<div class="bb_gallery">
  <ul>
    <li>
      <a href="path_to_full_image"><img src="path_to_thumbnail"/></a>
      <p>Caption text</p>
    </li>
    ... more list items ...
  </ul>
</div>

Without the Javascript, the gallery renders as a scrolling UL of thumbnail images. Each thumbnail is linked to its full-size version. The Javascript init routine runs when the layout finishes loading, called via Prototype’s dom:loaded event:

document.observe("dom:loaded", function() {
  McArtzt.Gallery.init();
});

The init() function iterates through all the bbGallery divs and inserts some additional markup for the gallery image. The completed markup for the gallery looks like this:

<div class="bb_gallery">
  <div class="bb_show">
    <div class="caption">Caption text</div>
    <div class="last"><img class="last" src="path_to_previous_gallery_image_or_spacer"/></div>
    <div class="current"><img class="current" src="path_to_current_gallery_image"/></div>
  </div>
  <ul>
    ... same as before
  </ul>
</div>

The init() also sets an event handler on each thumbnail link so that when clicked, it will swap out the gallery image with the clicked image:

anchors.each(function(a){a.observe('click', McArtzt.Gallery.click);});

The current and last images are both positioned absolute, so current overlays last. Additionally, the current div enclosing the current image has a spinner background graphic that shows while the image is being retrieved from my webserver. Once the image is loaded, the background spinner is hidden.

On init(), I also insert an onload event handler on the current image - when the image finishes loading, the callback function uses a Scriptaculous fade-in to reveal the current image over the last image. I bound the event handler to the current gallery image. This is necessary because the event passed to the event handler is attached to the document object, which does not help me determine which image to fade in.

Getting the observe to work, I encountered some cross-browser difficulties. Firefox and Safari on the Mac worked well with the following statement:

// imgCurrent is a Builder node
imgCurrent.observe('load',McArtzt.Gallery.loaded.bind(imgCurrent));

Internet Explorer 7 could not deal. I’m not exactly sure why, but I suspect that on IE, the builder node is not automatically hooked into the Element extended methods added by Prototype. Wrapping the builder node reference as follows fixed that:

$(imgCurrent).observe('load',McArtzt.Gallery.loaded.bind(imgCurrent));

The event handler is simple:

loaded : function(event) { 
  // this refers to the bound gallery image (imgCurrent from above)
  new Effect.Appear(this,{duration:1.0});
}

There are some good discussions of binding at the following links. I find this aspect of Javascript development really interesting (and challenging).


Baby Talk: interview with Michelle McKelvey

Posted by Eric Artzt Sun, 01 Jun 2008 16:38:00 GMT


Fixtures in Rails 2

Posted by Eric Artzt Wed, 21 May 2008 06:37:00 GMT

As part of my attempts to upgrade tinySIS to Rails 2, I am updating the test fixtures. I am starting with a basic set of fixtures to cover subject areas, contracts, users, enrollments, and settings. I’ll expand this fixture set later, but the goal right now is to get a test database up and limping so I can write a basic set of functional smoke-tests to verify the app before I deploy. Kind of sad, as the app has been in production for almost two school years now - and despite the lack of automated testing, it’s quite stable - but I am trying to move it in the 20th century.

I found a couple good resources on the new fixtures stuff:

Thanks, Ryans.

I won’t reiterate the great info in the above postings. I will just show you excerpts from my starter fixture set. I started by dumping my old test database to yml (the database was created using fixture_scenarios, which I did get to somewhat-work under Rails 2 but decided to go with the native Rails fixtures instead).

My mythological school is kind of inbred.


Functional shared Google calendars

Posted by Eric Artzt Wed, 14 May 2008 17:13:00 GMT

The Google Embeddable Calendar Helper rocks. You can create multiple Google calenders under your account and create one merged calender view showing all of them. We created a shared calendar for Church of the Resurrection, Hosanna Assemblea de Dios, and Holy Apostles church here:

http://resurrectionbellevue.org/happening/calendar

You can color code the various calenders. The view provides a drop-down selector where users can pick which calenders to display – and a “save as” feature off the print button that creates a PDF. Nice.


Rails on Dreamhost

Posted by Eric Artzt Tue, 13 May 2008 04:48:00 GMT

Dreamhost just rolled out Passenger / mod_rails — a simplified way to run Rails apps on Dreamhost shared servers. Here are my notes on setting up a nice Dreamhost environment for your Rails app. I use a separate user for each Rails app. My apps run pretty well. They are not fast to boot up, but once running, they are reasonably snappy - I don’t host any high traffic sites on my shared domains.

One lovely thing about mod_rails - when your app is screwed up and won’t boot, you get a helpful error screen with a Rails stack trace. Huge.