Over a million developers have joined DZone.

Loading Backbone Views into Lightboxes

· Web Dev Zone

Start coding today to experience the powerful engine that drives data application’s development, brought to you in partnership with Qlik.

y current project involves a client application written using Backbone.js, and the FAQ page will appear in a lightbox. No big deal, right? Unfortunately, it’s not just as simple as it sounds because if you take a naive approach you find that you don’t get any event handling.

The lightbox I’m using in this example is fancyBox – very stable, very well written and very customisable. I highly recommend it!

Demo – to try these three approaches out for yourself, you can check the example app I wrote. You can also download the source code from here.

My first attempt, which seemed quite reasonable at the time, was this:

render: function() {
  this.$el.empty().append(this.template());

  var self = this;
this.$el.fancybox({
    autoDimensions: true,
    autoCenter: true,
    afterClose: function() {
      self.close();
    }
  }
);
}

…and the result was…nothing. No lightbox appeared, and I didn’t even get an error reported in the log. Damn.

Try number two was more of an exploration to check that I can actually open a lightbox from within a Backbone view – it’s always worth confirming the basics when something doesn’t work as expected. With this code, the lightbox opens but no events are handled – you can click until you’re blue in the face, but nothing will happen.

render: function() {
  this.$el.empty().append(this.template());

  var self = this;
$.fancybox(this.$el.html(),{
    autoDimensions: true,
    autoCenter: true,
    afterClose: function() {
      self.close();
    }
  });
}

Progress, at least. Finally, when examining the DOM elements created by fancyBox when the box is open, I found the key to a) a solution and, b), a filthy hack.

<div style="overflow: auto; width: 843px; height: auto;" class="fancybox-inner">

Bingo! I figured the easiest way to achieve success here was to cheat, and it works beautifully. The solution was an evolution of attempt #2, and has a couple of extra steps (highlighted in red below):

render: function() {
  this.$el.empty().append(this.template());

  var self = this;
  $.fancybox(this.$el.html(),{
    autoDimensions: true,
    autoCenter: true,
    afterClose: function() {
      $('#overlayArea').append(self.$el);
      self.close();
    }
  });

  $('.fancybox-inner').empty().append(this.$el);
}

1. The afterClose callback has been updated to re-append the el into the parent. This is done prior to the call to close(), to ensure things are in order.
2. The el is appended to the inner content holder of the lightbox. Because the entire el DOM is moved, all event handlers are still in place.

Note: The lightbox is still created using $.fancybox(this.$el.html()) in order to have it sized correctly.

It’s not the cleanest solution in the world, but if you have a need for opening lightboxes with Backbone components inside – this may come in handy.

Create data driven applications in Qlik’s free and easy to use coding environment, brought to you in partnership with Qlik.

Topics:

Published at DZone with permission of Steve Chaloner, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}