Life as Clay

Posts Tagged ‘ColorBox

Using Colorbox with Rails 3.1

with 2 comments

I’m in the midst of creating a mini-Facebook like Rails app that I can use to track events in my daughter’s life. Part of that includes the ability to attach photos to events. I wanted to use a friendly modal popup for displaying larger versions of photos, so I elected to go with ColorBox. It’s a jQuery plugin that is dead simple to use, especially on static pages.

For the “timeline” page, a dynamic page, I never know whether there will be photos to display and if there are, how they are grouped. The idea is that photos that are attached to the same event should all be part of one gallery.

Here’s what I did…

Anything that can end up on the timeline is a “mark” in my app. I use a partial when iterating through the marks to display photos that may be associated with the mark. Here is that partial:

<% if mark.images.count > 0 %>
	<div class="mark_images">
		<% for image in mark.images %>
				<a href="<%= image.pic(:large) %>" class="gallery_<%= mark.id %>" title="<%= image.caption %>"><%= image_tag(image.pic(:tiny), :title => image.caption, :class => "mark_image") %></a>
		<% end%>
	</div>
<% end %>

As you can see, I’m using thumbnail images as links. The images, by the way, are attached using the Paperclip gem from thoughtbot. The code above sets up the HTML that ColorBox needs in order to display the modal.

The rest of the work comes in javascript. I elected to put the ColorBox javascript at the end of my application.js file. It looks like this:

$(document).ready(function() {
	galleries = [];
	$('a[class^="gallery_"]').each( function() {
		if ($.inArray($(this).attr("class"), galleries) == -1) {
			$(this).colorbox({
				rel: $(this).attr("class"),
				maxWidth: "95%",
				maxHeight: "95%"
			});
			galleries.push($(this).attr("class"));
		}
	});
});

Here I create an empty array called galleries. I then find all link elements on the page that have a class that begins with “gallery_“. I iterate on each of them. If the class of the element is not in the galleries array, then I set up ColorBox for that class (gallery) and I add the class name to the galleries array so that I know not to set it up again.

Finally, I use the class of the gallery to relate the images that share the same class together, so that I get the navigational buttons on the modal viewbox.

To make this all work, you have to drop the ColorBox .js file into your assets/javascripts directory and you need to include both the .css file that you prefer (from the ColorBox downloadable examples) and the images that accompany it. I chose to use example 3. I had to modify the css image paths so that it would locate the ColorBox images in my assets/images directory. I elected to rename the enclosing folder to colorbox_images. The css file I ended up with looks like this:

/*
    ColorBox Core Style:
    The following CSS is consistent between example themes and should not be altered.
*/
#colorbox, #cboxOverlay, #cboxWrapper{position:absolute; top:0; left:0; z-index:9999; overflow:hidden;}
#cboxOverlay{position:fixed; width:100%; height:100%;}
#cboxMiddleLeft, #cboxBottomLeft{clear:left;}
#cboxContent{position:relative;}
#cboxLoadedContent{overflow:auto;}
#cboxTitle{margin:0;}
#cboxLoadingOverlay, #cboxLoadingGraphic{position:absolute; top:0; left:0; width:100%;}
#cboxPrevious, #cboxNext, #cboxClose, #cboxSlideshow{cursor:pointer;}
.cboxPhoto{float:left; margin:auto; border:0; display:block;}
.cboxIframe{width:100%; height:100%; display:block; border:0;}

/*
    User Style:
    Change the following styles to modify the appearance of ColorBox.  They are
    ordered & tabbed in a way that represents the nesting of the generated HTML.
*/
#cboxOverlay{background:#000;}
#colorbox{}
    #cboxContent{margin-top:20px;margin-bottom:20px}
        .cboxIframe{background:#fff;}
        #cboxError{padding:50px; border:1px solid #ccc;}
        #cboxLoadedContent{border:5px solid #000; background:#fff;}
        #cboxTitle{position:absolute; bottom:-15px; left:0; color:#ccc;}
        #cboxCurrent{position:absolute; top:-20px; right:0px; color:#ccc;}
        #cboxSlideshow{position:absolute; top:-20px; right:90px; color:#fff;}
        #cboxPrevious{position:absolute; top:50%; left:5px; margin-top:-32px; background:url(/assets/colorbox_images/controls.png) no-repeat top left; width:28px; height:65px; text-indent:-9999px;}
        #cboxPrevious:hover{background-position:bottom left;}
        #cboxNext{position:absolute; top:50%; right:5px; margin-top:-32px; background:url(/assets/colorbox_images/controls.png) no-repeat top right; width:28px; height:65px; text-indent:-9999px;}
        #cboxNext:hover{background-position:bottom right;}
        #cboxLoadingOverlay{background:#000;}
        #cboxLoadingGraphic{background:url(/assets/colorbox_images/loading.gif) no-repeat center center;}
        #cboxClose{position:absolute; top:5px; right:5px; display:block; background:url(/assets/colorbox_images/controls.png) no-repeat top center; width:38px; height:19px; text-indent:-9999px;}
        #cboxClose:hover{background-position:bottom center;}

I also chose to move the title to the bottom of the image because that way, it doesn’t bump up against the image count when viewed on a mobile device. That required setting a bottom margin for #cboxContent and changing this line: #cboxTitle{position:absolute; bottom:-15px; left:0; color:#ccc;}.

There are a variety of other options that can be used with the javascript call to alter the modal dialogue. It’s worth taking a look at the ColorBox page for some examples.

Overall, I’m really happy with this solution and probably will use it again in the future. If you’re interested in the app that I’m developing, you can find it on github, called Blytheline. It’s an early work in progress, so it’s a bit rough around the edges!

Written by Clay

November 29, 2011 at 12:53