Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Loading Backbone Views into Lightboxes

DZone's Guide to

Loading Backbone Views into Lightboxes

· Web Dev Zone
Free Resource

Learn how to build modern digital experience apps with Crafter CMS. Download this eBook now. Brought to you in partnership with Crafter Software

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.

Crafter is a modern CMS platform for building modern websites and content-rich digital experiences. Download this eBook now. Brought to you in partnership with Crafter Software.

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 DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

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

X

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

{{ parent.tldr }}

{{ parent.urlSource.name }}