domingo 22 de junio de 2008

div lightbox with jQuery

I know there are next to thousands of lightbox versions, including several built over jQuery. But you know, none of them seem to fit your needs ever. This time around I was looking for one that could enhance parts of the page and not specifically images. Thickbox can present inline content (divs or iFrames) but it's not as pretty as others and it has some nasty CSS side effects. In addition it wasn't correctly working in IE6 for some corner cases and the syntax was (somehow) weird.

After a little search I found this plug-in from Leandro Vieira. It resembled the original lightbox plugin but, unfortunately, it was designed to view just images (alone or as a gallery). After realizing I was not going to get what I was looking for without some effort I decided to stick with it and modify it to suit my needs which basically where:
  • Visually attractive
  • HTML, Flash, other jQuery plugins as content
  • Working in FF, IE6+, Safari
  • Working inside a frameset
  • Simple to use (nothing beyond $("#id").lightbox())
Take into account that this is a hack as I wasn't expecting to release it in any form. A good solution would integrate with the original code and not just replace it! So I'm not going to explain the code in detail (or at all) but, for those interested, here are the modifications required:

settings = jQuery.extend({
   ...
   timeout: -1,
   hideOnClickOutside: false,
   alreadyOpened: false
}, settings);

function _initialize() {
   _start(this, jQueryMatchedObj)
   $(document).keydown(function(objEvent) {
      _keyboard_action(objEvent)
   })
   if (settings.timeout != -1)
      setTimeout("$('#lightbox-secNav-btnClose').click()", settings.timeout)
   return false
}

function _start(objClicked,jQueryMatchedObj) {
   if (!settings.alreadyOpened) {
      settings.alreadyOpened = true
      $('embed, object, select').css({ 'visibility' : 'hidden' });
      _set_interface();
      settings.placeHolder = objClicked
      _set_image_to_view();
      $("#lightbox-image object").css("visibility", "visible")
      $("#lightbox-image embed").css("visibility", "visible")
      $("#lightbox-image object embed").css("visibility", "visible")
   }
}

function _set_image_to_view() {
   $('#lightbox-image,
      #lightbox-nav,
      #lightbox-nav-btnPrev,
      #lightbox-nav-btnNext,
      #lightbox-container-image-data-box,
      #lightbox-image-details-currentNumber').hide();
   $(settings.placeHolder).appendTo($("#lightbox-image"))
   elem = $("#lightbox-image")
   _resize_container_image_box(elem.width(), elem.height())
}

The CSS had to be slightly modified as well. And finally (for the lazy ones) here's a sample. It's a WAR file, if you don't have a servlet container available just uncompress and change the paths. To access it in your localhost http://localhost:[8080]/demo/index.jsp (or flash.jsp, frames.jsp, carousel.jsp).